зеркало из https://github.com/mozilla/pjs.git
Bug 367557 - correct filter/pattern surface refcount. r=vlad, sr=roc
This commit is contained in:
Родитель
476346c376
Коммит
ffa16993ad
|
@ -49,6 +49,7 @@
|
|||
#include "nsSVGContainerFrame.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
typedef nsSVGContainerFrame nsSVGFilterFrameBase;
|
||||
|
||||
|
@ -359,26 +360,18 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
aTarget->NotifyCanvasTMChanged(PR_TRUE);
|
||||
|
||||
// paint the target geometry
|
||||
cairo_surface_t *surface =
|
||||
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
|
||||
filterResX, filterResY);
|
||||
if (!surface) {
|
||||
nsRefPtr<gfxImageSurface> tmpSurface =
|
||||
new gfxImageSurface(gfxASurface::ImageFormatARGB32,
|
||||
filterResX, filterResY);
|
||||
if (!tmpSurface) {
|
||||
FilterFailCleanup(aContext, aTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxUnknownSurface tmpSurface(surface);
|
||||
gfxContext tmpContext(&tmpSurface);
|
||||
|
||||
// thebes types don't like being stack allocated - addref the surface
|
||||
// so that gfxContext doesn't try destroying it (scope will delete it)
|
||||
tmpSurface.AddRef();
|
||||
|
||||
// tmpSurface now owns the cairo surface
|
||||
cairo_surface_destroy(surface);
|
||||
|
||||
gfxContext tmpContext(tmpSurface);
|
||||
nsSVGRenderState tmpState(&tmpContext);
|
||||
|
||||
memset(tmpSurface->Data(), 0, tmpSurface->Height() * tmpSurface->Stride());
|
||||
aTarget->PaintSVG(&tmpState, nsnull);
|
||||
|
||||
mPrimitiveUnits->GetAnimVal(&type);
|
||||
|
@ -397,9 +390,9 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint8 *data = cairo_image_surface_get_data(surface);
|
||||
PRUint8 *data = tmpSurface->Data();
|
||||
PRUint8 *alphaData = cairo_image_surface_get_data(alpha);
|
||||
PRUint32 stride = cairo_image_surface_get_stride(surface);
|
||||
PRUint32 stride = tmpSurface->Stride();
|
||||
|
||||
for (PRUint32 yy=0; yy<filterResY; yy++)
|
||||
for (PRUint32 xx=0; xx<filterResX; xx++) {
|
||||
|
@ -415,7 +408,8 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
|
||||
// this always needs to be defined last because the default image
|
||||
// for the first filter element is supposed to be SourceGraphic
|
||||
instance.DefineImage(NS_LITERAL_STRING("SourceGraphic"), surface,
|
||||
instance.DefineImage(NS_LITERAL_STRING("SourceGraphic"),
|
||||
tmpSurface->CairoSurface(),
|
||||
nsRect(0, 0, filterResX, filterResY));
|
||||
|
||||
for (PRUint32 k=0; k<count; ++k) {
|
||||
|
@ -428,11 +422,19 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
}
|
||||
}
|
||||
|
||||
cairo_surface_t *filterResult;
|
||||
cairo_surface_t *filterResult = nsnull;
|
||||
nsRect filterRect;
|
||||
nsRefPtr<gfxASurface> resultSurface;
|
||||
|
||||
instance.LookupImage(NS_LITERAL_STRING(""), &filterResult, &filterRect);
|
||||
|
||||
if (filterResult)
|
||||
resultSurface = gfxASurface::Wrap(filterResult);
|
||||
if (!resultSurface) {
|
||||
FilterFailCleanup(aContext, aTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> scale, fini;
|
||||
NS_NewSVGMatrix(getter_AddRefs(scale),
|
||||
width/filterResX, 0.0f,
|
||||
|
@ -441,10 +443,8 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
|
||||
ctm->Multiply(scale, getter_AddRefs(fini));
|
||||
|
||||
gfxUnknownSurface resultSurface(filterResult);
|
||||
|
||||
nsSVGUtils::CompositeSurfaceMatrix(aContext->GetGfxContext(),
|
||||
&resultSurface, fini, 1.0);
|
||||
resultSurface, fini, 1.0);
|
||||
|
||||
aTarget->SetOverrideCTM(nsnull);
|
||||
aTarget->SetMatrixPropagation(PR_TRUE);
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
#include "nsSVGPatternElement.h"
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
#include "nsSVGPatternFrame.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
static void printCTM(char *msg, nsIDOMSVGMatrix *aCTM);
|
||||
|
@ -281,17 +281,22 @@ nsSVGPatternFrame::PaintPattern(cairo_surface_t** surface,
|
|||
|
||||
// Now that we have all of the necessary geometries, we can
|
||||
// create our surface.
|
||||
cairo_surface_t *patternSurface = CreateSurface(bbox);
|
||||
if (!patternSurface)
|
||||
float surfaceWidth, surfaceHeight;
|
||||
bbox->GetWidth(&surfaceWidth);
|
||||
bbox->GetHeight(&surfaceHeight);
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
printf("Creating %dX%d surface\n",(int)(surfaceWidth),(int)(surfaceHeight));
|
||||
#endif
|
||||
|
||||
nsRefPtr<gfxImageSurface> tmpSurface =
|
||||
new gfxImageSurface(gfxASurface::ImageFormatARGB32,
|
||||
(int)surfaceWidth, (int)surfaceHeight);
|
||||
if (!tmpSurface)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
gfxUnknownSurface tmpSurface(patternSurface);
|
||||
gfxContext tmpContext(&tmpSurface);
|
||||
|
||||
// thebes types don't like being stack allocated - addref the surface
|
||||
// so that gfxContext doesn't try destroying it (scope will delete it)
|
||||
tmpSurface.AddRef();
|
||||
|
||||
memset(tmpSurface->Data(), 0, tmpSurface->Height() * tmpSurface->Stride());
|
||||
gfxContext tmpContext(tmpSurface);
|
||||
nsSVGRenderState tmpState(&tmpContext);
|
||||
|
||||
// OK, now render -- note that we use "firstKid", which
|
||||
|
@ -308,7 +313,9 @@ nsSVGPatternFrame::PaintPattern(cairo_surface_t** surface,
|
|||
}
|
||||
mSource = nsnull;
|
||||
|
||||
*surface = patternSurface;
|
||||
// caller now owns the cairo surface
|
||||
cairo_surface_reference(tmpSurface->CairoSurface());
|
||||
*surface = tmpSurface->CairoSurface();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -773,20 +780,6 @@ nsSVGPatternFrame::GetCallerGeometry(nsIDOMSVGMatrix **aCTM,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
nsSVGPatternFrame::CreateSurface(nsIDOMSVGRect *bbox)
|
||||
{
|
||||
float width, height;
|
||||
bbox->GetWidth(&width);
|
||||
bbox->GetHeight(&height);
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
printf("Creating %dX%d surface\n",(int)(width),(int)(height));
|
||||
#endif
|
||||
return cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
|
||||
(int)(width), (int)(height));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPaintServerFrame methods:
|
||||
|
||||
|
|
|
@ -140,7 +140,6 @@ protected:
|
|||
nsIDOMSVGRect *bbox,
|
||||
nsIDOMSVGMatrix *callerCTM);
|
||||
nsresult ConstructCTM(nsIDOMSVGMatrix **ctm, nsIDOMSVGRect *callerBBox);
|
||||
cairo_surface_t *CreateSurface(nsIDOMSVGRect *bbox);
|
||||
nsresult GetCallerGeometry(nsIDOMSVGMatrix **aCTM,
|
||||
nsIDOMSVGRect **aBBox,
|
||||
nsSVGElement **aContent,
|
||||
|
|
Загрузка…
Ссылка в новой задаче