Bug 1220629 - Part 6: Implement PushLayer/PopLayer API in several wrapper DT types. r=jrmuizel
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -771,28 +771,33 @@ DrawTargetD2D1::PushLayer(bool aOpaque,
}
PushAllClips();
mDC->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(), clip, D2D1_ANTIALIAS_MODE_ALIASED, D2DMatrix(maskTransform), aOpacity, mask, options), nullptr);
PushedLayer pushedLayer;
pushedLayer.mClipsArePushed = false;
pushedLayer.mIsOpaque = aOpaque;
+ pushedLayer.mOldPermitSubpixelAA = mPermitSubpixelAA;
+ mPermitSubpixelAA = aOpaque;
+
mDC->CreateCommandList(getter_AddRefs(pushedLayer.mCurrentList));
mPushedLayers.push_back(pushedLayer);
mDC->SetTarget(CurrentTarget());
}
void
DrawTargetD2D1::PopLayer()
{
MOZ_ASSERT(CurrentLayer().mPushedClips.size() == 0);
RefPtr<ID2D1CommandList> list = CurrentLayer().mCurrentList;
+ mPermitSubpixelAA = CurrentLayer().mOldPermitSubpixelAA;
+
mPushedLayers.pop_back();
mDC->SetTarget(CurrentTarget());
list->Close();
mDC->SetTransform(D2D1::IdentityMatrix());
mTransformDirty = true;
DCCommandSink sink(mDC);
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -238,23 +238,24 @@ private:
bool mIsPixelAligned;
};
RefPtr<PathD2D> mPath;
};
// List of pushed layers.
struct PushedLayer
{
- PushedLayer() : mClipsArePushed(false), mIsOpaque(false) {}
+ PushedLayer() : mClipsArePushed(false), mIsOpaque(false), mOldPermitSubpixelAA(false) {}
std::vector<PushedClip> mPushedClips;
RefPtr<ID2D1CommandList> mCurrentList;
// True if the current clip stack is pushed to the CurrentTarget().
bool mClipsArePushed;
bool mIsOpaque;
+ bool mOldPermitSubpixelAA;
};
std::vector<PushedLayer> mPushedLayers;
PushedLayer& CurrentLayer()
{
return mPushedLayers.back();
}
// The latest snapshot of this surface. This needs to be told when this
--- a/gfx/2d/DrawTargetDual.cpp
+++ b/gfx/2d/DrawTargetDual.cpp
@@ -10,16 +10,21 @@
namespace mozilla {
namespace gfx {
class DualSurface
{
public:
inline explicit DualSurface(SourceSurface *aSurface)
{
+ if (!aSurface) {
+ mA = mB = nullptr;
+ return;
+ }
+
if (aSurface->GetType() != SurfaceType::DUAL_DT) {
mA = mB = aSurface;
return;
}
SourceSurfaceDual *ssDual =
static_cast<SourceSurfaceDual*>(aSurface);
mA = ssDual->mA;
@@ -176,16 +181,26 @@ void
DrawTargetDual::Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions)
{
DualPattern source(aSource);
DualPattern mask(aMask);
mA->Mask(*source.mA, *mask.mA, aOptions);
mB->Mask(*source.mB, *mask.mB, aOptions);
}
+void
+DrawTargetDual::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
+ const Matrix& aMaskTransform, const IntRect& aBounds,
+ bool aCopyBackground)
+{
+ DualSurface mask(aMask);
+ mA->PushLayer(aOpaque, aOpacity, mask.mA, aMaskTransform, aBounds, aCopyBackground);
+ mB->PushLayer(aOpaque, aOpacity, mask.mB, aMaskTransform, aBounds, aCopyBackground);
+}
+
already_AddRefed<DrawTarget>
DrawTargetDual::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{
RefPtr<DrawTarget> dtA = mA->CreateSimilarDrawTarget(aSize, aFormat);
RefPtr<DrawTarget> dtB = mB->CreateSimilarDrawTarget(aSize, aFormat);
if (!dtA || !dtB) {
gfxWarning() << "Failure to allocate a similar DrawTargetDual. Size: " << aSize;
--- a/gfx/2d/DrawTargetDual.h
+++ b/gfx/2d/DrawTargetDual.h
@@ -49,16 +49,17 @@ public:
return MakeAndAddRef<SourceSurfaceDual>(mA, mB);
}
virtual IntSize GetSize() override { return mA->GetSize(); }
FORWARD_FUNCTION(Flush)
FORWARD_FUNCTION1(PushClip, const Path *, aPath)
FORWARD_FUNCTION1(PushClipRect, const Rect &, aRect)
FORWARD_FUNCTION(PopClip)
+ FORWARD_FUNCTION(PopLayer)
FORWARD_FUNCTION1(ClearRect, const Rect &, aRect)
virtual void SetTransform(const Matrix &aTransform) override {
mTransform = aTransform;
mA->SetTransform(aTransform);
mB->SetTransform(aTransform);
}
@@ -99,17 +100,23 @@ public:
virtual void Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions &aOptions) override;
virtual void FillGlyphs(ScaledFont *aScaledFont, const GlyphBuffer &aBuffer,
const Pattern &aPattern, const DrawOptions &aOptions,
const GlyphRenderingOptions *aRenderingOptions) override;
virtual void Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions) override;
-
+
+ virtual void PushLayer(bool aOpaque, Float aOpacity,
+ SourceSurface* aMask,
+ const Matrix& aMaskTransform,
+ const IntRect& aBounds = IntRect(),
+ bool aCopyBackground = false) override;
+
virtual already_AddRefed<SourceSurface>
CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const override
{
return mA->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
}
@@ -150,16 +157,18 @@ public:
{
return nullptr;
}
virtual bool IsDualDrawTarget() const override
{
return true;
}
+
+ virtual bool IsCurrentGroupOpaque() override { return mA->IsCurrentGroupOpaque(); }
private:
RefPtr<DrawTarget> mA;
RefPtr<DrawTarget> mB;
};
} // namespace gfx
} // namespace mozilla
--- a/gfx/2d/DrawTargetTiled.cpp
+++ b/gfx/2d/DrawTargetTiled.cpp
@@ -300,10 +300,34 @@ DrawTargetTiled::Fill(const Path* aPath,
mTiles[i].mTileOrigin.y,
mTiles[i].mDrawTarget->GetSize().width,
mTiles[i].mDrawTarget->GetSize().height))) {
mTiles[i].mDrawTarget->Fill(aPath, aPattern, aDrawOptions);
}
}
}
+void
+DrawTargetTiled::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
+ const Matrix& aMaskTransform, const IntRect& aBounds,
+ bool aCopyBackground)
+{
+ // XXX - not sure this is what we want or whether we want to continue drawing to a larger
+ // intermediate surface, that would require tweaking the code in here a little though.
+ for (size_t i = 0; i < mTiles.size(); i++) {
+ IntRect bounds = aBounds;
+ bounds.MoveBy(-mTiles[i].mTileOrigin);
+ mTiles[i].mDrawTarget->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, aBounds);
+ }
+}
+
+void
+DrawTargetTiled::PopLayer()
+{
+ // XXX - not sure this is what we want or whether we want to continue drawing to a larger
+ // intermediate surface, that would require tweaking the code in here a little though.
+ for (size_t i = 0; i < mTiles.size(); i++) {
+ mTiles[i].mDrawTarget->PopLayer();
+ }
+}
+
} // namespace gfx
} // namespace mozilla
--- a/gfx/2d/DrawTargetTiled.h
+++ b/gfx/2d/DrawTargetTiled.h
@@ -98,16 +98,23 @@ public:
const DrawOptions &aOptions = DrawOptions(),
const GlyphRenderingOptions *aRenderingOptions = nullptr) override;
virtual void Mask(const Pattern &aSource,
const Pattern &aMask,
const DrawOptions &aOptions = DrawOptions()) override;
virtual void PushClip(const Path *aPath) override;
virtual void PushClipRect(const Rect &aRect) override;
virtual void PopClip() override;
+ virtual void PushLayer(bool aOpaque, Float aOpacity,
+ SourceSurface* aMask,
+ const Matrix& aMaskTransform,
+ const IntRect& aBounds = IntRect(),
+ bool aCopyBackground = false) override;
+ virtual void PopLayer() override;
+
virtual void SetTransform(const Matrix &aTransform) override;
virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const override
{