Bug 367557 - correct filter/pattern surface refcount. r=vlad, sr=roc

This commit is contained in:
tor%cs.brown.edu 2007-01-22 23:19:54 +00:00
Родитель 476346c376
Коммит ffa16993ad
3 изменённых файлов: 39 добавлений и 47 удалений

Просмотреть файл

@ -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,