Bug 981794 - Fix incorrect clipping of tiles. r=Bas
authorNicolas Silva <nical@mozilla.com>
Tue, 11 Mar 2014 23:19:01 +0100
changeset 173094 499a25915134ae487e195b572a444dd5d389aaa3
parent 173093 aab0b6f3e34555982b12b8b6df6aea37e4dac1b8
child 173095 47b3d99c58a523e10bc1dc6d8ba7d733dce850e4
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersBas
bugs981794
milestone30.0a1
Bug 981794 - Fix incorrect clipping of tiles. r=Bas
gfx/layers/Compositor.h
gfx/layers/composite/TiledContentHost.cpp
gfx/layers/ipc/LayerTransactionParent.cpp
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -12,16 +12,17 @@
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float
 #include "mozilla/layers/CompositorTypes.h"  // for DiagnosticTypes, etc
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsRegion.h"
 #include <vector>
+#include "mozilla/WidgetUtils.h"
 
 /**
  * Different elements of a web pages are rendered into separate "layers" before
  * they are flattened into the final image that is brought to the screen.
  * See Layers.h for more informations about layers and why we use retained
  * structures.
  * Most of the documentation for layers is directly in the source code in the
  * form of doc comments. An overview can also be found in the the wiki:
@@ -196,16 +197,17 @@ public:
 class Compositor : public RefCounted<Compositor>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_TYPENAME(Compositor)
   Compositor(PCompositorParent* aParent = nullptr)
     : mCompositorID(0)
     , mDiagnosticTypes(DIAGNOSTIC_NONE)
     , mParent(aParent)
+    , mScreenRotation(ROTATION_0)
   {
     MOZ_COUNT_CTOR(Compositor);
   }
   virtual ~Compositor()
   {
     MOZ_COUNT_DTOR(Compositor);
   }
 
@@ -475,16 +477,40 @@ public:
     }
     return fillRatio;
   }
 
   virtual CompositorBackendSpecificData* GetCompositorBackendSpecificData() {
     return nullptr;
   }
 
+  ScreenRotation GetScreenRotation() const {
+    return mScreenRotation;
+  }
+
+  void SetScreenRotation(ScreenRotation aRotation) {
+    mScreenRotation = aRotation;
+  }
+
+  // On b2g the clip rect is in the coordinate space of the physical screen
+  // independently of its rotation, while the coordinate space of the layers,
+  // on the other hand, depends on the screen orientation.
+  // This only applies to b2g as with other platforms, orientation is handled
+  // at the OS level rather than in Gecko.
+  gfx::Rect ClipRectInLayersCoordinates(gfx::Rect aClip) const {
+    switch (mScreenRotation) {
+      case ROTATION_90:
+      case ROTATION_270:
+        return gfx::Rect(aClip.y, aClip.x, aClip.height, aClip.width);
+      case ROTATION_0:
+      case ROTATION_180:
+      default:
+        return aClip;
+    }
+  }
 protected:
   void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
                                const gfx::Rect& aVisibleRect,
                                const gfx::Rect& aClipRect,
                                const gfx::Matrix4x4& transform);
 
   bool ShouldDrawDiagnostics(DiagnosticFlags);
 
@@ -500,16 +526,18 @@ protected:
   /**
    * We keep track of the total number of pixels filled as we composite the
    * current frame. This value is an approximation and is not accurate,
    * especially in the presence of transforms.
    */
   size_t mPixelsPerFrame;
   size_t mPixelsFilled;
 
+  ScreenRotation mScreenRotation;
+
 private:
   static LayersBackend sBackend;
 
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/composite/TiledContentHost.cpp
+++ b/gfx/layers/composite/TiledContentHost.cpp
@@ -317,17 +317,17 @@ TiledContentHost::RenderTile(const TileH
     return;
   }
 
   nsIntRect screenBounds = aScreenRegion.GetBounds();
   Matrix mat = aTransform.As2D();
   Rect quad(screenBounds.x, screenBounds.y, screenBounds.width, screenBounds.height);
   quad = mat.TransformBounds(quad);
 
-  if (!quad.Intersects(aClipRect)) {
+  if (!quad.Intersects(mCompositor->ClipRectInLayersCoordinates(aClipRect))) {
     return;
   }
 
   AutoLockTextureHost autoLock(aTile.mTextureHost);
   if (autoLock.Failed()) {
     NS_WARNING("Failed to lock tile");
     return;
   }
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -206,16 +206,21 @@ LayerTransactionParent::RecvUpdate(const
 #endif
 
   MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length()));
 
   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
     return true;
   }
 
+  if (mLayerManager && mLayerManager->GetCompositor() &&
+      !targetConfig.naturalBounds().IsEmpty()) {
+    mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation());
+  }
+
   // Clear fence handles used in previsou transaction.
   ClearPrevFenceHandles();
 
   EditReplyVector replyv;
 
   {
     AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this));
     layer_manager()->BeginTransaction();