зеркало из https://github.com/mozilla/gecko-dev.git
Bug 709490 - Part 1: Let ImageBridge transfer CanvasClient async. r=nical
Thanks Jon Morton [:jmorton] (jonanin@gmail.com) for polishing patches. --HG-- extra : rebase_source : f4ec56dc106357e30660343166ff51e7d9dc0c62
This commit is contained in:
Родитель
7e228f0ac3
Коммит
acf60f0d3e
|
@ -21,6 +21,7 @@
|
|||
#include "mozilla/dom/MouseEvent.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/layers/AsyncCanvasRenderer.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -251,6 +252,10 @@ HTMLCanvasElement::~HTMLCanvasElement()
|
|||
if (mRequestedFrameRefreshObserver) {
|
||||
mRequestedFrameRefreshObserver->DetachFromRefreshDriver();
|
||||
}
|
||||
|
||||
if (mAsyncCanvasRenderer) {
|
||||
mAsyncCanvasRenderer->mHTMLCanvasElement = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLCanvasElement, nsGenericHTMLElement,
|
||||
|
@ -1237,5 +1242,38 @@ HTMLCanvasElement::GetSurfaceSnapshot(bool* aPremultAlpha)
|
|||
return mCurrentContext->GetSurfaceSnapshot(aPremultAlpha);
|
||||
}
|
||||
|
||||
AsyncCanvasRenderer*
|
||||
HTMLCanvasElement::GetAsyncCanvasRenderer()
|
||||
{
|
||||
if (!mAsyncCanvasRenderer) {
|
||||
mAsyncCanvasRenderer = new AsyncCanvasRenderer();
|
||||
mAsyncCanvasRenderer->mHTMLCanvasElement = this;
|
||||
}
|
||||
|
||||
return mAsyncCanvasRenderer;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
HTMLCanvasElement::SetAttrFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer)
|
||||
{
|
||||
HTMLCanvasElement *element = aRenderer->mHTMLCanvasElement;
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::IntSize asyncCanvasSize = aRenderer->GetSize();
|
||||
|
||||
ErrorResult rv;
|
||||
element->SetUnsignedIntAttr(nsGkAtoms::width, asyncCanvasSize.width, rv);
|
||||
if (rv.Failed()) {
|
||||
NS_WARNING("Failed to set width attribute to a canvas element asynchronously.");
|
||||
}
|
||||
|
||||
element->SetUnsignedIntAttr(nsGkAtoms::height, asyncCanvasSize.height, rv);
|
||||
if (rv.Failed()) {
|
||||
NS_WARNING("Failed to set height attribute to a canvas element asynchronously.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -22,6 +22,7 @@ class nsITimerCallback;
|
|||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
class AsyncCanvasRenderer;
|
||||
class CanvasLayer;
|
||||
class Image;
|
||||
class LayerManager;
|
||||
|
@ -91,6 +92,7 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
|
|||
DEFAULT_CANVAS_HEIGHT = 150
|
||||
};
|
||||
|
||||
typedef layers::AsyncCanvasRenderer AsyncCanvasRenderer;
|
||||
typedef layers::CanvasLayer CanvasLayer;
|
||||
typedef layers::LayerManager LayerManager;
|
||||
|
||||
|
@ -282,6 +284,8 @@ public:
|
|||
|
||||
nsresult GetContext(const nsAString& aContextId, nsISupports** aContext);
|
||||
|
||||
static void SetAttrFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
|
||||
|
||||
protected:
|
||||
virtual ~HTMLCanvasElement();
|
||||
|
||||
|
@ -307,6 +311,8 @@ protected:
|
|||
nsISupports** aResult);
|
||||
void CallPrintCallback();
|
||||
|
||||
AsyncCanvasRenderer* GetAsyncCanvasRenderer();
|
||||
|
||||
CanvasContextType mCurrentContextType;
|
||||
nsRefPtr<HTMLCanvasElement> mOriginalCanvas;
|
||||
nsRefPtr<PrintCallback> mPrintCallback;
|
||||
|
@ -314,6 +320,7 @@ protected:
|
|||
nsRefPtr<HTMLCanvasPrintState> mPrintState;
|
||||
nsTArray<WeakPtr<FrameCaptureListener>> mRequestedFrameListeners;
|
||||
nsRefPtr<RequestedFrameRefreshObserver> mRequestedFrameRefreshObserver;
|
||||
nsRefPtr<AsyncCanvasRenderer> mAsyncCanvasRenderer;
|
||||
|
||||
public:
|
||||
// Record whether this canvas should be write-only or not.
|
||||
|
|
|
@ -10,18 +10,32 @@
|
|||
#include "GLContext.h"
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "SharedSurfaceEGL.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "../layers/ipc/ShadowLayers.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "SharedSurfaceANGLE.h" // for SurfaceFactory_ANGLEShareHandle
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "SharedSurfaceIO.h"
|
||||
#endif
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "../layers/ipc/ShadowLayers.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
|
||||
#ifdef GL_PROVIDER_GLX
|
||||
#include "GLXLibrary.h"
|
||||
#include "SharedSurfaceGLX.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -51,6 +65,53 @@ GLScreenBuffer::Create(GLContext* gl,
|
|||
return Move(ret);
|
||||
}
|
||||
|
||||
/* static */ UniquePtr<SurfaceFactory>
|
||||
GLScreenBuffer::CreateFactory(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::CompositableForwarder>& forwarder,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
UniquePtr<SurfaceFactory> factory = nullptr;
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
switch (forwarder->GetCompositorBackendType()) {
|
||||
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
|
||||
#if defined(XP_MACOSX)
|
||||
factory = SurfaceFactory_IOSurface::Create(gl, caps, forwarder, flags);
|
||||
#elif defined(MOZ_WIDGET_GONK)
|
||||
factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps, forwarder, flags);
|
||||
#elif defined(GL_PROVIDER_GLX)
|
||||
if (sGLXLibrary.UseSurfaceSharing())
|
||||
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, forwarder, flags);
|
||||
#else
|
||||
if (gl->GetContextType() == GLContextType::EGL) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(gl, caps, forwarder, flags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
|
||||
#ifdef XP_WIN
|
||||
// Enable surface sharing only if ANGLE and compositing devices
|
||||
// are both WARP or both not WARP
|
||||
if (gl->IsANGLE() &&
|
||||
(gl->IsWARP() == gfxWindowsPlatform::GetPlatform()->IsWARP()) &&
|
||||
gfxWindowsPlatform::GetPlatform()->CompositorD3D11TextureSharingWorks())
|
||||
{
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(gl, caps, forwarder, flags);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
GLScreenBuffer::GLScreenBuffer(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
UniquePtr<SurfaceFactory> factory)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class CompositableForwarder;
|
||||
class SharedSurfaceTextureClient;
|
||||
} // namespace layers
|
||||
|
||||
|
@ -133,6 +134,12 @@ public:
|
|||
const gfx::IntSize& size,
|
||||
const SurfaceCaps& caps);
|
||||
|
||||
static UniquePtr<SurfaceFactory>
|
||||
CreateFactory(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::CompositableForwarder>& forwarder,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
protected:
|
||||
GLContext* const mGL; // Owns us.
|
||||
public:
|
||||
|
|
|
@ -311,6 +311,7 @@ SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
|
|||
, mAllocator(allocator)
|
||||
, mFlags(flags)
|
||||
, mFormats(gl->ChooseGLFormats(caps))
|
||||
, mMutex("SurfaceFactor::mMutex")
|
||||
{
|
||||
ChooseBufferBits(mCaps, &mDrawCaps, &mReadCaps);
|
||||
}
|
||||
|
@ -368,6 +369,7 @@ SurfaceFactory::StartRecycling(layers::SharedSurfaceTextureClient* tc)
|
|||
void
|
||||
SurfaceFactory::StopRecycling(layers::SharedSurfaceTextureClient* tc)
|
||||
{
|
||||
MutexAutoLock autoLock(mMutex);
|
||||
// Must clear before releasing ref.
|
||||
tc->ClearRecycleCallback();
|
||||
|
||||
|
@ -379,11 +381,8 @@ SurfaceFactory::StopRecycling(layers::SharedSurfaceTextureClient* tc)
|
|||
/*static*/ void
|
||||
SurfaceFactory::RecycleCallback(layers::TextureClient* rawTC, void* rawFactory)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<layers::SharedSurfaceTextureClient> tc;
|
||||
tc = static_cast<layers::SharedSurfaceTextureClient*>(rawTC);
|
||||
|
||||
SurfaceFactory* factory = static_cast<SurfaceFactory*>(rawFactory);
|
||||
|
||||
if (tc->mSurf->mCanRecycle) {
|
||||
|
@ -399,6 +398,7 @@ bool
|
|||
SurfaceFactory::Recycle(layers::SharedSurfaceTextureClient* texClient)
|
||||
{
|
||||
MOZ_ASSERT(texClient);
|
||||
MutexAutoLock autoLock(mMutex);
|
||||
|
||||
if (mRecycleFreePool.size() >= 2) {
|
||||
return false;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
|
@ -298,6 +299,7 @@ public:
|
|||
const RefPtr<layers::ISurfaceAllocator> mAllocator;
|
||||
const layers::TextureFlags mFlags;
|
||||
const GLFormats mFormats;
|
||||
Mutex mMutex;
|
||||
protected:
|
||||
SurfaceCaps mDrawCaps;
|
||||
SurfaceCaps mReadCaps;
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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 "AsyncCanvasRenderer.h"
|
||||
|
||||
#include "gfxUtils.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
AsyncCanvasRenderer::AsyncCanvasRenderer()
|
||||
: mWidth(0)
|
||||
, mHeight(0)
|
||||
, mCanvasClientAsyncID(0)
|
||||
, mCanvasClient(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(AsyncCanvasRenderer);
|
||||
}
|
||||
|
||||
AsyncCanvasRenderer::~AsyncCanvasRenderer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(AsyncCanvasRenderer);
|
||||
}
|
||||
|
||||
void
|
||||
AsyncCanvasRenderer::NotifyElementAboutAttributesChanged()
|
||||
{
|
||||
class Runnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit Runnable(AsyncCanvasRenderer* aRenderer)
|
||||
: mRenderer(aRenderer)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mRenderer) {
|
||||
dom::HTMLCanvasElement::SetAttrFromAsyncCanvasRenderer(mRenderer);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Revoke()
|
||||
{
|
||||
mRenderer = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<AsyncCanvasRenderer> mRenderer;
|
||||
};
|
||||
|
||||
nsRefPtr<nsRunnable> runnable = new Runnable(this);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch a runnable to the main-thread.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsyncCanvasRenderer::SetCanvasClient(CanvasClient* aClient)
|
||||
{
|
||||
mCanvasClient = aClient;
|
||||
if (aClient) {
|
||||
mCanvasClientAsyncID = aClient->GetAsyncID();
|
||||
} else {
|
||||
mCanvasClientAsyncID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,100 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#ifndef MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_
|
||||
#define MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_
|
||||
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/RefPtr.h" // for nsAutoPtr, nsRefPtr, etc
|
||||
|
||||
class nsICanvasRenderingContextInternal;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
class HTMLCanvasElement;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class CanvasClient;
|
||||
|
||||
/**
|
||||
* Since HTMLCanvasElement and OffscreenCanvas are not thread-safe, we create
|
||||
* AsyncCanvasRenderer which is thread-safe wrapper object for communicating
|
||||
* among main, worker and ImageBridgeChild threads.
|
||||
*
|
||||
* Each HTMLCanvasElement object is responsible for creating
|
||||
* AsyncCanvasRenderer object. Once Canvas is transfered to worker,
|
||||
* OffscreenCanvas will keep reference pointer of this object.
|
||||
* This object will pass to ImageBridgeChild for submitting frames to
|
||||
* Compositor.
|
||||
*/
|
||||
class AsyncCanvasRenderer final
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncCanvasRenderer)
|
||||
|
||||
public:
|
||||
AsyncCanvasRenderer();
|
||||
|
||||
void NotifyElementAboutAttributesChanged();
|
||||
|
||||
void SetCanvasClient(CanvasClient* aClient);
|
||||
|
||||
void SetWidth(uint32_t aWidth)
|
||||
{
|
||||
mWidth = aWidth;
|
||||
}
|
||||
|
||||
void SetHeight(uint32_t aHeight)
|
||||
{
|
||||
mHeight = aHeight;
|
||||
}
|
||||
|
||||
gfx::IntSize GetSize() const
|
||||
{
|
||||
return gfx::IntSize(mWidth, mHeight);
|
||||
}
|
||||
|
||||
uint64_t GetCanvasClientAsyncID() const
|
||||
{
|
||||
return mCanvasClientAsyncID;
|
||||
}
|
||||
|
||||
CanvasClient* GetCanvasClient() const
|
||||
{
|
||||
return mCanvasClient;
|
||||
}
|
||||
|
||||
// The lifetime is controllered by HTMLCanvasElement.
|
||||
dom::HTMLCanvasElement* mHTMLCanvasElement;
|
||||
|
||||
nsICanvasRenderingContextInternal* mContext;
|
||||
|
||||
// We need to keep a reference to the context around here, otherwise the
|
||||
// canvas' surface texture destructor will deref and destroy it too early
|
||||
RefPtr<gl::GLContext> mGLContext;
|
||||
|
||||
private:
|
||||
|
||||
virtual ~AsyncCanvasRenderer();
|
||||
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
uint64_t mCanvasClientAsyncID;
|
||||
|
||||
// The lifetime of this pointer is controlled by OffscreenCanvas
|
||||
CanvasClient* mCanvasClient;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_
|
|
@ -80,6 +80,10 @@ CopyableCanvasLayer::IsDataValid(const Data& aData)
|
|||
void
|
||||
CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
||||
{
|
||||
if (!mBufferProvider && !mGLContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBufferProvider) {
|
||||
mSurface = mBufferProvider->GetSnapshot();
|
||||
}
|
||||
|
@ -99,8 +103,6 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
|||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mGLContext);
|
||||
|
||||
SharedSurface* frontbuffer = nullptr;
|
||||
if (mGLFrontbuffer) {
|
||||
frontbuffer = mGLFrontbuffer.get();
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "mozilla/gfx/2D.h" // for DrawTarget
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
||||
#include "mozilla/layers/AsyncCanvasRenderer.h"
|
||||
#include "mozilla/layers/CompositableClient.h" // for CompositableClient
|
||||
#include "mozilla/layers/Compositor.h" // for Compositor
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
|
@ -2132,6 +2133,25 @@ ColorLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
|
|||
layer->set_color(mColor.ToABGR());
|
||||
}
|
||||
|
||||
CanvasLayer::CanvasLayer(LayerManager* aManager, void* aImplData)
|
||||
: Layer(aManager, aImplData)
|
||||
, mPreTransCallback(nullptr)
|
||||
, mPreTransCallbackData(nullptr)
|
||||
, mPostTransCallback(nullptr)
|
||||
, mPostTransCallbackData(nullptr)
|
||||
, mFilter(gfx::Filter::GOOD)
|
||||
, mDirty(false)
|
||||
{}
|
||||
|
||||
CanvasLayer::~CanvasLayer()
|
||||
{}
|
||||
|
||||
void
|
||||
CanvasLayer::SetAsyncRenderer(AsyncCanvasRenderer *aAsyncRenderer)
|
||||
{
|
||||
mAsyncRenderer = aAsyncRenderer;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
{
|
||||
|
|
|
@ -73,6 +73,7 @@ namespace layers {
|
|||
|
||||
class Animation;
|
||||
class AnimationData;
|
||||
class AsyncCanvasRenderer;
|
||||
class AsyncPanZoomController;
|
||||
class ClientLayerManager;
|
||||
class Layer;
|
||||
|
@ -2396,16 +2397,16 @@ public:
|
|||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
}
|
||||
|
||||
bool GetIsAsyncRenderer() const
|
||||
{
|
||||
return !!mAsyncRenderer;
|
||||
}
|
||||
|
||||
void SetAsyncRenderer(AsyncCanvasRenderer *aAsyncRenderer);
|
||||
|
||||
protected:
|
||||
CanvasLayer(LayerManager* aManager, void* aImplData)
|
||||
: Layer(aManager, aImplData)
|
||||
, mPreTransCallback(nullptr)
|
||||
, mPreTransCallbackData(nullptr)
|
||||
, mPostTransCallback(nullptr)
|
||||
, mPostTransCallbackData(nullptr)
|
||||
, mFilter(gfx::Filter::GOOD)
|
||||
, mDirty(false)
|
||||
{}
|
||||
CanvasLayer(LayerManager* aManager, void* aImplData);
|
||||
virtual ~CanvasLayer();
|
||||
|
||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
|
||||
|
||||
|
@ -2427,6 +2428,7 @@ protected:
|
|||
DidTransactionCallback mPostTransCallback;
|
||||
void* mPostTransCallbackData;
|
||||
gfx::Filter mFilter;
|
||||
nsRefPtr<AsyncCanvasRenderer> mAsyncRenderer;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -322,13 +341,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;
|
||||
|
@ -352,11 +396,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);
|
||||
|
||||
|
@ -372,6 +423,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) {
|
||||
|
@ -386,12 +445,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) );
|
||||
|
@ -407,6 +467,7 @@ void
|
|||
CanvasClientSharedSurface::ClearSurfaces()
|
||||
{
|
||||
mFront = nullptr;
|
||||
mNewFront = nullptr;
|
||||
mShSurfClient = nullptr;
|
||||
mReadbackClient = nullptr;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
|
||||
|
||||
// Fix X11 header brain damage that conflicts with MaybeOneOf::None
|
||||
#undef None
|
||||
#include "mozilla/MaybeOneOf.h"
|
||||
|
||||
#include "mozilla/mozalloc.h" // for operator delete
|
||||
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
|
@ -21,8 +26,10 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class AsyncCanvasRenderer;
|
||||
class ClientCanvasLayer;
|
||||
class CompositableForwarder;
|
||||
class ShadowableLayer;
|
||||
class SharedSurfaceTextureClient;
|
||||
|
||||
/**
|
||||
|
@ -31,6 +38,8 @@ class SharedSurfaceTextureClient;
|
|||
class CanvasClient : public CompositableClient
|
||||
{
|
||||
public:
|
||||
typedef MaybeOneOf<ClientCanvasLayer*, AsyncCanvasRenderer*> Renderer;
|
||||
|
||||
/**
|
||||
* Creates, configures, and returns a new canvas client. If necessary, a
|
||||
* message will be sent to the compositor to create a corresponding image
|
||||
|
@ -40,6 +49,7 @@ public:
|
|||
CanvasClientSurface,
|
||||
CanvasClientGLContext,
|
||||
CanvasClientTypeShSurf,
|
||||
CanvasClientAsync, // webgl on workers
|
||||
};
|
||||
static already_AddRefed<CanvasClient> CreateCanvasClient(CanvasClientType aType,
|
||||
CompositableForwarder* aFwd,
|
||||
|
@ -57,6 +67,8 @@ public:
|
|||
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) = 0;
|
||||
|
||||
virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) {}
|
||||
|
||||
virtual void Updated() { }
|
||||
};
|
||||
|
||||
|
@ -111,6 +123,7 @@ private:
|
|||
RefPtr<SharedSurfaceTextureClient> mShSurfClient;
|
||||
RefPtr<TextureClient> mReadbackClient;
|
||||
RefPtr<TextureClient> mFront;
|
||||
RefPtr<TextureClient> mNewFront;
|
||||
|
||||
void ClearSurfaces();
|
||||
|
||||
|
@ -130,12 +143,54 @@ public:
|
|||
|
||||
virtual void Update(gfx::IntSize aSize,
|
||||
ClientCanvasLayer* aLayer) override;
|
||||
void UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer);
|
||||
|
||||
virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) override;
|
||||
|
||||
virtual void Updated() override;
|
||||
|
||||
virtual void OnDetach() override {
|
||||
ClearSurfaces();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for OMT<canvas> uploads using the image bridge protocol.
|
||||
* Actual CanvasClient is on the ImageBridgeChild thread, so we
|
||||
* only forward its AsyncID here
|
||||
*/
|
||||
class CanvasClientBridge final : public CanvasClient
|
||||
{
|
||||
public:
|
||||
CanvasClientBridge(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags)
|
||||
: CanvasClient(aLayerForwarder, aFlags)
|
||||
, mAsyncID(0)
|
||||
, mLayer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
TextureInfo GetTextureInfo() const override
|
||||
{
|
||||
return TextureInfo(CompositableType::IMAGE);
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) override
|
||||
{
|
||||
}
|
||||
|
||||
virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) override;
|
||||
|
||||
void SetLayer(ShadowableLayer* aLayer)
|
||||
{
|
||||
mLayer = aLayer;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint64_t mAsyncID;
|
||||
ShadowableLayer* mLayer;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "SharedSurfaceGL.h" // for SurfaceFactory_GLTexture, etc
|
||||
#include "ClientLayerManager.h" // for ClientLayerManager, etc
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/layers/AsyncCanvasRenderer.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
|
@ -19,24 +20,6 @@
|
|||
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
|
||||
#include "gfxPrefs.h" // for WebGLForceLayersReadback
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "SharedSurfaceANGLE.h" // for SurfaceFactory_ANGLEShareHandle
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "SharedSurfaceIO.h"
|
||||
#endif
|
||||
|
||||
#ifdef GL_PROVIDER_GLX
|
||||
#include "GLXLibrary.h"
|
||||
#include "SharedSurfaceGLX.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
|
||||
|
@ -82,46 +65,7 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
|||
mFlags |= TextureFlags::NON_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
UniquePtr<SurfaceFactory> factory;
|
||||
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
switch (forwarder->GetCompositorBackendType()) {
|
||||
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
|
||||
#if defined(XP_MACOSX)
|
||||
factory = SurfaceFactory_IOSurface::Create(mGLContext, caps, forwarder, mFlags);
|
||||
#elif defined(MOZ_WIDGET_GONK)
|
||||
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, forwarder, mFlags);
|
||||
#elif defined(GL_PROVIDER_GLX)
|
||||
if (sGLXLibrary.UseSurfaceSharing())
|
||||
factory = SurfaceFactory_GLXDrawable::Create(mGLContext, caps, forwarder, mFlags);
|
||||
#else
|
||||
if (mGLContext->GetContextType() == GLContextType::EGL) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps, forwarder,
|
||||
mFlags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
|
||||
#ifdef XP_WIN
|
||||
// Enable surface sharing only if ANGLE and compositing devices
|
||||
// are both WARP or both not WARP
|
||||
if (mGLContext->IsANGLE() &&
|
||||
(mGLContext->IsWARP() == gfxWindowsPlatform::GetPlatform()->IsWARP()) &&
|
||||
gfxWindowsPlatform::GetPlatform()->CompositorD3D11TextureSharingWorks())
|
||||
{
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps, forwarder,
|
||||
mFlags);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
UniquePtr<SurfaceFactory> factory = GLScreenBuffer::CreateFactory(mGLContext, caps, forwarder, mFlags);
|
||||
|
||||
if (mGLFrontbuffer) {
|
||||
// We're using a source other than the one in the default screen.
|
||||
|
@ -145,11 +89,6 @@ ClientCanvasLayer::RenderLayer()
|
|||
|
||||
RenderMaskLayers(this);
|
||||
|
||||
if (!IsDirty()) {
|
||||
return;
|
||||
}
|
||||
Painted();
|
||||
|
||||
if (!mCanvasClient) {
|
||||
TextureFlags flags = TextureFlags::IMMEDIATE_UPLOAD;
|
||||
if (mOriginPos == gl::OriginPos::BottomLeft) {
|
||||
|
@ -172,11 +111,24 @@ ClientCanvasLayer::RenderLayer()
|
|||
return;
|
||||
}
|
||||
if (HasShadow()) {
|
||||
mCanvasClient->Connect();
|
||||
ClientManager()->AsShadowForwarder()->Attach(mCanvasClient, this);
|
||||
if (mAsyncRenderer) {
|
||||
static_cast<CanvasClientBridge*>(mCanvasClient.get())->SetLayer(this);
|
||||
} else {
|
||||
mCanvasClient->Connect();
|
||||
ClientManager()->AsShadowForwarder()->Attach(mCanvasClient, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mCanvasClient && mAsyncRenderer) {
|
||||
mCanvasClient->UpdateAsync(mAsyncRenderer);
|
||||
}
|
||||
|
||||
if (!IsDirty()) {
|
||||
return;
|
||||
}
|
||||
Painted();
|
||||
|
||||
FirePreTransactionCallback();
|
||||
mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
|
||||
|
||||
|
@ -189,6 +141,10 @@ ClientCanvasLayer::RenderLayer()
|
|||
CanvasClient::CanvasClientType
|
||||
ClientCanvasLayer::GetCanvasClientType()
|
||||
{
|
||||
if (mAsyncRenderer) {
|
||||
return CanvasClient::CanvasClientAsync;
|
||||
}
|
||||
|
||||
if (mGLContext) {
|
||||
return CanvasClient::CanvasClientTypeShSurf;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,6 @@ protected:
|
|||
|
||||
TextureFlags mFlags;
|
||||
|
||||
friend class DeprecatedCanvasClient2D;
|
||||
friend class CanvasClient2D;
|
||||
friend class CanvasClientSharedSurface;
|
||||
};
|
||||
|
|
|
@ -169,6 +169,7 @@ TextureChild::ActorDestroy(ActorDestroyReason why)
|
|||
{
|
||||
if (mTextureClient) {
|
||||
mTextureClient->mActor = nullptr;
|
||||
mTextureClient->mAllocator = nullptr;
|
||||
}
|
||||
mWaitForRecycle = nullptr;
|
||||
mKeep = nullptr;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
|
||||
#include "mozilla/ipc/Transport.h" // for Transport
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/layers/AsyncCanvasRenderer.h"
|
||||
#include "mozilla/media/MediaSystemResourceManager.h" // for MediaSystemResourceManager
|
||||
#include "mozilla/media/MediaSystemResourceManagerChild.h" // for MediaSystemResourceManagerChild
|
||||
#include "mozilla/layers/CompositableClient.h" // for CompositableChild, etc
|
||||
|
@ -236,6 +237,19 @@ static void CreateImageClientSync(RefPtr<ImageClient>* result,
|
|||
barrier->NotifyAll();
|
||||
}
|
||||
|
||||
// dispatched function
|
||||
static void CreateCanvasClientSync(ReentrantMonitor* aBarrier,
|
||||
CanvasClient::CanvasClientType aType,
|
||||
TextureFlags aFlags,
|
||||
RefPtr<CanvasClient>* const outResult,
|
||||
bool* aDone)
|
||||
{
|
||||
ReentrantMonitorAutoEnter autoMon(*aBarrier);
|
||||
*outResult = sImageBridgeChildSingleton->CreateCanvasClientNow(aType, aFlags);
|
||||
*aDone = true;
|
||||
aBarrier->NotifyAll();
|
||||
}
|
||||
|
||||
static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * parent)
|
||||
{
|
||||
MessageLoop *parentMsgLoop = parent->GetMessageLoop();
|
||||
|
@ -274,9 +288,14 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable,
|
|||
MOZ_ASSERT(aCompositable);
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
uint64_t id = 0;
|
||||
|
||||
PImageContainerChild* imageContainerChild = nullptr;
|
||||
if (aImageContainer)
|
||||
imageContainerChild = aImageContainer->GetPImageContainerChild();
|
||||
|
||||
PCompositableChild* child =
|
||||
SendPCompositableConstructor(aCompositable->GetTextureInfo(),
|
||||
aImageContainer->GetPImageContainerChild(), &id);
|
||||
imageContainerChild, &id);
|
||||
MOZ_ASSERT(child);
|
||||
aCompositable->InitIPDLActor(child, id);
|
||||
}
|
||||
|
@ -379,6 +398,35 @@ void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient,
|
|||
NewRunnableFunction(&ReleaseImageClientNow, aClient, aChild));
|
||||
}
|
||||
|
||||
static void ReleaseCanvasClientNow(CanvasClient* aClient)
|
||||
{
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
aClient->Release();
|
||||
}
|
||||
|
||||
// static
|
||||
void ImageBridgeChild::DispatchReleaseCanvasClient(CanvasClient* aClient)
|
||||
{
|
||||
if (!aClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsCreated()) {
|
||||
// CompositableClient::Release should normally happen in the ImageBridgeChild
|
||||
// thread because it usually generate some IPDL messages.
|
||||
// However, if we take this branch it means that the ImageBridgeChild
|
||||
// has already shut down, along with the CompositableChild, which means no
|
||||
// message will be sent and it is safe to run this code from any thread.
|
||||
MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
|
||||
aClient->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&ReleaseCanvasClientNow, aClient));
|
||||
}
|
||||
|
||||
static void ReleaseTextureClientNow(TextureClient* aClient)
|
||||
{
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
|
@ -422,7 +470,7 @@ static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContaine
|
|||
sImageBridgeChildSingleton->EndTransaction();
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
|
||||
ImageContainer* aContainer)
|
||||
{
|
||||
|
@ -447,6 +495,51 @@ void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
|
|||
nsRefPtr<ImageContainer> >(&UpdateImageClientNow, aClient, aContainer));
|
||||
}
|
||||
|
||||
static void UpdateAsyncCanvasRendererSync(AsyncCanvasRenderer* aWrapper,
|
||||
ReentrantMonitor* aBarrier,
|
||||
bool* const outDone)
|
||||
{
|
||||
ImageBridgeChild::UpdateAsyncCanvasRendererNow(aWrapper);
|
||||
|
||||
ReentrantMonitorAutoEnter autoMon(*aBarrier);
|
||||
*outDone = true;
|
||||
aBarrier->NotifyAll();
|
||||
}
|
||||
|
||||
// static
|
||||
void ImageBridgeChild::UpdateAsyncCanvasRenderer(AsyncCanvasRenderer* aWrapper)
|
||||
{
|
||||
aWrapper->GetCanvasClient()->UpdateAsync(aWrapper);
|
||||
|
||||
if (InImageBridgeChildThread()) {
|
||||
UpdateAsyncCanvasRendererNow(aWrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
ReentrantMonitor barrier("UpdateAsyncCanvasRenderer Lock");
|
||||
ReentrantMonitorAutoEnter autoMon(barrier);
|
||||
bool done = false;
|
||||
|
||||
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&UpdateAsyncCanvasRendererSync, aWrapper, &barrier, &done));
|
||||
|
||||
// should stop the thread until the CanvasClient has been created on
|
||||
// the other thread
|
||||
while (!done) {
|
||||
barrier.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void ImageBridgeChild::UpdateAsyncCanvasRendererNow(AsyncCanvasRenderer* aWrapper)
|
||||
{
|
||||
MOZ_ASSERT(aWrapper);
|
||||
sImageBridgeChildSingleton->BeginTransaction();
|
||||
aWrapper->GetCanvasClient()->Updated();
|
||||
sImageBridgeChildSingleton->EndTransaction();
|
||||
}
|
||||
|
||||
static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer,
|
||||
AsyncTransactionWaiter* aWaiter)
|
||||
{
|
||||
|
@ -475,7 +568,7 @@ static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer,
|
|||
aWaiter->DecrementWaitCount();
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
void ImageBridgeChild::FlushAllImages(ImageClient* aClient,
|
||||
ImageContainer* aContainer)
|
||||
{
|
||||
|
@ -731,6 +824,42 @@ ImageBridgeChild::CreateImageClientNow(CompositableType aType,
|
|||
return client.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasClient>
|
||||
ImageBridgeChild::CreateCanvasClient(CanvasClient::CanvasClientType aType,
|
||||
TextureFlags aFlag)
|
||||
{
|
||||
if (InImageBridgeChildThread()) {
|
||||
return CreateCanvasClientNow(aType, aFlag);
|
||||
}
|
||||
ReentrantMonitor barrier("CreateCanvasClient Lock");
|
||||
ReentrantMonitorAutoEnter autoMon(barrier);
|
||||
bool done = false;
|
||||
|
||||
RefPtr<CanvasClient> result = nullptr;
|
||||
GetMessageLoop()->PostTask(FROM_HERE,
|
||||
NewRunnableFunction(&CreateCanvasClientSync,
|
||||
&barrier, aType, aFlag, &result, &done));
|
||||
// should stop the thread until the CanvasClient has been created on the
|
||||
// other thread
|
||||
while (!done) {
|
||||
barrier.Wait();
|
||||
}
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasClient>
|
||||
ImageBridgeChild::CreateCanvasClientNow(CanvasClient::CanvasClientType aType,
|
||||
TextureFlags aFlag)
|
||||
{
|
||||
RefPtr<CanvasClient> client
|
||||
= CanvasClient::CreateCanvasClient(aType, this, aFlag);
|
||||
MOZ_ASSERT(client, "failed to create CanvasClient");
|
||||
if (client) {
|
||||
client->Connect();
|
||||
}
|
||||
return client.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBridgeChild::AllocUnsafeShmem(size_t aSize,
|
||||
ipc::SharedMemory::SharedMemoryType aType,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "mozilla/RefPtr.h" // for already_AddRefed
|
||||
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTrackerHolder
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/PImageBridgeChild.h"
|
||||
|
@ -32,6 +33,7 @@ class Shmem;
|
|||
|
||||
namespace layers {
|
||||
|
||||
class AsyncCanvasRenderer;
|
||||
class AsyncTransactionTracker;
|
||||
class ImageClient;
|
||||
class ImageContainer;
|
||||
|
@ -210,12 +212,20 @@ public:
|
|||
ImageContainer* aImageContainer);
|
||||
already_AddRefed<ImageClient> CreateImageClientNow(CompositableType aType,
|
||||
ImageContainer* aImageContainer);
|
||||
already_AddRefed<CanvasClient> CreateCanvasClient(CanvasClient::CanvasClientType aType,
|
||||
TextureFlags aFlag);
|
||||
already_AddRefed<CanvasClient> CreateCanvasClientNow(CanvasClient::CanvasClientType aType,
|
||||
TextureFlags aFlag);
|
||||
|
||||
static void DispatchReleaseImageClient(ImageClient* aClient,
|
||||
PImageContainerChild* aChild = nullptr);
|
||||
static void DispatchReleaseCanvasClient(CanvasClient* aClient);
|
||||
static void DispatchReleaseTextureClient(TextureClient* aClient);
|
||||
static void DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer);
|
||||
|
||||
static void UpdateAsyncCanvasRenderer(AsyncCanvasRenderer* aClient);
|
||||
static void UpdateAsyncCanvasRendererNow(AsyncCanvasRenderer* aClient);
|
||||
|
||||
/**
|
||||
* Flush all Images sent to CompositableHost.
|
||||
*/
|
||||
|
|
|
@ -58,7 +58,7 @@ parent:
|
|||
sync Stop();
|
||||
|
||||
sync PCompositable(TextureInfo aInfo,
|
||||
PImageContainer aImageContainer) returns (uint64_t id);
|
||||
nullable PImageContainer aImageContainer) returns (uint64_t id);
|
||||
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags);
|
||||
async PMediaSystemResourceManager();
|
||||
async PImageContainer();
|
||||
|
|
|
@ -108,6 +108,7 @@ EXPORTS.mozilla.layers += [
|
|||
'apz/util/ChromeProcessController.h',
|
||||
'apz/util/DoubleTapToZoom.h',
|
||||
'apz/util/InputAPZContext.h',
|
||||
'AsyncCanvasRenderer.h',
|
||||
'AtomicRefCountedWithFinalize.h',
|
||||
'AxisPhysicsModel.h',
|
||||
'AxisPhysicsMSDModel.h',
|
||||
|
@ -253,6 +254,7 @@ UNIFIED_SOURCES += [
|
|||
'apz/util/ChromeProcessController.cpp',
|
||||
'apz/util/DoubleTapToZoom.cpp',
|
||||
'apz/util/InputAPZContext.cpp',
|
||||
'AsyncCanvasRenderer.cpp',
|
||||
'AxisPhysicsModel.cpp',
|
||||
'AxisPhysicsMSDModel.cpp',
|
||||
'basic/BasicCanvasLayer.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче