Bug 353827 - Remove nsISVGRendererSurface from filter code. r=amenzie, sr=roc

This commit is contained in:
tor%cs.brown.edu 2006-09-25 16:46:22 +00:00
Родитель af2134c04a
Коммит cdbc54905e
6 изменённых файлов: 110 добавлений и 123 удалений

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

@ -232,7 +232,7 @@ public:
* Returns total length of data buffer in bytes
*/
PRUint32 GetDataLength() {
return mLength;
return mStride * mHeight;
}
/*
@ -243,11 +243,6 @@ public:
}
private:
/*
* Unlocks the source image if it exists
*/
void ReleaseSource();
/*
* If the target image exists then it is unlocked and FixupTarget() is called
*/
@ -262,20 +257,20 @@ private:
nsAutoString mInput, mResult;
nsRect mRect;
nsCOMPtr<nsISVGRendererSurface> mSourceImage, mTargetImage;
cairo_surface_t *mTargetImage;
nsSVGFilterInstance* mInstance;
PRUint8 *mSourceData, *mTargetData;
PRUint32 mWidth, mHeight, mLength;
PRUint32 mWidth, mHeight;
PRInt32 mStride;
};
nsSVGFilterResource::nsSVGFilterResource(nsSVGFilterInstance* aInstance):
mTargetImage(nsnull),
mInstance(aInstance),
mSourceData(nsnull),
mTargetData(nsnull),
mWidth(0),
mHeight(0),
mLength(0),
mStride(0)
{
}
@ -283,25 +278,26 @@ nsSVGFilterResource::nsSVGFilterResource(nsSVGFilterInstance* aInstance):
nsSVGFilterResource::~nsSVGFilterResource()
{
ReleaseTarget();
ReleaseSource();
}
nsresult
nsSVGFilterResource::AcquireSourceImage(nsIDOMSVGAnimatedString* aIn,
nsSVGFE* aFilter, PRUint8** aSourceData)
{
ReleaseSource();
nsRect defaultRect;
aIn->GetAnimVal(mInput);
mInstance->LookupRegion(mInput, &defaultRect);
mInstance->GetFilterSubregion(aFilter, defaultRect, &mRect);
mInstance->LookupImage(mInput, getter_AddRefs(mSourceImage));
if (!mSourceImage) {
nsRect defaultRect;
cairo_surface_t *surface;
mInstance->LookupImage(mInput, &surface, &defaultRect);
if (!surface) {
return NS_ERROR_FAILURE;
}
mSourceImage->Lock();
mSourceImage->GetData(&mSourceData, &mLength, &mStride);
mInstance->GetFilterSubregion(aFilter, defaultRect, &mRect);
mSourceData = cairo_image_surface_get_data(surface);
mStride = cairo_image_surface_get_stride(surface);
*aSourceData = mSourceData;
return NS_OK;
}
@ -311,28 +307,20 @@ nsSVGFilterResource::AcquireTargetImage(nsIDOMSVGAnimatedString* aResult,
PRUint8** aTargetData)
{
aResult->GetAnimVal(mResult);
mInstance->GetImage(getter_AddRefs(mTargetImage));
mTargetImage = mInstance->GetImage();
if (!mTargetImage) {
return NS_ERROR_FAILURE;
}
mTargetImage->Lock();
mTargetImage->GetData(&mTargetData, &mLength, &mStride);
mTargetImage->GetWidth(&mWidth);
mTargetImage->GetHeight(&mHeight);
mTargetData = cairo_image_surface_get_data(mTargetImage);
mStride = cairo_image_surface_get_stride(mTargetImage);
mWidth = cairo_image_surface_get_width(mTargetImage);
mHeight = cairo_image_surface_get_height(mTargetImage);
*aTargetData = mTargetData;
return NS_OK;
}
void
nsSVGFilterResource::ReleaseSource()
{
if (!mSourceImage) {
return;
}
mSourceImage->Unlock();
mSourceImage = nsnull;
}
void
nsSVGFilterResource::ReleaseTarget()
{
@ -340,9 +328,7 @@ nsSVGFilterResource::ReleaseTarget()
return;
}
FixupTarget();
mTargetImage->Unlock();
mInstance->DefineImage(mResult, mTargetImage);
mInstance->DefineRegion(mResult, mRect);
mInstance->DefineImage(mResult, mTargetImage, mRect);
mTargetImage = nsnull;
}

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

@ -359,43 +359,39 @@ nsSVGFilterFrame::FilterPaint(nsISVGRendererCanvas *aCanvas,
aTarget->NotifyCanvasTMChanged(PR_TRUE);
// paint the target geometry
nsSVGOuterSVGFrame* outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
nsCOMPtr<nsISVGRenderer> renderer;
nsCOMPtr<nsISVGRendererSurface> surface;
outerSVGFrame->GetRenderer(getter_AddRefs(renderer));
renderer->CreateSurface(filterResX, filterResY, getter_AddRefs(surface));
cairo_surface_t *surface =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
filterResX, filterResY);
if (!surface) {
FilterFailCleanup(aCanvas, aTarget);
return NS_OK;
}
aCanvas->PushSurface(surface, PR_FALSE);
aCanvas->PushCairoSurface(surface, PR_FALSE);
aTarget->PaintSVG(aCanvas, nsnull);
aCanvas->PopSurface();
mPrimitiveUnits->GetAnimVal(&type);
nsSVGFilterInstance instance(renderer, target, bbox,
nsSVGFilterInstance instance(target, bbox,
x, y, width, height,
filterResX, filterResY,
type);
if (requirements & NS_FE_SOURCEALPHA) {
nsCOMPtr<nsISVGRendererSurface> alpha;
renderer->CreateSurface(filterResX, filterResY, getter_AddRefs(alpha));
cairo_surface_t *alpha =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
filterResX, filterResY);
if (!alpha) {
cairo_surface_destroy(surface);
FilterFailCleanup(aCanvas, aTarget);
return NS_OK;
}
PRUint8 *data, *alphaData;
PRUint32 length;
PRInt32 stride;
surface->Lock();
alpha->Lock();
surface->GetData(&data, &length, &stride);
alpha->GetData(&alphaData, &length, &stride);
PRUint8 *data = cairo_image_surface_get_data(surface);
PRUint8 *alphaData = cairo_image_surface_get_data(alpha);
PRUint32 stride = cairo_image_surface_get_stride(surface);
for (PRUint32 yy=0; yy<filterResY; yy++)
for (PRUint32 xx=0; xx<filterResX; xx++) {
@ -405,19 +401,14 @@ nsSVGFilterFrame::FilterPaint(nsISVGRendererCanvas *aCanvas,
alphaData[stride*yy + 4*xx + 3] = data[stride*yy + 4*xx + 3];
}
surface->Unlock();
alpha->Unlock();
instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), alpha);
instance.DefineRegion(NS_LITERAL_STRING("SourceAlpha"),
nsRect(0, 0, filterResX, filterResY));
instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), alpha,
nsRect(0, 0, filterResX, filterResY));
}
// 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.DefineRegion(NS_LITERAL_STRING("SourceGraphic"),
nsRect(0, 0, filterResX, filterResY));
instance.DefineImage(NS_LITERAL_STRING("SourceGraphic"), surface,
nsRect(0, 0, filterResX, filterResY));
for (PRUint32 k=0; k<count; ++k) {
nsIContent* child = mContent->GetChildAt(k);
@ -429,8 +420,10 @@ nsSVGFilterFrame::FilterPaint(nsISVGRendererCanvas *aCanvas,
}
}
nsCOMPtr<nsISVGRendererSurface> filterResult;
instance.LookupImage(NS_LITERAL_STRING(""), getter_AddRefs(filterResult));
cairo_surface_t *filterResult;
nsRect filterRect;
instance.LookupImage(NS_LITERAL_STRING(""), &filterResult, &filterRect);
nsCOMPtr<nsIDOMSVGMatrix> scale, fini;
NS_NewSVGMatrix(getter_AddRefs(scale),
@ -634,45 +627,43 @@ nsSVGFilterInstance::GetFilterSubregion(
#endif
}
void
nsSVGFilterInstance::GetImage(nsISVGRendererSurface **result)
cairo_surface_t *
nsSVGFilterInstance::GetImage()
{
mRenderer->CreateSurface(mFilterResX, mFilterResY, result);
return cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
mFilterResX, mFilterResY);
}
void
nsSVGFilterInstance::LookupImage(const nsAString &aName,
nsISVGRendererSurface **aImage)
nsSVGFilterInstance::LookupImage(const nsAString &aName,
cairo_surface_t **aImage,
nsRect *aRegion)
{
if (aName.IsEmpty()) {
*aImage = mLastImage;
NS_IF_ADDREF(*aImage);
} else
mImageDictionary.Get(aName, aImage);
}
ImageEntry *entry;
void
nsSVGFilterInstance::DefineImage(const nsAString &aName,
nsISVGRendererSurface *aImage)
{
mImageDictionary.Put(aName, aImage);
mLastImage = aImage;
}
void
nsSVGFilterInstance::LookupRegion(const nsAString &aName,
nsRect *aRect)
{
if (aName.IsEmpty())
*aRect = mLastRegion;
entry = mLastImage;
else
mRegionDictionary.Get(aName, aRect);
mImageDictionary.Get(aName, &entry);
if (entry) {
*aImage = entry->mImage;
*aRegion = entry->mRegion;
} else {
*aImage = nsnull;
aRegion->Empty();
}
}
void
nsSVGFilterInstance::DefineRegion(const nsAString &aName,
nsRect aRect)
nsSVGFilterInstance::DefineImage(const nsAString &aName,
cairo_surface_t *aImage,
nsRect aRegion)
{
mRegionDictionary.Put(aName, aRect);
mLastRegion = aRect;
ImageEntry *entry = new ImageEntry(aImage, aRegion);
if (entry)
mImageDictionary.Put(aName, entry);
mLastImage = entry;
}

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

@ -40,15 +40,15 @@
#include "nsIDOMSVGLength.h"
#include "nsIDOMSVGRect.h"
#include "nsIDOMSVGAnimatedEnum.h"
#include "nsISVGRendererSurface.h"
#include "nsInterfaceHashtable.h"
#include "nsDataHashtable.h"
#include "nsISVGRenderer.h"
#include "nsClassHashtable.h"
#include "nsIDOMSVGFilters.h"
#include "nsRect.h"
#include "nsIContent.h"
#include "nsAutoPtr.h"
#include "cairo.h"
class nsSVGLength2;
class nsSVGElement;
@ -61,42 +61,47 @@ public:
nsRect defaultRegion,
nsRect *result);
void GetImage(nsISVGRendererSurface **result);
void LookupImage(const nsAString &aName, nsISVGRendererSurface **aImage);
void DefineImage(const nsAString &aName, nsISVGRendererSurface *aImage);
void LookupRegion(const nsAString &aName, nsRect *aRect);
void DefineRegion(const nsAString &aName, nsRect aRect);
cairo_surface_t *GetImage();
void LookupImage(const nsAString &aName,
cairo_surface_t **aImage, nsRect *aRegion);
void DefineImage(const nsAString &aName,
cairo_surface_t *aImage, nsRect aRegion);
nsSVGFilterInstance(nsISVGRenderer *aRenderer,
nsSVGElement *aTarget,
nsSVGFilterInstance(nsSVGElement *aTarget,
nsIDOMSVGRect *aTargetBBox,
float aFilterX, float aFilterY,
float aFilterWidth, float aFilterHeight,
PRUint32 aFilterResX, PRUint32 aFilterResY,
PRUint16 aPrimitiveUnits) :
mRenderer(aRenderer),
mTarget(aTarget),
mTargetBBox(aTargetBBox),
mLastImage(nsnull),
mFilterX(aFilterX), mFilterY(aFilterY),
mFilterWidth(aFilterWidth), mFilterHeight(aFilterHeight),
mFilterResX(aFilterResX), mFilterResY(aFilterResY),
mPrimitiveUnits(aPrimitiveUnits) {
mImageDictionary.Init();
mRegionDictionary.Init();
}
private:
nsCOMPtr<nsISVGRenderer> mRenderer;
class ImageEntry {
public:
ImageEntry(cairo_surface_t *aImage, nsRect aRegion) :
mImage(aImage), mRegion(aRegion) {}
~ImageEntry() { cairo_surface_destroy(mImage); }
cairo_surface_t *mImage;
nsRect mRegion;
};
nsClassHashtable<nsStringHashKey,ImageEntry> mImageDictionary;
nsRefPtr<nsSVGElement> mTarget;
nsCOMPtr<nsIDOMSVGRect> mTargetBBox;
ImageEntry *mLastImage;
float mFilterX, mFilterY, mFilterWidth, mFilterHeight;
PRUint32 mFilterResX, mFilterResY;
PRUint16 mPrimitiveUnits;
nsInterfaceHashtable<nsStringHashKey,nsISVGRendererSurface> mImageDictionary;
nsDataHashtable<nsStringHashKey,nsRect> mRegionDictionary;
nsCOMPtr<nsISVGRendererSurface> mLastImage;
nsRect mLastRegion;
};
#endif

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

@ -42,7 +42,6 @@
#include "nsIDOMSVGGElement.h"
#include "nsPresContext.h"
#include "nsSVGContainerFrame.h"
#include "nsISVGRendererCanvas.h"
#include "nsLayoutAtoms.h"
typedef nsSVGDisplayContainerFrame nsSVGGenericContainerFrameBase;

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

@ -40,10 +40,12 @@
%{C++
#include "cairo.h"
struct nsRect;
%}
[ref] native nsRectRef(nsRect);
[ptr] native cairo_surface_t(cairo_surface_t);
typedef PRUint32 nscolor;
@ -69,7 +71,7 @@ interface nsISVGRendererSurface;
* Mozilla-native rendering object with a call to
* nsISVGRenderer::createCanvas().
*/
[uuid(81eb1fc4-ea69-45dd-b31e-fe2cbcab04a5)]
[uuid(e20d952c-ed16-4beb-a3f5-e995f0688bff)]
interface nsISVGRendererCanvas : nsISupports
{
/**
@ -136,6 +138,7 @@ interface nsISVGRendererCanvas : nsISupports
* or as an absolute surface.
*/
void pushSurface(in nsISVGRendererSurface surface, in boolean isSubSurface);
void pushCairoSurface(in cairo_surface_t surface, in boolean isSubSurface);
void popSurface();
/**
@ -152,7 +155,7 @@ interface nsISVGRendererCanvas : nsISupports
void compositeSurfaceWithMask(in nsISVGRendererSurface surface,
in nsISVGRendererSurface mask);
void compositeSurfaceMatrix(in nsISVGRendererSurface surface,
void compositeSurfaceMatrix(in cairo_surface_t surface,
in nsIDOMSVGMatrix canvasTM,
in float opacity);
};

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

@ -729,6 +729,13 @@ nsSVGCairoCanvas::PushSurface(nsISVGRendererSurface *aSurface,
if (!cairoSurface)
return NS_ERROR_FAILURE;
return PushCairoSurface(cairoSurface->GetSurface(), isSubSurface);
}
NS_IMETHODIMP
nsSVGCairoCanvas::PushCairoSurface(cairo_surface_t *aSurface,
PRBool isSubSurface)
{
ctxEntry *ctx = new ctxEntry;
if (!ctx)
return NS_ERROR_OUT_OF_MEMORY;
@ -743,9 +750,9 @@ nsSVGCairoCanvas::PushSurface(nsISVGRendererSurface *aSurface,
mContextStack.AppendElement(NS_STATIC_CAST(void*, ctx));
mCR = cairo_create(cairoSurface->GetSurface());
aSurface->GetWidth(&mWidth);
aSurface->GetHeight(&mHeight);
mCR = cairo_create(aSurface);
mWidth = cairo_image_surface_get_width(aSurface);
mHeight = cairo_image_surface_get_height(aSurface);
return NS_OK;
}
@ -822,22 +829,18 @@ nsSVGCairoCanvas::CompositeSurfaceWithMask(nsISVGRendererSurface *aSurface,
return NS_OK;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
/** Implements void compositeSurface(in cairo_surface_t surface,
in nsIDOMSVGMatrix canvasTM,
in float opacity); */
NS_IMETHODIMP
nsSVGCairoCanvas::CompositeSurfaceMatrix(nsISVGRendererSurface *aSurface,
nsSVGCairoCanvas::CompositeSurfaceMatrix(cairo_surface_t *aSurface,
nsIDOMSVGMatrix *aCTM, float aOpacity)
{
nsCOMPtr<nsISVGCairoSurface> cairoSurface = do_QueryInterface(aSurface);
if (!cairoSurface)
return NS_ERROR_FAILURE;
cairo_save(mCR);
SetupCairoMatrix(aCTM);
cairo_set_source_surface(mCR, cairoSurface->GetSurface(), 0.0, 0.0);
cairo_set_source_surface(mCR, aSurface, 0.0, 0.0);
cairo_paint_with_alpha(mCR, aOpacity);
cairo_restore(mCR);