Support all blend modes in the basic compositor. (bug 1203829 part 1, r=mattwoodrow)
authorDavid Anderson <dvander@alliedmods.net>
Tue, 15 Sep 2015 13:07:05 -0700
changeset 295272 c76ccb113197cacd158a011b0f985da4bff94853
parent 295271 60fdd3ce9836cb81adebfe7a21a3e48e094f11a2
child 295273 9d08ea4e6be94fb007b765e4f99fbc466379c7ad
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1203829
milestone43.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
Support all blend modes in the basic compositor. (bug 1203829 part 1, r=mattwoodrow)
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/BasicCompositor.h
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -104,16 +104,30 @@ BasicCompositingRenderTarget::BindRender
 }
 
 void BasicCompositor::Destroy()
 {
   mWidget->CleanupRemoteDrawing();
   mWidget = nullptr;
 }
 
+TextureFactoryIdentifier
+BasicCompositor::GetTextureFactoryIdentifier()
+{
+  TextureFactoryIdentifier ident(LayersBackend::LAYERS_BASIC,
+                                 XRE_GetProcessType(),
+                                 GetMaxTextureSize());
+
+  // All composition ops are supported in software.
+  for (uint8_t op = 0; op < uint8_t(CompositionOp::OP_COUNT); op++) {
+    ident.mSupportedBlendModes += CompositionOp(op);
+  }
+  return ident;
+}
+
 already_AddRefed<CompositingRenderTarget>
 BasicCompositor::CreateRenderTarget(const IntRect& aRect, SurfaceInitMode aInit)
 {
   MOZ_ASSERT(aRect.width != 0 && aRect.height != 0, "Trying to create a render target of invalid size");
 
   if (aRect.width * aRect.height == 0) {
     return nullptr;
   }
@@ -152,17 +166,17 @@ BasicCompositor::SupportsEffect(EffectTy
 }
 
 static void
 DrawSurfaceWithTextureCoords(DrawTarget *aDest,
                              const gfx::Rect& aDestRect,
                              SourceSurface *aSource,
                              const gfx::Rect& aTextureCoords,
                              gfx::Filter aFilter,
-                             float aOpacity,
+                             const DrawOptions& aOptions,
                              SourceSurface *aMask,
                              const Matrix* aMaskTransform)
 {
   // Convert aTextureCoords into aSource's coordinate space
   gfxRect sourceRect(aTextureCoords.x * aSource->GetSize().width,
                      aTextureCoords.y * aSource->GetSize().height,
                      aTextureCoords.width * aSource->GetSize().width,
                      aTextureCoords.height * aSource->GetSize().height);
@@ -177,17 +191,17 @@ DrawSurfaceWithTextureCoords(DrawTarget 
                                   gfx::IntPoint(aDestRect.x, aDestRect.y),
                                   gfx::IntPoint(aDestRect.XMost(), aDestRect.y),
                                   gfx::IntPoint(aDestRect.XMost(), aDestRect.YMost()));
 
   // Only use REPEAT if aTextureCoords is outside (0, 0, 1, 1).
   gfx::Rect unitRect(0, 0, 1, 1);
   ExtendMode mode = unitRect.Contains(aTextureCoords) ? ExtendMode::CLAMP : ExtendMode::REPEAT;
 
-  FillRectWithMask(aDest, aDestRect, aSource, aFilter, DrawOptions(aOpacity),
+  FillRectWithMask(aDest, aDestRect, aSource, aFilter, aOptions,
                    mode, aMask, aMaskTransform, &matrix);
 }
 
 #ifdef MOZ_ENABLE_SKIA
 static SkMatrix
 Matrix3DToSkia(const Matrix4x4& aMatrix)
 {
   SkMatrix transform;
@@ -378,48 +392,55 @@ BasicCompositor::DrawQuad(const gfx::Rec
     EffectMask *effectMask = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EffectTypes::MASK].get());
     sourceMask = effectMask->mMaskTexture->AsSourceBasic()->GetSurface(dest);
     MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!");
     MOZ_ASSERT(!effectMask->mIs3D);
     maskTransform = effectMask->mMaskTransform.As2D();
     maskTransform.PreTranslate(-offset.x, -offset.y);
   }
 
+  CompositionOp blendMode = CompositionOp::OP_OVER;
+  if (Effect* effect = aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get()) {
+    blendMode = static_cast<EffectBlendMode*>(effect)->mBlendMode;
+  }
+
   switch (aEffectChain.mPrimaryEffect->mType) {
     case EffectTypes::SOLID_COLOR: {
       EffectSolidColor* effectSolidColor =
         static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());
 
       FillRectWithMask(dest, aRect, effectSolidColor->mColor,
-                       DrawOptions(aOpacity), sourceMask, &maskTransform);
+                       DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform);
       break;
     }
     case EffectTypes::RGB: {
       TexturedEffect* texturedEffect =
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic();
 
       if (texturedEffect->mPremultiplied) {
           DrawSurfaceWithTextureCoords(dest, aRect,
                                        source->GetSurface(dest),
                                        texturedEffect->mTextureCoords,
                                        texturedEffect->mFilter,
-                                       aOpacity, sourceMask, &maskTransform);
+                                       DrawOptions(aOpacity, blendMode),
+                                       sourceMask, &maskTransform);
       } else {
           RefPtr<DataSourceSurface> srcData = source->GetSurface(dest)->GetDataSurface();
 
           // Yes, we re-create the premultiplied data every time.
           // This might be better with a cache, eventually.
           RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData);
 
           DrawSurfaceWithTextureCoords(dest, aRect,
                                        premultData,
                                        texturedEffect->mTextureCoords,
                                        texturedEffect->mFilter,
-                                       aOpacity, sourceMask, &maskTransform);
+                                       DrawOptions(aOpacity, blendMode),
+                                       sourceMask, &maskTransform);
       }
       break;
     }
     case EffectTypes::YCBCR: {
       NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!");
       break;
     }
     case EffectTypes::RENDER_TARGET: {
@@ -428,17 +449,18 @@ BasicCompositor::DrawQuad(const gfx::Rec
       RefPtr<BasicCompositingRenderTarget> surface
         = static_cast<BasicCompositingRenderTarget*>(effectRenderTarget->mRenderTarget.get());
       RefPtr<SourceSurface> sourceSurf = surface->mDrawTarget->Snapshot();
 
       DrawSurfaceWithTextureCoords(dest, aRect,
                                    sourceSurf,
                                    effectRenderTarget->mTextureCoords,
                                    effectRenderTarget->mFilter,
-                                   aOpacity, sourceMask, &maskTransform);
+                                   DrawOptions(aOpacity, blendMode),
+                                   sourceMask, &maskTransform);
       break;
     }
     case EffectTypes::COMPONENT_ALPHA: {
       NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!");
       break;
     }
     default: {
       NS_RUNTIMEABORT("Invalid effect type!");
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -45,22 +45,17 @@ public:
 protected:
   virtual ~BasicCompositor();
 
 public:
   virtual bool Initialize() override;
 
   virtual void Destroy() override;
 
-  virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override
-  {
-    return TextureFactoryIdentifier(LayersBackend::LAYERS_BASIC,
-                                    XRE_GetProcessType(),
-                                    GetMaxTextureSize());
-  }
+  virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override;
 
   virtual already_AddRefed<CompositingRenderTarget>
   CreateRenderTarget(const gfx::IntRect &aRect, SurfaceInitMode aInit) override;
 
   virtual already_AddRefed<CompositingRenderTarget>
   CreateRenderTargetFromSource(const gfx::IntRect &aRect,
                                const CompositingRenderTarget *aSource,
                                const gfx::IntPoint &aSourcePoint) override;