Bug 1276923. BasicCompositor: Properly transform the clip. r=mstange
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Fri, 03 Jun 2016 14:34:30 -0400
changeset 341501 49762b7df7479802962bd1a6c985a21f83822f1a
parent 341500 3978ffc8e928ddb29dac43b99e49635d79a913c2
child 341502 d35a3e8043bda4cfcfeb38690261c789bbbc8b43
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1276923
milestone49.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 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.
gfx/layers/basic/BasicCompositor.cpp
--- 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));
+
   buffer->PushClipRect(Rect(aClipRect));
 
   newTransform.PostTranslate(-offset.x, -offset.y);
   buffer->SetTransform(newTransform);
 
   RefPtr<SourceSurface> sourceMask;
   Matrix maskTransform;
   if (aTransform.Is2D()) {
@@ -430,17 +438,17 @@ BasicCompositor::DrawQuad(const gfx::Rec
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       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,
                               texturedEffect,
-                              newTransform, aRect, aClipRect - offset,
+                              newTransform, aRect, transformedClipRect,
                               dest, buffer)) {
           // we succeeded in scaling
         } else {
           DrawSurfaceWithTextureCoords(dest, aRect,
                                        source->GetSurface(dest),
                                        texturedEffect->mTextureCoords,
                                        texturedEffect->mSamplingFilter,
                                        DrawOptions(aOpacity, blendMode),