Bug 993004 - Fix the clipping of tiles when the screen is rotated. r=botond
authorNicolas Silva <nical@mozilla.com>
Fri, 25 Apr 2014 13:38:17 +0200
changeset 180547 a14c6bf99d13848a30b4287de0e0d663da5763fc
parent 180546 7711e1bc8d4b5f1d8f9ccea14d8e4c18e5a079e7
child 180548 fbb86a21aba02addaf21d8047f828205f0813bef
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersbotond
bugs993004
milestone31.0a1
Bug 993004 - Fix the clipping of tiles when the screen is rotated. r=botond
gfx/layers/Compositor.cpp
gfx/layers/Compositor.h
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/BasicCompositor.h
gfx/layers/d3d11/CompositorD3D11.h
gfx/layers/d3d9/CompositorD3D9.h
gfx/layers/opengl/CompositorOGL.h
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -102,28 +102,43 @@ Compositor::DrawDiagnostics(DiagnosticFl
 
   DrawDiagnosticsInternal(aFlags, aVisibleRect, aClipRect, aTransform,
                           aFlashCounter);
 }
 
 gfx::Rect
 Compositor::ClipRectInLayersCoordinates(gfx::Rect aClip) const {
   gfx::Rect result;
+  aClip = aClip + GetCurrentRenderTarget()->GetOrigin();
+  gfx::IntSize destSize = GetWidgetSize();
+
   switch (mScreenRotation) {
-    case ROTATION_90:
-    case ROTATION_270:
-      result = gfx::Rect(aClip.y, aClip.x, aClip.height, aClip.width);
-      break;
     case ROTATION_0:
-    case ROTATION_180:
-    default:
       result = aClip;
       break;
+    case ROTATION_90:
+      result = gfx::Rect(aClip.y,
+                         destSize.width - aClip.x - aClip.width,
+                         aClip.height, aClip.width);
+      break;
+    case ROTATION_270:
+      result = gfx::Rect(destSize.height - aClip.y - aClip.height,
+                         aClip.x,
+                         aClip.height, aClip.width);
+      break;
+    case ROTATION_180:
+      result = gfx::Rect(destSize.width - aClip.x - aClip.width,
+                         destSize.height - aClip.y - aClip.height,
+                         aClip.width, aClip.height);
+      break;
+      // ScreenRotation has a sentinel value, need to catch it in the switch
+      // statement otherwise the build fails (-WError)
+    default: {}
   }
-  return result + GetCurrentRenderTarget()->GetOrigin();
+  return result;
 }
 
 void
 Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags,
                                     const gfx::Rect& aVisibleRect,
                                     const gfx::Rect& aClipRect,
                                     const gfx::Matrix4x4& aTransform,
                                     uint32_t aFlashCounter)
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -495,16 +495,17 @@ public:
   // 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.
   // In addition, the clip rect needs to be offset by the rendering origin.
   // This becomes important if intermediate surfaces are used.
   gfx::Rect ClipRectInLayersCoordinates(gfx::Rect aClip) const;
+
 protected:
   void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
                                const gfx::Rect& aVisibleRect,
                                const gfx::Rect& aClipRect,
                                const gfx::Matrix4x4& transform,
                                uint32_t aFlashCounter);
 
   bool ShouldDrawDiagnostics(DiagnosticFlags);
@@ -523,16 +524,18 @@ protected:
    * 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;
 
+  virtual gfx::IntSize GetWidgetSize() const = 0;
+
 private:
   static LayersBackend sBackend;
 
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -373,16 +373,17 @@ BasicCompositor::BeginFrame(const nsIntR
                             const gfx::Rect *aClipRectIn,
                             const gfx::Matrix& aTransform,
                             const gfx::Rect& aRenderBounds,
                             gfx::Rect *aClipRectOut /* = nullptr */,
                             gfx::Rect *aRenderBoundsOut /* = nullptr */)
 {
   nsIntRect intRect;
   mWidget->GetClientBounds(intRect);
+  mWidgetSize = gfx::ToIntSize(intRect.Size());
 
   // The result of GetClientBounds is shifted over by the size of the window
   // manager styling. We want to ignore that.
   intRect.MoveTo(0, 0);
   Rect rect = Rect(0, 0, intRect.width, intRect.height);
 
   // Sometimes the invalid region is larger than we want to draw.
   nsIntRegion invalidRegionSafe;
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -120,19 +120,22 @@ public:
     return LayersBackend::LAYERS_BASIC;
   }
 
   virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
 
   gfx::DrawTarget *GetDrawTarget() { return mDrawTarget; }
 
 private:
+
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE { return mWidgetSize; }
+
   // Widget associated with this compositor
   nsIWidget *mWidget;
-  nsIntSize mWidgetSize;
+  gfx::IntSize mWidgetSize;
 
   // The final destination surface
   RefPtr<gfx::DrawTarget> mDrawTarget;
   // The current render target for drawing
   RefPtr<BasicCompositingRenderTarget> mRenderTarget;
   // An optional destination target to copy the results
   // to after drawing is completed.
   RefPtr<gfx::DrawTarget> mCopyTarget;
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -152,16 +152,18 @@ private:
   void VerifyBufferSize();
   void UpdateRenderTarget();
   bool CreateShaders();
   void UpdateConstantBuffers();
   void SetSamplerForFilter(gfx::Filter aFilter);
   void SetPSForEffect(Effect *aEffect, MaskType aMaskType, gfx::SurfaceFormat aFormat);
   void PaintToTarget();
 
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE { return gfx::ToIntSize(mSize); }
+
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<ID3D11Device> mDevice;
   RefPtr<IDXGISwapChain> mSwapChain;
   RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
 
   DeviceAttachmentsD3D11* mAttachments;
 
--- a/gfx/layers/d3d9/CompositorD3D9.h
+++ b/gfx/layers/d3d9/CompositorD3D9.h
@@ -148,16 +148,21 @@ private:
    * everything and render it all. This method checks the reset counts
    * match and if not invalidates everything (a long comment on that in
    * the cpp file).
    */
   void CheckResetCount();
 
   void ReportFailure(const nsACString &aMsg, HRESULT aCode);
 
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE
+  {
+    return gfx::ToIntSize(mSize);
+  }
+
   /* Device manager instance for this compositor */
   nsRefPtr<DeviceManagerD3D9> mDeviceManager;
 
   /* Swap chain associated with this compositor */
   nsRefPtr<SwapChainD3D9> mSwapChain;
 
   /* Widget associated with this layer manager */
   nsIWidget *mWidget;
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -280,16 +280,21 @@ public:
 private:
   virtual void DrawQuadInternal(const gfx::Rect& aRect,
                                 const gfx::Rect& aClipRect,
                                 const EffectChain &aEffectChain,
                                 gfx::Float aOpacity,
                                 const gfx::Matrix4x4 &aTransformi,
                                 GLuint aDrawMode);
 
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE
+  {
+    return gfx::ToIntSize(mWidgetSize);
+  }
+
   /**
    * Context target, nullptr when drawing directly to our swap chain.
    */
   RefPtr<gfx::DrawTarget> mTarget;
 
   /** Widget associated with this compositor */
   nsIWidget *mWidget;
   nsIntSize mWidgetSize;