diff --git a/native/DriftFX/CMakeLists.txt b/native/DriftFX/CMakeLists.txt index d4cfa5f..558dcd4 100644 --- a/native/DriftFX/CMakeLists.txt +++ b/native/DriftFX/CMakeLists.txt @@ -24,6 +24,7 @@ set(DriftFX-Headers set(DriftFX-Sources src/Context.cpp src/JNINativeSurface.cpp + src/NativeSurface.h src/NativeSurface.cpp src/NativeSurfaceAPI.cpp src/NativeSurfaceRegistry.cpp diff --git a/native/DriftFX/src/JNINativeSurface.cpp b/native/DriftFX/src/JNINativeSurface.cpp index 05b528d..3115f6a 100644 --- a/native/DriftFX/src/JNINativeSurface.cpp +++ b/native/DriftFX/src/JNINativeSurface.cpp @@ -66,7 +66,7 @@ void JNINativeSurface::Initialize() { jFrameDataClass = ResolveClass(env, "org/eclipse/fx/drift/internal/JNINativeSurface$FrameData"); jNativeSurface_Present2Method = ResolveMethod(env, jNativeSurfaceClass, "present", "(Lorg/eclipse/fx/drift/internal/JNINativeSurface$FrameData;)V"); - jNativeSurface_Present3Method = ResolveMethod(env, jNativeSurfaceClass, "present", "(JJIII)V"); + jNativeSurface_Present3Method = ResolveMethod(env, jNativeSurfaceClass, "present", "(JJJIII)V"); jFrameData_d3dShareHandleField = ResolveField(env, jFrameDataClass, "d3dShareHandle", "J"); jFrameData_widthField = ResolveField(env, jFrameDataClass, "width", "I"); @@ -95,7 +95,7 @@ void JNINativeSurface::Present(FrameData frameData) { LogDebug("going to call present") JNIEnv *env = JNIHelper::GetJNIEnv(true); - env->CallVoidMethod(jNativeSurfaceInstance, jNativeSurface_Present3Method, frameData.d3dSharedHandle, frameData.ioSurfaceHandle, frameData.glTextureName, frameData.width, frameData.height); + env->CallVoidMethod(jNativeSurfaceInstance, jNativeSurface_Present3Method, frameData.id, frameData.d3dSharedHandle, frameData.ioSurfaceHandle, frameData.glTextureName, frameData.width, frameData.height); // LogDebug("got jni env: " << env) // // jobject instance = env->NewObject(jFrameDataClass, jFrameData_constructor); diff --git a/native/DriftFX/src/NativeSurface.cpp b/native/DriftFX/src/NativeSurface.cpp index 7f24cec..d259b9b 100644 --- a/native/DriftFX/src/NativeSurface.cpp +++ b/native/DriftFX/src/NativeSurface.cpp @@ -27,9 +27,7 @@ using namespace driftfx::internal::prism; NativeSurface::NativeSurface(JNINativeSurface* api) : api(api), - context(nullptr), - lastPresented(nullptr), - toDispose(nullptr) { + context(nullptr) { LogDebug("NativeSurface constructor") } @@ -43,14 +41,30 @@ void NativeSurface::Initialize() { context = PrismBridge::Get()->GetDefaultContext()->CreateSharedContext(); } -void NativeSurface::Cleanup() { +void NativeSurface::DisposeSharedTexture(long long id) { + toDisposeMutex.lock(); + SharedTexture* texture = (SharedTexture*) id; + toDispose.push_back(texture); - LogDebug("clean textures"); - if (toDispose != nullptr) { - delete toDispose; - toDispose = nullptr; + toDisposeMutex.unlock(); +} + +void NativeSurface::DisposeSharedTextures() { + LogDebug("Disposing shared textures"); + toDisposeMutex.lock(); + for (std::vector::iterator it = toDispose.begin(); it != toDispose.end(); ++it) { + SharedTexture* tex = (*it); + LogDebug(" - " << tex); + delete tex; } + toDispose.clear(); + toDisposeMutex.unlock(); +} + +void NativeSurface::Cleanup() { + LogDebug("clean textures"); + DisposeSharedTextures(); // // TODO send some kind of signal to tell FX we are going to dispose our textures FrameData* frameData = new FrameData(); @@ -66,11 +80,6 @@ void NativeSurface::Cleanup() { // NOTE: since textures know their context and set it current upon deletion // we must ensure that all textures from a context are deleted before the context is deleted! - if (lastPresented != nullptr) { - delete lastPresented; - lastPresented = nullptr; - } - LogDebug("clean GLContext"); delete context; context = nullptr; @@ -100,10 +109,7 @@ RenderTarget* NativeSurface::Acquire() { RenderTarget* NativeSurface::Acquire(unsigned int width, unsigned int height) { LogDebug("acquire0"); - if (toDispose != nullptr) { - delete toDispose; - toDispose = nullptr; - } + DisposeSharedTextures(); PrismBridge* bridge = PrismBridge::Get(); // in case the system was destroyed @@ -139,9 +145,6 @@ void NativeSurface::Present(RenderTarget* target, PresentationHint hint) { api->Present(*frameData); delete frameData; - - toDispose = lastPresented; - lastPresented = texture; } Context* NativeSurface::GetFxContext() { diff --git a/native/DriftFX/src/NativeSurface.h b/native/DriftFX/src/NativeSurface.h index 6c16ffa..0f7aade 100644 --- a/native/DriftFX/src/NativeSurface.h +++ b/native/DriftFX/src/NativeSurface.h @@ -17,6 +17,9 @@ #include #include +#include +#include + #include "JNINativeSurface.h" namespace driftfx { @@ -79,6 +82,8 @@ class NativeSurface : public DriftFXSurface { */ virtual void UpdateSize(int width, int height); + virtual void DisposeSharedTexture(long long id); + static NativeSurface* Create(JNINativeSurface* api); virtual Context* GetFxContext(); @@ -93,10 +98,14 @@ class NativeSurface : public DriftFXSurface { volatile unsigned int width; volatile unsigned int height; + + private: - SharedTexture* lastPresented; - SharedTexture* toDispose; + std::mutex toDisposeMutex; + std::vector toDispose; + + void DisposeSharedTextures(); }; } diff --git a/native/DriftFX/src/NativeSurfaceAPI.cpp b/native/DriftFX/src/NativeSurfaceAPI.cpp index 2dde4f1..731247c 100644 --- a/native/DriftFX/src/NativeSurfaceAPI.cpp +++ b/native/DriftFX/src/NativeSurfaceAPI.cpp @@ -57,3 +57,10 @@ extern "C" JNIEXPORT void JNICALL Java_org_eclipse_fx_drift_internal_NativeAPI_n } +extern "C" JNIEXPORT void JNICALL Java_org_eclipse_fx_drift_internal_NativeAPI_nDisposeFrameData(JNIEnv* env, jclass cls, jlong surfaceId, jlong frameDataId) { + LogDebug("dispose frame data " << surfaceId << ": " << frameDataId); + NativeSurface* surface = NativeSurfaceRegistry::Get()->Get((long) surfaceId); + surface->DisposeSharedTexture((long long) frameDataId); +} + + diff --git a/native/DriftFX/src/SharedTexture.h b/native/DriftFX/src/SharedTexture.h index 293a07f..c7e6116 100644 --- a/native/DriftFX/src/SharedTexture.h +++ b/native/DriftFX/src/SharedTexture.h @@ -25,8 +25,9 @@ using namespace gl; namespace internal { struct FrameData { - long d3dSharedHandle; - long ioSurfaceHandle; + long long id; + long long d3dSharedHandle; + long long ioSurfaceHandle; int glTextureName; int width; int height; diff --git a/native/DriftFX/src/prism/d3d/D3DSharedTexture.cpp b/native/DriftFX/src/prism/d3d/D3DSharedTexture.cpp index b0dde0a..321e407 100644 --- a/native/DriftFX/src/prism/d3d/D3DSharedTexture.cpp +++ b/native/DriftFX/src/prism/d3d/D3DSharedTexture.cpp @@ -161,7 +161,8 @@ bool D3DSharedTexture::Unlock() { FrameData* D3DSharedTexture::CreateFrameData() { FrameData* data = new FrameData(); - data->d3dSharedHandle = (long) (long long) d3dTexture->GetShareHandle(); + data->id = (long long) this; + data->d3dSharedHandle = (long long) d3dTexture->GetShareHandle(); data->height = GetHeight(); data->width = GetWidth(); return data; diff --git a/native/DriftFX/src/prism/es2/cgl/IOSurfaceSharedTexture.cpp b/native/DriftFX/src/prism/es2/cgl/IOSurfaceSharedTexture.cpp index e9decd2..24e9acf 100644 --- a/native/DriftFX/src/prism/es2/cgl/IOSurfaceSharedTexture.cpp +++ b/native/DriftFX/src/prism/es2/cgl/IOSurfaceSharedTexture.cpp @@ -160,6 +160,7 @@ bool IOSurfaceSharedTexture::Unlock() { FrameData* IOSurfaceSharedTexture::CreateFrameData() { FrameData* data = new FrameData(); + data->id = (long long) this; data->width = GetWidth(); data->height = GetHeight(); data->glTextureName = fxTexture->Name(); diff --git a/native/DriftFX/src/prism/es2/glx/GLXSharedTexture.cpp b/native/DriftFX/src/prism/es2/glx/GLXSharedTexture.cpp index 10a0cd2..0531a11 100644 --- a/native/DriftFX/src/prism/es2/glx/GLXSharedTexture.cpp +++ b/native/DriftFX/src/prism/es2/glx/GLXSharedTexture.cpp @@ -69,6 +69,7 @@ FrameData* GLXSharedTexture::CreateFrameData() { FrameData* data = new FrameData(); + data->id = (long long) this; data->width = GetWidth(); data->height = GetHeight(); data->glTextureName = glTexture->Name(); diff --git a/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/impl/NGDriftFXSurface.java b/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/impl/NGDriftFXSurface.java index 8b537f1..90a0d53 100644 --- a/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/impl/NGDriftFXSurface.java +++ b/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/impl/NGDriftFXSurface.java @@ -47,7 +47,15 @@ public class NGDriftFXSurface extends NGNode { private Texture currentTexture; public void present(FrameData frame) { + FrameData oldData = currentFrameData; currentFrameData = frame; + if (oldData != null) { + dispose(oldData); + } + } + + private void dispose(FrameData frame) { + NativeAPI.disposeFrameData(nativeSurfaceHandle, frame); } public NGDriftFXSurface(DriftFXSurface node, long nativeSurfaceId) { diff --git a/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/JNINativeSurface.java b/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/JNINativeSurface.java index 577d39d..19e1588 100644 --- a/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/JNINativeSurface.java +++ b/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/JNINativeSurface.java @@ -15,6 +15,8 @@ public class JNINativeSurface { public static class FrameData { + public long frameId; + public long d3dShareHandle; public long ioSurfaceHandle; public int width; @@ -69,8 +71,9 @@ public JNINativeSurface(Consumer presentFrame) { this.presentFrame = presentFrame; } - public void present(long handle, long ioSurfaceHandle, int textureName, int width, int height) { + public void present(long id, long handle, long ioSurfaceHandle, int textureName, int width, int height) { FrameData dat = new FrameData(); + dat.frameId = id; dat.d3dShareHandle = handle; dat.ioSurfaceHandle = ioSurfaceHandle; dat.textureName = textureName; diff --git a/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/NativeAPI.java b/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/NativeAPI.java index 5bfef84..d9d9af1 100644 --- a/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/NativeAPI.java +++ b/org.eclipse.fx.drift/src/main/java/org/eclipse/fx/drift/internal/NativeAPI.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.fx.drift.internal; +import org.eclipse.fx.drift.internal.JNINativeSurface.FrameData; + import com.sun.prism.Texture; //Note: this implementation is against internal JavafX API @@ -81,6 +83,11 @@ public static void Destroy() { nDestroy(); } + private static native void nDisposeFrameData(long nativeSurfaceHandle, long frameDataId); + public static void disposeFrameData(long nativeSurfaceHandle, FrameData frameData) { + nDisposeFrameData(nativeSurfaceHandle, frameData.frameId); + } + private static native long nCreateNativeSurface(JNINativeSurface surface); public static long createNativeSurface(JNINativeSurface surface) { return nCreateNativeSurface(surface);