Bug 1395497 - Create SurfaceTexture in detached state, attach on first use r=jgilbert draft
authorJames Willcox <snorp@snorp.net>
Wed, 27 Sep 2017 18:13:46 -0500
changeset 672659 005f7929279f81615895ba7886826926bb1dda14
parent 672593 cd9c8c48e4b3ded47a776f757008f3dcf570c59c
child 672660 e1deac0b9b0fa4619901f6f8b3479f83fed94a84
push id82325
push userbmo:snorp@snorp.net
push dateFri, 29 Sep 2017 15:30:39 +0000
reviewersjgilbert
bugs1395497
milestone58.0a1
Bug 1395497 - Create SurfaceTexture in detached state, attach on first use r=jgilbert MozReview-Commit-ID: HfkEUH9aiBo
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TexturePoolOGL.cpp
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurfaceTexture.java
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -481,16 +481,24 @@ SurfaceTextureHost::Lock()
     mTextureSource = new SurfaceTextureSource(mProvider,
                                               mSurfTex,
                                               format,
                                               target,
                                               wrapMode,
                                               mSize);
   }
 
+  if (!mSurfTex->IsAttachedToGLContext((int64_t)gl)) {
+    GLuint texName;
+    gl->fGenTextures(1, &texName);
+    if (NS_FAILED(mSurfTex->AttachToGLContext((int64_t)gl, texName))) {
+      return false;
+    }
+  }
+
   return true;
 }
 
 void
 SurfaceTextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
 {
   if (mProvider != aProvider) {
     if (!aProvider || !aProvider->GetGLContext()) {
--- a/gfx/layers/opengl/TexturePoolOGL.cpp
+++ b/gfx/layers/opengl/TexturePoolOGL.cpp
@@ -8,20 +8,16 @@
 #include "mozilla/Logging.h"
 #include "mozilla/Monitor.h"            // for Monitor, MonitorAutoLock
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "mozilla/layers/CompositorThread.h"
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_ERROR, etc
 #include "nsDeque.h"                    // for nsDeque
 #include "nsThreadUtils.h"
 
-#ifdef MOZ_WIDGET_ANDROID
-#include "GeneratedJNINatives.h"
-#endif
-
 static const unsigned int TEXTURE_POOL_SIZE = 10;
 static const unsigned int TEXTURE_REFILL_THRESHOLD = TEXTURE_POOL_SIZE / 2;
 
 static mozilla::LazyLogModule gTexturePoolLog("TexturePoolOGL");
 #define LOG(arg, ...) MOZ_LOG(gTexturePoolLog, mozilla::LogLevel::Debug, ("TexturePoolOGL::%s: " arg, __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 namespace gl {
@@ -35,29 +31,16 @@ enum class PoolState : uint8_t {
   NOT_INITIALIZE,
   INITIALIZED,
   SHUTDOWN
 };
 static PoolState sPoolState = PoolState::NOT_INITIALIZE;
 
 static bool sHasPendingFillTask = false;
 
-#ifdef MOZ_WIDGET_ANDROID
-
-class GeckoSurfaceTextureSupport final
-    : public java::GeckoSurfaceTexture::Natives<GeckoSurfaceTextureSupport>
-{
-public:
-  static int32_t NativeAcquireTexture() {
-    return TexturePoolOGL::AcquireTexture();
-  }
-};
-
-#endif // MOZ_WIDGET_ANDROID
-
 void TexturePoolOGL::MaybeFillTextures()
 {
   if (sTextures->GetSize() < TEXTURE_REFILL_THRESHOLD &&
       !sHasPendingFillTask) {
     LOG("need to refill the texture pool.");
     sHasPendingFillTask = true;
     MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
     MOZ_ASSERT(loop);
@@ -165,21 +148,16 @@ GLContext* TexturePoolOGL::GetGLContext(
 }
 
 void TexturePoolOGL::Init()
 {
   MOZ_ASSERT(sPoolState != PoolState::INITIALIZED);
   sMonitor = new Monitor("TexturePoolOGL.sMonitor");
   sTextures = new nsDeque();
 
-#ifdef MOZ_WIDGET_ANDROID
-  if (jni::IsAvailable()) {
-    GeckoSurfaceTextureSupport::Init();
-  }
-#endif
   sPoolState = PoolState::INITIALIZED;
 }
 
 void TexturePoolOGL::Shutdown()
 {
   MOZ_ASSERT(sPoolState == PoolState::INITIALIZED);
   sPoolState = PoolState::SHUTDOWN;
   delete sMonitor;
--- 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
@@ -16,50 +16,77 @@ import org.mozilla.gecko.AppConstants.Ve
 
 public final class GeckoSurfaceTexture extends SurfaceTexture {
     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 long mAttachedContext;
     private int mTexName;
+
     private GeckoSurfaceTexture.Callbacks mListener;
     private AtomicInteger mUseCount;
 
-    @WrapForJNI(dispatchTo = "current")
-    private static native int nativeAcquireTexture();
-
-    private GeckoSurfaceTexture(int handle, int texName) {
-        super(texName);
-        init(handle, texName, false);
+    private GeckoSurfaceTexture(int handle) {
+        super(0);
+        init(handle, false);
     }
 
-    private GeckoSurfaceTexture(int handle, int texName, boolean singleBufferMode) {
-        super(texName, singleBufferMode);
-        init(handle, texName, singleBufferMode);
+    private GeckoSurfaceTexture(int handle, boolean singleBufferMode) {
+        super(0, singleBufferMode);
+        init(handle, singleBufferMode);
     }
 
-    private void init(int handle, int texName, boolean singleBufferMode) {
+    private void init(int handle, boolean singleBufferMode) {
         mHandle = handle;
         mIsSingleBuffer = singleBufferMode;
-        mTexName = texName;
         mUseCount = new AtomicInteger(1);
+
+        // Start off detached
+        detachFromGLContext();
     }
 
     @WrapForJNI
     public int getHandle() {
         return mHandle;
     }
 
     @WrapForJNI
     public int getTexName() {
         return mTexName;
     }
 
+    @WrapForJNI(exceptionMode = "nsresult")
+    public void attachToGLContext(long context, int texName) {
+        if (context == mAttachedContext && texName == mTexName) {
+            return;
+        }
+
+        attachToGLContext(texName);
+
+        mAttachedContext = context;
+        mTexName = texName;
+    }
+
+    @Override
+    @WrapForJNI(exceptionMode = "nsresult")
+    public void detachFromGLContext() {
+        super.detachFromGLContext();
+
+        mAttachedContext = mTexName = 0;
+    }
+
+    @WrapForJNI
+    public boolean isAttachedToGLContext(long context) {
+        return mAttachedContext == context;
+    }
+
     @WrapForJNI
     public boolean isSingleBuffer() {
         return mIsSingleBuffer;
     }
 
     @Override
     @WrapForJNI
     public synchronized void updateTexImage() {
@@ -125,23 +152,22 @@ public final class GeckoSurfaceTexture e
     }
 
     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();
 
         final GeckoSurfaceTexture gst;
         if (isSingleBufferSupported()) {
-            gst = new GeckoSurfaceTexture(handle, texName, singleBufferMode);
+            gst = new GeckoSurfaceTexture(handle, singleBufferMode);
         } else {
-            gst = new GeckoSurfaceTexture(handle, texName);
+            gst = new GeckoSurfaceTexture(handle);
         }
 
         synchronized (sSurfaceTextures) {
             if (sSurfaceTextures.containsKey(handle)) {
                 gst.release();
                 throw new IllegalArgumentException("Already have a GeckoSurfaceTexture with that handle");
             }