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 198638 a14c6bf99d13848a30b4287de0e0d663da5763fc
parent 198637 7711e1bc8d4b5f1d8f9ccea14d8e4c18e5a079e7
child 198639 fbb86a21aba02addaf21d8047f828205f0813bef
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs993004
milestone31.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 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;