Bug 1052751 - Part 1: Cull translated layers on the compositor. r=roc
☠☠ backed out by 0b3ddcde7580 ☠ ☠
authorBenoit Girard <b56girard@gmail.com>
Fri, 15 Aug 2014 13:46:23 -0400
changeset 199910 926c83cd24f043df996f9d4808c2cc5f918b7d3a
parent 199909 229181c88a3c57bdcd9df78077a2e172d767a463
child 199911 b4e84ff5a4671364c70a1ddf106a6ca1939d8825
push id27326
push userryanvm@gmail.com
push dateSat, 16 Aug 2014 21:43:28 +0000
treeherdermozilla-central@94ba78a42305 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1052751
milestone34.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 1052751 - Part 1: Cull translated layers on the compositor. r=roc
gfx/layers/composite/ContainerLayerComposite.cpp
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -29,16 +29,19 @@
 #include "nsISupportsUtils.h"           // for NS_ADDREF, NS_RELEASE
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRect.h"                     // for nsIntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsAutoTArray
 #include "TextRenderer.h"               // for TextRenderer
 #include <vector>
 
+#define CULLING_LOG(...)
+// #define CULLING_LOG(...) printf_stderr("CULLING: " __VA_ARGS__)
+
 namespace mozilla {
 namespace layers {
 
 using namespace gfx;
 
 /**
  * Returns a rectangle of content painted opaquely by aLayer. Very consertative;
  * bails by returning an empty rect in any tricky situations.
@@ -316,40 +319,54 @@ ContainerPrepare(ContainerT* aContainer,
     }
 
     nsIntRect clipRect = layerToRender->GetLayer()->
         CalculateScissorRect(aClipRect, &aManager->GetWorldTransform());
     if (clipRect.IsEmpty()) {
       continue;
     }
 
+    CULLING_LOG("Preparing sublayer %p\n", layerToRender->GetLayer());
+
     nsIntRegion savedVisibleRegion;
     bool restoreVisibleRegion = false;
+    gfx::Matrix matrix;
+    bool is2D = layerToRender->GetLayer()->GetBaseTransform().Is2D(&matrix);
     if (i + 1 < children.Length() &&
-        layerToRender->GetLayer()->GetEffectiveTransform().IsIdentity()) {
+        is2D && !matrix.HasNonIntegerTranslation()) {
       LayerComposite* nextLayer = static_cast<LayerComposite*>(children.ElementAt(i + 1)->ImplData());
+      CULLING_LOG("Culling against %p\n", nextLayer->GetLayer());
       nsIntRect nextLayerOpaqueRect;
       if (nextLayer && nextLayer->GetLayer()) {
         nextLayerOpaqueRect = GetOpaqueRect(nextLayer->GetLayer());
+        gfx::Point point = matrix.GetTranslation();
+        nextLayerOpaqueRect.MoveBy(static_cast<int>(-point.x), static_cast<int>(-point.y));
+        CULLING_LOG("  point %i, %i\n", static_cast<int>(-point.x), static_cast<int>(-point.y));
+        CULLING_LOG("  opaque rect %i, %i, %i, %i\n", nextLayerOpaqueRect.x, nextLayerOpaqueRect.y, nextLayerOpaqueRect.width, nextLayerOpaqueRect.height);
       }
       if (!nextLayerOpaqueRect.IsEmpty()) {
+        CULLING_LOG("  draw\n");
         savedVisibleRegion = layerToRender->GetShadowVisibleRegion();
         nsIntRegion visibleRegion;
         visibleRegion.Sub(savedVisibleRegion, nextLayerOpaqueRect);
         if (visibleRegion.IsEmpty()) {
           continue;
         }
         layerToRender->SetShadowVisibleRegion(visibleRegion);
         restoreVisibleRegion = true;
+      } else {
+        CULLING_LOG("  skip\n");
       }
     }
     layerToRender->Prepare(clipRect);
     aContainer->mPrepared->mLayers.AppendElement(PreparedLayer(layerToRender, clipRect, restoreVisibleRegion, savedVisibleRegion));
   }
 
+  CULLING_LOG("Preparing container layer %p\n", aContainer->GetLayer());
+
   /**
    * Setup our temporary surface for rendering the contents of this container.
    */
 
   bool surfaceCopyNeeded;
   // DefaultComputeSupportsComponentAlphaChildren can mutate aContainer so call it unconditionally
   aContainer->DefaultComputeSupportsComponentAlphaChildren(&surfaceCopyNeeded);
   if (aContainer->UseIntermediateSurface()) {