From ca2e75f93facd7be883cafd7b74e036f1920fc7a Mon Sep 17 00:00:00 2001 From: "tor%cs.brown.edu" Date: Wed, 6 Dec 2006 22:23:10 +0000 Subject: [PATCH] Bug 362008 - remove nsSVGImageFrame copy of image data. r=pavlov, sr=roc git-svn-id: svn://10.0.0.236/trunk@216606 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/svg/base/src/Makefile.in | 1 + .../layout/svg/base/src/nsSVGFilterFrame.cpp | 4 +- .../layout/svg/base/src/nsSVGImageFrame.cpp | 230 +++--------------- mozilla/layout/svg/base/src/nsSVGUtils.cpp | 6 +- mozilla/layout/svg/base/src/nsSVGUtils.h | 2 +- 5 files changed, 38 insertions(+), 205 deletions(-) diff --git a/mozilla/layout/svg/base/src/Makefile.in b/mozilla/layout/svg/base/src/Makefile.in index f2709a55620..06ddfcf3832 100644 --- a/mozilla/layout/svg/base/src/Makefile.in +++ b/mozilla/layout/svg/base/src/Makefile.in @@ -121,6 +121,7 @@ LOCAL_INCLUDES = \ -I$(srcdir)/../../../xul/base/src \ -I$(srcdir)/../../../../content/svg/content/src \ -I$(srcdir)/../../../../content/base/src \ + -I$(topsrcdir)/gfx/src/thebes \ $(NULL) libs:: diff --git a/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp b/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp index 9c3653ed1a4..c5c31b2d9c1 100644 --- a/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp @@ -441,8 +441,10 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext, ctm->Multiply(scale, getter_AddRefs(fini)); + gfxUnknownSurface resultSurface(filterResult); + nsSVGUtils::CompositeSurfaceMatrix(aContext->GetGfxContext(), - filterResult, fini, 1.0); + &resultSurface, fini, 1.0); aTarget->SetOverrideCTM(nsnull); aTarget->SetMatrixPropagation(PR_TRUE); diff --git a/mozilla/layout/svg/base/src/nsSVGImageFrame.cpp b/mozilla/layout/svg/base/src/nsSVGImageFrame.cpp index 9a1b4a9641a..ae670e9f3e2 100644 --- a/mozilla/layout/svg/base/src/nsSVGImageFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGImageFrame.cpp @@ -45,10 +45,11 @@ #include "nsIDOMSVGImageElement.h" #include "nsSVGElement.h" #include "nsSVGUtils.h" -#include "nsIImage.h" /* for MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP */ #include "nsSVGMatrix.h" #include "cairo.h" #include "gfxContext.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsThebesImage.h" #define NS_GET_BIT(rowptr, x) (rowptr[(x)>>3] & (1<<(7-(x)&0x7))) @@ -58,7 +59,6 @@ class nsSVGImageListener : public nsStubImageDecoderObserver { public: nsSVGImageListener(nsSVGImageFrame *aFrame); - virtual ~nsSVGImageListener(); NS_DECL_ISUPPORTS // imgIDecoderObserver (override nsStubImageDecoderObserver) @@ -124,12 +124,10 @@ private: nsCOMPtr mPreserveAspectRatio; nsCOMPtr mListener; - cairo_surface_t *mSurface; - nsresult ConvertFrame(gfxIImageFrame *aNewFrame); + nsCOMPtr mImageContainer; friend class nsSVGImageListener; - PRPackedBool mSurfaceInvalid; }; //---------------------------------------------------------------------- @@ -160,9 +158,6 @@ nsSVGImageFrame::~nsSVGImageFrame() NS_REINTERPRET_CAST(nsSVGImageListener*, mListener.get())->SetFrame(nsnull); } mListener = nsnull; - - if (mSurface) - cairo_surface_destroy(mSurface); } NS_IMETHODIMP @@ -182,9 +177,6 @@ nsSVGImageFrame::InitSVG() if (!mPreserveAspectRatio) return NS_ERROR_FAILURE; } - mSurface = nsnull; - mSurfaceInvalid = PR_TRUE; - mListener = new nsSVGImageListener(this); if (!mListener) return NS_ERROR_OUT_OF_MEMORY; nsCOMPtr imageLoader = do_QueryInterface(mContent); @@ -226,9 +218,9 @@ nsSVGImageFrame::GetImageTransform() nsSVGElement *element = NS_STATIC_CAST(nsSVGElement*, mContent); element->GetAnimatedLengthValues(&x, &y, &width, &height, nsnull); - PRUint32 nativeWidth, nativeHeight; - nativeWidth = cairo_image_surface_get_width(mSurface); - nativeHeight = cairo_image_surface_get_height(mSurface); + PRInt32 nativeWidth, nativeHeight; + mImageContainer->GetWidth(&nativeWidth); + mImageContainer->GetHeight(&nativeHeight); nsCOMPtr image = do_QueryInterface(mContent); nsCOMPtr ratio; @@ -257,30 +249,34 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext, nsRect *aDirtyRect) if (!GetStyleVisibility()->IsVisible()) return NS_OK; - if (mSurfaceInvalid) { + if (!mImageContainer) { nsCOMPtr currentRequest; nsCOMPtr imageLoader = do_QueryInterface(mContent); if (imageLoader) imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, getter_AddRefs(currentRequest)); - nsCOMPtr currentContainer; if (currentRequest) - currentRequest->GetImage(getter_AddRefs(currentContainer)); - - nsCOMPtr currentFrame; - if (currentContainer) - currentContainer->GetCurrentFrame(getter_AddRefs(currentFrame)); - - if (currentFrame) { - ConvertFrame(currentFrame); - mSurfaceInvalid = PR_FALSE; - } else { - return NS_OK; - } + currentRequest->GetImage(getter_AddRefs(mImageContainer)); } - if (mSurface) { + nsCOMPtr currentFrame; + if (mImageContainer) + mImageContainer->GetCurrentFrame(getter_AddRefs(currentFrame)); + + gfxASurface *thebesSurface = nsnull; + if (currentFrame) { + nsCOMPtr img(do_GetInterface(currentFrame)); + + nsThebesImage *thebesImage = nsnull; + if (img) + thebesImage = NS_STATIC_CAST(nsThebesImage*, img.get()); + + if (thebesImage) + thebesSurface = thebesImage->ThebesSurface(); + } + + if (thebesSurface) { gfxContext *gfx = aContext->GetGfxContext(); nsCOMPtr ctm; @@ -297,7 +293,7 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext, nsRect *aDirtyRect) nsSVGUtils::SetClipRect(gfx, ctm, x, y, width, height); } - nsSVGUtils::CompositeSurfaceMatrix(gfx, mSurface, fini, + nsSVGUtils::CompositeSurfaceMatrix(gfx, thebesSurface, fini, mStyleContext->GetStyleDisplay()->mOpacity); if (GetStyleDisplay()->IsScrollableOverflow()) @@ -310,10 +306,10 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext, nsRect *aDirtyRect) NS_IMETHODIMP nsSVGImageFrame::GetFrameForPointSVG(float x, float y, nsIFrame** hit) { - if (GetStyleDisplay()->IsScrollableOverflow() && mSurface) { - PRUint32 nativeWidth, nativeHeight; - nativeWidth = cairo_image_surface_get_width(mSurface); - nativeHeight = cairo_image_surface_get_height(mSurface); + if (GetStyleDisplay()->IsScrollableOverflow() && mImageContainer) { + PRInt32 nativeWidth, nativeHeight; + mImageContainer->GetWidth(&nativeWidth); + mImageContainer->GetHeight(&nativeHeight); nsCOMPtr fini = GetImageTransform(); @@ -334,166 +330,6 @@ nsSVGImageFrame::GetType() const return nsLayoutAtoms::svgImageFrame; } -nsresult -nsSVGImageFrame::ConvertFrame(gfxIImageFrame *aNewFrame) -{ - PRInt32 width, height; - aNewFrame->GetWidth(&width); - aNewFrame->GetHeight(&height); - - mSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - if (!mSurface) - return NS_ERROR_FAILURE; - - PRUint8 *data, *target; - PRUint32 length; - PRInt32 stride; - - data = cairo_image_surface_get_data(mSurface); - stride = cairo_image_surface_get_stride(mSurface); - -#ifdef MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP - stride = -stride; -#endif - - aNewFrame->LockImageData(); - aNewFrame->LockAlphaData(); - - PRUint8 *rgb, *alpha = nsnull; - PRUint32 bpr, abpr; - aNewFrame->GetImageData(&rgb, &length); - aNewFrame->GetImageBytesPerRow(&bpr); - if (!rgb) { - aNewFrame->UnlockImageData(); - aNewFrame->UnlockAlphaData(); - return NS_ERROR_FAILURE; - } - -#ifdef MOZ_CAIRO_GFX - // cairo gfx already has the data in the order/format - just copy - memcpy(data, rgb, bpr*height); -#else - - aNewFrame->GetAlphaData(&alpha, &length); - aNewFrame->GetAlphaBytesPerRow(&abpr); - - // some platforms return 4bpp (OSX and Win32 under some circumstances) - const PRUint32 bpp = bpr/width; - -#ifdef XP_MACOSX - // pixels on os-x have a lead byte we don't care about (alpha or - // garbage, depending on the image format) - shift our pointer down - // one so we can use the rest of the code as-is - rgb++; -#endif - -#if (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(MOZ_CAIRO_GFX) -#define REVERSE_CHANNELS -#endif - -#if defined(XP_MACOSX) && defined(__i386__) -#define REVERSE_CHANNELS -#endif - - // cairo/os-x wants ABGR format, GDI+ wants RGBA, cairo/unix wants BGRA - if (!alpha) { - for (PRInt32 y=0; y 0) - target = data + stride * y; - else - target = data + stride * (1 - height) + stride * y; - for (PRInt32 x=0; x= width) { - /* 8-bit alpha */ - for (PRInt32 y=0; y 0) - target = data + stride * y; - else - target = data + stride * (1 - height) + stride * y; - for (PRInt32 x=0; x 0) - target = data + stride * y; - else - target = data + stride * (1 - height) + stride * y; - PRUint8 *alphaRow = alpha + y*abpr; - - for (PRUint32 x=0; xUnlockImageData(); - aNewFrame->UnlockAlphaData(); - - return NS_OK; -} - //---------------------------------------------------------------------- // nsSVGPathGeometryFrame methods: @@ -548,10 +384,6 @@ nsSVGImageListener::nsSVGImageListener(nsSVGImageFrame *aFrame) : mFrame(aFrame { } -nsSVGImageListener::~nsSVGImageListener() -{ -} - NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest, nsresult status, const PRUnichar *statusArg) @@ -559,7 +391,6 @@ NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest, if (!mFrame) return NS_ERROR_FAILURE; - mFrame->mSurfaceInvalid = PR_TRUE; mFrame->UpdateGraphic(); return NS_OK; } @@ -571,7 +402,6 @@ NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIContainer *aContainer, if (!mFrame) return NS_ERROR_FAILURE; - mFrame->mSurfaceInvalid = PR_TRUE; mFrame->UpdateGraphic(); return NS_OK; } diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.cpp b/mozilla/layout/svg/base/src/nsSVGUtils.cpp index f7d52ab63d5..d61b354e6be 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.cpp +++ b/mozilla/layout/svg/base/src/nsSVGUtils.cpp @@ -1007,7 +1007,7 @@ nsSVGUtils::UserToDeviceBBox(cairo_t *ctx, void nsSVGUtils::CompositeSurfaceMatrix(gfxContext *aContext, - cairo_surface_t *aSurface, + gfxASurface *aSurface, nsIDOMSVGMatrix *aCTM, float aOpacity) { cairo_matrix_t matrix = ConvertSVGMatrixToCairo(aCTM); @@ -1018,8 +1018,8 @@ nsSVGUtils::CompositeSurfaceMatrix(gfxContext *aContext, aContext->Multiply(gfxMatrix(matrix)); - cairo_set_source_surface(aContext->GetCairo(), aSurface, 0.0, 0.0); - cairo_paint_with_alpha(aContext->GetCairo(), aOpacity); + aContext->SetSource(aSurface); + aContext->Paint(aOpacity); aContext->Restore(); } diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.h b/mozilla/layout/svg/base/src/nsSVGUtils.h index d8ae06c26de..2bd672cc9bc 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.h +++ b/mozilla/layout/svg/base/src/nsSVGUtils.h @@ -316,7 +316,7 @@ public: double *xmax, double *ymax); static void CompositeSurfaceMatrix(gfxContext *aContext, - cairo_surface_t *aSurface, + gfxASurface *aSurface, nsIDOMSVGMatrix *aCTM, float aOpacity); static void SetClipRect(gfxContext *aContext,