Bug 709490 - Part 1: Let ImageBridge transfer CanvasClient async. r=nical

Thanks Jon Morton [:jmorton] (jonanin@gmail.com) for polishing patches.
This commit is contained in:
Morris Tseng
2015-10-05 10:50:15 +08:00
parent 44b1f00a42
commit f3a9959ded
20 changed files with 631 additions and 99 deletions

View File

@@ -13,6 +13,7 @@
#include "gfxPlatform.h" // for gfxPlatform
#include "GLReadTexImageHelper.h"
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/layers/AsyncCanvasRenderer.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/CompositorChild.h" // for CompositorChild
#include "mozilla/layers/GrallocTextureClient.h"
@@ -38,14 +39,32 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
switch (aType) {
case CanvasClientTypeShSurf:
return MakeAndAddRef<CanvasClientSharedSurface>(aForwarder, aFlags);
break;
case CanvasClientAsync:
return MakeAndAddRef<CanvasClientBridge>(aForwarder, aFlags);
default:
return MakeAndAddRef<CanvasClient2D>(aForwarder, aFlags);
break;
}
}
void
CanvasClientBridge::UpdateAsync(AsyncCanvasRenderer* aRenderer)
{
if (!GetForwarder() || !mLayer || !aRenderer ||
!aRenderer->GetCanvasClient()) {
return;
}
uint64_t asyncID = aRenderer->GetCanvasClientAsyncID();
if (asyncID == 0 || mAsyncID == asyncID) {
return;
}
static_cast<ShadowLayerForwarder*>(GetForwarder())
->AttachAsyncCompositable(asyncID, mLayer);
mAsyncID = asyncID;
}
void
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
@@ -321,13 +340,38 @@ CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
void
CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
auto gl = aLayer->mGLContext;
Renderer renderer;
renderer.construct<ClientCanvasLayer*>(aLayer);
UpdateRenderer(aSize, renderer);
}
void
CanvasClientSharedSurface::UpdateAsync(AsyncCanvasRenderer* aRenderer)
{
Renderer renderer;
renderer.construct<AsyncCanvasRenderer*>(aRenderer);
UpdateRenderer(aRenderer->GetSize(), renderer);
}
void
CanvasClientSharedSurface::UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer)
{
GLContext* gl = nullptr;
ClientCanvasLayer* layer = nullptr;
AsyncCanvasRenderer* asyncRenderer = nullptr;
if (aRenderer.constructed<ClientCanvasLayer*>()) {
layer = aRenderer.ref<ClientCanvasLayer*>();
gl = layer->mGLContext;
} else {
asyncRenderer = aRenderer.ref<AsyncCanvasRenderer*>();
gl = asyncRenderer->mGLContext;
}
gl->MakeCurrent();
RefPtr<TextureClient> newFront;
if (aLayer->mGLFrontbuffer) {
mShSurfClient = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
if (layer && layer->mGLFrontbuffer) {
mShSurfClient = CloneSurface(layer->mGLFrontbuffer.get(), layer->mFactory.get());
if (!mShSurfClient) {
gfxCriticalError() << "Invalid canvas front buffer";
return;
@@ -351,11 +395,18 @@ CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
bool needsReadback = (surf->mType == SharedSurfaceType::Basic);
if (needsReadback) {
TextureFlags flags = aLayer->Flags() |
TextureFlags::IMMUTABLE;
TextureFlags flags = TextureFlags::IMMUTABLE;
CompositableForwarder* shadowForwarder = nullptr;
if (layer) {
flags |= layer->Flags();
shadowForwarder = layer->ClientManager()->AsShadowForwarder();
} else {
MOZ_ASSERT(asyncRenderer);
flags |= mTextureFlags;
shadowForwarder = GetForwarder();
}
auto manager = aLayer->ClientManager();
auto shadowForwarder = manager->AsShadowForwarder();
auto layersBackend = shadowForwarder->GetCompositorBackendType();
mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend);
@@ -371,6 +422,14 @@ CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
return;
}
mNewFront = newFront;
}
void
CanvasClientSharedSurface::Updated()
{
auto forwarder = GetForwarder();
#ifndef MOZ_WIDGET_GONK
if (mFront) {
if (mFront->GetFlags() & TextureFlags::RECYCLE) {
@@ -385,12 +444,13 @@ CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
// - Call RemoveTexture() after newFront's UseTextures() call.
// It could improve performance of Host side's EGL handling on gonk
AutoRemoveTexture autoRemove(this);
if (mFront && mFront != newFront) {
if (mFront && mFront != mNewFront) {
autoRemove.mTexture = mFront;
}
#endif
mFront = newFront;
mFront = mNewFront;
mNewFront = nullptr;
// Add the new TexClient.
MOZ_ALWAYS_TRUE( AddTextureClient(mFront) );
@@ -406,6 +466,7 @@ void
CanvasClientSharedSurface::ClearSurfaces()
{
mFront = nullptr;
mNewFront = nullptr;
mShSurfClient = nullptr;
mReadbackClient = nullptr;
}