Backout bug 781731.

This commit is contained in:
Ms2ger 2012-08-27 12:27:40 +02:00
parent 0ef99da2cc
commit a77fd1cc47
7 changed files with 60 additions and 150 deletions

View File

@ -287,8 +287,7 @@ public:
mTempRect = mgfx::Rect(0, 0, ctx->mWidth, ctx->mHeight);
static const gfxFloat GAUSSIAN_SCALE_FACTOR = (3 * sqrt(2 * M_PI) / 4) * 1.5;
int32_t blurRadius = (int32_t) floor(mSigma * GAUSSIAN_SCALE_FACTOR + 0.5);
Float blurRadius = mSigma * 3;
// We need to enlarge and possibly offset our temporary surface
// so that things outside of the canvas may cast shadows.
@ -306,21 +305,14 @@ public:
mTempRect = mTempRect.Intersect(*aBounds);
}
// Nothing to draw
if (mTempRect.IsEmpty()) {
mTarget = ctx->mTarget;
mCtx = nullptr;
return;
}
mTempRect.ScaleRoundOut(1.0f);
transform._31 -= mTempRect.x;
transform._32 -= mTempRect.y;
mTarget =
mCtx->mTarget->CreateShadowDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
FORMAT_B8G8R8A8, mSigma);
mCtx->mTarget->CreateSimilarDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
FORMAT_B8G8R8A8);
if (!mTarget) {
// XXX - Deal with the situation where our temp size is too big to
@ -3110,9 +3102,8 @@ struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiP
buffer.mGlyphs = &glyphBuf.front();
buffer.mNumGlyphs = glyphBuf.size();
Rect bounds(mBoundingBox.x, mBoundingBox.y, mBoundingBox.width, mBoundingBox.height);
if (mOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL) {
AdjustedTarget(mCtx, &bounds)->
AdjustedTarget(mCtx)->
FillGlyphs(scaledFont, buffer,
CanvasGeneralPattern().
ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_FILL, mCtx->mTarget),
@ -3121,7 +3112,7 @@ struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiP
RefPtr<Path> path = scaledFont->GetPathForGlyphs(buffer, mCtx->mTarget);
const ContextState& state = *mState;
AdjustedTarget(mCtx, &bounds)->
AdjustedTarget(mCtx)->
Stroke(path, CanvasGeneralPattern().
ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_STROKE, mCtx->mTarget),
StrokeOptions(state.lineWidth, state.lineJoin,

View File

@ -727,21 +727,6 @@ public:
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0;
/*
* Create a draw target optimized for drawing a shadow.
*
* Note that aSigma is the blur radius that must be used when we draw the
* shadow. Also note that this doesn't affect the size of the allocated
* surface, the caller is still responsible for including the shadow area in
* its size.
*/
virtual TemporaryRef<DrawTarget>
CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat,
float aSigma) const
{
return CreateSimilarDrawTarget(aSize, aFormat);
}
/*
* Create a path builder with the specified fillmode.
*

View File

@ -330,8 +330,7 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
const Rect* aSkipRect)
: mSpreadRadius(aSpreadRadius),
mBlurRadius(aBlurRadius),
mData(nullptr),
mFreeData(true)
mData(nullptr)
{
Rect rect(aRect);
rect.Inflate(Size(aBlurRadius + aSpreadRadius));
@ -385,25 +384,9 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
}
}
AlphaBoxBlur::AlphaBoxBlur(uint8_t* aData,
const Rect& aRect,
int32_t aStride,
float aSigma)
: mSpreadRadius(),
mBlurRadius(CalculateBlurRadius(Point(aSigma, aSigma))),
mData(aData),
mFreeData(false),
mStride(aStride),
mRect(aRect.x, aRect.y, aRect.width, aRect.height)
{
}
AlphaBoxBlur::~AlphaBoxBlur()
{
if (mFreeData) {
delete mData;
}
free(mData);
}
unsigned char*

View File

@ -57,11 +57,6 @@ public:
const Rect* aDirtyRect,
const Rect* aSkipRect);
AlphaBoxBlur(uint8_t* aData,
const Rect& aRect,
int32_t aStride,
float aSigma);
~AlphaBoxBlur();
/**
@ -140,12 +135,7 @@ private:
/**
* A pointer to the backing 8-bit alpha surface.
*/
uint8_t* mData;
/**
* True if we need to dispose the data.
*/
bool mFreeData;
unsigned char* mData;
/**
* The stride of the data contained in mData.

View File

@ -11,7 +11,6 @@
#include "ScaledFontBase.h"
#include "cairo.h"
#include "cairo-tee.h"
#include <string.h>
#include "Blur.h"
@ -388,35 +387,49 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
return;
}
WillChange();
Float width = aSurface->GetSize().width;
Float height = aSurface->GetSize().height;
SourceSurfaceCairo* source = static_cast<SourceSurfaceCairo*>(aSurface);
cairo_surface_t* sourcesurf = source->GetSurface();
cairo_surface_t* blursurf;
cairo_surface_t* surf;
Rect extents(0, 0, width, height);
// We only use the A8 surface for blurred shadows. Unblurred shadows can just
// use the RGBA surface directly.
if (cairo_surface_get_type(sourcesurf) == CAIRO_SURFACE_TYPE_TEE) {
blursurf = cairo_tee_surface_index(sourcesurf, 0);
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,
cairo_image_surface_get_stride(blursurf),
aSigma);
blur.Blur();
} else {
blursurf = sourcesurf;
surf = sourcesurf;
AlphaBoxBlur blur(extents, IntSize(0, 0),
AlphaBoxBlur::CalculateBlurRadius(Point(aSigma, aSigma)),
nullptr, nullptr);
if (!blur.GetData()) {
return;
}
WillChange();
IntSize blursize = blur.GetSize();
cairo_surface_t* blursurf = cairo_image_surface_create_for_data(blur.GetData(),
CAIRO_FORMAT_A8,
blursize.width,
blursize.height,
blur.GetStride());
ClearSurfaceForUnboundedSource(aOperator);
// Draw the source surface into the surface we're going to blur.
SourceSurfaceCairo* source = static_cast<SourceSurfaceCairo*>(aSurface);
cairo_surface_t* surf = source->GetSurface();
cairo_pattern_t* pat = cairo_pattern_create_for_surface(surf);
cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD);
cairo_t* ctx = cairo_create(blursurf);
cairo_set_source(ctx, pat);
IntRect blurrect = blur.GetRect();
cairo_new_path(ctx);
cairo_rectangle(ctx, blurrect.x, blurrect.y, blurrect.width, blurrect.height);
cairo_clip(ctx);
cairo_paint(ctx);
cairo_destroy(ctx);
// Blur the result, then use that blurred result as a mask to draw the shadow
// colour to the surface.
blur.Blur();
cairo_save(mContext);
cairo_set_operator(mContext, GfxOpToCairoOp(aOperator));
cairo_identity_matrix(mContext);
@ -427,26 +440,33 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
cairo_push_group(mContext);
cairo_set_source_rgba(mContext, aColor.r, aColor.g, aColor.b, aColor.a);
cairo_mask_surface(mContext, blursurf, aOffset.x, aOffset.y);
// Now that the shadow has been drawn, we can draw the surface on top.
cairo_set_source_surface(mContext, surf, 0, 0);
cairo_new_path(mContext);
cairo_rectangle(mContext, 0, 0, width, height);
cairo_fill(mContext);
cairo_pop_group_to_source(mContext);
cairo_paint(mContext);
// Now that the shadow has been drawn, we can draw the surface on top.
cairo_push_group(mContext);
cairo_new_path(mContext);
cairo_rectangle(mContext, 0, 0, width, height);
cairo_set_source(mContext, pat);
cairo_fill(mContext);
cairo_pop_group_to_source(mContext);
} else {
cairo_set_source_rgba(mContext, aColor.r, aColor.g, aColor.b, aColor.a);
cairo_mask_surface(mContext, blursurf, aOffset.x, aOffset.y);
// Now that the shadow has been drawn, we can draw the surface on top.
cairo_set_source_surface(mContext, surf, 0, 0);
cairo_set_source(mContext, pat);
cairo_new_path(mContext);
cairo_rectangle(mContext, 0, 0, width, height);
cairo_fill(mContext);
cairo_clip(mContext);
}
cairo_paint(mContext);
cairo_restore(mContext);
cairo_pattern_destroy(pat);
cairo_surface_destroy(blursurf);
}
void
@ -801,49 +821,6 @@ DrawTargetCairo::InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize&
return true;
}
TemporaryRef<DrawTarget>
DrawTargetCairo::CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat,
float aSigma) 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;
}
// If we don't have a blur then we can use the RGBA mask and keep all the
// operations in graphics memory.
if (aSigma == 0.0F) {
RefPtr<DrawTargetCairo> target = new DrawTargetCairo();
target->InitAlreadyReferenced(similar, aSize);
return target;
}
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,9 +115,6 @@ 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,
float aSigma) const;
virtual TemporaryRef<GradientStops>
CreateGradientStops(GradientStop *aStops,

View File

@ -535,21 +535,8 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
dt->Flush();
}
srcBuffer = aTarget->CreateSourceSurfaceFromNativeSurface(surf);
} else
#endif
if (aSurface->CairoSurface()) {
// If this is an xlib cairo surface we don't want to fetch it into memory
// because this is a major slow down.
NativeSurface surf;
surf.mFormat = format;
surf.mType = NATIVE_SURFACE_CAIRO_SURFACE;
surf.mSurface = aSurface->CairoSurface();
srcBuffer = aTarget->CreateSourceSurfaceFromNativeSurface(surf);
// It's cheap enough to make a new one so we won't keep it around and
// keeping it creates a cycle.
return srcBuffer;
}
#endif
if (!srcBuffer) {
nsRefPtr<gfxImageSurface> imgSurface = aSurface->GetAsImageSurface();