зеркало из https://github.com/mozilla/gecko-dev.git
Bug 353827 - Remove nsISVGRendererSurface from filter code. r=amenzie, sr=roc
This commit is contained in:
Родитель
af2134c04a
Коммит
cdbc54905e
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче