Bug 950372 - Convert imgIContainer::GetFrame to return a Moz2D SourceSurface instead of a Thebes gfxASurface. r=mattwoodrow

This commit is contained in:
Jonathan Watt 2014-04-15 19:02:23 +01:00
parent f0300f6626
commit 10e73de9e6
23 changed files with 210 additions and 203 deletions

View File

@ -753,17 +753,19 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
{
nsresult rv;
nsRefPtr<gfxASurface> thebesSurface =
RefPtr<SourceSurface> surface =
aImage->GetFrame(imgIContainer::FRAME_FIRST,
imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
nsRefPtr<gfxImageSurface> thebesImageSurface =
thebesSurface->GetAsReadableARGB32ImageSurface();
NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE);
// For either of the following formats we want to set the biBitCount member
// of the BITMAPINFOHEADER struct to 32, below. For that value the bitmap
// format defines that the A8/X8 WORDs in the bitmap byte stream be ignored
// for the BI_RGB value we use for the biCompression member.
MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
surface->GetFormat() == SurfaceFormat::B8G8R8X8);
RefPtr<DataSourceSurface> dataSurface =
thebesImageSurface->CopyToB8G8R8A8DataSourceSurface();
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
int32_t width = dataSurface->GetSize().width;

View File

@ -8,6 +8,8 @@
#include "mozilla/EventStates.h"
#include "mozilla/dom/SVGFEImageElementBinding.h"
#include "mozilla/dom/SVGFilterElement.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"
#include "nsSVGUtils.h"
@ -211,22 +213,16 @@ SVGFEImageElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
currentRequest->GetImage(getter_AddRefs(imageContainer));
}
nsRefPtr<gfxASurface> currentFrame;
RefPtr<SourceSurface> image;
if (imageContainer) {
currentFrame =
imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
image = imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
}
if (!currentFrame) {
if (!image) {
return FilterPrimitiveDescription(PrimitiveType::Empty);
}
gfxPlatform* platform = gfxPlatform::GetPlatform();
DrawTarget* dt = platform->ScreenReferenceDrawTarget();
RefPtr<SourceSurface> image =
platform->GetSourceSurfaceForSurface(dt, currentFrame);
IntSize nativeSize;
imageContainer->GetWidth(&nativeSize.width);
imageContainer->GetHeight(&nativeSize.height);

View File

@ -25,19 +25,21 @@ CopySurfaceDataToPackedArray(uint8_t* aSrc, uint8_t* aDst, IntSize aSrcSize,
/**
* Convert aSurface to a packed buffer in BGRA format. The pixel data is
* returned in a buffer allocated with new uint8_t[].
* returned in a buffer allocated with new uint8_t[]. The caller then has
* ownership of the buffer and is responsible for delete[]'ing it.
*/
uint8_t*
SurfaceToPackedBGRA(DataSourceSurface *aSurface);
/**
* Convert aSurface to a packed buffer in BGR format. The pixel data is
* returned in a buffer allocated with new uint8_t[].
* returned in a buffer allocated with new uint8_t[]. The caller then has
* ownership of the buffer and is responsible for delete[]'ing it.
*
* This function is currently only intended for use with surfaces of format
* SurfaceFormat::B8G8R8X8 since the X components of the pixel data are simply
* dropped (no attempt is made to un-pre-multiply alpha from the color
* components).
* SurfaceFormat::B8G8R8X8 since the X components of the pixel data (if any)
* are simply dropped (no attempt is made to un-pre-multiply alpha from the
* color components).
*/
uint8_t*
SurfaceToPackedBGR(DataSourceSurface *aSurface);

View File

@ -13,6 +13,8 @@
#include "gfxRect.h"
#include "GraphicsFilter.h"
#include "gfxASurface.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "nsRect.h"
#include "nsSize.h"
#include "limits.h"
@ -55,7 +57,7 @@ native nsSize(nsSize);
native Orientation(mozilla::image::Orientation);
[ref] native TimeStamp(mozilla::TimeStamp);
[ptr] native SVGImageContext(mozilla::SVGImageContext);
native already_AddRefed_gfxASurface(already_AddRefed<gfxASurface>);
native TempRefSourceSurface(mozilla::TemporaryRef<mozilla::gfx::SourceSurface>);
/**
@ -65,7 +67,7 @@ native already_AddRefed_gfxASurface(already_AddRefed<gfxASurface>);
*
* Internally, imgIContainer also manages animation of images.
*/
[scriptable, builtinclass, uuid(8b7db7dd-bfe9-40d3-9114-3a79c0658afd)]
[scriptable, builtinclass, uuid(503a830c-734d-4362-91f6-73f83ac59646)]
interface imgIContainer : nsISupports
{
/**
@ -150,6 +152,7 @@ interface imgIContainer : nsISupports
const long FLAG_DECODE_NO_COLORSPACE_CONVERSION = 0x4;
const long FLAG_CLAMP = 0x8;
const long FLAG_HIGH_QUALITY_SCALING = 0x10;
const long FLAG_WANT_DATA_SURFACE = 0x20;
/**
* Constants for specifying various "special" frames.
@ -173,9 +176,8 @@ interface imgIContainer : nsISupports
* @param aWhichFrame Frame specifier of the FRAME_* variety.
* @param aFlags Flags of the FLAG_* variety
*/
[noscript, notxpcom] already_AddRefed_gfxASurface
getFrame(in uint32_t aWhichFrame,
in uint32_t aFlags);
[noscript, notxpcom] TempRefSourceSurface getFrame(in uint32_t aWhichFrame,
in uint32_t aFlags);
/**
* Whether the given frame is opaque; that is, needs the background painted

View File

@ -6,11 +6,15 @@
#include "gfxDrawable.h"
#include "gfxPlatform.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "ClippedImage.h"
#include "Orientation.h"
#include "SVGImageContext.h"
using namespace mozilla;
using namespace mozilla::gfx;
using mozilla::layers::LayerManager;
using mozilla::layers::ImageContainer;
@ -20,7 +24,7 @@ namespace image {
class ClippedImageCachedSurface
{
public:
ClippedImageCachedSurface(mozilla::gfx::DrawTarget* aSurface,
ClippedImageCachedSurface(TemporaryRef<SourceSurface> aSurface,
const nsIntSize& aViewportSize,
const SVGImageContext* aSVGContext,
float aFrame,
@ -49,13 +53,12 @@ public:
mFlags == aFlags;
}
already_AddRefed<gfxASurface> Surface() {
nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mSurface);
return surf.forget();
TemporaryRef<SourceSurface> Surface() {
return mSurface;
}
private:
nsRefPtr<mozilla::gfx::DrawTarget> mSurface;
RefPtr<SourceSurface> mSurface;
const nsIntSize mViewportSize;
Maybe<SVGImageContext> mSVGContext;
const float mFrame;
@ -209,14 +212,14 @@ ClippedImage::GetIntrinsicRatio(nsSize* aRatio)
return NS_OK;
}
NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
ClippedImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
{
return GetFrameInternal(mClip.Size(), nullptr, aWhichFrame, aFlags);
}
already_AddRefed<gfxASurface>
TemporaryRef<SourceSurface>
ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize,
const SVGImageContext* aSVGContext,
uint32_t aWhichFrame,
@ -232,13 +235,11 @@ ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize,
frameToDraw,
aFlags)) {
// Create a surface to draw into.
mozilla::RefPtr<mozilla::gfx::DrawTarget> target;
nsRefPtr<gfxContext> ctx;
RefPtr<DrawTarget> target = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(IntSize(mClip.width, mClip.height),
SurfaceFormat::B8G8R8A8);
target = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(gfx::IntSize(mClip.width, mClip.height),
gfx::SurfaceFormat::B8G8R8A8);
ctx = new gfxContext(target);
nsRefPtr<gfxContext> ctx = new gfxContext(target);
// Create our callback.
nsRefPtr<gfxDrawingCallback> drawTileCallback =
@ -254,7 +255,7 @@ ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize,
GraphicsFilter::FILTER_FAST);
// Cache the resulting surface.
mCachedSurface = new ClippedImageCachedSurface(target,
mCachedSurface = new ClippedImageCachedSurface(target->Snapshot(),
aViewportSize,
aSVGContext,
frameToDraw,
@ -322,7 +323,7 @@ ClippedImage::Draw(gfxContext* aContext,
if (MustCreateSurface(aContext, aUserSpaceToImageSpace, sourceRect, aSubimage, aFlags)) {
// Create a temporary surface containing a single tile of this image.
// GetFrame will call DrawSingleTile internally.
nsRefPtr<gfxASurface> surface =
RefPtr<SourceSurface> surface =
GetFrameInternal(aViewportSize, aSVGContext, aWhichFrame, aFlags);
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);

View File

@ -7,7 +7,9 @@
#define MOZILLA_IMAGELIB_CLIPPEDIMAGE_H_
#include "ImageWrapper.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace image {
@ -24,6 +26,8 @@ class DrawSingleTileCallback;
*/
class ClippedImage : public ImageWrapper
{
typedef mozilla::gfx::SourceSurface SourceSurface;
public:
NS_DECL_ISUPPORTS
@ -35,8 +39,8 @@ public:
NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD_(mozilla::TemporaryRef<SourceSurface>)
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager,
mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE;
NS_IMETHOD Draw(gfxContext* aContext,
@ -55,10 +59,11 @@ protected:
ClippedImage(Image* aImage, nsIntRect aClip);
private:
already_AddRefed<gfxASurface> GetFrameInternal(const nsIntSize& aViewportSize,
const SVGImageContext* aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags);
mozilla::TemporaryRef<SourceSurface>
GetFrameInternal(const nsIntSize& aViewportSize,
const SVGImageContext* aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags);
bool ShouldClip();
bool MustCreateSurface(gfxContext* aContext,
const gfxMatrix& aTransform,

View File

@ -5,6 +5,8 @@
#include "FrozenImage.h"
using namespace mozilla::gfx;
namespace mozilla {
namespace image {
@ -40,7 +42,7 @@ FrozenImage::GetAnimated(bool* aAnimated)
return rv;
}
NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
FrozenImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
{

View File

@ -7,6 +7,8 @@
#define MOZILLA_IMAGELIB_FROZENIMAGE_H_
#include "ImageWrapper.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace image {
@ -24,6 +26,8 @@ namespace image {
*/
class FrozenImage : public ImageWrapper
{
typedef mozilla::gfx::SourceSurface SourceSurface;
public:
NS_DECL_ISUPPORTS
@ -34,8 +38,8 @@ public:
virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
NS_IMETHOD GetAnimated(bool* aAnimated) MOZ_OVERRIDE;
NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD_(TemporaryRef<SourceSurface>)
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD_(bool) FrameIsOpaque(uint32_t aWhichFrame) MOZ_OVERRIDE;
NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
layers::ImageContainer** _retval) MOZ_OVERRIDE;

View File

@ -4,10 +4,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ImageWrapper.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "Orientation.h"
#include "mozilla/MemoryReporting.h"
using mozilla::gfx::DataSourceSurface;
using mozilla::gfx::SourceSurface;
using mozilla::layers::LayerManager;
using mozilla::layers::ImageContainer;
@ -196,7 +200,7 @@ ImageWrapper::GetAnimated(bool* aAnimated)
return mInnerImage->GetAnimated(aAnimated);
}
NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
ImageWrapper::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
{

View File

@ -11,6 +11,8 @@
#include "OrientedImage.h"
using namespace mozilla::gfx;
using std::swap;
using mozilla::layers::LayerManager;
using mozilla::layers::ImageContainer;
@ -75,7 +77,7 @@ OrientedImage::GetIntrinsicRatio(nsSize* aRatio)
return rv;
}
NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
OrientedImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
{
@ -87,12 +89,12 @@ OrientedImage::GetFrame(uint32_t aWhichFrame,
// Get the underlying dimensions.
int32_t width, height;
rv = InnerImage()->GetWidth(&width);
NS_ENSURE_SUCCESS(rv, nullptr);
rv = InnerImage()->GetHeight(&height);
NS_ENSURE_SUCCESS(rv, nullptr);
if (mOrientation.SwapsWidthAndHeight()) {
rv = InnerImage()->GetWidth(&height);
rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&width);
} else {
rv = InnerImage()->GetWidth(&width);
rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&height);
swap(width, height);
}
NS_ENSURE_SUCCESS(rv, nullptr);
@ -108,12 +110,12 @@ OrientedImage::GetFrame(uint32_t aWhichFrame,
}
// Create a surface to draw into.
mozilla::RefPtr<mozilla::gfx::DrawTarget> target;
target = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(gfx::IntSize(width, height), surfaceFormat);
mozilla::RefPtr<DrawTarget> target =
gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(IntSize(width, height), surfaceFormat);
// Create our drawable.
nsRefPtr<gfxASurface> innerSurface =
RefPtr<SourceSurface> innerSurface =
InnerImage()->GetFrame(aWhichFrame, aFlags);
NS_ENSURE_TRUE(innerSurface, nullptr);
nsRefPtr<gfxDrawable> drawable =
@ -126,10 +128,7 @@ OrientedImage::GetFrame(uint32_t aWhichFrame,
imageRect, imageRect, imageRect, imageRect,
imageFormat, GraphicsFilter::FILTER_FAST);
nsRefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->
GetThebesSurfaceForDrawTarget(target);
return surface.forget();
return target->Snapshot();
}
NS_IMETHODIMP

View File

@ -7,6 +7,8 @@
#define MOZILLA_IMAGELIB_ORIENTEDIMAGE_H_
#include "ImageWrapper.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "Orientation.h"
namespace mozilla {
@ -21,6 +23,8 @@ namespace image {
*/
class OrientedImage : public ImageWrapper
{
typedef mozilla::gfx::SourceSurface SourceSurface;
public:
NS_DECL_ISUPPORTS
@ -32,8 +36,8 @@ public:
NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD_(mozilla::TemporaryRef<SourceSurface>)
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager,
mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE;
NS_IMETHOD Draw(gfxContext* aContext,

View File

@ -3,13 +3,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/histogram.h"
// Must #include ImageLogging.h before any IPDL-generated files or other files that #include prlog.h
#include "ImageLogging.h"
#include "RasterImage.h"
#include "base/histogram.h"
#include "gfxPlatform.h"
#include "nsComponentManagerUtils.h"
#include "imgDecoderObserver.h"
#include "nsError.h"
#include "Decoder.h"
#include "RasterImage.h"
#include "nsAutoPtr.h"
#include "prenv.h"
#include "prsystem.h"
@ -30,6 +34,8 @@
#include "gfxContext.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Services.h"
#include "mozilla/Preferences.h"
@ -48,6 +54,7 @@
#endif
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
using namespace mozilla::layers;
@ -880,9 +887,9 @@ RasterImage::CopyFrame(uint32_t aWhichFrame,
}
//******************************************************************************
/* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame,
* in uint32_t aFlags); */
NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
* in uint32_t aFlags); */
NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
RasterImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
{
@ -951,7 +958,22 @@ RasterImage::GetFrame(uint32_t aWhichFrame,
framesurf = imgsurf;
}
return framesurf.forget();
RefPtr<SourceSurface> result;
// As far as Moz2D is concerned, SourceSurface contains premultiplied alpha.
// If we're abusing it to contain non-premultiplied alpha then we want to
// avoid having Moz2D do any conversions on it (like copy to another
// surface). Hence why we try to wrap framesurf's data here for
// FLAG_DECODE_NO_PREMULTIPLY_ALPHA.
if ((aFlags & FLAG_WANT_DATA_SURFACE) != 0 ||
(aFlags & FLAG_DECODE_NO_PREMULTIPLY_ALPHA) != 0) {
result = gfxPlatform::GetPlatform()->GetWrappedDataSourceSurface(framesurf);
}
if (!result) {
result = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
framesurf);
}
return result.forget();
}
already_AddRefed<layers::Image>
@ -964,8 +986,8 @@ RasterImage::GetCurrentImage()
return nullptr;
}
nsRefPtr<gfxASurface> imageSurface = GetFrame(FRAME_CURRENT, FLAG_NONE);
if (!imageSurface) {
RefPtr<SourceSurface> surface = GetFrame(FRAME_CURRENT, FLAG_NONE);
if (!surface) {
// The OS threw out some or all of our buffer. Start decoding again.
// GetFrame will only return null in the case that the image was
// discarded. We already checked that the image is decoded, so other
@ -982,7 +1004,7 @@ RasterImage::GetCurrentImage()
CairoImage::Data cairoData;
GetWidth(&cairoData.mSize.width);
GetHeight(&cairoData.mSize.height);
cairoData.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, imageSurface);
cairoData.mSourceSurface = surface;
nsRefPtr<layers::Image> image = mImageContainer->CreateImage(ImageFormat::CAIRO_SURFACE);
NS_ASSERTION(image, "Failed to create Image");

View File

@ -649,9 +649,9 @@ VectorImage::FrameIsOpaque(uint32_t aWhichFrame)
}
//******************************************************************************
/* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame,
* in uint32_t aFlags; */
NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
* in uint32_t aFlags; */
NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
VectorImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
{
@ -674,27 +674,14 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
return nullptr;
}
// Create a surface that we'll ultimately return
// ---------------------------------------------
// Make our surface the size of what will ultimately be drawn to it.
// (either the full image size, or the restricted region)
gfxIntSize surfaceSize(imageIntSize.width, imageIntSize.height);
nsRefPtr<gfxImageSurface> surface =
new gfxImageSurface(surfaceSize, gfxImageFormat::ARGB32);
RefPtr<DrawTarget> drawTarget =
Factory::CreateDrawTargetForData(BackendType::CAIRO,
surface->Data(),
IntSize(imageIntSize.width,
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(IntSize(imageIntSize.width,
imageIntSize.height),
surface->Stride(),
SurfaceFormat::B8G8R8A8);
nsRefPtr<gfxContext> context = new gfxContext(dt);
nsRefPtr<gfxContext> context = new gfxContext(drawTarget);
// Draw to our surface!
// --------------------
nsresult rv = Draw(context, GraphicsFilter::FILTER_NEAREST, gfxMatrix(),
gfxRect(gfxPoint(0,0), gfxIntSize(imageIntSize.width,
imageIntSize.height)),
@ -702,7 +689,7 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
imageIntSize, nullptr, aWhichFrame, aFlags);
NS_ENSURE_SUCCESS(rv, nullptr);
return surface.forget();
return dt->Snapshot();
}
//******************************************************************************

View File

@ -6,6 +6,7 @@
#include "imgTools.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "nsCOMPtr.h"
@ -97,20 +98,6 @@ NS_IMETHODIMP imgTools::DecodeImage(nsIInputStream* aInStr,
return NS_OK;
}
static TemporaryRef<SourceSurface>
GetFirstImageFrame(imgIContainer *aContainer)
{
nsRefPtr<gfxASurface> frame =
aContainer->GetFrame(imgIContainer::FRAME_FIRST,
imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(frame, nullptr);
nsRefPtr<gfxImageSurface> imageSurface = frame->CopyToARGB32ImageSurface();
NS_ENSURE_TRUE(imageSurface, nullptr);
return imageSurface->CopyToB8G8R8A8DataSourceSurface();
}
/**
* This takes a DataSourceSurface rather than a SourceSurface because some
* of the callers have a DataSourceSurface and we don't want to call
@ -161,10 +148,22 @@ NS_IMETHODIMP imgTools::EncodeImage(imgIContainer *aContainer,
nsIInputStream **aStream)
{
// Use frame 0 from the image container.
RefPtr<SourceSurface> frame = GetFirstImageFrame(aContainer);
RefPtr<SourceSurface> frame =
aContainer->GetFrame(imgIContainer::FRAME_FIRST,
imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
RefPtr<DataSourceSurface> dataSurface = frame->GetDataSurface();
RefPtr<DataSourceSurface> dataSurface;
if (frame->GetFormat() == SurfaceFormat::B8G8R8A8) {
dataSurface = frame->GetDataSurface();
} else {
// Convert format to SurfaceFormat::B8G8R8A8
dataSurface = gfxUtils::
CopySurfaceToDataSourceSurfaceWithFormat(frame,
SurfaceFormat::B8G8R8A8);
}
NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
return EncodeImageData(dataSurface, aMimeType, aOutputOptions, aStream);
@ -186,7 +185,9 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
}
// Use frame 0 from the image container.
RefPtr<SourceSurface> frame = GetFirstImageFrame(aContainer);
RefPtr<SourceSurface> frame =
aContainer->GetFrame(imgIContainer::FRAME_FIRST,
imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
int32_t frameWidth = frame->GetSize().width;
@ -247,7 +248,9 @@ NS_IMETHODIMP imgTools::EncodeCroppedImage(imgIContainer *aContainer,
}
// Use frame 0 from the image container.
RefPtr<SourceSurface> frame = GetFirstImageFrame(aContainer);
RefPtr<SourceSurface> frame =
aContainer->GetFrame(imgIContainer::FRAME_FIRST,
imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
int32_t frameWidth = frame->GetSize().width;

View File

@ -5397,21 +5397,12 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement,
return result;
if (!noRasterize || imgContainer->GetType() == imgIContainer::TYPE_RASTER) {
bool wantImageSurface = (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) != 0;
if (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) {
wantImageSurface = true;
}
nsRefPtr<gfxASurface> gfxsurf =
imgContainer->GetFrame(whichFrame, frameFlags);
if (!gfxsurf)
return result;
if (wantImageSurface) {
result.mSourceSurface = gfxPlatform::GetPlatform()->GetWrappedDataSourceSurface(gfxsurf);
if (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) {
frameFlags |= imgIContainer::FLAG_WANT_DATA_SURFACE;
}
result.mSourceSurface = imgContainer->GetFrame(whichFrame, frameFlags);
if (!result.mSourceSurface) {
result.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, gfxsurf);
return result;
}
} else {
result.mDrawInfo.mImgContainer = imgContainer;

View File

@ -466,15 +466,9 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
continue;
}
nsRefPtr<gfxASurface> thebesSurface =
RefPtr<SourceSurface> surface =
image->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
if (!thebesSurface) {
continue;
}
RefPtr<SourceSurface> surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget(), thebesSurface);
if (!surface) {
continue;
}

View File

@ -5,6 +5,7 @@
#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "gfxUtils.h"
#include "nsCocoaUtils.h"
#include "nsChildView.h"
#include "nsMenuBarX.h"
@ -26,7 +27,12 @@
using namespace mozilla;
using namespace mozilla::widget;
using mozilla::gfx::BackendType;
using mozilla::gfx::DataSourceSurface;
using mozilla::gfx::DrawTarget;
using mozilla::gfx::Factory;
using mozilla::gfx::IntPoint;
using mozilla::gfx::IntRect;
using mozilla::gfx::IntSize;
using mozilla::gfx::SurfaceFormat;
using mozilla::gfx::SourceSurface;
@ -278,10 +284,19 @@ void data_ss_release_callback(void *aDataSourceSurface,
nsresult nsCocoaUtils::CreateCGImageFromSurface(SourceSurface* aSurface,
CGImageRef* aResult)
{
RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
RefPtr<DataSourceSurface> dataSurface;
MOZ_ASSERT(dataSurface->GetFormat() == SurfaceFormat::B8G8R8A8,
"We assume B8G8R8A8 when calling CGImageCreate");
if (aSurface->GetFormat() == SurfaceFormat::B8G8R8A8) {
dataSurface = aSurface->GetDataSurface();
} else {
// CGImageCreate only supports 16- and 32-bit bit-depth
// Convert format to SurfaceFormat::B8G8R8A8
dataSurface = gfxUtils::
CopySurfaceToDataSourceSurfaceWithFormat(aSurface,
SurfaceFormat::B8G8R8A8);
}
NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
int32_t width = dataSurface->GetSize().width;
int32_t height = dataSurface->GetSize().height;
@ -401,17 +416,7 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer *aImage, ui
surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, frame);
} else {
nsRefPtr<gfxASurface> thebesSurface =
aImage->GetFrame(aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE);
nsRefPtr<gfxImageSurface> thebesImageSurface =
thebesSurface->GetAsReadableARGB32ImageSurface();
NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE);
surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
thebesImageSurface);
surface = aImage->GetFrame(aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
}
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);

View File

@ -387,18 +387,14 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest)
if (mImageRegionRect.IsEmpty()) {
mImageRegionRect.SetRect(0, 0, origWidth, origHeight);
}
nsRefPtr<gfxASurface> thebesSurface =
RefPtr<SourceSurface> surface =
imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_NONE);
if (!thebesSurface) {
if (!surface) {
[mNativeMenuItem setImage:nil];
return NS_ERROR_FAILURE;
}
RefPtr<SourceSurface> surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
thebesSurface);
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
CGImageRef origImage = NULL;
nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &origImage);

View File

@ -43,7 +43,7 @@ nsImageToPixbuf::ConvertImageToPixbuf(imgIContainer* aImage)
GdkPixbuf*
nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage)
{
nsRefPtr<gfxASurface> thebesSurface =
RefPtr<SourceSurface> surface =
aImage->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
@ -51,15 +51,10 @@ nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage)
// in an imgINotificationObserver event, meaning that we're not allowed request
// a sync decode. Presumably the originating event is something sensible like
// OnStopFrame(), so we can just retry the call without a sync decode.
if (!thebesSurface)
thebesSurface = aImage->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_NONE);
if (!surface)
surface = aImage->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_NONE);
NS_ENSURE_TRUE(thebesSurface, nullptr);
RefPtr<SourceSurface> surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
thebesSurface);
NS_ENSURE_TRUE(surface, nullptr);
return SourceSurfaceToPixbuf(surface,

View File

@ -179,15 +179,9 @@ nsClipboard::SetNativeClipboardData( nsITransferable *aTransferable,
if (!image) // Not getting an image for an image mime type!?
continue;
nsRefPtr<gfxASurface> thebesSurface =
RefPtr<SourceSurface> surface =
image->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
if (!thebesSurface)
continue;
RefPtr<SourceSurface> surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
thebesSurface);
if (!surface)
continue;

View File

@ -731,12 +731,8 @@ AsyncFaviconDataReady::OnComplete(nsIURI *aFaviconURI,
getter_AddRefs(container));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<gfxASurface> imgFrame =
container->GetFrame(imgIContainer::FRAME_FIRST, 0);
NS_ENSURE_TRUE(imgFrame, NS_ERROR_FAILURE);
RefPtr<SourceSurface> surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, imgFrame);
container->GetFrame(imgIContainer::FRAME_FIRST, 0);
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
RefPtr<DataSourceSurface> dataSurface;

View File

@ -3,10 +3,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsImageClipboard.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "mozilla/RefPtr.h"
#include "nsITransferable.h"
#include "nsImageClipboard.h"
#include "nsGfxCIID.h"
#include "nsMemory.h"
#include "prmem.h"
@ -120,22 +123,24 @@ nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap
nsresult rv;
*outBitmap = nullptr;
nsRefPtr<gfxASurface> thebesSurface =
RefPtr<SourceSurface> surface =
inImage->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
nsRefPtr<gfxImageSurface> thebesImageSurface =
thebesSurface->GetAsReadableARGB32ImageSurface();
NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE);
MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
surface->GetFormat() == SurfaceFormat::B8G8R8X8);
IntSize surfaceSize(thebesImageSurface->GetSize().width,
thebesImageSurface->GetSize().height);
RefPtr<DataSourceSurface> dataSurface =
Factory::CreateWrappingDataSourceSurface(thebesImageSurface->Data(),
thebesImageSurface->Stride(),
surfaceSize,
SurfaceFormat::B8G8R8A8);
RefPtr<DataSourceSurface> dataSurface;
if (surface->GetFormat() == SurfaceFormat::B8G8R8A8) {
dataSurface = surface->GetDataSurface();
} else {
// XXXjwatt Bug 995923 - get rid of this copy and handle B8G8R8X8
// directly below once bug 995807 is fixed.
dataSurface = gfxUtils::
CopySurfaceToDataSourceSurfaceWithFormat(surface,
SurfaceFormat::B8G8R8A8);
}
NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/bmp", &rv);
@ -153,11 +158,15 @@ nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap
format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
options.AppendInt(32);
break;
#if 0
// XXXjwatt Bug 995923 - fix |format| and reenable once bug 995807 is fixed.
case SurfaceFormat::B8G8R8X8:
format = imgIEncoder::INPUT_FORMAT_RGB;
options.AppendInt(24);
break;
#endif
default:
NS_NOTREACHED("Unexpected surface format");
return NS_ERROR_INVALID_ARG;
}

View File

@ -53,7 +53,6 @@ using mozilla::plugins::PluginInstanceParent;
#include "nsUXThemeData.h"
#include "nsUXThemeConstants.h"
#include "mozilla/gfx/2D.h"
extern "C" {
#define PIXMAN_DONT_DEFINE_STDINT
@ -616,31 +615,26 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer,
(aScaledSize.width == 0 && aScaledSize.height == 0));
// Get the image data
nsRefPtr<gfxASurface> thebesSurface =
RefPtr<SourceSurface> surface =
aContainer->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(thebesSurface, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(surface, NS_ERROR_NOT_AVAILABLE);
RefPtr<SourceSurface> surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
thebesSurface);
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
IntSize surfaceSize(surface->GetSize().width, surface->GetSize().height);
if (surfaceSize.IsEmpty()) {
IntSize frameSize = surface->GetSize();
if (frameSize.IsEmpty()) {
return NS_ERROR_FAILURE;
}
IntSize iconSize(aScaledSize.width, aScaledSize.height);
if (iconSize == IntSize(0, 0)) { // use frame's intrinsic size
iconSize = surfaceSize;
iconSize = frameSize;
}
RefPtr<DataSourceSurface> dataSurface;
bool mappedOK;
DataSourceSurface::MappedSurface map;
if (iconSize != surfaceSize) {
if (iconSize != frameSize) {
// Scale the surface
dataSurface = Factory::CreateDataSourceSurface(iconSize,
SurfaceFormat::B8G8R8A8);
@ -656,7 +650,7 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer,
SurfaceFormat::B8G8R8A8);
dt->DrawSurface(surface,
Rect(0, 0, iconSize.width, iconSize.height),
Rect(0, 0, surfaceSize.width, surfaceSize.height),
Rect(0, 0, frameSize.width, frameSize.height),
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
} else if (surface->GetFormat() != SurfaceFormat::B8G8R8A8) {