Bug 997014 - Part 1: Improve GetSurfaceSnapshot. r=roc

This commit is contained in:
Matt Woodrow 2014-04-17 17:28:17 +12:00
parent 3af065c262
commit 9b9ba8d636
4 changed files with 64 additions and 8 deletions

View File

@ -14,8 +14,8 @@
#include "mozilla/RefPtr.h"
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
{ 0x9a6a5bdf, 0x1261, 0x4057, \
{ 0x85, 0xcc, 0xaf, 0x97, 0x6c, 0x36, 0x99, 0xa9 } }
{ 0xf74397d9, 0x25d9, 0x43ed, \
{ 0xb4, 0x6a, 0xf5, 0x4e, 0xa1, 0x17, 0xae, 0x6e } }
class gfxContext;
class gfxASurface;
@ -90,7 +90,10 @@ public:
// This gets an Azure SourceSurface for the canvas, this will be a snapshot
// of the canvas at the time it was called.
virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() = 0;
// If aPremultAlpha is provided, then it assumed the callee can handle
// un-premultiplied surfaces, and *aPremultAlpha will be set to false
// if one is returned.
virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) = 0;
// If this context is opaque, the backing store of the canvas should
// be created as opaque; all compositing operators should assume the

View File

@ -465,8 +465,14 @@ public:
nsIInputStream **aStream) MOZ_OVERRIDE;
NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE
{ EnsureTarget(); return mTarget->Snapshot(); }
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) MOZ_OVERRIDE
{
EnsureTarget();
if (aPremultAlpha) {
*aPremultAlpha = true;
}
return mTarget->Snapshot();
}
NS_IMETHOD SetIsOpaque(bool isOpaque) MOZ_OVERRIDE;
bool GetIsOpaque() MOZ_OVERRIDE { return mOpaque; }

View File

@ -1376,9 +1376,56 @@ void
WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); }
mozilla::TemporaryRef<mozilla::gfx::SourceSurface>
WebGLContext::GetSurfaceSnapshot()
WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
{
return nullptr;
if (!gl)
return nullptr;
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
gfxImageFormat::ARGB32);
if (surf->CairoStatus() != 0) {
return nullptr;
}
gl->MakeCurrent();
ReadScreenIntoImageSurface(gl, surf);
if (aPremultAlpha) {
*aPremultAlpha = true;
}
bool srcPremultAlpha = mOptions.premultipliedAlpha;
if (!srcPremultAlpha) {
if (aPremultAlpha) {
*aPremultAlpha = false;
} else {
gfxUtils::PremultiplyImageSurface(surf);
surf->MarkDirty();
}
}
RefPtr<DrawTarget> dt =
Factory::CreateDrawTarget(BackendType::CAIRO,
IntSize(mWidth, mHeight),
SurfaceFormat::B8G8R8A8);
if (!dt) {
return nullptr;
}
RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, surf);
Matrix m;
m.Translate(0.0, mHeight);
m.Scale(1.0, -1.0);
dt->SetTransform(m);
dt->DrawSurface(source,
Rect(0, 0, mWidth, mHeight),
Rect(0, 0, mWidth, mHeight),
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
return dt->Snapshot();
}
//

View File

@ -173,7 +173,7 @@ public:
const char16_t* aEncoderOptions,
nsIInputStream **aStream) MOZ_OVERRIDE;
NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha) MOZ_OVERRIDE;
NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; };
bool GetIsOpaque() MOZ_OVERRIDE { return false; }