Bug 1276923. BasicCompositor: Properly transform the clip. r=mstange
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Fri, 03 Jun 2016 14:34:30 -0400
changeset 300405 49762b7df7479802962bd1a6c985a21f83822f1a
parent 300404 3978ffc8e928ddb29dac43b99e49635d79a913c2
child 300406 d35a3e8043bda4cfcfeb38690261c789bbbc8b43
push id77933
push userjmuizelaar@mozilla.com
push dateFri, 03 Jun 2016 18:49:58 +0000
treeherdermozilla-inbound@49762b7df747 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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 1276923. BasicCompositor: Properly transform the clip. r=mstange We push the clip on the buffer while it has the original transform, and then we overwrite the transform with something else. But the fast path operates in device space and ignores the existing clip on the buffer, so we need to know the original clip at the original transform.
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -280,52 +280,56 @@ SetupMask(const EffectChain& aEffectChai
 static bool
 AttemptVideoScale(TextureSourceBasic* aSource, const SourceSurface* aSourceMask,
                        gfx::Float aOpacity, CompositionOp aBlendMode,
                        const TexturedEffect* aTexturedEffect,
                        const Matrix& aNewTransform, const gfx::Rect& aRect,
-                       const gfx::IntRect& aClipRect,
+                       const gfx::Rect& aClipRect,
                        DrawTarget* aDest, const DrawTarget* aBuffer)
-  if (true || !mozilla::supports_ssse3())
+  if (!mozilla::supports_ssse3())
       return false;
   if (aNewTransform.IsTranslation()) // unscaled painting should take the regular path
       return false;
   if (aNewTransform.HasNonAxisAlignedTransform() || aNewTransform.HasNegativeScaling())
       return false;
   if (aSourceMask || aOpacity != 1.0f)
       return false;
   if (aBlendMode != CompositionOp::OP_OVER && aBlendMode != CompositionOp::OP_SOURCE)
       return false;
   IntRect dstRect;
   // the compiler should know a lot about aNewTransform at this point
   // maybe it can do some sophisticated optimization of the following
   if (!aNewTransform.TransformBounds(aRect).ToIntRect(&dstRect))
       return false;
+  IntRect clipRect;
+  if (!aClipRect.ToIntRect(&clipRect))
+      return false;
   if (!(aTexturedEffect->mTextureCoords == Rect(0.0f, 0.0f, 1.0f, 1.0f)))
       return false;
   if (aDest->GetFormat() == SurfaceFormat::R5G6B5_UINT16)
       return false;
   uint8_t* dstData;
   IntSize dstSize;
   int32_t dstStride;
   SurfaceFormat dstFormat;
   if (aDest->LockBits(&dstData, &dstSize, &dstStride, &dstFormat)) {
     // If we're not painting to aBuffer the clip will
     // be applied later
     IntRect fillRect = dstRect;
     if (aDest == aBuffer) {
       // we need to clip fillRect because LockBits ignores the clip on the aDest
-      fillRect = fillRect.Intersect(aClipRect);
+      fillRect = fillRect.Intersect(clipRect);
     fillRect = fillRect.Intersect(IntRect(IntPoint(0, 0), aDest->GetSize()));
     IntPoint offset = fillRect.TopLeft() - dstRect.TopLeft();
     RefPtr<DataSourceSurface> srcSource = aSource->GetSurface(aDest)->GetDataSurface();
     DataSourceSurface::ScopedMap mapSrc(srcSource, DataSourceSurface::READ);
@@ -386,16 +390,20 @@ BasicCompositor::DrawQuad(const gfx::Rec
     newTransform = Matrix();
     // When we apply the 3D transformation, we do it against a temporary
     // surface, so undo the coordinate offset.
     new3DTransform = aTransform;
     new3DTransform.PreTranslate(aRect.x, aRect.y, 0);
+  // XXX the transform is probably just an integer offset so this whole
+  // business here is a bit silly.
+  Rect transformedClipRect = buffer->GetTransform().TransformBounds(Rect(aClipRect));
   newTransform.PostTranslate(-offset.x, -offset.y);
   RefPtr<SourceSurface> sourceMask;
   Matrix maskTransform;
   if (aTransform.Is2D()) {
@@ -430,17 +438,17 @@ BasicCompositor::DrawQuad(const gfx::Rec
       TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic();
       if (source && texturedEffect->mPremultiplied) {
         // we have a fast path for video here
         if (source->mFromYCBCR &&
             AttemptVideoScale(source, sourceMask, aOpacity, blendMode,
-                              newTransform, aRect, aClipRect - offset,
+                              newTransform, aRect, transformedClipRect,
                               dest, buffer)) {
           // we succeeded in scaling
         } else {
           DrawSurfaceWithTextureCoords(dest, aRect,
                                        DrawOptions(aOpacity, blendMode),