Bug 781731 - Speed up shadows by using tee surface to avoid doing a read back. r=jrmuizel

This commit is contained in:
Anthony Jones 2012-08-29 17:00:09 -04:00
parent b44de8c0d9
commit d744f8915d
4 changed files with 51 additions and 14 deletions

View File

@ -311,7 +311,7 @@ public:
transform._32 -= mTempRect.y;
mTarget =
mCtx->mTarget->CreateSimilarDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
mCtx->mTarget->CreateShadowDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
FORMAT_B8G8R8A8);
if (!mTarget) {

View File

@ -727,6 +727,15 @@ public:
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0;
/*
* Create a draw target optimized for drawing a shadow.
*/
virtual TemporaryRef<DrawTarget>
CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{
return CreateSimilarDrawTarget(aSize, aFormat);
}
/*
* Create a path builder with the specified fillmode.
*

View File

@ -11,6 +11,7 @@
#include "ScaledFontBase.h"
#include "cairo.h"
#include "cairo-tee.h"
#include <string.h>
#include "Blur.h"
@ -391,19 +392,11 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
Float height = aSurface->GetSize().height;
SourceSurfaceCairo* source = static_cast<SourceSurfaceCairo*>(aSurface);
cairo_surface_t* surf = source->GetSurface();
cairo_surface_t* blursurf = cairo_image_surface_create(CAIRO_FORMAT_A8,
width,
height);
cairo_t* ctx = cairo_create(blursurf);
cairo_set_source_surface(ctx, surf, 0, 0);
cairo_new_path(ctx);
cairo_rectangle(ctx, 0, 0, width, height);
cairo_fill(ctx);
cairo_destroy(ctx);
cairo_surface_t* sourcesurf = source->GetSurface();
cairo_surface_t* blursurf = cairo_tee_surface_index(sourcesurf, 0);
cairo_surface_t* surf = cairo_tee_surface_index(sourcesurf, 1);
MOZ_ASSERT(cairo_surface_get_type(blursurf) == CAIRO_SURFACE_TYPE_IMAGE);
Rect extents(0, 0, width, height);
AlphaBoxBlur blur(cairo_image_surface_get_data(blursurf),
extents,
@ -444,7 +437,6 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
}
cairo_restore(mContext);
cairo_surface_destroy(blursurf);
}
void
@ -799,6 +791,40 @@ DrawTargetCairo::InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize&
return true;
}
TemporaryRef<DrawTarget>
DrawTargetCairo::CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{
cairo_surface_t* similar = cairo_surface_create_similar(cairo_get_target(mContext),
GfxFormatToCairoContent(aFormat),
aSize.width, aSize.height);
if (cairo_surface_status(similar)) {
return nullptr;
}
cairo_surface_t* blursurf = cairo_image_surface_create(CAIRO_FORMAT_A8,
aSize.width,
aSize.height);
if (cairo_surface_status(blursurf)) {
return nullptr;
}
cairo_surface_t* tee = cairo_tee_surface_create(blursurf);
cairo_surface_destroy(blursurf);
if (cairo_surface_status(tee)) {
cairo_surface_destroy(similar);
return nullptr;
}
cairo_tee_surface_add(tee, similar);
cairo_surface_destroy(similar);
RefPtr<DrawTargetCairo> target = new DrawTargetCairo();
target->InitAlreadyReferenced(tee, aSize);
return target;
}
bool
DrawTargetCairo::Init(cairo_surface_t* aSurface, const IntSize& aSize)
{

View File

@ -115,6 +115,8 @@ public:
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
virtual TemporaryRef<DrawTarget>
CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
virtual TemporaryRef<GradientStops>
CreateGradientStops(GradientStop *aStops,