Bug 917703 - Avoid copying to a sub image in CreateSamplingRestrictedDrawable if possible. r=roc

This commit is contained in:
Matt Woodrow 2013-09-19 17:23:31 +12:00
parent 50e2bf6382
commit ca7201f9f8
4 changed files with 27 additions and 8 deletions

View File

@ -134,6 +134,12 @@ gfxSurfaceDrawable::Draw(gfxContext* aContext,
return true;
}
already_AddRefed<gfxImageSurface>
gfxSurfaceDrawable::GetAsImageSurface()
{
return mSurface->GetAsImageSurface();
}
gfxCallbackDrawable::gfxCallbackDrawable(gfxDrawingCallback* aCallback,
const gfxIntSize aSize)
: gfxDrawable(aSize)

View File

@ -15,6 +15,7 @@
#include "gfxPattern.h"
class gfxASurface;
class gfxImageSurface;
class gfxContext;
/**
@ -41,6 +42,7 @@ public:
bool aRepeat,
const gfxPattern::GraphicsFilter& aFilter,
const gfxMatrix& aTransform = gfxMatrix()) = 0;
virtual already_AddRefed<gfxImageSurface> GetAsImageSurface() { return nullptr; }
virtual gfxIntSize Size() { return mSize; }
protected:
@ -62,6 +64,8 @@ public:
bool aRepeat,
const gfxPattern::GraphicsFilter& aFilter,
const gfxMatrix& aTransform = gfxMatrix());
virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
protected:
nsRefPtr<gfxASurface> mSurface;

View File

@ -297,6 +297,8 @@ gfxImageSurface::GetSubimage(const gfxRect& aRect)
{
gfxRect r(aRect);
r.Round();
MOZ_ASSERT(gfxRect(0, 0, mSize.width, mSize.height).Contains(r));
unsigned char* subData = Data() +
(Stride() * (int)r.Y()) +
(int)r.X() * gfxASurface::BytePerPixelFromFormat(Format());

View File

@ -245,16 +245,23 @@ CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable,
if (needed.IsEmpty())
return nullptr;
nsRefPtr<gfxASurface> temp;
gfxIntSize size(int32_t(needed.Width()), int32_t(needed.Height()));
nsRefPtr<gfxASurface> temp =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, gfxASurface::ContentFromFormat(aFormat));
if (!temp || temp->CairoStatus())
return nullptr;
nsRefPtr<gfxContext> tmpCtx = new gfxContext(temp);
tmpCtx->SetOperator(OptimalFillOperator());
aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), true,
gfxPattern::FILTER_FAST, gfxMatrix().Translate(needed.TopLeft()));
nsRefPtr<gfxImageSurface> image = aDrawable->GetAsImageSurface();
if (image && gfxRect(0, 0, image->GetSize().width, image->GetSize().height).Contains(needed)) {
temp = image->GetSubimage(needed);
} else {
temp =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, gfxASurface::ContentFromFormat(aFormat));
if (!temp || temp->CairoStatus())
return nullptr;
nsRefPtr<gfxContext> tmpCtx = new gfxContext(temp);
tmpCtx->SetOperator(OptimalFillOperator());
aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), true,
gfxPattern::FILTER_FAST, gfxMatrix().Translate(needed.TopLeft()));
}
nsRefPtr<gfxDrawable> drawable =
new gfxSurfaceDrawable(temp, size, gfxMatrix().Translate(-needed.TopLeft()));