Store the AL render region separately from the shadow visible region. (bug 1408781 part 1, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Fri, 20 Oct 2017 15:09:12 -0700
changeset 387491 97aeedf3aa5d49dd2dfc034499a76b13cea64e9f
parent 387490 8dba09333346ba9f445c6648622596a96a841e8d
child 387492 5bf42ef768d80ebeba9f0a634a38446c33f1c125
push id32721
push userarchaeopteryx@coole-files.de
push dateSat, 21 Oct 2017 08:59:38 +0000
treeherdermozilla-central@d697979497a6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1408781
milestone58.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
Store the AL render region separately from the shadow visible region. (bug 1408781 part 1, r=mattwoodrow)
gfx/layers/mlgpu/CanvasLayerMLGPU.cpp
gfx/layers/mlgpu/CanvasLayerMLGPU.h
gfx/layers/mlgpu/ImageLayerMLGPU.cpp
gfx/layers/mlgpu/ImageLayerMLGPU.h
gfx/layers/mlgpu/LayerMLGPU.cpp
gfx/layers/mlgpu/LayerMLGPU.h
gfx/layers/mlgpu/PaintedLayerMLGPU.cpp
gfx/layers/mlgpu/PaintedLayerMLGPU.h
gfx/layers/mlgpu/RenderPassMLGPU.cpp
gfx/layers/mlgpu/RenderPassMLGPU.h
gfx/layers/mlgpu/RenderViewMLGPU.cpp
--- a/gfx/layers/mlgpu/CanvasLayerMLGPU.cpp
+++ b/gfx/layers/mlgpu/CanvasLayerMLGPU.cpp
@@ -90,16 +90,16 @@ CanvasLayerMLGPU::Disconnect()
 
 void
 CanvasLayerMLGPU::ClearCachedResources()
 {
   CleanupResources();
 }
 
 void
-CanvasLayerMLGPU::SetRegionToRender(LayerIntRegion&& aRegion)
+CanvasLayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion)
 {
   aRegion.AndWith(LayerIntRect::FromUnknownRect(mPictureRect));
-  LayerMLGPU::SetRegionToRender(Move(aRegion));
+  LayerMLGPU::SetRenderRegion(Move(aRegion));
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/mlgpu/CanvasLayerMLGPU.h
+++ b/gfx/layers/mlgpu/CanvasLayerMLGPU.h
@@ -34,17 +34,17 @@ protected:
 public:
   Layer* GetLayer() override;
   void Disconnect() override;
 
   HostLayer* AsHostLayer() override { return this; }
   CanvasLayerMLGPU* AsCanvasLayerMLGPU() override { return this; }
   gfx::SamplingFilter GetSamplingFilter() override;
   void ClearCachedResources() override;
-  void SetRegionToRender(LayerIntRegion&& aRegion) override;
+  void SetRenderRegion(LayerIntRegion&& aRegion) override;
 
   MOZ_LAYER_DECL_NAME("CanvasLayerMLGPU", TYPE_CANVAS)
 
 protected:
   CanvasRenderer* CreateCanvasRendererInternal() override {
     MOZ_CRASH("Incompatible surface type");
     return nullptr;
   }
--- a/gfx/layers/mlgpu/ImageLayerMLGPU.cpp
+++ b/gfx/layers/mlgpu/ImageLayerMLGPU.cpp
@@ -70,30 +70,30 @@ ImageLayerMLGPU::IsContentOpaque()
   }
   if (mScaleMode == ScaleMode::STRETCH) {
     return gfx::IsOpaque(mHost->CurrentTextureHost()->GetFormat());
   }
   return false;
 }
 
 void
-ImageLayerMLGPU::SetRegionToRender(LayerIntRegion&& aRegion)
+ImageLayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion)
 {
   switch (mScaleMode) {
   case ScaleMode::STRETCH:
     // See bug 1264142.
     aRegion.AndWith(LayerIntRect(0, 0, mScaleToSize.width, mScaleToSize.height));
     break;
   default:
     // Clamp the visible region to the texture size. (see bug 1396507)
     MOZ_ASSERT(mScaleMode == ScaleMode::SCALE_NONE);
     aRegion.AndWith(LayerIntRect(0, 0, mPictureRect.width, mPictureRect.height));
     break;
   }
-  LayerMLGPU::SetRegionToRender(Move(aRegion));
+  LayerMLGPU::SetRenderRegion(Move(aRegion));
 }
 
 void
 ImageLayerMLGPU::CleanupResources()
 {
   if (mHost) {
     mHost->CleanupResources();
     mHost->Detach(this);
--- a/gfx/layers/mlgpu/ImageLayerMLGPU.h
+++ b/gfx/layers/mlgpu/ImageLayerMLGPU.h
@@ -21,17 +21,17 @@ public:
   explicit ImageLayerMLGPU(LayerManagerMLGPU* aManager);
 
 
   Layer* GetLayer() override { return this; }
   HostLayer* AsHostLayer() override { return this; }
   ImageLayerMLGPU* AsImageLayerMLGPU() override { return this; }
 
   void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override;
-  void SetRegionToRender(LayerIntRegion&& aRegion) override;
+  void SetRenderRegion(LayerIntRegion&& aRegion) override;
   gfx::SamplingFilter GetSamplingFilter() override;
   void ClearCachedResources() override;
   bool IsContentOpaque() override;
   void Disconnect() override;
 
   Maybe<gfx::Size> GetPictureScale() const override {
     return mScale;
   }
--- a/gfx/layers/mlgpu/LayerMLGPU.cpp
+++ b/gfx/layers/mlgpu/LayerMLGPU.cpp
@@ -120,19 +120,19 @@ LayerMLGPU::MarkPrepared()
 
 bool
 LayerMLGPU::IsContentOpaque()
 {
   return GetLayer()->IsOpaque();
 }
 
 void
-LayerMLGPU::SetRegionToRender(LayerIntRegion&& aRegion)
+LayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion)
 {
-  SetShadowVisibleRegion(Move(aRegion));
+  mRenderRegion = Move(aRegion);
 }
 
 void
 LayerMLGPU::SetLayerManager(HostLayerManager* aManager)
 {
   LayerManagerMLGPU* manager = aManager->AsLayerManagerMLGPU();
   MOZ_RELEASE_ASSERT(manager);
 
--- a/gfx/layers/mlgpu/LayerMLGPU.h
+++ b/gfx/layers/mlgpu/LayerMLGPU.h
@@ -69,23 +69,29 @@ public:
   bool IsPrepared() const {
     return mFrameKey == sFrameKey && mPrepared;
   }
 
   // Return true if the content in this layer is opaque (not factoring in
   // blend modes or opacity), false otherwise.
   virtual bool IsContentOpaque();
 
-  // This is a wrapper around SetShadowVisibleRegion. Some layers have visible
-  // regions that extend beyond what is actually drawn. When performing CPU-
-  // based occlusion culling we must clamp the visible region to the actual
-  // area. Note that if a layer is opaque, it must not expand its visible
-  // region such that it might include non-opaque pixels, as may be the case
-  // for PaintedLayers with a restricted visible region.
-  virtual void SetRegionToRender(LayerIntRegion&& aRegion);
+  // This is used by RenderPasses for deciding which rects to draw. This
+  // region factors in occulsion culling and any layer-specific adjustments,
+  // whereas the local/shadow visible region does not.
+  const LayerIntRegion& GetRenderRegion() const {
+    return mRenderRegion;
+  }
+
+  // Some layers have visible regions that extend beyond what is actually drawn.
+  // When performing CPU-based occlusion culling we must clamp the visible region
+  // to the actual area. Note that if a layer is opaque, it must not expand its
+  // visible region such that it might include non-opaque pixels, as may be the
+  // case for PaintedLayers with a restricted visible region.
+  virtual void SetRenderRegion(LayerIntRegion&& aRegion);
 
   virtual void AssignToView(FrameBuilder* aBuilder,
                             RenderViewMLGPU* aView,
                             Maybe<gfx::Polygon>&& aGeometry);
 
   // Callback for when PrepareToRender has finished successfully. If this
   // returns false, PrepareToRender will return false.
   virtual bool OnPrepareToRender(FrameBuilder* aBuilder) {
@@ -119,16 +125,17 @@ private:
 
 protected:
   // These are set during PrepareToRender.
   RenderTargetIntRect mComputedClipRect;
   RefPtr<MaskOperation> mMask;
   uint64_t mFrameKey;
   float mComputedOpacity;
   bool mPrepared;
+  LayerIntRegion mRenderRegion;
 };
 
 class RefLayerMLGPU final : public RefLayer
                           , public LayerMLGPU
 {
 public:
   explicit RefLayerMLGPU(LayerManagerMLGPU* aManager);
   ~RefLayerMLGPU() override;
--- a/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp
+++ b/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PaintedLayerMLGPU.h"
 #include "LayerManagerMLGPU.h"
 #include "mozilla/layers/LayersHelpers.h"
+#include "UnitTransforms.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
 PaintedLayerMLGPU::PaintedLayerMLGPU(LayerManagerMLGPU* aManager)
@@ -37,39 +38,37 @@ PaintedLayerMLGPU::OnPrepareToRender(Fra
   mTexture = mHost->AcquireTextureSource();
   if (!mTexture) {
     return false;
   }
   mTextureOnWhite = mHost->AcquireTextureSourceOnWhite();
   return true;
 }
 
-nsIntRegion
-PaintedLayerMLGPU::GetRenderRegion()
+void
+PaintedLayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion)
 {
-  nsIntRegion region;
+  mRenderRegion = Move(aRegion);
 
 #ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
   // Note: we don't set PaintWillResample on our ContentTextureHost. The old
   // compositor must do this since ContentHost is responsible for issuing
   // draw calls, but in AL we can handle it directly here.
   //
   // Note that when AL performs CPU-based occlusion culling (the default
   // behavior), we might break up the visible region again. If that turns
   // out to be a problem, we can factor this into ForEachDrawRect instead.
   if (MayResample()) {
-    region = GetShadowVisibleRegion().GetBounds().ToUnknownRect();
-  } else
+    mRenderRegion = mRenderRegion.GetBounds();
+  }
 #endif
-  {
-    region = GetShadowVisibleRegion().ToUnknownRegion();
-  }
 
-  region.AndWith(gfx::IntRect(region.GetBounds().TopLeft(), mTexture->GetSize()));
-  return region;
+  LayerIntRect bounds(mRenderRegion.GetBounds().TopLeft(),
+                      ViewAs<LayerPixel>(mTexture->GetSize()));
+  mRenderRegion.AndWith(bounds);
 }
 
 bool
 PaintedLayerMLGPU::SetCompositableHost(CompositableHost* aHost)
 {
   switch (aHost->GetType()) {
     case CompositableType::CONTENT_SINGLE:
     case CompositableType::CONTENT_DOUBLE:
--- a/gfx/layers/mlgpu/PaintedLayerMLGPU.h
+++ b/gfx/layers/mlgpu/PaintedLayerMLGPU.h
@@ -54,20 +54,17 @@ public:
     // Note that when resamping, we must break the texture coordinates into
     // no-repeat rects. When we have simple integer translations we can
     // simply wrap around the edge of the buffer texture.
     return MayResample()
            ? SamplerMode::LinearClamp
            : SamplerMode::LinearRepeat;
   }
 
-  // This can return a different region than GetShadowVisibleRegion or
-  // GetLocalVisibleRegion, since we make sure to clamp it to the
-  // texture size and account for resampling.
-  nsIntRegion GetRenderRegion();
+  void SetRenderRegion(LayerIntRegion&& aRegion) override;
 
   MOZ_LAYER_DECL_NAME("PaintedLayerMLGPU", TYPE_PAINTED)
 
   void CleanupCachedResources();
 
 protected:
   void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
   bool OnPrepareToRender(FrameBuilder* aBuilder) override;
--- a/gfx/layers/mlgpu/RenderPassMLGPU.cpp
+++ b/gfx/layers/mlgpu/RenderPassMLGPU.cpp
@@ -376,17 +376,17 @@ ClearViewPass::IsCompatible(const ItemIn
   // We don't support opacity here since it would not blend correctly.
   MOZ_ASSERT(mColor.a == 1.0f);
   return true;
 }
 
 bool
 ClearViewPass::AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo)
 {
-  const LayerIntRegion& region = aItem->GetShadowVisibleRegion();
+  const LayerIntRegion& region = aItem->GetRenderRegion();
   for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) {
     IntRect rect = iter.Get().ToUnknownRect();
     rect += aInfo.translation.value();
     rect -= mView->GetTargetOffset();
     mRects.AppendElement(rect);
   }
   return true;
 }
@@ -409,17 +409,17 @@ SolidColorPass::AddToPass(LayerMLGPU* aL
   MOZ_ASSERT(aLayer->GetType() == Layer::TYPE_COLOR);
 
   ColorLayer* colorLayer = aLayer->GetLayer()->AsColorLayer();
 
   Txn txn(this);
 
   gfx::Color color = ComputeLayerColor(aLayer, colorLayer->GetColor());
 
-  const LayerIntRegion& region = aLayer->GetShadowVisibleRegion();
+  const LayerIntRegion& region = aLayer->GetRenderRegion();
   for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) {
     const IntRect rect = iter.Get().ToUnknownRect();
     ColorTraits traits(aInfo, Rect(rect), color);
 
     if (!txn.Add(traits)) {
       return false;
     }
   }
@@ -614,25 +614,26 @@ SingleTexturePass::AddToPass(LayerMLGPU*
     mTexture = texture;
     mSamplerMode = sampler;
     mOpacity = opacity;
     mTextureFlags = flags;
   }
 
   Txn txn(this);
 
+  // Note: these are two separate cases since no Info constructor takes in a
+  // base LayerMLGPU class.
   if (PaintedLayerMLGPU* layer = aLayer->AsPaintedLayerMLGPU()) {
     Info info(aItem, layer);
     if (!AddItems(txn, info, layer->GetRenderRegion())) {
       return false;
     }
   } else if (TexturedLayerMLGPU* layer = aLayer->AsTexturedLayerMLGPU()) {
     Info info(aItem, layer);
-    nsIntRegion visible = layer->GetShadowVisibleRegion().ToUnknownRegion();
-    if (!AddItems(txn, info, visible)) {
+    if (!AddItems(txn, info, layer->GetRenderRegion())) {
       return false;
     }
   }
 
   return txn.Commit();
 }
 
 Maybe<MLGBlendState>
@@ -773,18 +774,17 @@ VideoRenderPass::AddToPass(LayerMLGPU* a
   }
   MOZ_ASSERT(!mTexture->AsBigImageIterator());
   MOZ_ASSERT(!(mHost->GetFlags() & TextureFlags::NON_PREMULTIPLIED));
   MOZ_ASSERT(!(mHost->GetFlags() & TextureFlags::ORIGIN_BOTTOM_LEFT));
 
   Txn txn(this);
 
   Info info(aItem, layer);
-  nsIntRegion visible = layer->GetShadowVisibleRegion().ToUnknownRegion();
-  if (!AddItems(txn, info, visible)) {
+  if (!AddItems(txn, info, layer->GetRenderRegion())) {
     return false;
   }
   return txn.Commit();
 }
 
 void
 VideoRenderPass::SetupPipeline()
 {
@@ -876,17 +876,17 @@ RenderViewPass::AddToPass(LayerMLGPU* aL
   mParentView = aItem.view;
 
   Txn txn(this);
 
   IntPoint offset = mAssignedLayer->GetTargetOffset();
   IntSize size = mAssignedLayer->GetTargetSize();
 
   // Clamp the visible region to the texture size.
-  nsIntRegion visible = mAssignedLayer->GetShadowVisibleRegion().ToUnknownRegion();
+  nsIntRegion visible = mAssignedLayer->GetRenderRegion().ToUnknownRegion();
   visible.AndWith(IntRect(offset, size));
 
   Info info(aItem, mAssignedLayer);
   if (!AddItems(txn, info, visible)) {
     return false;
   }
   return txn.Commit();
 }
@@ -929,17 +929,17 @@ GetShaderForBlendMode(CompositionOp aOp)
     MOZ_ASSERT_UNREACHABLE("Unexpected blend mode");
     return PixelShaderID::TexturedVertexRGBA;
   }
 }
 
 bool
 RenderViewPass::PrepareBlendState()
 {
-  Rect visibleRect(mAssignedLayer->GetShadowVisibleRegion().GetBounds().ToUnknownRect());
+  Rect visibleRect(mAssignedLayer->GetRenderRegion().GetBounds().ToUnknownRect());
   IntRect clipRect(mAssignedLayer->GetComputedClipRect().ToUnknownRect());
   const Matrix4x4& transform = mAssignedLayer->GetLayer()->GetEffectiveTransformForBuffer();
 
   // Note that we must use our parent RenderView for this calculation,
   // since we're copying the backdrop, not our actual local target.
   IntRect rtRect(mParentView->GetTargetOffset(), mParentView->GetSize());
 
   Matrix4x4 backdropTransform;
@@ -1019,17 +1019,17 @@ RenderViewPass::RenderWithBackdropCopy()
   const Matrix4x4& transform = mAssignedLayer->GetEffectiveTransform();
   MOZ_ASSERT(transform.Is2D(&transform2d) &&
              !gfx::ThebesMatrix(transform2d).HasNonIntegerTranslation());
 
   IntPoint translation = IntPoint::Truncate(transform._41, transform._42);
 
   RenderViewMLGPU* childView = mAssignedLayer->GetRenderView();
 
-  IntRect visible = mAssignedLayer->GetShadowVisibleRegion().GetBounds().ToUnknownRect();
+  IntRect visible = mAssignedLayer->GetRenderRegion().GetBounds().ToUnknownRect();
   IntRect sourceRect = visible + translation - mParentView->GetTargetOffset();
   IntPoint destPoint = visible.TopLeft() - childView->GetTargetOffset();
 
   RefPtr<MLGTexture> dest = mAssignedLayer->GetRenderTarget()->GetTexture();
   RefPtr<MLGTexture> source = mParentView->GetRenderTarget()->GetTexture();
 
   // Clamp the source rect to the source texture size.
   sourceRect = sourceRect.Intersect(IntRect(IntPoint(0, 0), source->GetSize()));
--- a/gfx/layers/mlgpu/RenderPassMLGPU.h
+++ b/gfx/layers/mlgpu/RenderPassMLGPU.h
@@ -309,22 +309,23 @@ protected:
   //
   // The origin is the offset from the draw rect to the layer bounds. You can
   // also think of it as the translation from layer space into texture space,
   // pre-scaling. For example, ImageLayers use the texture bounds as their
   // draw rect, so the origin will be (0, 0). ContainerLayer intermediate
   // surfaces, on the other hand, are relative to the target offset of the
   // layer. In all cases the visible region may be partially occluded, so
   // knowing the true origin is important.
+  template <typename RegionType>
   bool AddItems(Txn& aTxn,
                 const Info& aInfo,
-                const nsIntRegion& aDrawRegion)
+                const RegionType& aDrawRegion)
   {
     for (auto iter = aDrawRegion.RectIter(); !iter.Done(); iter.Next()) {
-      gfx::Rect drawRect = gfx::Rect(iter.Get());
+      gfx::Rect drawRect = gfx::Rect(iter.Get().ToUnknownRect());
       if (!AddItem(aTxn, aInfo, drawRect)) {
         return false;
       }
     }
     return true;
   }
 
 private:
--- a/gfx/layers/mlgpu/RenderViewMLGPU.cpp
+++ b/gfx/layers/mlgpu/RenderViewMLGPU.cpp
@@ -130,17 +130,17 @@ RenderViewMLGPU::Render()
 void
 RenderViewMLGPU::RenderAfterBackdropCopy()
 {
   MOZ_ASSERT(mContainer && mContainer->NeedsSurfaceCopy());
 
   // Update the invalid bounds based on the container's visible region. This
   // of course won't affect the prepared pipeline, but it will change the
   // scissor rect in SetDeviceState.
-  mInvalidBounds = mContainer->GetShadowVisibleRegion().GetBounds().ToUnknownRect() -
+  mInvalidBounds = mContainer->GetRenderRegion().GetBounds().ToUnknownRect() -
                    GetTargetOffset();
 
   ExecuteRendering();
 }
 
 void
 RenderViewMLGPU::FinishBuilding()
 {
@@ -210,18 +210,18 @@ RenderViewMLGPU::UpdateVisibleRegion(Ite
   // culling work for us.
   if (mUseDepthBuffer ||
       !aItem.translation ||
       !gfxPrefs::AdvancedLayersEnableCPUOcclusion())
   {
     // Update the render region even if we won't compute visibility, since some
     // layer types (like Canvas and Image) need to have the visible region
     // clamped.
-    LayerIntRegion region = Move(aItem.layer->GetShadowVisibleRegion());
-    aItem.layer->SetRegionToRender(Move(region));
+    LayerIntRegion region = aItem.layer->GetShadowVisibleRegion();
+    aItem.layer->SetRenderRegion(Move(region));
 
     AL_LOG("RenderView %p simple occlusion test, bounds=%s, translation?=%d\n",
       this,
       Stringify(aItem.bounds).c_str(),
       aItem.translation ? 1 : 0);
     return mInvalidBounds.Intersects(aItem.bounds);
   }
 
@@ -233,39 +233,39 @@ RenderViewMLGPU::UpdateVisibleRegion(Ite
   // Compute the translation into render target space.
   LayerIntPoint translation =
     LayerIntPoint::FromUnknownPoint(aItem.translation.value() - mTargetOffset);
   AL_LOG("  translation=%s\n", Stringify(translation).c_str());
 
   IntRect clip = aItem.layer->GetComputedClipRect().ToUnknownRect();
   AL_LOG("  clip=%s\n", Stringify(translation).c_str());
 
-  LayerIntRegion region = Move(aItem.layer->GetShadowVisibleRegion());
+  LayerIntRegion region = aItem.layer->GetShadowVisibleRegion();
   region.MoveBy(translation);
   AL_LOG("  effective-visible=%s\n", Stringify(region).c_str());
 
   region.SubOut(mOccludedRegion);
   region.AndWith(LayerIntRect::FromUnknownRect(mInvalidBounds));
   region.AndWith(LayerIntRect::FromUnknownRect(clip));
   if (region.IsEmpty()) {
     return false;
   }
 
   // Move the visible region back into layer space.
   region.MoveBy(-translation);
   AL_LOG("  new-local-visible=%s\n", Stringify(region).c_str());
 
-  aItem.layer->SetRegionToRender(Move(region));
+  aItem.layer->SetRenderRegion(Move(region));
 
   // Apply the new occluded area. We do another dance with the translation to
   // avoid copying the region. We do this after the SetRegionToRender call to
   // accomodate the possiblity of a layer changing its visible region.
   if (aItem.opaque) {
     mOccludedRegion.MoveBy(-translation);
-    mOccludedRegion.OrWith(aItem.layer->GetShadowVisibleRegion());
+    mOccludedRegion.OrWith(aItem.layer->GetRenderRegion());
     mOccludedRegion.MoveBy(translation);
     AL_LOG("  new-occluded=%s\n", Stringify(mOccludedRegion).c_str());
 
     // If the occluded region gets too complicated, we reset it.
     if (mOccludedRegion.GetNumRects() >= 32) {
       mOccludedRegion.SetEmpty();
       AL_LOG("  clear-occluded, too many rects\n");
     }