Bug 860466: Properly deal with SharedTextureHostOGL. r=nical
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 11 Apr 2013 19:42:26 -0400
changeset 128521 0a06b9069085aaa5337aac26196011aae9e1bb5f
parent 128520 058c640a3799b7c03839d98b713aea289be03941
child 128522 3135a6091d4cf5e64dcb073aab1273622c42bcc5
push id26361
push userjmuizelaar@mozilla.com
push dateThu, 11 Apr 2013 23:51:01 +0000
treeherdermozilla-inbound@0a06b9069085 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs860466
milestone23.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 860466: Properly deal with SharedTextureHostOGL. r=nical There were a number of issues with the current implementation. It couldn't deal with NULL mSharedHandles. Additionally it was binding things to the wrong samplers. Finally it was not properly setting the texture transform (which defaults to all 0). Finally in a debug build an assert would be hit upon client shutdown due to it not clearing mDescriptor. This patch fixes all of those issues which makes flash work again.
gfx/layers/Effects.h
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/TextureClientOGL.cpp
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.h
--- a/gfx/layers/Effects.h
+++ b/gfx/layers/Effects.h
@@ -34,17 +34,16 @@ namespace layers {
 enum EffectTypes
 {
   EFFECT_MASK,
   EFFECT_MAX_SECONDARY, // sentinel for the count of secondary effect types
   EFFECT_BGRX,
   EFFECT_RGBX,
   EFFECT_BGRA,
   EFFECT_RGBA,
-  EFFECT_RGBA_EXTERNAL,
   EFFECT_YCBCR,
   EFFECT_COMPONENT_ALPHA,
   EFFECT_SOLID_COLOR,
   EFFECT_RENDER_TARGET,
   EFFECT_MAX  //sentinel for the count of all effect types
 };
 
 struct Effect : public RefCounted<Effect>
@@ -171,33 +170,16 @@ struct EffectRGBA : public TexturedEffec
     : TexturedEffect(EFFECT_RGBA, aRGBATexture, aPremultiplied, aFilter)
   {}
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "EffectRGBA"; }
 #endif
 };
 
-struct EffectRGBAExternal : public TexturedEffect
-{
-  EffectRGBAExternal(TextureSource *aRGBATexture,
-                     const gfx::Matrix4x4 &aTextureTransform,
-                     bool aPremultiplied,
-                     gfx::Filter aFilter)
-    : TexturedEffect(EFFECT_RGBA_EXTERNAL, aRGBATexture, aPremultiplied, aFilter)
-    , mTextureTransform(aTextureTransform)
-  {}
-
-#ifdef MOZ_LAYERS_HAVE_LOG
-  virtual const char* Name() { return "EffectRGBAExternal"; }
-#endif
-
-  gfx::Matrix4x4 mTextureTransform;
-};
-
 struct EffectYCbCr : public TexturedEffect
 {
   EffectYCbCr(TextureSource *aSource, gfx::Filter aFilter)
     : TexturedEffect(EFFECT_YCBCR, aSource, false, aFilter)
   {}
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "EffectYCbCr"; }
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -929,17 +929,16 @@ CompositorOGL::CreateFBOWithTexture(cons
 
 gl::ShaderProgramType
 CompositorOGL::GetProgramTypeForEffect(Effect *aEffect) const
 {
   switch(aEffect->mType) {
   case EFFECT_SOLID_COLOR:
     return gl::ColorLayerProgramType;
   case EFFECT_RGBA:
-  case EFFECT_RGBA_EXTERNAL:
   case EFFECT_RGBX:
   case EFFECT_BGRA:
   case EFFECT_BGRX:
   {
     TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffect);
     TextureSourceOGL* source = texturedEffect->mTexture->AsSourceOGL();
     return source->GetShaderProgram();
@@ -1040,33 +1039,30 @@ CompositorOGL::DrawQuad(const Rect& aRec
 
       BindAndDrawQuad(program);
     }
     break;
 
   case EFFECT_BGRA:
   case EFFECT_BGRX:
   case EFFECT_RGBA:
-  case EFFECT_RGBX:
-  case EFFECT_RGBA_EXTERNAL: {
+  case EFFECT_RGBX: {
       TexturedEffect* texturedEffect =
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       Rect textureCoords;
       TextureSource *source = texturedEffect->mTexture;
 
       if (!texturedEffect->mPremultiplied) {
         mGLContext->fBlendFuncSeparate(LOCAL_GL_SRC_ALPHA, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                        LOCAL_GL_ONE, LOCAL_GL_ONE);
       }
 
       source->AsSourceOGL()->BindTexture(LOCAL_GL_TEXTURE0);
-      if (aEffectChain.mPrimaryEffect->mType == EFFECT_RGBA_EXTERNAL) {
-        EffectRGBAExternal* effectRGBAExternal =
-          static_cast<EffectRGBAExternal*>(aEffectChain.mPrimaryEffect.get());
-        program->SetTextureTransform(effectRGBAExternal->mTextureTransform);
+      if (programType == gl::RGBALayerExternalProgramType) {
+        program->SetTextureTransform(source->AsSourceOGL()->GetTextureTransform());
       }
 
       mGLContext->ApplyFilterToBoundTexture(source->AsSourceOGL()->GetTextureTarget(),
                                             ThebesFilter(texturedEffect->mFilter));
 
       program->SetTextureUnit(0);
       program->SetLayerOpacity(aOpacity);
 
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -20,20 +20,19 @@ TextureClientSharedOGL::TextureClientSha
 
 void
 TextureClientSharedOGL::ReleaseResources()
 {
   if (!IsSurfaceDescriptorValid(mDescriptor)) {
     return;
   }
   MOZ_ASSERT(mDescriptor.type() == SurfaceDescriptor::TSharedTextureDescriptor);
-  SharedTextureDescriptor handle = mDescriptor.get_SharedTextureDescriptor();
-  if (mGL && handle.handle()) {
-    mGL->ReleaseSharedHandle(handle.shareType(), handle.handle());
-  }
+  mDescriptor = SurfaceDescriptor();
+  // It's important our handle gets released! SharedTextureHostOGL will take
+  // care of this for us though.
 }
 
 void
 TextureClientSharedOGL::EnsureAllocated(gfx::IntSize aSize,
                                         gfxASurface::gfxContentType aContentType)
 {
   mSize = aSize;
 }
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -46,30 +46,29 @@ CreateTextureHostOGL(SurfaceDescriptorTy
 
   NS_ASSERTION(result, "Result should have been created.");
 
   result->SetFlags(aTextureFlags);
   return result.forget();
 }
 
 static void
-MakeTextureIfNeeded(gl::GLContext* gl, GLenum aTarget, GLuint& aTexture)
+MakeTextureIfNeeded(gl::GLContext* gl, GLuint& aTexture)
 {
   if (aTexture != 0)
     return;
 
   gl->fGenTextures(1, &aTexture);
 
-  gl->fActiveTexture(LOCAL_GL_TEXTURE0);
-  gl->fBindTexture(aTarget, aTexture);
+  gl->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
 
-  gl->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-  gl->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
-  gl->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-  gl->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
 }
 
 static gl::TextureImage::Flags
 FlagsToGLFlags(TextureFlags aFlags)
 {
   uint32_t result = TextureImage::NoFlags;
 
   if (aFlags & UseNearestFilter)
@@ -246,31 +245,37 @@ SharedTextureHostOGL::SwapTexturesImpl(c
   SharedTextureDescriptor texture = aImage.get_SharedTextureDescriptor();
 
   SharedTextureHandle newHandle = texture.handle();
   nsIntSize size = texture.size();
   mSize = gfx::IntSize(size.width, size.height);
   if (texture.inverted()) {
     mFlags |= NeedsYFlip;
   }
+
+  if (mSharedHandle && mSharedHandle != newHandle) {
+    mGL->ReleaseSharedHandle(mShareType, mSharedHandle);
+  }
+
   mShareType = texture.shareType();
   mSharedHandle = newHandle;
 
   GLContext::SharedHandleDetails handleDetails;
-  if (mGL->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
+  if (mSharedHandle && mGL->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
     mTextureTarget = handleDetails.mTarget;
     mShaderProgram = handleDetails.mProgramType;
     mFormat = FormatFromShaderType(mShaderProgram);
+    mTextureTransform = handleDetails.mTextureTransform;
   }
 }
 
 bool
 SharedTextureHostOGL::Lock()
 {
-  MakeTextureIfNeeded(mGL, mTextureTarget, mTextureHandle);
+  MakeTextureIfNeeded(mGL, mTextureHandle);
 
   mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
   mGL->fBindTexture(mTextureTarget, mTextureHandle);
   if (!mGL->AttachSharedHandle(mShareType, mSharedHandle)) {
     NS_ERROR("Failed to bind shared texture handle");
     return false;
   }
 
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -43,18 +43,20 @@ class TextureSourceOGL
 {
 public:
   virtual bool IsValid() const = 0;
   virtual void BindTexture(GLenum aTextureUnit) = 0;
   virtual gfx::IntSize GetSize() const = 0;
   virtual gl::ShaderProgramType GetShaderProgram() const {
     MOZ_NOT_REACHED("unhandled shader type");
   }
+  // TODO: Noone's implementing this anymore, should see if we need this.
   virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; }
   virtual GLenum GetWrapMode() const = 0;// { return LOCAL_GL_CLAMP_TO_EDGE; } // default
+  virtual gfx3DMatrix GetTextureTransform() const { return gfx3DMatrix(); }
 };
 
 inline gl::ShaderProgramType
 GetProgramTypeForTexture(const TextureHost *aTextureHost)
 {
   switch (aTextureHost->GetFormat()) {
   case gfx::FORMAT_B8G8R8A8:
     return gl::BGRALayerProgramType;;
@@ -315,17 +317,17 @@ public:
 
   virtual GLuint GetTextureHandle()
   {
     return mTextureHandle;
   }
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
 
-  bool IsValid() const MOZ_OVERRIDE { return GetFormat() != gfx::FORMAT_UNKNOWN; }
+  bool IsValid() const MOZ_OVERRIDE { return !!mSharedHandle; }
 
   // override from TextureHost, we support both buffered
   // and unbuffered operation.
   virtual void UpdateImpl(const SurfaceDescriptor& aImage,
                           nsIntRegion* aRegion = nullptr) MOZ_OVERRIDE;
   virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
                                 nsIntRegion* aRegion = nullptr) MOZ_OVERRIDE;
   virtual bool Lock() MOZ_OVERRIDE;
@@ -338,51 +340,52 @@ public:
   {
     return mShaderProgram;
   }
 
   gfx::IntSize GetSize() const MOZ_OVERRIDE {
     return mSize;
   }
 
-  virtual GLenum GetTextureTarget() const MOZ_OVERRIDE
-  {
-    return mTextureTarget;
-  }
-
   void BindTexture(GLenum activetex) MOZ_OVERRIDE
   {
     MOZ_ASSERT(mGL);
-    mGL->fActiveTexture(activetex);
-    mGL->fBindTexture(mTextureTarget, mTextureHandle);
+    // Lock already bound us!
+    MOZ_ASSERT(activetex == LOCAL_GL_TEXTURE0);
   }
   void ReleaseTexture() {}
   GLuint GetTextureID() { return mTextureHandle; }
   ContentType GetContentType()
   {
     return (mFormat == gfx::FORMAT_B8G8R8A8) ?
              gfxASurface::CONTENT_COLOR_ALPHA :
              gfxASurface::CONTENT_COLOR;
   }
 
+  virtual gfx3DMatrix GetTextureTransform() const MOZ_OVERRIDE
+  {
+    return mTextureTransform;
+  }
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "SharedTextureHostOGL"; }
 #endif
 
 protected:
   void DeleteTextures();
 
   gfx::IntSize mSize;
   nsRefPtr<gl::GLContext> mGL;
   GLuint mTextureHandle;
   GLenum mWrapMode;
   GLenum mTextureTarget;
   gl::SharedTextureHandle mSharedHandle;
   gl::ShaderProgramType mShaderProgram;
   gl::GLContext::SharedTextureShareType mShareType;
+  gfx3DMatrix mTextureTransform;
 };
 
 class SurfaceStreamHostOGL : public TextureHost
                            , public TextureSourceOGL
 {
 public:
   typedef gfxASurface::gfxContentType ContentType;
   typedef mozilla::gl::GLContext GLContext;