Bug 1412078 - Don't treat resampled layers as entirely opaque. r=mattwoodrow, a=ritu
authorDavid Anderson <danderson@mozilla.com>
Mon, 06 Nov 2017 12:18:01 -0800
changeset 435348 56086a67fdd5efd0ca04f75b1c82e772537e7699
parent 435347 33538b41a3525122ed2f315e1f1184b912957f8a
child 435349 9075468cdeb48f4bb3736728f2d2e9a17970ea6b
push id1578
push userryanvm@gmail.com
push dateWed, 08 Nov 2017 14:08:47 +0000
treeherdermozilla-release@ea14b85abeac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, ritu
bugs1412078
milestone57.0
Bug 1412078 - Don't treat resampled layers as entirely opaque. r=mattwoodrow, a=ritu
gfx/layers/mlgpu/LayerMLGPU.h
gfx/layers/mlgpu/PaintedLayerMLGPU.cpp
gfx/layers/mlgpu/PaintedLayerMLGPU.h
gfx/layers/mlgpu/RenderPassMLGPU.cpp
--- a/gfx/layers/mlgpu/LayerMLGPU.h
+++ b/gfx/layers/mlgpu/LayerMLGPU.h
@@ -69,19 +69,18 @@ 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 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.
+  // Returns the region that this layer will draw pixels to. If the layer and
+  // its content are opaque, this is the layer's opaque region.
   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
--- a/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp
+++ b/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp
@@ -43,32 +43,38 @@ PaintedLayerMLGPU::OnPrepareToRender(Fra
   return true;
 }
 
 void
 PaintedLayerMLGPU::SetRenderRegion(LayerIntRegion&& aRegion)
 {
   mRenderRegion = Move(aRegion);
 
+  LayerIntRect bounds(mRenderRegion.GetBounds().TopLeft(),
+                      ViewAs<LayerPixel>(mTexture->GetSize()));
+  mRenderRegion.AndWith(bounds);
+}
+
+const LayerIntRegion&
+PaintedLayerMLGPU::GetDrawRects()
+{
 #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()) {
-    mRenderRegion = mRenderRegion.GetBounds();
+    mDrawRects = mRenderRegion.GetBounds();
+    return mDrawRects;
   }
 #endif
-
-  LayerIntRect bounds(mRenderRegion.GetBounds().TopLeft(),
-                      ViewAs<LayerPixel>(mTexture->GetSize()));
-  mRenderRegion.AndWith(bounds);
+  return mRenderRegion;
 }
 
 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
@@ -56,30 +56,36 @@ public:
     // simply wrap around the edge of the buffer texture.
     return MayResample()
            ? SamplerMode::LinearClamp
            : SamplerMode::LinearRepeat;
   }
 
   void SetRenderRegion(LayerIntRegion&& aRegion) override;
 
+  // To avoid sampling issues with complex regions and transforms, we
+  // squash the visible region for PaintedLayers into a single draw
+  // rect. RenderPasses should use this method instead of GetRenderRegion.
+  const LayerIntRegion& GetDrawRects();
+
   MOZ_LAYER_DECL_NAME("PaintedLayerMLGPU", TYPE_PAINTED)
 
   void CleanupCachedResources();
 
 protected:
   void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
   bool OnPrepareToRender(FrameBuilder* aBuilder) override;
 
   void CleanupResources();
 
 private:
   RefPtr<ContentHostTexture> mHost;
   RefPtr<TextureSource> mTexture;
   RefPtr<TextureSource> mTextureOnWhite;
-  gfx::IntRegion mLocalDrawRegion;
-  gfx::IntRegion mTextureRegion;
+#ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
+  LayerIntRegion mDrawRects;
+#endif
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/mlgpu/RenderPassMLGPU.cpp
+++ b/gfx/layers/mlgpu/RenderPassMLGPU.cpp
@@ -618,17 +618,17 @@ SingleTexturePass::AddToPass(LayerMLGPU*
   }
 
   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())) {
+    if (!AddItems(txn, info, layer->GetDrawRects())) {
       return false;
     }
   } else if (TexturedLayerMLGPU* layer = aLayer->AsTexturedLayerMLGPU()) {
     Info info(aItem, layer);
     if (!AddItems(txn, info, layer->GetRenderRegion())) {
       return false;
     }
   }
@@ -694,17 +694,17 @@ ComponentAlphaPass::AddToPass(LayerMLGPU
     mAssignedLayer = layer;
     mTextureOnBlack = layer->GetTexture();
     mTextureOnWhite = layer->GetTextureOnWhite();
   } 
 
   Txn txn(this);
 
   Info info(aItem, layer);
-  if (!AddItems(txn, info, layer->GetRenderRegion())) {
+  if (!AddItems(txn, info, layer->GetDrawRects())) {
     return false;
   }
   return txn.Commit();
 }
 
 float
 ComponentAlphaPass::GetOpacity() const
 {