b=594642; [gl] use scissor rect when drawing layers; r=vlad
authorMatt Woodrow <matt.woodrow+bugzilla@gmail.com>
Thu, 09 Sep 2010 16:40:15 -0400
changeset 53688 45518cd69dd16275f8378764823aea847e911d96
parent 53687 0f15e23e7abe42289f07355897b49600d48a1421
child 53689 46c0a7c9e4f5ba256e620309f41f03dbb22bdeb1
push idunknown
push userunknown
push dateunknown
reviewersvlad
bugs594642
milestone2.0b6pre
b=594642; [gl] use scissor rect when drawing layers; r=vlad
gfx/layers/opengl/ContainerLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.cpp
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ b/gfx/layers/opengl/ContainerLayerOGL.cpp
@@ -150,57 +150,73 @@ ContainerLayerOGL::RenderLayer(int aPrev
 {
   /**
    * Setup our temporary texture for rendering the contents of this container.
    */
   GLuint containerSurface;
   GLuint frameBuffer;
 
   nsIntPoint childOffset(aOffset);
-  bool needsFramebuffer = false;
   nsIntRect visibleRect = mVisibleRegion.GetBounds();
 
   float opacity = GetOpacity();
-  if (opacity != 1.0 || !mTransform.IsIdentity()) {
+  bool needsFramebuffer = (opacity != 1.0) || !mTransform.IsIdentity();
+  if (needsFramebuffer) {
     mOGLManager->CreateFBOWithTexture(visibleRect.width,
                                       visibleRect.height,
                                       &frameBuffer,
                                       &containerSurface);
     childOffset.x = visibleRect.x;
     childOffset.y = visibleRect.y;
-    mOGLManager->gl()->fClearColor(0, 0, 0, 0);
+    mOGLManager->gl()->fClearColor(0.0, 0.0, 0.0, 0.0);
     mOGLManager->gl()->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
   } else {
     frameBuffer = aPreviousFrameBuffer;
   }
 
+  GLint savedScissor[4];
+  gl()->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, savedScissor);
+
   /**
    * Render this container's contents.
    */
   LayerOGL *layerToRender = GetFirstChildOGL();
   while (layerToRender) {
     const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect();
     if (clipRect) {
-      gl()->fScissor(clipRect->x - visibleRect.x,
-                     clipRect->y - visibleRect.y,
-                     clipRect->width,
-                     clipRect->height);
+      if (needsFramebuffer) {
+        gl()->fScissor(clipRect->x - visibleRect.x,
+                       clipRect->y - visibleRect.y,
+                       clipRect->width,
+                       clipRect->height);
+      } else {
+        gl()->fScissor(clipRect->x,
+                       clipRect->y,
+                       clipRect->width,
+                       clipRect->height);
+      }
     } else {
-      gl()->fScissor(0, 0, visibleRect.width, visibleRect.height);
+      if (needsFramebuffer) {
+        gl()->fScissor(0, 0, visibleRect.width, visibleRect.height);
+      } else {
+        gl()->fScissor(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height);
+      }
     }
 
     layerToRender->RenderLayer(frameBuffer, childOffset);
 
     Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
     layerToRender = nextSibling ? static_cast<LayerOGL*>(nextSibling->
                                                          ImplData())
                                 : nsnull;
   }
 
-  if (opacity != 1.0 || !mTransform.IsIdentity()) {
+  gl()->fScissor(savedScissor[0], savedScissor[1], savedScissor[2], savedScissor[3]);
+
+  if (needsFramebuffer) {
     // Unbind the current framebuffer and rebind the previous one.
     gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
     gl()->fDeleteFramebuffers(1, &frameBuffer);
 
     gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
 
     gl()->fBindTexture(mOGLManager->FBOTextureTarget(), containerSurface);
 
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -530,37 +530,26 @@ LayerManagerOGL::Render()
 
   // 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);
 
   DEBUG_GL_ERROR_CHECK(mGLContext);
 
-#if 0
-  // XXX for whatever reason, scissor is not working -- even with no
-  // cliprect set, so we go through the 0,0,w,h path, any updates
-  // after the initial render end up failing the scissor rectangle.  I
-  // have no idea why.  We disable it for now, because it's not actually
-  // helping us with anything -- we draw to a specific location in the
-  // front buffer as it is.
-
   const nsIntRect *clipRect = mRoot->GetClipRect();
 
   if (clipRect) {
     mGLContext->fScissor(clipRect->x, clipRect->y,
                          clipRect->width, clipRect->height);
   } else {
     mGLContext->fScissor(0, 0, width, height);
   }
 
   mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
-#else
-  mGLContext->fDisable(LOCAL_GL_SCISSOR_TEST);
-#endif
 
   DEBUG_GL_ERROR_CHECK(mGLContext);
 
   mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
   mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
 
   // Render our layers.
   RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,