Bug 801176 - part2-v5: Let Canvas 2d context works on Workers. r=roc

---
 dom/canvas/CanvasRenderingContext2D.cpp | 53 ++++++++++++-----------
 dom/canvas/OffscreenCanvas.cpp          | 46 +++++++++++---------
 dom/html/HTMLCanvasElement.cpp          |  1 +
 gfx/layers/AsyncCanvasRenderer.cpp      | 17 ++++++++
 gfx/layers/AsyncCanvasRenderer.h        | 16 +++++++
 gfx/layers/Effects.cpp                  |  6 +++
 gfx/layers/GLImages.cpp                 |  5 +--
 gfx/layers/client/CanvasClient.cpp      | 74 +++++++++++++++++++++++++--------
 gfx/layers/client/CanvasClient.h        | 10 ++++-
 9 files changed, 162 insertions(+), 66 deletions(-)
This commit is contained in:
vincentliu
2016-03-04 15:22:39 +08:00
parent a57559d183
commit fd0afbeb0e
9 changed files with 162 additions and 66 deletions

View File

@@ -26,6 +26,7 @@
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#include "TextureClientSharedSurface.h"
#include "VRManagerChild.h"
#include "gfxUtils.h"
using namespace mozilla::gfx;
using namespace mozilla::gl;
@@ -69,38 +70,69 @@ CanvasClientBridge::UpdateAsync(AsyncCanvasRenderer* aRenderer)
void
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
Renderer renderer;
renderer.construct<ClientCanvasLayer*>(aLayer);
UpdateRenderer(aSize, renderer);
}
void
CanvasClient2D::UpdateAsync(AsyncCanvasRenderer* aRenderer)
{
Renderer renderer;
renderer.construct<AsyncCanvasRenderer*>(aRenderer);
UpdateRenderer(aRenderer->GetSize(), renderer);
}
void
CanvasClient2D::UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer)
{
AutoRemoveTexture autoRemove(this);
ClientCanvasLayer* layer = nullptr;
AsyncCanvasRenderer* asyncRenderer = nullptr;
if (aRenderer.constructed<ClientCanvasLayer*>()) {
layer = aRenderer.ref<ClientCanvasLayer*>();
} else {
asyncRenderer = aRenderer.ref<AsyncCanvasRenderer*>();
}
if (mBuffer &&
(mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
autoRemove.mTexture = mBuffer;
mBuffer = nullptr;
}
bool bufferCreated = false;
mBufferCreated = false;
if (!mBuffer) {
bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
gfxContentType contentType = isOpaque
? gfxContentType::COLOR
: gfxContentType::COLOR_ALPHA;
gfx::SurfaceFormat surfaceFormat
= gfxPlatform::GetPlatform()->Optimal2DFormatForContent(contentType);
bool isOpaque;
gfxContentType contentType;
if (layer) {
isOpaque = (layer->GetContentFlags() & Layer::CONTENT_OPAQUE);
} else {
isOpaque = (asyncRenderer->GetOpaque() & Layer::CONTENT_OPAQUE);
}
contentType = isOpaque
? gfxContentType::COLOR
: gfxContentType::COLOR_ALPHA;
gfx::SurfaceFormat surfaceFormat =
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(contentType);
TextureFlags flags = TextureFlags::DEFAULT;
if (mTextureFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) {
flags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
}
mBuffer = CreateTextureClientForCanvas(surfaceFormat, aSize, flags, aLayer);
flags = TextureFlags::NO_FLAGS;
mBuffer = CreateTextureClientForCanvas(surfaceFormat, aSize, flags, layer);
if (!mBuffer) {
NS_WARNING("Failed to allocate the TextureClient");
return;
}
MOZ_ASSERT(mBuffer->CanExposeDrawTarget());
bufferCreated = true;
mBufferCreated = true;
}
bool updated = false;
mUpdated = false;
{
TextureClientAutoLock autoLock(mBuffer, OpenMode::OPEN_WRITE_ONLY);
if (!autoLock.Succeeded()) {
@@ -108,19 +140,27 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
return;
}
RefPtr<DrawTarget> target = mBuffer->BorrowDrawTarget();
if (target) {
aLayer->UpdateTarget(target);
updated = true;
if (layer) {
RefPtr<DrawTarget> target = mBuffer->BorrowDrawTarget();
if (target) {
layer->UpdateTarget(target);
}
} else {
asyncRenderer->UpdateTarget(mBuffer);
}
mUpdated = true;
}
}
if (bufferCreated && !AddTextureClient(mBuffer)) {
void
CanvasClient2D::Updated()
{
if (mBufferCreated && !AddTextureClient(mBuffer)) {
mBuffer = nullptr;
return;
}
if (updated) {
if (mUpdated) {
AutoTArray<CompositableForwarder::TimedTextureClient,1> textures;
CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
t->mTextureClient = mBuffer;
@@ -138,7 +178,7 @@ CanvasClient2D::CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
TextureFlags aFlags,
ClientCanvasLayer* aLayer)
{
if (aLayer->IsGLLayer()) {
if (aLayer && aLayer->IsGLLayer()) {
// We want a cairo backend here as we don't want to be copying into
// an accelerated backend and we like LockBits to work. This is currently
// the most effective way to make this work.