Bug 1367287 - Reference count GeckoSurfaceTexture r=jchen
authorJames Willcox <snorp@snorp.net>
Thu, 01 Jun 2017 12:12:55 -0500
changeset 410154 a8bfe68a333f2e3afea9c161f7cd00185f8da83b
parent 410153 b785a2a0cf1682682b13f7f11e74b7531cb610c8
child 410155 4448cfe7eed15f56957979a2fa4c1f2a1fc69185
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjchen
bugs1367287
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1367287 - Reference count GeckoSurfaceTexture r=jchen MozReview-Commit-ID: 1JJVzCmANyH
gfx/layers/opengl/TextureHostOGL.cpp
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurfaceTexture.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SurfaceAllocatorService.java
widget/android/GeneratedJNIWrappers.cpp
widget/android/GeneratedJNIWrappers.h
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -416,20 +416,26 @@ SurfaceTextureHost::SurfaceTextureHost(T
                                        bool aContinuousUpdate)
   : TextureHost(aFlags)
   , mSurfTex(aSurfTex)
   , mSize(aSize)
   , mContinuousUpdate(aContinuousUpdate)
 {
   // Continuous update makes no sense with single buffer mode
   MOZ_ASSERT(!mSurfTex->IsSingleBuffer() || !mContinuousUpdate);
+
+  mSurfTex->IncrementUse();
 }
 
 SurfaceTextureHost::~SurfaceTextureHost()
 {
+  if (mSurfTex) {
+    mSurfTex->DecrementUse();
+    mSurfTex = nullptr;
+  }
 }
 
 void
 SurfaceTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
 {
   GLContext* gl = this->gl();
   if (!gl || !gl->MakeCurrent()) {
     return;
@@ -511,17 +517,21 @@ SurfaceTextureHost::GetFormat() const
 }
 
 void
 SurfaceTextureHost::DeallocateDeviceData()
 {
   if (mTextureSource) {
     mTextureSource->DeallocateDeviceData();
   }
-  mSurfTex = nullptr;
+
+  if (mSurfTex) {
+    mSurfTex->DecrementUse();
+    mSurfTex = nullptr;
+  }
 }
 
 #endif // MOZ_WIDGET_ANDROID
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 // EGLImage
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurfaceTexture.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurfaceTexture.java
@@ -17,16 +17,17 @@ public final class GeckoSurfaceTexture e
     private static final String LOGTAG = "GeckoSurfaceTexture";
     private static volatile int sNextHandle = 1;
     private static HashMap<Integer, GeckoSurfaceTexture> sSurfaceTextures = new HashMap<Integer, GeckoSurfaceTexture>();
 
     private int mHandle;
     private boolean mIsSingleBuffer;
     private int mTexName;
     private GeckoSurfaceTexture.Callbacks mListener;
+    private volatile int mUseCount = 1;
 
     @WrapForJNI(dispatchTo = "current")
     private static native int nativeAcquireTexture();
 
     private GeckoSurfaceTexture(int handle, int texName) {
         super(texName);
         mHandle = handle;
         mIsSingleBuffer = false;
@@ -81,16 +82,40 @@ public final class GeckoSurfaceTexture e
         mListener = listener;
     }
 
     @WrapForJNI
     public static boolean isSingleBufferSupported() {
         return Versions.feature19Plus;
     }
 
+    @WrapForJNI
+    public void incrementUse() {
+        mUseCount++;
+    }
+
+    @WrapForJNI
+    public void decrementUse() {
+        mUseCount--;
+
+        if (mUseCount == 0) {
+            synchronized (sSurfaceTextures) {
+                sSurfaceTextures.remove(mHandle);
+            }
+
+            setListener(null);
+
+            if (Versions.feature16Plus) {
+                detachFromGLContext();
+            }
+
+            release();
+        }
+    }
+
     public static GeckoSurfaceTexture acquire(boolean singleBufferMode) {
         if (singleBufferMode && !isSingleBufferSupported()) {
             throw new IllegalArgumentException("single buffer mode not supported on API version < 19");
         }
 
         int handle = sNextHandle++;
         int texName = nativeAcquireTexture();
 
@@ -109,28 +134,16 @@ public final class GeckoSurfaceTexture e
 
             sSurfaceTextures.put(handle, gst);
         }
 
 
         return gst;
     }
 
-    public static void dispose(int handle) {
-        final GeckoSurfaceTexture gst;
-        synchronized (sSurfaceTextures) {
-            gst = sSurfaceTextures.remove(handle);
-        }
-
-        if (gst != null) {
-            gst.setListener(null);
-            gst.release();
-        }
-    }
-
     @WrapForJNI
     public static GeckoSurfaceTexture lookup(int handle) {
         synchronized (sSurfaceTextures) {
             return sSurfaceTextures.get(handle);
         }
     }
 
     public interface Callbacks {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SurfaceAllocatorService.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SurfaceAllocatorService.java
@@ -26,17 +26,20 @@ public class SurfaceAllocatorService ext
             if (width > 0 && height > 0) {
                 gst.setDefaultBufferSize(width, height);
             }
 
             return new GeckoSurface(gst);
         }
 
         public void releaseSurface(int handle) {
-            GeckoSurfaceTexture.dispose(handle);
+            final GeckoSurfaceTexture gst = GeckoSurfaceTexture.lookup(handle);
+            if (gst != null) {
+                gst.decrementUse();
+            }
         }
     };
 
     public IBinder onBind(final Intent intent) {
         return mBinder;
     }
 
     public boolean onUnbind(Intent intent) {
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -1097,32 +1097,48 @@ constexpr char GeckoSurface::SetAvailabl
 auto GeckoSurface::SetAvailable(bool a0) const -> void
 {
     return mozilla::jni::Method<SetAvailable_t>::Call(GeckoSurface::mCtx, nullptr, a0);
 }
 
 const char GeckoSurfaceTexture::name[] =
         "org/mozilla/gecko/gfx/GeckoSurfaceTexture";
 
+constexpr char GeckoSurfaceTexture::DecrementUse_t::name[];
+constexpr char GeckoSurfaceTexture::DecrementUse_t::signature[];
+
+auto GeckoSurfaceTexture::DecrementUse() const -> void
+{
+    return mozilla::jni::Method<DecrementUse_t>::Call(GeckoSurfaceTexture::mCtx, nullptr);
+}
+
 constexpr char GeckoSurfaceTexture::GetHandle_t::name[];
 constexpr char GeckoSurfaceTexture::GetHandle_t::signature[];
 
 auto GeckoSurfaceTexture::GetHandle() const -> int32_t
 {
     return mozilla::jni::Method<GetHandle_t>::Call(GeckoSurfaceTexture::mCtx, nullptr);
 }
 
 constexpr char GeckoSurfaceTexture::GetTexName_t::name[];
 constexpr char GeckoSurfaceTexture::GetTexName_t::signature[];
 
 auto GeckoSurfaceTexture::GetTexName() const -> int32_t
 {
     return mozilla::jni::Method<GetTexName_t>::Call(GeckoSurfaceTexture::mCtx, nullptr);
 }
 
+constexpr char GeckoSurfaceTexture::IncrementUse_t::name[];
+constexpr char GeckoSurfaceTexture::IncrementUse_t::signature[];
+
+auto GeckoSurfaceTexture::IncrementUse() const -> void
+{
+    return mozilla::jni::Method<IncrementUse_t>::Call(GeckoSurfaceTexture::mCtx, nullptr);
+}
+
 constexpr char GeckoSurfaceTexture::IsSingleBuffer_t::name[];
 constexpr char GeckoSurfaceTexture::IsSingleBuffer_t::signature[];
 
 auto GeckoSurfaceTexture::IsSingleBuffer() const -> bool
 {
     return mozilla::jni::Method<IsSingleBuffer_t>::Call(GeckoSurfaceTexture::mCtx, nullptr);
 }
 
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -3423,16 +3423,35 @@ public:
 
 class GeckoSurfaceTexture : public mozilla::jni::ObjectBase<GeckoSurfaceTexture>
 {
 public:
     static const char name[];
 
     explicit GeckoSurfaceTexture(const Context& ctx) : ObjectBase<GeckoSurfaceTexture>(ctx) {}
 
+    struct DecrementUse_t {
+        typedef GeckoSurfaceTexture Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "decrementUse";
+        static constexpr char signature[] =
+                "()V";
+        static const bool isStatic = false;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    auto DecrementUse() const -> void;
+
     struct GetHandle_t {
         typedef GeckoSurfaceTexture Owner;
         typedef int32_t ReturnType;
         typedef int32_t SetterType;
         typedef mozilla::jni::Args<> Args;
         static constexpr char name[] = "getHandle";
         static constexpr char signature[] =
                 "()I";
@@ -3461,16 +3480,35 @@ public:
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::ANY;
         static const mozilla::jni::DispatchTarget dispatchTarget =
                 mozilla::jni::DispatchTarget::CURRENT;
     };
 
     auto GetTexName() const -> int32_t;
 
+    struct IncrementUse_t {
+        typedef GeckoSurfaceTexture Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "incrementUse";
+        static constexpr char signature[] =
+                "()V";
+        static const bool isStatic = false;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    auto IncrementUse() const -> void;
+
     struct IsSingleBuffer_t {
         typedef GeckoSurfaceTexture Owner;
         typedef bool ReturnType;
         typedef bool SetterType;
         typedef mozilla::jni::Args<> Args;
         static constexpr char name[] = "isSingleBuffer";
         static constexpr char signature[] =
                 "()Z";