Bug 971914 - Don't set and restore state constantly inside CompositorOGL. r=nical
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 13 Mar 2014 13:37:17 +1300
changeset 191518 ceb23e4d75545648b09456665cce9846b0fadbc0
parent 191517 7ada8c5a0480053a374dffc1afcac5dc1cce4467
child 191519 badf9a3d3f79dae758271aee74fe81cb52cb0af4
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs971914
milestone30.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 971914 - Don't set and restore state constantly inside CompositorOGL. r=nical
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/TextureHostOGL.cpp
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -120,25 +120,22 @@ DrawQuads(GLContext *aGLContext,
                                bytes,
                                bytes,
                                aRects.texCoords().Elements());
     aGLContext->fEnableVertexAttribArray(texCoordAttribIndex);
     aGLContext->fVertexAttribPointer(texCoordAttribIndex,
                                      2, LOCAL_GL_FLOAT,
                                      LOCAL_GL_FALSE,
                                      0, BUFFER_OFFSET(bytes));
+  } else {
+    aGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
   }
 
   aGLContext->fDrawArrays(aMode, 0, aRects.elements());
 
-  aGLContext->fDisableVertexAttribArray(vertAttribIndex);
-  if (texCoords) {
-    aGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
-  }
-
   aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 }
 
 CompositorOGL::CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth,
                              int aSurfaceHeight, bool aUseExternalSurfaceSize)
   : mWidget(aWidget)
   , mWidgetSize(-1, -1)
   , mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
@@ -689,16 +686,18 @@ CompositorOGL::BeginFrame(const nsIntReg
   mWindowRenderTarget = mCurrentRenderTarget;
 #endif
 
   // Default blend function implements "OVER"
   mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                  LOCAL_GL_ONE, LOCAL_GL_ONE);
   mGLContext->fEnable(LOCAL_GL_BLEND);
 
+  mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
+
   if (aClipRectOut && !aClipRectIn) {
     aClipRectOut->SetRect(0, 0, width, height);
   }
 
   // If the Android compositor is being used, this clear will be done in
   // DrawWindowUnderlay. Make sure the bits used here match up with those used
   // in mobile/android/base/gfx/LayerRenderer.java
 #ifndef MOZ_ANDROID_OMTC
@@ -857,87 +856,16 @@ CompositorOGL::GetShaderProgramFor(const
     delete shader;
     return nullptr;
   }
 
   mPrograms[aConfig] = shader;
   return shader;
 }
 
-struct MOZ_STACK_CLASS AutoBindTexture
-  : public ScopedGLWrapper<AutoBindTexture>
-{
-  friend struct ScopedGLWrapper<AutoBindTexture>;
-
-protected:
-  GLenum mTexUnit;
-  GLuint mOldTexId;
-
-public:
-  explicit AutoBindTexture(GLContext* aGL)
-    : ScopedGLWrapper<AutoBindTexture>(aGL)
-    , mTexUnit(0)
-    , mOldTexId(GLuint(-1))
-  { }
-
-  AutoBindTexture(GLContext* aGL, TextureSourceOGL* aTexture,
-                  GLenum aTexUnit = LOCAL_GL_TEXTURE0)
-    : ScopedGLWrapper<AutoBindTexture>(aGL)
-    , mTexUnit(0)
-    , mOldTexId(GLuint(-1))
-  {
-    MOZ_ASSERT(aTexture);
-    MOZ_ASSERT(mOldTexId == GLuint(-1));
-    mTexUnit = aTexUnit;
-
-    ScopedBindTextureUnit autoBindTexUnit(mGL, aTexUnit);
-
-    mGL->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &mOldTexId);
-    aTexture->BindTexture(mTexUnit);
-  }
-
-protected:
-  void UnwrapImpl()
-  {
-    if (mOldTexId == GLuint(-1))
-      return;
-
-    ScopedBindTextureUnit autoBindTexUnit(mGL, mTexUnit);
-    mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mOldTexId);
-  }
-};
-
-struct MOZ_STACK_CLASS AutoSaveTexture
-  : public ScopedGLWrapper<AutoSaveTexture>
-{
-  friend struct ScopedGLWrapper<AutoSaveTexture>;
-
-protected:
-  GLenum mTexUnit;
-  GLuint mOldTexId;
-
-public:
-  AutoSaveTexture(GLContext* aGL, GLenum aTexUnit = LOCAL_GL_TEXTURE0)
-    : ScopedGLWrapper<AutoSaveTexture>(aGL)
-    , mTexUnit(aTexUnit)
-    , mOldTexId(GLuint(-1))
-  {
-    ScopedBindTextureUnit savedTexUnit(mGL, mTexUnit);
-    mGL->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &mOldTexId);
-  }
-
-protected:
-  void UnwrapImpl()
-  {
-    ScopedBindTextureUnit savedTexUnit(mGL, mTexUnit);
-    mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mOldTexId);
-  }
-};
-
-
 void
 CompositorOGL::DrawLines(const std::vector<gfx::Point>& aLines, const gfx::Rect& aClipRect,
                          const gfx::Color& aColor,
                          gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform)
 {
   mGLContext->fLineWidth(2.0);
 
   EffectChain effects;
@@ -979,22 +907,18 @@ CompositorOGL::DrawQuadInternal(const Re
 
   Rect clipRect = aClipRect;
   if (!mTarget) {
     clipRect.MoveBy(mRenderOffset.x, mRenderOffset.y);
   }
   IntRect intClipRect;
   clipRect.ToIntRect(&intClipRect);
 
-  ScopedGLState scopedScissorTestState(mGLContext, LOCAL_GL_SCISSOR_TEST, true);
-  ScopedScissorRect autoScissor(mGLContext,
-                                intClipRect.x,
-                                FlipY(intClipRect.y + intClipRect.height),
-                                intClipRect.width,
-                                intClipRect.height);
+  gl()->fScissor(intClipRect.x, FlipY(intClipRect.y + intClipRect.height),
+                 intClipRect.width, intClipRect.height);
 
   LayerScope::SendEffectChain(mGLContext, aEffectChain,
                               aRect.width, aRect.height);
 
   MaskType maskType;
   EffectMask* effectMask;
   TextureSourceOGL* sourceMask = nullptr;
   gfx::Matrix4x4 maskQuadTransform;
@@ -1065,17 +989,16 @@ CompositorOGL::DrawQuadInternal(const Re
     // This is used by IOSurface that use 0,0...w,h coordinate rather then 0,0..1,1.
     program->SetTexCoordMultiplier(source->GetSize().width, source->GetSize().height);
   }
 
   switch (aEffectChain.mPrimaryEffect->mType) {
     case EFFECT_SOLID_COLOR: {
       program->SetRenderColor(color);
 
-      AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE0);
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE0, maskQuadTransform);
       }
 
       BindAndDrawQuad(program, false, aDrawMode);
     }
     break;
 
@@ -1084,17 +1007,17 @@ CompositorOGL::DrawQuadInternal(const Re
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       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);
       }
 
-      AutoBindTexture bindSource(mGLContext, source->AsSourceOGL(), LOCAL_GL_TEXTURE0);
+      source->AsSourceOGL()->BindTexture(LOCAL_GL_TEXTURE0);
 
       GraphicsFilter filter = ThebesFilter(texturedEffect->mFilter);
       gfx3DMatrix textureTransform;
       gfx::To3DMatrix(source->AsSourceOGL()->GetTextureTransform(), textureTransform);
 
 #ifdef MOZ_WIDGET_ANDROID
       gfxMatrix textureTransform2D;
       if (filter != GraphicsFilter::FILTER_NEAREST &&
@@ -1107,17 +1030,16 @@ CompositorOGL::DrawQuadInternal(const Re
         filter = GraphicsFilter::FILTER_NEAREST;
       }
 #endif
       ApplyFilterToBoundTexture(mGLContext, filter,
                                 source->AsSourceOGL()->GetTextureTarget());
 
       program->SetTextureUnit(0);
 
-      AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE1);
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1, maskQuadTransform);
       }
 
       BindAndDrawQuadWithTextureRect(program, textureTransform,
                                      texturedEffect->mTextureCoords, source);
 
       if (!texturedEffect->mPremultiplied) {
@@ -1137,26 +1059,25 @@ CompositorOGL::DrawQuadInternal(const Re
 
       if (!sourceY && !sourceCb && !sourceCr) {
         NS_WARNING("Invalid layer texture.");
         return;
       }
 
       GraphicsFilter filter = ThebesFilter(effectYCbCr->mFilter);
 
-      AutoBindTexture bindY(mGLContext, sourceY, LOCAL_GL_TEXTURE0);
+      sourceY->BindTexture(LOCAL_GL_TEXTURE0);
       ApplyFilterToBoundTexture(mGLContext, filter);
-      AutoBindTexture bindCb(mGLContext, sourceCb, LOCAL_GL_TEXTURE1);
+      sourceCb->BindTexture(LOCAL_GL_TEXTURE1);
       ApplyFilterToBoundTexture(mGLContext, filter);
-      AutoBindTexture bindCr(mGLContext, sourceCr, LOCAL_GL_TEXTURE2);
+      sourceCr->BindTexture(LOCAL_GL_TEXTURE2);
       ApplyFilterToBoundTexture(mGLContext, filter);
 
       program->SetYCbCrTextureUnits(Y, Cb, Cr);
 
-      AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE3);
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE3, maskQuadTransform);
       }
       BindAndDrawQuadWithTextureRect(program,
                                      gfx3DMatrix(),
                                      effectYCbCr->mTextureCoords,
                                      sourceYCbCr->GetSubSource(Y));
     }
@@ -1167,17 +1088,16 @@ CompositorOGL::DrawQuadInternal(const Re
       RefPtr<CompositingRenderTargetOGL> surface
         = static_cast<CompositingRenderTargetOGL*>(effectRenderTarget->mRenderTarget.get());
 
       surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget);
 
       program->SetTextureTransform(Matrix4x4());
       program->SetTextureUnit(0);
 
-      AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE1);
       if (maskType != MaskNone) {
         sourceMask->BindTexture(LOCAL_GL_TEXTURE1);
         program->SetMaskTextureUnit(1);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
 
       if (config.mFeatures & ENABLE_TEXTURE_RECT) {
         // 2DRect case, get the multiplier right for a sampler2DRect
@@ -1198,24 +1118,23 @@ CompositorOGL::DrawQuadInternal(const Re
       TextureSourceOGL* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceOGL();
 
       if (!sourceOnBlack->IsValid() ||
           !sourceOnWhite->IsValid()) {
         NS_WARNING("Invalid layer texture for component alpha");
         return;
       }
 
-      AutoBindTexture bindSourceOnBlack(mGLContext, sourceOnBlack, LOCAL_GL_TEXTURE0);
-      AutoBindTexture bindSourceOnWhite(mGLContext, sourceOnWhite, LOCAL_GL_TEXTURE1);
+      sourceOnBlack->BindTexture(LOCAL_GL_TEXTURE0);
+      sourceOnWhite->BindTexture(LOCAL_GL_TEXTURE1);
 
       program->SetBlackTextureUnit(0);
       program->SetWhiteTextureUnit(1);
       program->SetTextureTransform(gfx::Matrix4x4());
 
-      AutoBindTexture bindMask(mGLContext);
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2, maskQuadTransform);
       }
       // Pass 1.
       gl()->fBlendFuncSeparate(LOCAL_GL_ZERO, LOCAL_GL_ONE_MINUS_SRC_COLOR,
                                LOCAL_GL_ONE, LOCAL_GL_ONE);
       program->SetTexturePass2(false);
       BindAndDrawQuadWithTextureRect(program,
@@ -1236,17 +1155,16 @@ CompositorOGL::DrawQuadInternal(const Re
                                      LOCAL_GL_ONE, LOCAL_GL_ONE);
     }
     break;
   default:
     MOZ_ASSERT(false, "Unhandled effect type");
     break;
   }
 
-  mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
   // in case rendering has used some other GL context
   MakeCurrent();
 }
 
 void
 CompositorOGL::EndFrame()
 {
   PROFILER_LABEL("CompositorOGL", "EndFrame");
@@ -1281,16 +1199,27 @@ CompositorOGL::EndFrame()
   mCurrentRenderTarget = nullptr;
 
   if (mTexturePool) {
     mTexturePool->EndFrame();
   }
 
   mGLContext->SwapBuffers();
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
+
+  // Unbind all textures
+  mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
+  mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
+  mGLContext->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
+  mGLContext->fActiveTexture(LOCAL_GL_TEXTURE1);
+  mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
+  mGLContext->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
+  mGLContext->fActiveTexture(LOCAL_GL_TEXTURE2);
+  mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
+  mGLContext->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
 }
 
 void
 CompositorOGL::EndFrameForExternalComposition(const gfx::Matrix& aTransform)
 {
   // This lets us reftest and screenshot content rendered externally
   if (mTarget) {
     MakeCurrent();
@@ -1471,21 +1400,16 @@ CompositorOGL::BindAndDrawQuad(GLuint aV
   }
 
   mGLContext->fEnableVertexAttribArray(aVertAttribIndex);
   if (aDrawMode == LOCAL_GL_LINE_STRIP) {
     mGLContext->fDrawArrays(aDrawMode, 1, 2);
   } else {
     mGLContext->fDrawArrays(aDrawMode, 0, 4);
   }
-  mGLContext->fDisableVertexAttribArray(aVertAttribIndex);
-
-  if (aTexCoordAttribIndex != GLuint(-1)) {
-    mGLContext->fDisableVertexAttribArray(aTexCoordAttribIndex);
-  }
 }
 
 void
 CompositorOGL::BindAndDrawQuad(ShaderProgramOGL *aProg,
                                bool aFlipped,
                                GLuint aDrawMode)
 {
   NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -326,17 +326,16 @@ SharedTextureSourceOGL::BindTexture(GLen
   GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(mTextureTarget, tex);
   if (!AttachSharedHandle(gl(), mShareType, mSharedHandle)) {
     NS_ERROR("Failed to bind shared texture handle");
     return;
   }
-  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
 }
 
 void
 SharedTextureSourceOGL::DetachSharedHandle()
 {
   if (!gl()) {
     return;
   }
@@ -1071,17 +1070,16 @@ void GrallocDeprecatedTextureHostOGL::Bi
   if (!gl()->MakeCurrent()) {
     return;
   }
 
   GLuint tex = GetGLTexture();
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(mTextureTarget, tex);
-  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
 }
 
 bool
 GrallocDeprecatedTextureHostOGL::IsValid() const
 {
   return !!gl() && !!mGraphicBuffer.get();
 }