Bug 1429508 - Make SnapshotTiled::GetDataSurface return a surface the size of backed tiles only. r?jrmuizel
Fix the DrawTargetTiled::mRect initialization, and expose through the
virtual function GetRect(). Make SnapshotTiled::GetDataSurface()
allocate a surface the size of this rect, rather the XMost and
YMost. Callers of SourceSurface::GetDataSurface() can query
SourceSurface::GetRect() and apply the necessary offset themselves.
MozReview-Commit-ID: C31FGirQ0oK
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -364,16 +364,19 @@ class DrawTargetCaptureImpl;
class SourceSurface : public external::AtomicRefCounted<SourceSurface>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
virtual ~SourceSurface() {}
virtual SurfaceType GetType() const = 0;
virtual IntSize GetSize() const = 0;
+ virtual IntRect GetRect() const {
+ return IntRect(IntPoint(0, 0), GetSize());
+ }
virtual SurfaceFormat GetFormat() const = 0;
/** This returns false if some event has made this source surface invalid for
* usage with current DrawTargets. For example in the case of Direct2D this
* could return false if we have switched devices since this surface was
* created.
*/
virtual bool IsValid() const { return true; }
@@ -933,16 +936,19 @@ public:
*/
virtual already_AddRefed<SourceSurface> Snapshot() = 0;
// Snapshots the contents and returns an alpha mask
// based on the RGB values.
virtual already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType,
float aOpacity);
virtual IntSize GetSize() const = 0;
+ virtual IntRect GetRect() const {
+ return IntRect(IntPoint(0, 0), GetSize());
+ }
/**
* If possible returns the bits to this DrawTarget for direct manipulation. While
* the bits is locked any modifications to this DrawTarget is forbidden.
* Release takes the original data pointer for safety.
*/
virtual bool LockBits(uint8_t** aData, IntSize* aSize,
int32_t* aStride, SurfaceFormat* aFormat,
--- a/gfx/2d/DrawTargetTiled.cpp
+++ b/gfx/2d/DrawTargetTiled.cpp
@@ -33,18 +33,22 @@ DrawTargetTiled::Init(const TileSet& aTi
if (mTiles[0].mDrawTarget->GetFormat() != mTiles.back().mDrawTarget->GetFormat() ||
mTiles[0].mDrawTarget->GetBackendType() != mTiles.back().mDrawTarget->GetBackendType()) {
return false;
}
uint32_t newXMost = max(mRect.XMost(),
mTiles[i].mTileOrigin.x + mTiles[i].mDrawTarget->GetSize().width);
uint32_t newYMost = max(mRect.YMost(),
mTiles[i].mTileOrigin.y + mTiles[i].mDrawTarget->GetSize().height);
- mRect.MoveTo(min(mRect.X(), mTiles[i].mTileOrigin.x),
- min(mRect.Y(), mTiles[i].mTileOrigin.y));
+ if (i == 0) {
+ mRect.MoveTo(mTiles[0].mTileOrigin.x, mTiles[0].mTileOrigin.y);
+ } else {
+ mRect.MoveTo(min(mRect.X(), mTiles[i].mTileOrigin.x),
+ min(mRect.Y(), mTiles[i].mTileOrigin.y));
+ }
mRect.SetRightEdge(newXMost);
mRect.SetBottomEdge(newYMost);
mTiles[i].mDrawTarget->SetTransform(Matrix::Translation(-mTiles[i].mTileOrigin.x,
-mTiles[i].mTileOrigin.y));
}
mFormat = mTiles[0].mDrawTarget->GetFormat();
SetPermitSubpixelAA(IsOpaque(mFormat));
return true;
--- a/gfx/2d/DrawTargetTiled.h
+++ b/gfx/2d/DrawTargetTiled.h
@@ -46,16 +46,19 @@ public:
virtual DrawTargetType GetType() const override { return mTiles[0].mDrawTarget->GetType(); }
virtual BackendType GetBackendType() const override { return mTiles[0].mDrawTarget->GetBackendType(); }
virtual already_AddRefed<SourceSurface> Snapshot() override;
virtual void DetachAllSnapshots() override;
virtual IntSize GetSize() const override {
MOZ_ASSERT(mRect.Width() > 0 && mRect.Height() > 0);
return IntSize(mRect.XMost(), mRect.YMost());
}
+ virtual IntRect GetRect() const override {
+ return mRect;
+ }
virtual void Flush() override;
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions,
const DrawOptions &aOptions) override;
virtual void DrawFilter(FilterNode *aNode,
@@ -193,45 +196,48 @@ public:
}
}
virtual SurfaceType GetType() const override { return SurfaceType::TILED; }
virtual IntSize GetSize() const override {
MOZ_ASSERT(mRect.Width() > 0 && mRect.Height() > 0);
return IntSize(mRect.XMost(), mRect.YMost());
}
+ virtual IntRect GetRect() const override {
+ return mRect;
+ }
virtual SurfaceFormat GetFormat() const override { return mSnapshots[0]->GetFormat(); }
virtual already_AddRefed<DataSourceSurface> GetDataSurface() override
{
- RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurface(GetSize(), GetFormat());
+ RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurface(mRect.Size(), GetFormat());
if (!surf) {
gfxCriticalError() << "DrawTargetTiled::GetDataSurface failed to allocate surface";
return nullptr;
}
DataSourceSurface::MappedSurface mappedSurf;
if (!surf->Map(DataSourceSurface::MapType::WRITE, &mappedSurf)) {
gfxCriticalError() << "DrawTargetTiled::GetDataSurface failed to map surface";
return nullptr;
}
{
RefPtr<DrawTarget> dt =
Factory::CreateDrawTargetForData(BackendType::CAIRO, mappedSurf.mData,
- GetSize(), mappedSurf.mStride, GetFormat());
+ mRect.Size(), mappedSurf.mStride, GetFormat());
if (!dt) {
gfxWarning() << "DrawTargetTiled::GetDataSurface failed in CreateDrawTargetForData";
surf->Unmap();
return nullptr;
}
for (size_t i = 0; i < mSnapshots.size(); i++) {
RefPtr<DataSourceSurface> dataSurf = mSnapshots[i]->GetDataSurface();
- dt->CopySurface(dataSurf, IntRect(IntPoint(0, 0), mSnapshots[i]->GetSize()), mOrigins[i]);
+ dt->CopySurface(dataSurf, IntRect(IntPoint(0, 0), mSnapshots[i]->GetSize()), mOrigins[i] - mRect.TopLeft());
}
}
surf->Unmap();
return surf.forget();
}
std::vector<RefPtr<SourceSurface>> mSnapshots;