Commit 4adc8a10 authored by Matt Woodrow's avatar Matt Woodrow
Browse files

Bug 1727876 - Remove BasicCompositor. r=jrmuizel

Depends on D123882

Differential Revision: https://phabricator.services.mozilla.com/D123883
parent 5c99a197
Loading
Loading
Loading
Loading

gfx/layers/basic/AutoMaskData.h

deleted100644 → 0
+0 −54
Original line number Diff line number Diff line
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef GFX_AUTOMASKDATA_H_
#define GFX_AUTOMASKDATA_H_

#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor

namespace mozilla {
namespace layers {

/**
 * Drawing with a mask requires a mask surface and a transform.
 *
 * This helper class manages the SourceSurface logic.
 */
class MOZ_STACK_CLASS AutoMoz2DMaskData {
 public:
  AutoMoz2DMaskData() = default;
  ~AutoMoz2DMaskData() = default;

  void Construct(const gfx::Matrix& aTransform, gfx::SourceSurface* aSurface) {
    MOZ_ASSERT(!IsConstructed());
    mTransform = aTransform;
    mSurface = aSurface;
  }

  gfx::SourceSurface* GetSurface() {
    MOZ_ASSERT(IsConstructed());
    return mSurface.get();
  }

  const gfx::Matrix& GetTransform() {
    MOZ_ASSERT(IsConstructed());
    return mTransform;
  }

 private:
  bool IsConstructed() { return !!mSurface; }

  gfx::Matrix mTransform;
  RefPtr<gfx::SourceSurface> mSurface;

  AutoMoz2DMaskData(const AutoMoz2DMaskData&) = delete;
  AutoMoz2DMaskData& operator=(const AutoMoz2DMaskData&) = delete;
};

}  // namespace layers
}  // namespace mozilla

#endif  // GFX_AUTOMASKDATA_H_
+0 −1256

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −240
Original line number Diff line number Diff line
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_GFX_BASICCOMPOSITOR_H
#define MOZILLA_GFX_BASICCOMPOSITOR_H

#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Triangle.h"
#include "mozilla/gfx/Polygon.h"

namespace mozilla {
namespace layers {

class BasicCompositingRenderTarget : public CompositingRenderTarget {
 public:
  BasicCompositingRenderTarget(gfx::DrawTarget* aDrawTarget,
                               const gfx::IntRect& aRect,
                               const gfx::IntPoint& aClipSpaceOrigin)
      : CompositingRenderTarget(aRect.TopLeft()),
        mDrawTarget(aDrawTarget),
        mSize(aRect.Size()),
        mClipSpaceOrigin(aClipSpaceOrigin) {}

  const char* Name() const override { return "BasicCompositingRenderTarget"; }

  gfx::IntSize GetSize() const override { return mSize; }

  // The point that DrawGeometry's aClipRect is relative to. Will be (0, 0) for
  // root render targets and equal to GetOrigin() for non-root render targets.
  gfx::IntPoint GetClipSpaceOrigin() const { return mClipSpaceOrigin; }

  // In render target coordinates, i.e. the same space as GetOrigin().
  // NOT relative to mClipSpaceOrigin!
  void SetClipRect(const Maybe<gfx::IntRect>& aRect) { mClipRect = aRect; }
  const Maybe<gfx::IntRect>& GetClipRect() const { return mClipRect; }

  void BindRenderTarget();

  gfx::SurfaceFormat GetFormat() const override {
    return mDrawTarget ? mDrawTarget->GetFormat()
                       : gfx::SurfaceFormat(gfx::SurfaceFormat::UNKNOWN);
  }

  RefPtr<gfx::DrawTarget> mDrawTarget;
  gfx::IntSize mSize;
  gfx::IntPoint mClipSpaceOrigin;
  Maybe<gfx::IntRect> mClipRect;
};

class BasicCompositor : public Compositor {
 public:
  BasicCompositor(CompositorBridgeParent* aParent,
                  widget::CompositorWidget* aWidget);

 protected:
  virtual ~BasicCompositor();

 public:
  BasicCompositor* AsBasicCompositor() override { return this; }

  bool Initialize(nsCString* const out_failureReason) override;

  void Destroy() override;

  TextureFactoryIdentifier GetTextureFactoryIdentifier() override;

  already_AddRefed<CompositingRenderTarget> CreateRenderTarget(
      const gfx::IntRect& aRect, SurfaceInitMode aInit) override;

  already_AddRefed<CompositingRenderTarget> CreateRenderTargetFromSource(
      const gfx::IntRect& aRect, const CompositingRenderTarget* aSource,
      const gfx::IntPoint& aSourcePoint) override;

  virtual already_AddRefed<CompositingRenderTarget> CreateRootRenderTarget(
      gfx::DrawTarget* aDrawTarget, const gfx::IntRect& aDrawTargetRect,
      const gfx::IntRegion& aClearRegion);

  already_AddRefed<DataTextureSource> CreateDataTextureSource(
      TextureFlags aFlags = TextureFlags::NO_FLAGS) override;

  already_AddRefed<DataTextureSource> CreateDataTextureSourceAround(
      gfx::DataSourceSurface* aSurface) override;

  already_AddRefed<DataTextureSource> CreateDataTextureSourceAroundYCbCr(
      TextureHost* aTexture) override;

  bool SupportsEffect(EffectTypes aEffect) override;

  bool SupportsLayerGeometry() const override;

  bool ReadbackRenderTarget(CompositingRenderTarget* aSource,
                            AsyncReadbackBuffer* aDest) override;

  already_AddRefed<AsyncReadbackBuffer> CreateAsyncReadbackBuffer(
      const gfx::IntSize& aSize) override;

  bool BlitRenderTarget(CompositingRenderTarget* aSource,
                        const gfx::IntSize& aSourceSize,
                        const gfx::IntSize& aDestSize) override;

  void SetRenderTarget(CompositingRenderTarget* aSource) override {
    mRenderTarget = static_cast<BasicCompositingRenderTarget*>(aSource);
    mRenderTarget->BindRenderTarget();
  }

  already_AddRefed<CompositingRenderTarget> GetWindowRenderTarget()
      const override {
    return do_AddRef(mFullWindowRenderTarget);
  }

  already_AddRefed<CompositingRenderTarget> GetCurrentRenderTarget()
      const override {
    return do_AddRef(mRenderTarget);
  }

  void DrawQuad(const gfx::Rect& aRect, const gfx::IntRect& aClipRect,
                const EffectChain& aEffectChain, gfx::Float aOpacity,
                const gfx::Matrix4x4& aTransform,
                const gfx::Rect& aVisibleRect) override;

  void ClearRect(const gfx::Rect& aRect) override;

  Maybe<gfx::IntRect> BeginFrameForWindow(
      const nsIntRegion& aInvalidRegion, const Maybe<gfx::IntRect>& aClipRect,
      const gfx::IntRect& aRenderBounds,
      const nsIntRegion& aOpaqueRegion) override;

  Maybe<gfx::IntRect> BeginFrameForTarget(
      const nsIntRegion& aInvalidRegion, const Maybe<gfx::IntRect>& aClipRect,
      const gfx::IntRect& aRenderBounds, const nsIntRegion& aOpaqueRegion,
      gfx::DrawTarget* aTarget, const gfx::IntRect& aTargetBounds) override;

  void BeginFrameForNativeLayers() override;

  Maybe<gfx::IntRect> BeginRenderingToNativeLayer(
      const nsIntRegion& aInvalidRegion, const Maybe<gfx::IntRect>& aClipRect,
      const nsIntRegion& aOpaqueRegion, NativeLayer* aNativeLayer) override;

  void EndRenderingToNativeLayer() override;

  void NormalDrawingDone() override;
  void EndFrame() override;

  RefPtr<SurfacePoolHandle> GetSurfacePoolHandle() override;

  bool SupportsPartialTextureUpdate() override { return true; }
  bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) override {
    return true;
  }
  int32_t GetMaxTextureSize() const override;
  void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override {}

  void MakeCurrent(MakeCurrentFlags aFlags = 0) override {}

#ifdef MOZ_DUMP_PAINTING
  const char* Name() const override { return "Basic"; }
#endif  // MOZ_DUMP_PAINTING

  LayersBackend GetBackendType() const override {
    return LayersBackend::LAYERS_BASIC;
  }

  bool IsPendingComposite() override { return mIsPendingEndRemoteDrawing; }

  void FinishPendingComposite() override;

 private:
  template <typename Geometry>
  void DrawGeometry(const Geometry& aGeometry, const gfx::Rect& aRect,
                    const gfx::IntRect& aClipRect,
                    const EffectChain& aEffectChain, gfx::Float aOpacity,
                    const gfx::Matrix4x4& aTransform,
                    const gfx::Rect& aVisibleRect, const bool aEnableAA);

  void DrawPolygon(const gfx::Polygon& aPolygon, const gfx::Rect& aRect,
                   const gfx::IntRect& aClipRect,
                   const EffectChain& aEffectChain, gfx::Float aOpacity,
                   const gfx::Matrix4x4& aTransform,
                   const gfx::Rect& aVisibleRect) override;

  void TryToEndRemoteDrawing();
  void EndRemoteDrawing();

  bool NeedsToDeferEndRemoteDrawing();

  bool NeedToRecreateFullWindowRenderTarget() const;

  // When rendering to a back buffer, this is the front buffer that the contents
  // of the back buffer need to be copied to. Only non-null between
  // BeginFrameForWindow and EndRemoteDrawing, and only when using a back
  // buffer.
  RefPtr<gfx::DrawTarget> mFrontBuffer;

  // The current render target for drawing
  RefPtr<BasicCompositingRenderTarget> mRenderTarget;

  // The native layer that we're currently rendering to, if any.
  // Non-null only between BeginFrameForWindow and EndFrame if
  // BeginFrameForWindow has been called with a non-null aNativeLayer.
  RefPtr<NativeLayer> mCurrentNativeLayer;

  RefPtr<SurfacePoolHandle> mSurfacePoolHandle;

  gfx::IntRegion mInvalidRegion;

  uint32_t mMaxTextureSize;
  bool mIsPendingEndRemoteDrawing;
  bool mShouldInvalidateWindow = false;

  // Where the current frame is being rendered to.
  enum class FrameDestination : uint8_t {
    NO_CURRENT_FRAME,  // before BeginFrameForXYZ or after EndFrame
    WINDOW,            // between BeginFrameForWindow and EndFrame
    TARGET,            // between BeginFrameForTarget and EndFrame
    NATIVE_LAYERS      // between BeginFrameForNativeLayers and EndFrame
  };
  FrameDestination mCurrentFrameDest = FrameDestination::NO_CURRENT_FRAME;

  // mDrawTarget will not be the full window on all platforms. We therefore need
  // to keep a full window render target around when we are capturing
  // screenshots on those platforms.
  RefPtr<BasicCompositingRenderTarget> mFullWindowRenderTarget;

  // The 1x1 dummy render target that's the "current" render target between
  // BeginFrameForNativeLayers and EndFrame but outside pairs of
  // Begin/EndRenderingToNativeLayer. Created on demand.
  RefPtr<CompositingRenderTarget> mNativeLayersReferenceRT;
};

BasicCompositor* AssertBasicCompositor(Compositor* aCompositor);

}  // namespace layers
}  // namespace mozilla

#endif /* MOZILLA_GFX_BASICCOMPOSITOR_H */

gfx/layers/basic/BasicImplData.h

deleted100644 → 0
+0 −140
Original line number Diff line number Diff line
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef GFX_BASICIMPLDATA_H
#define GFX_BASICIMPLDATA_H

#include "mozilla/AlreadyAddRefed.h"  // for already_AddRefed
#include "mozilla/gfx/Point.h"        // for Point
#include "mozilla/gfx/Types.h"  // for CompositionOp, CompositionOp::OP_OVER, CompositionOp::OP_SOURCE
#include "mozilla/layers/LayerManager.h"  // for LayerManager, LayerManager::DrawPaintedLayerCallback
#include "nsDebug.h"      // for NS_ASSERTION
#include "nsISupports.h"  // for MOZ_COUNTED_DTOR_VIRTUAL, MOZ_COUNT_CTOR

class gfxContext;

namespace mozilla {
namespace gfx {
class DrawTarget;
class SourceSurface;
}  // namespace gfx

namespace layers {

class Layer;
class ReadbackProcessor;

/**
 * This is the ImplData for all Basic layers. It also exposes methods
 * private to the Basic implementation that are common to all Basic layer types.
 * In particular, there is an internal Paint() method that we can use
 * to paint the contents of non-PaintedLayers.
 *
 * The class hierarchy for Basic layers is like this:
 *                                 BasicImplData
 * Layer                            |   |   |
 *  |                               |   |   |
 *  +-> ContainerLayer              |   |   |
 *  |    |                          |   |   |
 *  |    +-> BasicContainerLayer <--+   |   |
 *  |                                   |   |
 *  +-> PaintedLayer                     |   |
 *  |    |                              |   |
 *  |    +-> BasicPaintedLayer <---------+   |
 *  |                                       |
 *  +-> ImageLayer                          |
 *       |                                  |
 *       +-> BasicImageLayer <--------------+
 */
class BasicImplData {
 public:
  BasicImplData()
      : mHidden(false),
        mClipToVisibleRegion(false),
        mDrawAtomically(false),
        mOperator(gfx::CompositionOp::OP_OVER) {
    MOZ_COUNT_CTOR(BasicImplData);
  }
  MOZ_COUNTED_DTOR_VIRTUAL(BasicImplData)

  /**
   * Layers that paint themselves, such as ImageLayers, should paint
   * in response to this method call. aContext will already have been
   * set up to account for all the properties of the layer (transform,
   * opacity, etc).
   */
  virtual void Paint(gfx::DrawTarget* aDT, const gfx::Point& aDeviceOffset,
                     Layer* aMaskLayer) {}

  /**
   * Like Paint() but called for PaintedLayers with the additional parameters
   * they need.
   * If mClipToVisibleRegion is set, then the layer must clip to its
   * effective visible region (snapped or unsnapped, it doesn't matter).
   */
  virtual void PaintThebes(gfxContext* aContext, Layer* aMasklayer,
                           LayerManager::DrawPaintedLayerCallback aCallback,
                           void* aCallbackData) {}

  virtual void Validate(LayerManager::DrawPaintedLayerCallback aCallback,
                        void* aCallbackData, ReadbackProcessor* aReadback) {}

  /**
   * Layers will get this call when their layer manager is destroyed, this
   * indicates they should clear resources they don't really need after their
   * LayerManager ceases to exist.
   */
  virtual void ClearCachedResources() {}

  /**
   * This variable is set by MarkLayersHidden() before painting. It indicates
   * that the layer should not be composited during this transaction.
   */
  void SetHidden(bool aCovered) { mHidden = aCovered; }
  bool IsHidden() const { return false; }
  /**
   * This variable is set by MarkLayersHidden() before painting. This is
   * the operator to be used when compositing the layer in this transaction. It
   * must be OVER or SOURCE.
   */
  void SetOperator(gfx::CompositionOp aOperator) {
    NS_ASSERTION(aOperator == gfx::CompositionOp::OP_OVER ||
                     aOperator == gfx::CompositionOp::OP_SOURCE,
                 "Bad composition operator");
    mOperator = aOperator;
  }

  gfx::CompositionOp GetOperator() const { return mOperator; }

  /**
   * Return a surface for this layer. Will use an existing surface, if
   * possible, or may create a temporary surface.  Implement this
   * method for any layers that might be used as a mask.  Should only
   * return false if a surface cannot be created.  If true is
   * returned, only one of |aSurface| or |aDescriptor| is valid.
   */
  virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() {
    return nullptr;
  }

  bool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
  void SetClipToVisibleRegion(bool aClip) { mClipToVisibleRegion = aClip; }

  void SetDrawAtomically(bool aDrawAtomically) {
    mDrawAtomically = aDrawAtomically;
  }

 protected:
  bool mHidden;
  bool mClipToVisibleRegion;
  bool mDrawAtomically;
  gfx::CompositionOp mOperator;
};

}  // namespace layers
}  // namespace mozilla

#endif
+0 −219
Original line number Diff line number Diff line
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "BasicLayersImpl.h"
#include <new>                    // for operator new
#include "Layers.h"               // for Layer, etc
#include "basic/BasicImplData.h"  // for BasicImplData
#include "mozilla/Assertions.h"   // for MOZ_ASSERT, etc
#include "mozilla/DebugOnly.h"    // for DebugOnly
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "AutoMaskData.h"

namespace mozilla {
namespace layers {

using namespace mozilla::gfx;

bool GetMaskData(Layer* aMaskLayer, const Point& aDeviceOffset,
                 AutoMoz2DMaskData* aMaskData) {
  if (aMaskLayer) {
    RefPtr<SourceSurface> surface =
        static_cast<BasicImplData*>(aMaskLayer->ImplData())
            ->GetAsSourceSurface();
    if (surface) {
      Matrix transform;
      Matrix4x4 effectiveTransform = aMaskLayer->GetEffectiveTransform();
      DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
      NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
      transform.PostTranslate(-aDeviceOffset.x, -aDeviceOffset.y);
      aMaskData->Construct(transform, surface);
      return true;
    }
  }
  return false;
}

already_AddRefed<SourceSurface> GetMaskForLayer(Layer* aLayer,
                                                Matrix* aMaskTransform) {
  if (!aLayer->GetMaskLayer()) {
    return nullptr;
  }

  MOZ_ASSERT(aMaskTransform);

  AutoMoz2DMaskData mask;
  if (GetMaskData(aLayer->GetMaskLayer(), Point(), &mask)) {
    *aMaskTransform = mask.GetTransform();
    RefPtr<SourceSurface> surf = mask.GetSurface();
    return surf.forget();
  }

  return nullptr;
}

void PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer) {
  AutoMoz2DMaskData mask;
  if (GetMaskData(aMaskLayer, Point(), &mask)) {
    aContext->SetMatrix(mask.GetTransform());
    aContext->Mask(mask.GetSurface(), aOpacity);
    return;
  }

  // if there is no mask, just paint normally
  aContext->Paint(aOpacity);
}

void FillRectWithMask(DrawTarget* aDT, const Rect& aRect,
                      const DeviceColor& aColor, const DrawOptions& aOptions,
                      SourceSurface* aMaskSource,
                      const Matrix* aMaskTransform) {
  if (aMaskSource && aMaskTransform) {
    aDT->PushClipRect(aRect);
    Matrix oldTransform = aDT->GetTransform();

    aDT->SetTransform(*aMaskTransform);
    aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
    aDT->SetTransform(oldTransform);
    aDT->PopClip();
    return;
  }

  aDT->FillRect(aRect, ColorPattern(aColor), aOptions);
}
void FillRectWithMask(DrawTarget* aDT, const gfx::Point& aDeviceOffset,
                      const Rect& aRect, const DeviceColor& aColor,
                      const DrawOptions& aOptions, Layer* aMaskLayer) {
  AutoMoz2DMaskData mask;
  if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
    const Matrix& maskTransform = mask.GetTransform();
    FillRectWithMask(aDT, aRect, aColor, aOptions, mask.GetSurface(),
                     &maskTransform);
    return;
  }

  FillRectWithMask(aDT, aRect, aColor, aOptions);
}

void FillRectWithMask(DrawTarget* aDT, const Rect& aRect,
                      SourceSurface* aSurface, SamplingFilter aSamplingFilter,
                      const DrawOptions& aOptions, ExtendMode aExtendMode,
                      SourceSurface* aMaskSource, const Matrix* aMaskTransform,
                      const Matrix* aSurfaceTransform) {
  if (aMaskSource && aMaskTransform) {
    aDT->PushClipRect(aRect);
    Matrix oldTransform = aDT->GetTransform();

    Matrix inverseMask = *aMaskTransform;
    inverseMask.Invert();

    Matrix transform = oldTransform * inverseMask;
    if (aSurfaceTransform) {
      transform = (*aSurfaceTransform) * transform;
    }

    SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);

    aDT->SetTransform(*aMaskTransform);
    aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);

    aDT->SetTransform(oldTransform);
    aDT->PopClip();
    return;
  }

  aDT->FillRect(
      aRect,
      SurfacePattern(aSurface, aExtendMode,
                     aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
                     aSamplingFilter),
      aOptions);
}

void FillRectWithMask(DrawTarget* aDT, const gfx::Point& aDeviceOffset,
                      const Rect& aRect, SourceSurface* aSurface,
                      SamplingFilter aSamplingFilter,
                      const DrawOptions& aOptions, Layer* aMaskLayer) {
  AutoMoz2DMaskData mask;
  if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
    const Matrix& maskTransform = mask.GetTransform();
    FillRectWithMask(aDT, aRect, aSurface, aSamplingFilter, aOptions,
                     ExtendMode::CLAMP, mask.GetSurface(), &maskTransform);
    return;
  }

  FillRectWithMask(aDT, aRect, aSurface, aSamplingFilter, aOptions,
                   ExtendMode::CLAMP);
}

void FillPathWithMask(DrawTarget* aDT, const Path* aPath, const Rect& aClipRect,
                      const DeviceColor& aColor, const DrawOptions& aOptions,
                      SourceSurface* aMaskSource,
                      const Matrix* aMaskTransform) {
  if (aMaskSource && aMaskTransform) {
    aDT->PushClipRect(aClipRect);
    Matrix oldTransform = aDT->GetTransform();

    aDT->SetTransform(*aMaskTransform);
    aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
    aDT->SetTransform(oldTransform);
    aDT->PopClip();
    return;
  }

  aDT->Fill(aPath, ColorPattern(aColor), aOptions);
}

void FillPathWithMask(DrawTarget* aDT, const Path* aPath, const Rect& aClipRect,
                      SourceSurface* aSurface, SamplingFilter aSamplingFilter,
                      const DrawOptions& aOptions, ExtendMode aExtendMode,
                      SourceSurface* aMaskSource, const Matrix* aMaskTransform,
                      const Matrix* aSurfaceTransform) {
  if (aMaskSource && aMaskTransform) {
    aDT->PushClipRect(aClipRect);
    Matrix oldTransform = aDT->GetTransform();

    Matrix inverseMask = *aMaskTransform;
    inverseMask.Invert();

    Matrix transform = oldTransform * inverseMask;
    if (aSurfaceTransform) {
      transform = (*aSurfaceTransform) * transform;
    }

    SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);

    aDT->SetTransform(*aMaskTransform);
    aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
    aDT->SetTransform(oldTransform);
    aDT->PopClip();
    return;
  }

  aDT->Fill(aPath,
            SurfacePattern(aSurface, aExtendMode,
                           aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
                           aSamplingFilter),
            aOptions);
}

BasicImplData* ToData(Layer* aLayer) {
  return static_cast<BasicImplData*>(aLayer->ImplData());
}

gfx::CompositionOp GetEffectiveOperator(Layer* aLayer) {
  CompositionOp op = aLayer->GetEffectiveMixBlendMode();

  if (op != CompositionOp::OP_OVER) {
    return op;
  }

  return ToData(aLayer)->GetOperator();
}

}  // namespace layers
}  // namespace mozilla
Loading