mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Backed out changeset 8681fc7a918b (bug 997014)
This commit is contained in:
parent
c3cc67ccbe
commit
7d7feda648
@ -14,8 +14,8 @@
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
|
||||
{ 0x06166dd1, 0xd540, 0x4f29, \
|
||||
{ 0x91, 0x5c, 0x08, 0x7d, 0xce, 0x1f, 0x79, 0x59 } }
|
||||
{ 0xf74397d9, 0x25d9, 0x43ed, \
|
||||
{ 0xb4, 0x6a, 0xf5, 0x4e, 0xa1, 0x17, 0xae, 0x6e } }
|
||||
|
||||
class gfxContext;
|
||||
class gfxASurface;
|
||||
@ -41,6 +41,10 @@ public:
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
|
||||
|
||||
enum {
|
||||
RenderFlagPremultAlpha = 0x1
|
||||
};
|
||||
|
||||
void SetCanvasElement(mozilla::dom::HTMLCanvasElement* aParentCanvas)
|
||||
{
|
||||
mCanvasElement = aParentCanvas;
|
||||
@ -62,6 +66,11 @@ public:
|
||||
|
||||
NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) = 0;
|
||||
|
||||
// Render the canvas at the origin of the given gfxContext
|
||||
NS_IMETHOD Render(gfxContext *ctx,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) = 0;
|
||||
|
||||
// Creates an image buffer. Returns null on failure.
|
||||
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) = 0;
|
||||
|
||||
|
@ -1053,6 +1053,51 @@ CanvasRenderingContext2D::SetIsIPC(bool isIPC)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasRenderingContext2D::Render(gfxContext *ctx, GraphicsFilter aFilter, uint32_t aFlags)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
EnsureTarget();
|
||||
if (!IsTargetValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
|
||||
if (NS_FAILED(GetThebesSurface(getter_AddRefs(surface)))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
||||
|
||||
pat->SetFilter(aFilter);
|
||||
pat->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
|
||||
gfxContext::GraphicsOperator op = ctx->CurrentOperator();
|
||||
if (mOpaque)
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
|
||||
// XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
|
||||
// pixel alignment for this stuff!
|
||||
ctx->NewPath();
|
||||
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
|
||||
ctx->Fill();
|
||||
|
||||
if (mOpaque)
|
||||
ctx->SetOperator(op);
|
||||
|
||||
if (!(aFlags & RenderFlagPremultAlpha)) {
|
||||
nsRefPtr<gfxASurface> curSurface = ctx->CurrentSurface();
|
||||
nsRefPtr<gfxImageSurface> gis = curSurface->GetAsImageSurface();
|
||||
MOZ_ASSERT(gis, "If non-premult alpha, must be able to get image surface!");
|
||||
|
||||
gfxUtils::UnpremultiplyImageSurface(gis);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions)
|
||||
{
|
||||
|
@ -457,6 +457,9 @@ public:
|
||||
NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
|
||||
NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD Render(gfxContext *ctx,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetInputStream(const char* aMimeType,
|
||||
const char16_t* aEncoderOptions,
|
||||
nsIInputStream **aStream) MOZ_OVERRIDE;
|
||||
|
@ -625,6 +625,48 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::Render(gfxContext *ctx, GraphicsFilter f, uint32_t aFlags)
|
||||
{
|
||||
if (!gl)
|
||||
return NS_OK;
|
||||
|
||||
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
|
||||
gfxImageFormat::ARGB32);
|
||||
if (surf->CairoStatus() != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
gl->MakeCurrent();
|
||||
ReadScreenIntoImageSurface(gl, surf);
|
||||
|
||||
bool srcPremultAlpha = mOptions.premultipliedAlpha;
|
||||
bool dstPremultAlpha = aFlags & RenderFlagPremultAlpha;
|
||||
|
||||
if (!srcPremultAlpha && dstPremultAlpha) {
|
||||
gfxUtils::PremultiplyImageSurface(surf);
|
||||
} else if (srcPremultAlpha && !dstPremultAlpha) {
|
||||
gfxUtils::UnpremultiplyImageSurface(surf);
|
||||
}
|
||||
surf->MarkDirty();
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
|
||||
pat->SetFilter(f);
|
||||
|
||||
// Pixels from ReadPixels will be "upside down" compared to
|
||||
// what cairo wants, so draw with a y-flip and a translte to
|
||||
// flip them.
|
||||
gfxMatrix m;
|
||||
m.Translate(gfxPoint(0.0, mHeight));
|
||||
m.Scale(1.0, -1.0);
|
||||
pat->SetMatrix(m);
|
||||
|
||||
ctx->NewPath();
|
||||
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
|
||||
ctx->Fill();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
|
||||
{
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
@ -716,31 +758,25 @@ WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat)
|
||||
*aImageBuffer = nullptr;
|
||||
*aFormat = 0;
|
||||
|
||||
// Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied
|
||||
bool premult;
|
||||
RefPtr<SourceSurface> snapshot =
|
||||
GetSurfaceSnapshot(mOptions.premultipliedAlpha ? nullptr : &premult);
|
||||
if (!snapshot) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mOptions.premultipliedAlpha || !premult, "We must get unpremult when we ask for it!");
|
||||
nsRefPtr<gfxImageSurface> imgsurf =
|
||||
new gfxImageSurface(gfxIntSize(mWidth, mHeight),
|
||||
gfxImageFormat::ARGB32);
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurface = snapshot->GetDataSurface();
|
||||
|
||||
DataSourceSurface::MappedSurface map;
|
||||
if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) {
|
||||
if (!imgsurf || imgsurf->CairoStatus()) {
|
||||
return;
|
||||
}
|
||||
|
||||
static const fallible_t fallible = fallible_t();
|
||||
uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4];
|
||||
if (!imageBuffer) {
|
||||
dataSurface->Unmap();
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf);
|
||||
if (!ctx || ctx->HasError()) {
|
||||
return;
|
||||
}
|
||||
memcpy(imageBuffer, map.mData, mWidth * mHeight * 4);
|
||||
|
||||
dataSurface->Unmap();
|
||||
// Use Render() to make sure that appropriate y-flip gets applied
|
||||
uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0;
|
||||
nsresult rv = Render(ctx, GraphicsFilter::FILTER_NEAREST, flags);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
|
||||
if (!mOptions.premultipliedAlpha) {
|
||||
@ -749,10 +785,17 @@ WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat)
|
||||
// Yes, it is THAT silly.
|
||||
// Except for different lossy conversions by color,
|
||||
// we could probably just change the label, and not change the data.
|
||||
gfxUtils::ConvertBGRAtoRGBA(imageBuffer, mWidth * mHeight * 4);
|
||||
gfxUtils::ConvertBGRAtoRGBA(imgsurf);
|
||||
format = imgIEncoder::INPUT_FORMAT_RGBA;
|
||||
}
|
||||
|
||||
static const fallible_t fallible = fallible_t();
|
||||
uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4];
|
||||
if (!imageBuffer) {
|
||||
return;
|
||||
}
|
||||
memcpy(imageBuffer, imgsurf->Data(), mWidth * mHeight * 4);
|
||||
|
||||
*aImageBuffer = imageBuffer;
|
||||
*aFormat = format;
|
||||
}
|
||||
@ -1339,8 +1382,7 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
|
||||
return nullptr;
|
||||
|
||||
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
|
||||
gfxImageFormat::ARGB32,
|
||||
mWidth * 4, 0, false);
|
||||
gfxImageFormat::ARGB32);
|
||||
if (surf->CairoStatus() != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -165,6 +165,9 @@ public:
|
||||
{ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD Reset() MOZ_OVERRIDE
|
||||
{ /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD Render(gfxContext *ctx,
|
||||
GraphicsFilter f,
|
||||
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
|
||||
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
|
||||
NS_IMETHOD GetInputStream(const char* aMimeType,
|
||||
const char16_t* aEncoderOptions,
|
||||
|
@ -246,24 +246,6 @@ gfxUtils::ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxUtils::ConvertBGRAtoRGBA(uint8_t* aData, uint32_t aLength)
|
||||
{
|
||||
uint8_t *src = aData;
|
||||
uint8_t *srcEnd = src + aLength;
|
||||
|
||||
uint8_t buffer[4];
|
||||
for (; src != srcEnd; src += 4) {
|
||||
buffer[0] = src[2];
|
||||
buffer[1] = src[1];
|
||||
buffer[2] = src[0];
|
||||
|
||||
src[0] = buffer[0];
|
||||
src[1] = buffer[1];
|
||||
src[2] = buffer[2];
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
IsSafeImageTransformComponent(gfxFloat aValue)
|
||||
{
|
||||
|
@ -48,7 +48,6 @@ public:
|
||||
|
||||
static void ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
|
||||
gfxImageSurface *aDestSurface = nullptr);
|
||||
static void ConvertBGRAtoRGBA(uint8_t* aData, uint32_t aLength);
|
||||
|
||||
/**
|
||||
* Draw something drawable while working around limitations like bad support
|
||||
|
Loading…
Reference in New Issue
Block a user