Bug 1317774 - Add gfx code needed to use WebRender in gecko. r=gfx
The overall architecture here is that we add a new layers type, LAYERS_WR, which can be used in place of client layers. The WebRenderLayerManager, in the EndTransaction call, paints content into images and ships them over the PWebRenderBridge to the compositor thread. The WebRenderBridgeParent code on the compositor side talks to WebRender via the API in webrender.h. MozReview-Commit-ID: JKLTLJWVXiN
This commit is contained in:
@@ -194,6 +194,10 @@ static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered_accel[] = {
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFAAllowOfflineRenderers,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
#ifdef MOZ_ENABLE_WEBRENDER
|
||||
NSOpenGLPFAOpenGLProfile,
|
||||
NSOpenGLProfileVersion3_2Core,
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
@@ -1133,7 +1133,12 @@ CreateForWidget(Display* aXDisplay, Window aXWindow, bool aForceAccelerated)
|
||||
RefPtr<GLContextGLX> gl = GLContextGLX::CreateGLContext(CreateContextFlags::NONE,
|
||||
caps, shareContext, false,
|
||||
aXDisplay, aXWindow, config,
|
||||
#ifdef MOZ_ENABLE_WEBRENDER
|
||||
//TODO: we might want to pass an additional bool to select GL core/compat
|
||||
false, nullptr, ContextProfile::OpenGLCore); //WR: required GL 3.2+
|
||||
#else
|
||||
false);
|
||||
#endif
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ class SpecificLayerAttributes;
|
||||
class Compositor;
|
||||
class FrameUniformityData;
|
||||
class PersistentBufferProvider;
|
||||
class WebRenderLayerManager;
|
||||
|
||||
namespace layerscope {
|
||||
class LayersPacket;
|
||||
@@ -200,6 +201,9 @@ public:
|
||||
virtual BasicLayerManager* AsBasicLayerManager()
|
||||
{ return nullptr; }
|
||||
|
||||
virtual WebRenderLayerManager* AsWebRenderLayerManager()
|
||||
{ return nullptr; }
|
||||
|
||||
/**
|
||||
* Returns true if this LayerManager is owned by an nsIWidget,
|
||||
* and is used for drawing into the widget.
|
||||
|
||||
@@ -45,6 +45,7 @@ enum class LayersBackend : int8_t {
|
||||
LAYERS_D3D9,
|
||||
LAYERS_D3D11,
|
||||
LAYERS_CLIENT,
|
||||
LAYERS_WR,
|
||||
LAYERS_LAST
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "mozilla/layers/PLayerTransactionChild.h"
|
||||
#include "mozilla/layers/TextureClient.h"// for TextureClient
|
||||
#include "mozilla/layers/TextureClientPool.h"// for TextureClientPool
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
@@ -1144,6 +1145,22 @@ CompositorBridgeChild::HandleFatalError(const char* aName, const char* aMsg) con
|
||||
dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
|
||||
}
|
||||
|
||||
PWebRenderBridgeChild*
|
||||
CompositorBridgeChild::AllocPWebRenderBridgeChild(const uint64_t& aPipelineId)
|
||||
{
|
||||
WebRenderBridgeChild* child = new WebRenderBridgeChild(aPipelineId);
|
||||
child->AddRef();
|
||||
return child;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor)
|
||||
{
|
||||
WebRenderBridgeChild* child = static_cast<WebRenderBridgeChild*>(aActor);
|
||||
child->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -228,6 +228,9 @@ public:
|
||||
|
||||
void WillEndTransaction();
|
||||
|
||||
PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const uint64_t& aPipelineId) override;
|
||||
bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor) override;
|
||||
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
virtual ~CompositorBridgeChild();
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/layers/PLayerTransactionParent.h"
|
||||
#include "mozilla/layers/RemoteContentController.h"
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
@@ -1839,6 +1840,45 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
PWebRenderBridgeParent*
|
||||
CompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId)
|
||||
{
|
||||
#ifndef MOZ_ENABLE_WEBRENDER
|
||||
// Extra guard since this in the parent process and we don't want a malicious
|
||||
// child process invoking this codepath before it's ready
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
#endif
|
||||
MOZ_ASSERT(aPipelineId == mRootLayerTreeID);
|
||||
|
||||
RefPtr<gl::GLContext> glc(gl::GLContextProvider::CreateForCompositorWidget(mWidget, true));
|
||||
WebRenderBridgeParent* parent = new WebRenderBridgeParent(aPipelineId, mWidget, glc.get(), nullptr);
|
||||
parent->AddRef(); // IPDL reference
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
MOZ_ASSERT(sIndirectLayerTrees[aPipelineId].mWRBridge == nullptr);
|
||||
sIndirectLayerTrees[aPipelineId].mWRBridge = parent;
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor)
|
||||
{
|
||||
#ifndef MOZ_ENABLE_WEBRENDER
|
||||
// Extra guard since this in the parent process and we don't want a malicious
|
||||
// child process invoking this codepath before it's ready
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
#endif
|
||||
WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
|
||||
{
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
auto it = sIndirectLayerTrees.find(parent->PipelineId());
|
||||
if (it != sIndirectLayerTrees.end()) {
|
||||
it->second.mWRBridge = nullptr;
|
||||
}
|
||||
}
|
||||
parent->Release(); // IPDL reference
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
EraseLayerState(uint64_t aId)
|
||||
{
|
||||
|
||||
@@ -69,6 +69,7 @@ class PAPZParent;
|
||||
class CrossProcessCompositorBridgeParent;
|
||||
class CompositorThreadHolder;
|
||||
class InProcessCompositorSession;
|
||||
class WebRenderBridgeParent;
|
||||
|
||||
struct ScopedLayerTreeRegistration
|
||||
{
|
||||
@@ -444,6 +445,7 @@ public:
|
||||
APZCTreeManagerParent* mApzcTreeManagerParent;
|
||||
CompositorBridgeParent* mParent;
|
||||
LayerManagerComposite* mLayerManager;
|
||||
RefPtr<WebRenderBridgeParent> mWRBridge;
|
||||
// Pointer to the CrossProcessCompositorBridgeParent. Used by APZCs to share
|
||||
// their FrameMetrics with the corresponding child process that holds
|
||||
// the PCompositorBridgeChild
|
||||
@@ -537,6 +539,9 @@ public:
|
||||
return !!mApzcTreeManager;
|
||||
}
|
||||
|
||||
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const uint64_t& aPipelineId) override;
|
||||
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
|
||||
|
||||
private:
|
||||
|
||||
void Initialize();
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/layers/PLayerTransactionParent.h"
|
||||
#include "mozilla/layers/RemoteContentController.h"
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
@@ -246,6 +247,54 @@ CrossProcessCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
PWebRenderBridgeParent*
|
||||
CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId)
|
||||
{
|
||||
#ifndef MOZ_ENABLE_WEBRENDER
|
||||
// Extra guard since this in the parent process and we don't want a malicious
|
||||
// child process invoking this codepath before it's ready
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
#endif
|
||||
// Check to see if this child process has access to this layer tree.
|
||||
if (!LayerTreeOwnerTracker::Get()->IsMapped(aPipelineId, OtherPid())) {
|
||||
NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message...");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
MOZ_ASSERT(sIndirectLayerTrees.find(aPipelineId) != sIndirectLayerTrees.end());
|
||||
MOZ_ASSERT(sIndirectLayerTrees[aPipelineId].mWRBridge == nullptr);
|
||||
CompositorBridgeParent* cbp = sIndirectLayerTrees[aPipelineId].mParent;
|
||||
WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWRBridge.get();
|
||||
|
||||
WebRenderBridgeParent* parent = new WebRenderBridgeParent(
|
||||
aPipelineId, nullptr, root->GLContext(), root->WindowState());
|
||||
parent->AddRef(); // IPDL reference
|
||||
sIndirectLayerTrees[aPipelineId].mWRBridge = parent;
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool
|
||||
CrossProcessCompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor)
|
||||
{
|
||||
#ifndef MOZ_ENABLE_WEBRENDER
|
||||
// Extra guard since this in the parent process and we don't want a malicious
|
||||
// child process invoking this codepath before it's ready
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
#endif
|
||||
WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
|
||||
{
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
auto it = sIndirectLayerTrees.find(parent->PipelineId());
|
||||
if (it != sIndirectLayerTrees.end()) {
|
||||
it->second.mWRBridge = nullptr;
|
||||
}
|
||||
}
|
||||
parent->Release(); // IPDL reference
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
CrossProcessCompositorBridgeParent::RecvNotifyChildCreated(const uint64_t& child)
|
||||
{
|
||||
|
||||
@@ -153,6 +153,9 @@ public:
|
||||
|
||||
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) override;
|
||||
|
||||
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const uint64_t& aPipelineId) override;
|
||||
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
|
||||
|
||||
protected:
|
||||
void OnChannelConnected(int32_t pid) override {
|
||||
mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
|
||||
|
||||
@@ -17,6 +17,7 @@ include protocol PImageContainer;
|
||||
include protocol PLayer;
|
||||
include protocol PLayerTransaction;
|
||||
include protocol PTexture;
|
||||
include protocol PWebRenderBridge;
|
||||
include "mozilla/GfxMessageUtils.h";
|
||||
|
||||
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
|
||||
@@ -53,6 +54,7 @@ sync protocol PCompositorBridge
|
||||
manages PLayerTransaction;
|
||||
manages PTexture;
|
||||
manages PCompositorWidget;
|
||||
manages PWebRenderBridge;
|
||||
|
||||
child:
|
||||
// The child should invalidate retained layers. This is used for local
|
||||
@@ -228,6 +230,9 @@ parent:
|
||||
|
||||
sync SyncWithCompositor();
|
||||
|
||||
// The pipelineId is the same as the layersId
|
||||
async PWebRenderBridge(uint64_t pipelineId);
|
||||
|
||||
child:
|
||||
// Send back Compositor Frame Metrics from APZCs so tiled layers can
|
||||
// update progressively.
|
||||
|
||||
49
gfx/layers/ipc/PWebRenderBridge.ipdl
Normal file
49
gfx/layers/ipc/PWebRenderBridge.ipdl
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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 "mozilla/GfxMessageUtils.h";
|
||||
|
||||
include protocol PCompositorBridge;
|
||||
|
||||
using WRImageFormat from "webrender.h";
|
||||
using WRImageKey from "webrender.h";
|
||||
using WRRect from "webrender.h";
|
||||
using MaybeImageMask from "mozilla/layers/WebRenderTypes.h";
|
||||
using mozilla::gfx::ByteBuffer from "mozilla/layers/WebRenderTypes.h";
|
||||
using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
sync protocol PWebRenderBridge
|
||||
{
|
||||
manager PCompositorBridge;
|
||||
|
||||
parent:
|
||||
sync Create(uint32_t aWidth, uint32_t aHeight);
|
||||
sync Destroy();
|
||||
sync AddImage(uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
|
||||
WRImageFormat aFormat, ByteBuffer aBytes)
|
||||
returns (WRImageKey aOutImageKey);
|
||||
sync UpdateImage(WRImageKey aImageKey, uint32_t aWidth, uint32_t aHeight,
|
||||
WRImageFormat aFormat, ByteBuffer aBytes);
|
||||
sync DeleteImage(WRImageKey aImageKey);
|
||||
sync PushDLBuilder();
|
||||
sync PopDLBuilder(WRRect aBounds, WRRect aOverflow, Matrix4x4 aMatrix,
|
||||
uint64_t aScrollId);
|
||||
sync DPBegin(uint32_t aWidth, uint32_t aHeight)
|
||||
returns (bool aOutSuccess);
|
||||
sync DPEnd();
|
||||
sync DPPushRect(WRRect aBounds, WRRect aClip, float r, float g, float b, float a);
|
||||
sync DPPushImage(WRRect aBounds, WRRect aClip, MaybeImageMask aMask, WRImageKey aKey);
|
||||
sync DPPushIframe(WRRect aBounds, WRRect aClip, uint64_t aLayersId);
|
||||
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // layers
|
||||
} // mozilla
|
||||
@@ -202,6 +202,10 @@ EXPORTS.mozilla.layers += [
|
||||
'RenderTrace.h',
|
||||
'TextureWrapperImage.h',
|
||||
'TransactionIdAllocator.h',
|
||||
'wr/WebRenderBridgeChild.h',
|
||||
'wr/WebRenderBridgeParent.h',
|
||||
'wr/WebRenderLayerManager.h',
|
||||
'wr/WebRenderTypes.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_X11']:
|
||||
@@ -372,6 +376,14 @@ UNIFIED_SOURCES += [
|
||||
'RenderTrace.cpp',
|
||||
'RotatedBuffer.cpp',
|
||||
'TextureWrapperImage.cpp',
|
||||
'wr/WebRenderBridgeChild.cpp',
|
||||
'wr/WebRenderBridgeParent.cpp',
|
||||
'wr/WebRenderCanvasLayer.cpp',
|
||||
'wr/WebRenderColorLayer.cpp',
|
||||
'wr/WebRenderContainerLayer.cpp',
|
||||
'wr/WebRenderImageLayer.cpp',
|
||||
'wr/WebRenderLayerManager.cpp',
|
||||
'wr/WebRenderPaintedLayer.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
@@ -413,6 +425,7 @@ IPDL_SOURCES = [
|
||||
'ipc/PLayerTransaction.ipdl',
|
||||
'ipc/PTexture.ipdl',
|
||||
'ipc/PVideoBridge.ipdl',
|
||||
'ipc/PWebRenderBridge.ipdl',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
19
gfx/layers/wr/WebRenderBridgeChild.cpp
Normal file
19
gfx/layers/wr/WebRenderBridgeChild.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* 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 "mozilla/layers/WebRenderBridgeChild.h"
|
||||
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
WebRenderBridgeChild::WebRenderBridgeChild(const uint64_t& aPipelineId)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
35
gfx/layers/wr/WebRenderBridgeChild.h
Normal file
35
gfx/layers/wr/WebRenderBridgeChild.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* 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_WebRenderBridgeChild_h
|
||||
#define mozilla_layers_WebRenderBridgeChild_h
|
||||
|
||||
#include "mozilla/layers/PWebRenderBridgeChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace widget {
|
||||
class CompositorWidget;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class WebRenderBridgeParent;
|
||||
|
||||
class WebRenderBridgeChild final : public PWebRenderBridgeChild
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeChild)
|
||||
|
||||
public:
|
||||
explicit WebRenderBridgeChild(const uint64_t& aPipelineId);
|
||||
protected:
|
||||
~WebRenderBridgeChild() {}
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_WebRenderBridgeChild_h
|
||||
199
gfx/layers/wr/WebRenderBridgeParent.cpp
Normal file
199
gfx/layers/wr/WebRenderBridgeParent.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* 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 "mozilla/layers/WebRenderBridgeParent.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
WebRenderBridgeParent::WebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
widget::CompositorWidget* aWidget,
|
||||
gl::GLContext* aGlContext,
|
||||
wrwindowstate* aWrWindowState)
|
||||
: mPipelineId(aPipelineId)
|
||||
, mWidget(aWidget)
|
||||
, mWRState(nullptr)
|
||||
, mGLContext(aGlContext)
|
||||
, mWRWindowState(aWrWindowState)
|
||||
{
|
||||
MOZ_ASSERT(mGLContext);
|
||||
if (!mWRWindowState) {
|
||||
// mWRWindowState should only be null for the root WRBP of a layers tree,
|
||||
// i.e. the one created by the CompositorBridgeParent as opposed to the
|
||||
// CrossProcessCompositorBridgeParent
|
||||
MOZ_ASSERT(mWidget);
|
||||
mWRWindowState = wr_init_window(mPipelineId);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvCreate(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight)
|
||||
{
|
||||
if (mWRState) {
|
||||
return IPC_OK();
|
||||
}
|
||||
MOZ_ASSERT(mWRWindowState);
|
||||
mGLContext->MakeCurrent();
|
||||
mWRState = wr_create(mWRWindowState, aWidth, aHeight, mPipelineId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDestroy()
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
wr_destroy(mWRState);
|
||||
mWRState = nullptr;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvAddImage(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
const uint32_t& aStride,
|
||||
const WRImageFormat& aFormat,
|
||||
const ByteBuffer& aBuffer,
|
||||
WRImageKey* aOutImageKey)
|
||||
{
|
||||
MOZ_ASSERT(mWRWindowState);
|
||||
*aOutImageKey = wr_add_image(mWRWindowState, aWidth, aHeight, aStride, aFormat,
|
||||
aBuffer.mData, aBuffer.mLength);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvUpdateImage(const WRImageKey& aImageKey,
|
||||
const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
const WRImageFormat& aFormat,
|
||||
const ByteBuffer& aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(mWRWindowState);
|
||||
wr_update_image(mWRWindowState, aImageKey, aWidth, aHeight, aFormat,
|
||||
aBuffer.mData, aBuffer.mLength);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDeleteImage(const WRImageKey& aImageKey)
|
||||
{
|
||||
MOZ_ASSERT(mWRWindowState);
|
||||
mKeysToDelete.push_back(aImageKey);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvPushDLBuilder()
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
wr_push_dl_builder(mWRState);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvPopDLBuilder(const WRRect& aBounds,
|
||||
const WRRect& aOverflow,
|
||||
const gfx::Matrix4x4& aMatrix,
|
||||
const uint64_t& aScrollId)
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
wr_pop_dl_builder(mWRWindowState, mWRState, aBounds, aOverflow, &aMatrix.components[0], aScrollId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPBegin(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
bool* aOutSuccess)
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
if (mWidget) {
|
||||
mozilla::widget::WidgetRenderingContext widgetContext;
|
||||
#if defined(XP_MACOSX)
|
||||
widgetContext.mGL = mGLContext;
|
||||
#endif
|
||||
if (!mWidget->PreRender(&widgetContext)) {
|
||||
*aOutSuccess = false;
|
||||
return IPC_OK();
|
||||
}
|
||||
}
|
||||
mGLContext->MakeCurrent();
|
||||
wr_dp_begin(mWRWindowState, mWRState, aWidth, aHeight);
|
||||
*aOutSuccess = true;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPEnd()
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
mGLContext->MakeCurrent();
|
||||
wr_dp_end(mWRWindowState, mWRState);
|
||||
mGLContext->SwapBuffers();
|
||||
if (mWidget) {
|
||||
mozilla::widget::WidgetRenderingContext widgetContext;
|
||||
#if defined(XP_MACOSX)
|
||||
widgetContext.mGL = mGLContext;
|
||||
#endif
|
||||
mWidget->PostRender(&widgetContext);
|
||||
}
|
||||
|
||||
DeleteOldImages();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPPushRect(const WRRect& aBounds,
|
||||
const WRRect& aClip,
|
||||
const float& r, const float& g,
|
||||
const float& b, const float& a)
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
wr_dp_push_rect(mWRState, aBounds, aClip, r, g, b, a);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPPushImage(const WRRect& aBounds,
|
||||
const WRRect& aClip,
|
||||
const Maybe<WRImageMask>& aMask,
|
||||
const WRImageKey& aKey)
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
wr_dp_push_image(mWRState, aBounds, aClip, aMask.ptrOr(nullptr), aKey);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPPushIframe(const WRRect& aBounds,
|
||||
const WRRect& aClip,
|
||||
const uint64_t& aLayersId)
|
||||
{
|
||||
MOZ_ASSERT(mWRState);
|
||||
wr_dp_push_iframe(mWRState, aBounds, aClip, aLayersId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
WebRenderBridgeParent::~WebRenderBridgeParent()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::DeleteOldImages()
|
||||
{
|
||||
for (WRImageKey key : mKeysToDelete) {
|
||||
wr_delete_image(mWRWindowState, key);
|
||||
}
|
||||
mKeysToDelete.clear();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
95
gfx/layers/wr/WebRenderBridgeParent.h
Normal file
95
gfx/layers/wr/WebRenderBridgeParent.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* 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_WebRenderBridgeParent_h
|
||||
#define mozilla_layers_WebRenderBridgeParent_h
|
||||
|
||||
#include "GLContextProvider.h"
|
||||
#include "mozilla/layers/PWebRenderBridgeParent.h"
|
||||
#include "mozilla/layers/WebRenderTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
}
|
||||
|
||||
namespace widget {
|
||||
class CompositorWidget;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class WebRenderBridgeParent final : public PWebRenderBridgeParent
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeParent)
|
||||
|
||||
public:
|
||||
WebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
widget::CompositorWidget* aWidget,
|
||||
gl::GLContext* aGlContext,
|
||||
wrwindowstate* aWrWindowState);
|
||||
uint64_t PipelineId() { return mPipelineId; }
|
||||
gl::GLContext* GLContext() { return mGLContext.get(); }
|
||||
wrwindowstate* WindowState() { return mWRWindowState; }
|
||||
|
||||
mozilla::ipc::IPCResult RecvCreate(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight) override;
|
||||
mozilla::ipc::IPCResult RecvDestroy() override;
|
||||
mozilla::ipc::IPCResult RecvAddImage(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
const uint32_t& aStride,
|
||||
const WRImageFormat& aFormat,
|
||||
const ByteBuffer& aBuffer,
|
||||
WRImageKey* aOutImageKey) override;
|
||||
mozilla::ipc::IPCResult RecvUpdateImage(const WRImageKey& aImageKey,
|
||||
const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
const WRImageFormat& aFormat,
|
||||
const ByteBuffer& aBuffer) override;
|
||||
mozilla::ipc::IPCResult RecvDeleteImage(const WRImageKey& aImageKey) override;
|
||||
mozilla::ipc::IPCResult RecvPushDLBuilder() override;
|
||||
mozilla::ipc::IPCResult RecvPopDLBuilder(const WRRect& aBounds,
|
||||
const WRRect& aOverflow,
|
||||
const gfx::Matrix4x4& aMatrix,
|
||||
const uint64_t& aScrollId) override;
|
||||
mozilla::ipc::IPCResult RecvDPBegin(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
bool* aOutSuccess) override;
|
||||
mozilla::ipc::IPCResult RecvDPEnd() override;
|
||||
mozilla::ipc::IPCResult RecvDPPushRect(const WRRect& aBounds,
|
||||
const WRRect& aClip,
|
||||
const float& r,
|
||||
const float& g,
|
||||
const float& b,
|
||||
const float& a) override;
|
||||
mozilla::ipc::IPCResult RecvDPPushImage(const WRRect& aBounds,
|
||||
const WRRect& aClip,
|
||||
const Maybe<WRImageMask>& aMask,
|
||||
const WRImageKey& aKey) override;
|
||||
mozilla::ipc::IPCResult RecvDPPushIframe(const WRRect& aBounds,
|
||||
const WRRect& aClip,
|
||||
const uint64_t& aLayersId) override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override {}
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderBridgeParent();
|
||||
void DeleteOldImages();
|
||||
|
||||
private:
|
||||
uint64_t mPipelineId;
|
||||
RefPtr<widget::CompositorWidget> mWidget;
|
||||
wrstate* mWRState;
|
||||
RefPtr<gl::GLContext> mGLContext;
|
||||
wrwindowstate* mWRWindowState;
|
||||
std::vector<WRImageKey> mKeysToDelete;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_WebRenderBridgeParent_h
|
||||
123
gfx/layers/wr/WebRenderCanvasLayer.cpp
Normal file
123
gfx/layers/wr/WebRenderCanvasLayer.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "WebRenderCanvasLayer.h"
|
||||
|
||||
#include "AsyncCanvasRenderer.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "PersistentBufferProvider.h"
|
||||
#include "SharedSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
WebRenderCanvasLayer::~WebRenderCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderCanvasLayer);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCanvasLayer::RenderLayer()
|
||||
{
|
||||
FirePreTransactionCallback();
|
||||
RefPtr<gfx::SourceSurface> surface;
|
||||
// Get the canvas buffer
|
||||
AutoReturnSnapshot autoReturn;
|
||||
if (mAsyncRenderer) {
|
||||
MOZ_ASSERT(!mBufferProvider);
|
||||
MOZ_ASSERT(!mGLContext);
|
||||
surface = mAsyncRenderer->GetSurface();
|
||||
} else if (mGLContext) {
|
||||
gl::SharedSurface* frontbuffer = nullptr;
|
||||
if (mGLFrontbuffer) {
|
||||
frontbuffer = mGLFrontbuffer.get();
|
||||
} else {
|
||||
gl::GLScreenBuffer* screen = mGLContext->Screen();
|
||||
const auto& front = screen->Front();
|
||||
if (front) {
|
||||
frontbuffer = front->Surf();
|
||||
}
|
||||
}
|
||||
|
||||
if (!frontbuffer) {
|
||||
NS_WARNING("Null frame received.");
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::IntSize readSize(frontbuffer->mSize);
|
||||
gfx::SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||
? gfx::SurfaceFormat::B8G8R8X8
|
||||
: gfx::SurfaceFormat::B8G8R8A8;
|
||||
bool needsPremult = frontbuffer->mHasAlpha && !mIsAlphaPremultiplied;
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> resultSurf = GetTempSurface(readSize, format);
|
||||
// There will already be a warning from inside of GetTempSurface, but
|
||||
// it doesn't hurt to complain:
|
||||
if (NS_WARN_IF(!resultSurf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Readback handles Flush/MarkDirty.
|
||||
mGLContext->Readback(frontbuffer, resultSurf);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(resultSurf, resultSurf);
|
||||
}
|
||||
surface = resultSurf;
|
||||
} else if (mBufferProvider) {
|
||||
surface = mBufferProvider->BorrowSnapshot();
|
||||
autoReturn.mSnapshot = &surface;
|
||||
autoReturn.mBufferProvider = mBufferProvider;
|
||||
}
|
||||
FireDidTransactionCallback();
|
||||
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
WRScrollFrameStackingContextGenerator scrollFrames(this);
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
gfx::DataSourceSurface::ScopedMap map(dataSurface, gfx::DataSourceSurface::MapType::READ);
|
||||
//XXX
|
||||
MOZ_RELEASE_ASSERT(surface->GetFormat() == gfx::SurfaceFormat::B8G8R8X8 ||
|
||||
surface->GetFormat() == gfx::SurfaceFormat::B8G8R8A8, "bad format");
|
||||
|
||||
gfx::IntSize size = surface->GetSize();
|
||||
|
||||
WRImageKey key;
|
||||
gfx::ByteBuffer buf(size.height * map.GetStride(), map.GetData());
|
||||
WRBridge()->SendAddImage(size.width, size.height, map.GetStride(), RGBA8, buf, &key);
|
||||
|
||||
gfx::Matrix4x4 transform;// = GetTransform();
|
||||
const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
|
||||
if (needsYFlip) {
|
||||
transform.PreTranslate(0, size.height, 0).PreScale(1, -1, 1);
|
||||
}
|
||||
gfx::Rect rect(0, 0, size.width, size.height);
|
||||
|
||||
gfx::Rect clip;
|
||||
if (GetClipRect().isSome()) {
|
||||
clip = RelativeToTransformedVisible(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
|
||||
} else {
|
||||
clip = rect;
|
||||
}
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("CanvasLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
|
||||
WRBridge()->SendPushDLBuilder();
|
||||
WRBridge()->SendDPPushImage(toWrRect(rect), toWrRect(clip), Nothing(), key);
|
||||
Manager()->AddImageKeyForDiscard(key);
|
||||
|
||||
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("CanvasLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
|
||||
WRBridge()->SendPopDLBuilder(toWrRect(relBounds), toWrRect(relBounds), transform, FrameMetrics::NULL_SCROLL_ID);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
44
gfx/layers/wr/WebRenderCanvasLayer.h
Normal file
44
gfx/layers/wr/WebRenderCanvasLayer.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 GFX_WEBRENDERCANVASLAYER_H
|
||||
#define GFX_WEBRENDERCANVASLAYER_H
|
||||
|
||||
#include "CopyableCanvasLayer.h"
|
||||
#include "WebRenderLayerManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
}; // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
|
||||
class WebRenderCanvasLayer : public WebRenderLayer,
|
||||
public CopyableCanvasLayer
|
||||
{
|
||||
public:
|
||||
explicit WebRenderCanvasLayer(WebRenderLayerManager* aLayerManager)
|
||||
: CopyableCanvasLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderCanvasLayer);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderCanvasLayer();
|
||||
WebRenderLayerManager* Manager()
|
||||
{
|
||||
return static_cast<WebRenderLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_WEBRENDERCANVASLAYER_H
|
||||
33
gfx/layers/wr/WebRenderColorLayer.cpp
Normal file
33
gfx/layers/wr/WebRenderColorLayer.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "WebRenderColorLayer.h"
|
||||
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "webrender.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
void
|
||||
WebRenderColorLayer::RenderLayer()
|
||||
{
|
||||
WRScrollFrameStackingContextGenerator scrollFrames(this);
|
||||
|
||||
gfx::Rect rect = RelativeToParent(GetTransform().TransformBounds(IntRectToRect(mBounds)));
|
||||
gfx::Rect clip;
|
||||
if (GetClipRect().isSome()) {
|
||||
clip = RelativeToParent(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
|
||||
} else {
|
||||
clip = rect;
|
||||
}
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("ColorLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
|
||||
WRBridge()->SendDPPushRect(toWrRect(rect), toWrRect(clip),
|
||||
mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
38
gfx/layers/wr/WebRenderColorLayer.h
Normal file
38
gfx/layers/wr/WebRenderColorLayer.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 GFX_WEBRENDERCOLORLAYER_H
|
||||
#define GFX_WEBRENDERCOLORLAYER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "WebRenderLayerManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class WebRenderColorLayer : public WebRenderLayer,
|
||||
public ColorLayer {
|
||||
public:
|
||||
explicit WebRenderColorLayer(WebRenderLayerManager* aLayerManager)
|
||||
: ColorLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderColorLayer);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderColorLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderColorLayer);
|
||||
}
|
||||
|
||||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_WEBRENDERCOLORLAYER_H
|
||||
46
gfx/layers/wr/WebRenderContainerLayer.cpp
Normal file
46
gfx/layers/wr/WebRenderContainerLayer.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "WebRenderContainerLayer.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "LayersLogging.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
void
|
||||
WebRenderContainerLayer::RenderLayer()
|
||||
{
|
||||
WRScrollFrameStackingContextGenerator scrollFrames(this);
|
||||
|
||||
AutoTArray<Layer*, 12> children;
|
||||
SortChildrenBy3DZOrder(children);
|
||||
|
||||
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
|
||||
gfx::Matrix4x4 transform;// = GetTransform();
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("ContainerLayer %p using %s as bounds/overflow, %s as transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
|
||||
|
||||
WRBridge()->SendPushDLBuilder();
|
||||
for (Layer* child : children) {
|
||||
ToWebRenderLayer(child)->RenderLayer();
|
||||
}
|
||||
WRBridge()->SendPopDLBuilder(toWrRect(relBounds), toWrRect(relBounds), transform, FrameMetrics::NULL_SCROLL_ID);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderRefLayer::RenderLayer()
|
||||
{
|
||||
WRScrollFrameStackingContextGenerator scrollFrames(this);
|
||||
|
||||
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
|
||||
gfx::Matrix4x4 transform;// = GetTransform();
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("RefLayer %p (%" PRIu64 ") using %s as bounds/overflow, %s as transform\n", this, mId, Stringify(relBounds).c_str(), Stringify(transform).c_str());
|
||||
WRBridge()->SendDPPushIframe(toWrRect(relBounds), toWrRect(relBounds), mId);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
69
gfx/layers/wr/WebRenderContainerLayer.h
Normal file
69
gfx/layers/wr/WebRenderContainerLayer.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 GFX_WEBRENDERCONTAINERLAYER_H
|
||||
#define GFX_WEBRENDERCONTAINERLAYER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "WebRenderLayerManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class WebRenderContainerLayer : public WebRenderLayer,
|
||||
public ContainerLayer
|
||||
{
|
||||
public:
|
||||
explicit WebRenderContainerLayer(WebRenderLayerManager* aManager)
|
||||
: ContainerLayer(aManager, static_cast<WebRenderLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderContainerLayer);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderContainerLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderContainerLayer);
|
||||
}
|
||||
|
||||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
|
||||
{
|
||||
DefaultComputeEffectiveTransforms(aTransformToSurface);
|
||||
}
|
||||
};
|
||||
|
||||
class WebRenderRefLayer : public WebRenderLayer,
|
||||
public RefLayer {
|
||||
public:
|
||||
explicit WebRenderRefLayer(WebRenderLayerManager* aManager) :
|
||||
RefLayer(aManager, static_cast<WebRenderLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderRefLayer);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderRefLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderRefLayer);
|
||||
}
|
||||
|
||||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
|
||||
{
|
||||
DefaultComputeEffectiveTransforms(aTransformToSurface);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_WEBRENDERCONTAINERLAYER_H
|
||||
74
gfx/layers/wr/WebRenderImageLayer.cpp
Normal file
74
gfx/layers/wr/WebRenderImageLayer.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "WebRenderImageLayer.h"
|
||||
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
already_AddRefed<gfx::SourceSurface>
|
||||
WebRenderImageLayer::GetAsSourceSurface()
|
||||
{
|
||||
AutoLockImage autoLock(mContainer);
|
||||
Image *image = autoLock.GetImage();
|
||||
if (!image) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
|
||||
if (!surface || !surface->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
return surface.forget();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderImageLayer::RenderLayer()
|
||||
{
|
||||
RefPtr<gfx::SourceSurface> surface = GetAsSourceSurface();
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
WRScrollFrameStackingContextGenerator scrollFrames(this);
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::MapType::READ);
|
||||
//XXX
|
||||
MOZ_RELEASE_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8X8 ||
|
||||
surface->GetFormat() == SurfaceFormat::B8G8R8A8, "bad format");
|
||||
|
||||
gfx::IntSize size = surface->GetSize();
|
||||
|
||||
WRImageKey key;
|
||||
gfx::ByteBuffer buf(size.height * map.GetStride(), map.GetData());
|
||||
WRBridge()->SendAddImage(size.width, size.height, map.GetStride(), RGBA8, buf, &key);
|
||||
|
||||
Rect rect(0, 0, size.width, size.height);
|
||||
|
||||
Rect clip;
|
||||
if (GetClipRect().isSome()) {
|
||||
clip = RelativeToTransformedVisible(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
|
||||
} else {
|
||||
clip = rect;
|
||||
}
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("ImageLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
|
||||
WRBridge()->SendPushDLBuilder();
|
||||
WRBridge()->SendDPPushImage(toWrRect(rect), toWrRect(clip), Nothing(), key);
|
||||
Manager()->AddImageKeyForDiscard(key);
|
||||
|
||||
Rect relBounds = TransformedVisibleBoundsRelativeToParent();
|
||||
Matrix4x4 transform;// = GetTransform();
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("ImageLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
|
||||
WRBridge()->SendPopDLBuilder(toWrRect(relBounds), toWrRect(relBounds), transform, FrameMetrics::NULL_SCROLL_ID);
|
||||
|
||||
//mContainer->SetImageFactory(originalIF);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
44
gfx/layers/wr/WebRenderImageLayer.h
Normal file
44
gfx/layers/wr/WebRenderImageLayer.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 GFX_WEBRENDERIMAGELAYER_H
|
||||
#define GFX_WEBRENDERIMAGELAYER_H
|
||||
|
||||
#include "ImageLayers.h"
|
||||
#include "WebRenderLayerManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class WebRenderImageLayer : public WebRenderLayer,
|
||||
public ImageLayer {
|
||||
public:
|
||||
explicit WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
|
||||
: ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderImageLayer);
|
||||
}
|
||||
|
||||
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
||||
protected:
|
||||
virtual ~WebRenderImageLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderImageLayer);
|
||||
}
|
||||
|
||||
WebRenderLayerManager* Manager()
|
||||
{
|
||||
return static_cast<WebRenderLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_WEBRENDERIMAGELAYER_H
|
||||
286
gfx/layers/wr/WebRenderLayerManager.cpp
Normal file
286
gfx/layers/wr/WebRenderLayerManager.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "WebRenderLayerManager.h"
|
||||
|
||||
#include "apz/src/AsyncPanZoomController.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/layers/APZCTreeManager.h"
|
||||
#include "mozilla/layers/AsyncCompositionManager.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "TreeTraversal.h"
|
||||
#include "WebRenderCanvasLayer.h"
|
||||
#include "WebRenderColorLayer.h"
|
||||
#include "WebRenderContainerLayer.h"
|
||||
#include "WebRenderImageLayer.h"
|
||||
#include "WebRenderPaintedLayer.h"
|
||||
#include "webrender.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
namespace layers {
|
||||
|
||||
WebRenderLayerManager*
|
||||
WebRenderLayer::WRManager()
|
||||
{
|
||||
return static_cast<WebRenderLayerManager*>(GetLayer()->Manager());
|
||||
}
|
||||
|
||||
WebRenderBridgeChild*
|
||||
WebRenderLayer::WRBridge()
|
||||
{
|
||||
return WRManager()->WRBridge();
|
||||
}
|
||||
|
||||
Rect
|
||||
WebRenderLayer::RelativeToVisible(Rect aRect)
|
||||
{
|
||||
IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
|
||||
aRect.MoveBy(-bounds.x, -bounds.y);
|
||||
return aRect;
|
||||
}
|
||||
|
||||
Rect
|
||||
WebRenderLayer::RelativeToTransformedVisible(Rect aRect)
|
||||
{
|
||||
IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
|
||||
Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
|
||||
aRect.MoveBy(-transformed.x, -transformed.y);
|
||||
return aRect;
|
||||
}
|
||||
|
||||
Rect
|
||||
WebRenderLayer::ParentStackingContextBounds(size_t aScrollMetadataIndex)
|
||||
{
|
||||
// Walk up to find the parent stacking context. This will be created either
|
||||
// by the nearest scrollable metrics, or by the parent layer which must be a
|
||||
// ContainerLayer.
|
||||
Layer* layer = GetLayer();
|
||||
for (size_t i = aScrollMetadataIndex + 1; i < layer->GetScrollMetadataCount(); i++) {
|
||||
if (layer->GetFrameMetrics(i).IsScrollable()) {
|
||||
return layer->GetFrameMetrics(i).GetCompositionBounds().ToUnknownRect();
|
||||
}
|
||||
}
|
||||
if (layer->GetParent()) {
|
||||
return IntRectToRect(layer->GetParent()->GetVisibleRegion().GetBounds().ToUnknownRect());
|
||||
}
|
||||
return Rect();
|
||||
}
|
||||
|
||||
Rect
|
||||
WebRenderLayer::RelativeToParent(Rect aRect)
|
||||
{
|
||||
Rect parentBounds = ParentStackingContextBounds(-1);
|
||||
aRect.MoveBy(-parentBounds.x, -parentBounds.y);
|
||||
return aRect;
|
||||
}
|
||||
|
||||
Rect
|
||||
WebRenderLayer::TransformedVisibleBoundsRelativeToParent()
|
||||
{
|
||||
IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
|
||||
Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
|
||||
return RelativeToParent(transformed);
|
||||
}
|
||||
|
||||
WRScrollFrameStackingContextGenerator::WRScrollFrameStackingContextGenerator(
|
||||
WebRenderLayer* aLayer)
|
||||
: mLayer(aLayer)
|
||||
{
|
||||
Layer* layer = mLayer->GetLayer();
|
||||
for (size_t i = layer->GetScrollMetadataCount(); i > 0; i--) {
|
||||
const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
|
||||
if (!fm.IsScrollable()) {
|
||||
continue;
|
||||
}
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("Pushing stacking context id %" PRIu64"\n", fm.GetScrollId());
|
||||
mLayer->WRBridge()->SendPushDLBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
WRScrollFrameStackingContextGenerator::~WRScrollFrameStackingContextGenerator()
|
||||
{
|
||||
Matrix4x4 identity;
|
||||
Layer* layer = mLayer->GetLayer();
|
||||
for (size_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
|
||||
const FrameMetrics& fm = layer->GetFrameMetrics(i);
|
||||
if (!fm.IsScrollable()) {
|
||||
continue;
|
||||
}
|
||||
Rect bounds = fm.GetCompositionBounds().ToUnknownRect();
|
||||
Rect overflow = (fm.GetExpandedScrollableRect() * fm.LayersPixelsPerCSSPixel()).ToUnknownRect();
|
||||
Point scrollPos = (fm.GetScrollOffset() * fm.LayersPixelsPerCSSPixel()).ToUnknownPoint();
|
||||
Rect parentBounds = mLayer->ParentStackingContextBounds(i);
|
||||
bounds.MoveBy(-parentBounds.x, -parentBounds.y);
|
||||
// Subtract the MT scroll position from the overflow here so that the WR
|
||||
// scroll offset (which is the APZ async scroll component) always fits in
|
||||
// the available overflow. If we didn't do this and WR did bounds checking
|
||||
// on the scroll offset, we'd fail those checks.
|
||||
overflow.MoveBy(bounds.x - scrollPos.x, bounds.y - scrollPos.y);
|
||||
if (gfxPrefs::LayersDump()) {
|
||||
printf_stderr("Popping stacking context id %" PRIu64 " with bounds=%s overflow=%s\n",
|
||||
fm.GetScrollId(), Stringify(bounds).c_str(), Stringify(overflow).c_str());
|
||||
}
|
||||
mLayer->WRBridge()->SendPopDLBuilder(toWrRect(bounds), toWrRect(overflow), identity, fm.GetScrollId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
|
||||
: mWidget(aWidget)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::Initialize(PCompositorBridgeChild* aCBChild, uint64_t aLayersId)
|
||||
{
|
||||
MOZ_ASSERT(mWRChild == nullptr);
|
||||
|
||||
PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(aLayersId);
|
||||
MOZ_ASSERT(bridge);
|
||||
mWRChild = static_cast<WebRenderBridgeChild*>(bridge);
|
||||
LayoutDeviceIntSize size = mWidget->GetClientSize();
|
||||
WRBridge()->SendCreate(size.width, size.height);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::Destroy()
|
||||
{
|
||||
DiscardImages();
|
||||
}
|
||||
|
||||
WebRenderLayerManager::~WebRenderLayerManager()
|
||||
{
|
||||
WRBridge()->SendDestroy();
|
||||
}
|
||||
|
||||
CompositorBridgeChild*
|
||||
WebRenderLayerManager::GetCompositorBridgeChild()
|
||||
{
|
||||
return mWidget ? mWidget->GetRemoteRenderer() : nullptr;
|
||||
}
|
||||
|
||||
int32_t
|
||||
WebRenderLayerManager::GetMaxTextureSize() const
|
||||
{
|
||||
return 4096;
|
||||
}
|
||||
|
||||
bool
|
||||
WebRenderLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
{
|
||||
return BeginTransaction();
|
||||
}
|
||||
|
||||
bool
|
||||
WebRenderLayerManager::BeginTransaction()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags)
|
||||
{
|
||||
DiscardImages();
|
||||
|
||||
mPaintedLayerCallback = aCallback;
|
||||
mPaintedLayerCallbackData = aCallbackData;
|
||||
|
||||
if (gfxPrefs::LayersDump()) {
|
||||
this->Dump();
|
||||
}
|
||||
|
||||
// Since we don't do repeat transactions right now, just set the time
|
||||
mAnimationReadyTime = TimeStamp::Now();
|
||||
|
||||
LayoutDeviceIntSize size = mWidget->GetClientSize();
|
||||
bool success = false;
|
||||
WRBridge()->SendDPBegin(size.width, size.height, &success);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer();
|
||||
|
||||
WRBridge()->SendDPEnd();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::AddImageKeyForDiscard(WRImageKey key)
|
||||
{
|
||||
mImageKeys.push_back(key);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::DiscardImages()
|
||||
{
|
||||
for (auto key : mImageKeys) {
|
||||
WRBridge()->SendDeleteImage(key);
|
||||
}
|
||||
mImageKeys.clear();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::SetRoot(Layer* aLayer)
|
||||
{
|
||||
mRoot = aLayer;
|
||||
}
|
||||
|
||||
already_AddRefed<PaintedLayer>
|
||||
WebRenderLayerManager::CreatePaintedLayer()
|
||||
{
|
||||
return MakeAndAddRef<WebRenderPaintedLayer>(this);
|
||||
}
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
WebRenderLayerManager::CreateContainerLayer()
|
||||
{
|
||||
return MakeAndAddRef<WebRenderContainerLayer>(this);
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
WebRenderLayerManager::CreateImageLayer()
|
||||
{
|
||||
return MakeAndAddRef<WebRenderImageLayer>(this);
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
WebRenderLayerManager::CreateCanvasLayer()
|
||||
{
|
||||
return MakeAndAddRef<WebRenderCanvasLayer>(this);
|
||||
}
|
||||
|
||||
already_AddRefed<ReadbackLayer>
|
||||
WebRenderLayerManager::CreateReadbackLayer()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<ColorLayer>
|
||||
WebRenderLayerManager::CreateColorLayer()
|
||||
{
|
||||
return MakeAndAddRef<WebRenderColorLayer>(this);
|
||||
}
|
||||
|
||||
already_AddRefed<RefLayer>
|
||||
WebRenderLayerManager::CreateRefLayer()
|
||||
{
|
||||
return MakeAndAddRef<WebRenderRefLayer>(this);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
141
gfx/layers/wr/WebRenderLayerManager.h
Normal file
141
gfx/layers/wr/WebRenderLayerManager.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 GFX_WEBRENDERLAYERMANAGER_H
|
||||
#define GFX_WEBRENDERLAYERMANAGER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "mozilla/layers/CompositorController.h"
|
||||
#include "webrender.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class WebRenderBridgeChild;
|
||||
|
||||
template<class T>
|
||||
static inline WRRect toWrRect(const gfx::RectTyped<T>& rect)
|
||||
{
|
||||
WRRect r;
|
||||
r.x = rect.x;
|
||||
r.y = rect.y;
|
||||
r.width = rect.width;
|
||||
r.height = rect.height;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WRRect toWrRect(const gfx::IntRectTyped<T>& rect)
|
||||
{
|
||||
return toWrRect(IntRectToRect(rect));
|
||||
}
|
||||
|
||||
|
||||
class WebRenderLayerManager;
|
||||
class APZCTreeManager;
|
||||
|
||||
class WebRenderLayer
|
||||
{
|
||||
public:
|
||||
virtual Layer* GetLayer() = 0;
|
||||
virtual void RenderLayer() = 0;
|
||||
|
||||
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; }
|
||||
static inline WebRenderLayer*
|
||||
ToWebRenderLayer(Layer* aLayer)
|
||||
{
|
||||
return static_cast<WebRenderLayer*>(aLayer->ImplData());
|
||||
}
|
||||
|
||||
WebRenderLayerManager* WRManager();
|
||||
WebRenderBridgeChild* WRBridge();
|
||||
|
||||
gfx::Rect RelativeToVisible(gfx::Rect aRect);
|
||||
gfx::Rect RelativeToTransformedVisible(gfx::Rect aRect);
|
||||
gfx::Rect ParentStackingContextBounds(size_t aScrollMetadataIndex);
|
||||
gfx::Rect RelativeToParent(gfx::Rect aRect);
|
||||
gfx::Rect TransformedVisibleBoundsRelativeToParent();
|
||||
};
|
||||
|
||||
class MOZ_RAII WRScrollFrameStackingContextGenerator
|
||||
{
|
||||
public:
|
||||
explicit WRScrollFrameStackingContextGenerator(WebRenderLayer* aLayer);
|
||||
~WRScrollFrameStackingContextGenerator();
|
||||
private:
|
||||
WebRenderLayer* mLayer;
|
||||
};
|
||||
|
||||
class WebRenderLayerManager final : public LayerManager
|
||||
{
|
||||
public:
|
||||
explicit WebRenderLayerManager(nsIWidget* aWidget);
|
||||
void Initialize(PCompositorBridgeChild* aCBChild, uint64_t aLayersId);
|
||||
|
||||
virtual void Destroy() override;
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderLayerManager();
|
||||
|
||||
public:
|
||||
WebRenderLayerManager* AsWebRenderLayerManager() override { return this; }
|
||||
CompositorBridgeChild* GetCompositorBridgeChild();
|
||||
|
||||
virtual int32_t GetMaxTextureSize() const override;
|
||||
|
||||
virtual bool BeginTransactionWithTarget(gfxContext* aTarget) override;
|
||||
virtual bool BeginTransaction() override;
|
||||
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override;
|
||||
virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags = END_DEFAULT) override;
|
||||
|
||||
virtual LayersBackend GetBackendType() override { return LayersBackend::LAYERS_WR; }
|
||||
virtual void GetBackendName(nsAString& name) override { name.AssignLiteral("WebRender"); }
|
||||
virtual const char* Name() const override { return "WebRender"; }
|
||||
|
||||
virtual void SetRoot(Layer* aLayer) override;
|
||||
|
||||
virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
|
||||
virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override;
|
||||
virtual already_AddRefed<ImageLayer> CreateImageLayer() override;
|
||||
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
|
||||
virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() override;
|
||||
virtual already_AddRefed<ColorLayer> CreateColorLayer() override;
|
||||
virtual already_AddRefed<RefLayer> CreateRefLayer() override;
|
||||
|
||||
virtual bool NeedsWidgetInvalidation() override { return true; }
|
||||
|
||||
DrawPaintedLayerCallback GetPaintedLayerCallback() const
|
||||
{ return mPaintedLayerCallback; }
|
||||
|
||||
void* GetPaintedLayerCallbackData() const
|
||||
{ return mPaintedLayerCallbackData; }
|
||||
|
||||
// adds an imagekey to a list of keys that will be discarded on the next
|
||||
// transaction or destruction
|
||||
void AddImageKeyForDiscard(WRImageKey);
|
||||
void DiscardImages();
|
||||
|
||||
WebRenderBridgeChild* WRBridge() { return mWRChild; }
|
||||
|
||||
private:
|
||||
nsIWidget* MOZ_NON_OWNING_REF mWidget;
|
||||
std::vector<WRImageKey> mImageKeys;
|
||||
|
||||
/* PaintedLayer callbacks; valid at the end of a transaciton,
|
||||
* while rendering */
|
||||
DrawPaintedLayerCallback mPaintedLayerCallback;
|
||||
void *mPaintedLayerCallbackData;
|
||||
|
||||
RefPtr<WebRenderBridgeChild> mWRChild;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* GFX_WEBRENDERLAYERMANAGER_H */
|
||||
80
gfx/layers/wr/WebRenderPaintedLayer.cpp
Normal file
80
gfx/layers/wr/WebRenderPaintedLayer.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "WebRenderPaintedLayer.h"
|
||||
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "gfxUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
void
|
||||
WebRenderPaintedLayer::RenderLayer()
|
||||
{
|
||||
LayerIntRegion visibleRegion = GetVisibleRegion();
|
||||
LayerIntRect bounds = visibleRegion.GetBounds();
|
||||
LayerIntSize size = bounds.Size();
|
||||
if (size.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
WRScrollFrameStackingContextGenerator scrollFrames(this);
|
||||
WRBridge()->SendPushDLBuilder();
|
||||
|
||||
RefPtr<DrawTarget> target = gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, size.ToUnknownSize(), SurfaceFormat::B8G8R8A8);
|
||||
target->SetTransform(Matrix().PreTranslate(-bounds.x, -bounds.y));
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target);
|
||||
MOZ_ASSERT(ctx); // already checked the target above
|
||||
|
||||
Manager()->GetPaintedLayerCallback()(this,
|
||||
ctx,
|
||||
visibleRegion.ToUnknownRegion(), visibleRegion.ToUnknownRegion(),
|
||||
DrawRegionClip::DRAW, nsIntRegion(), Manager()->GetPaintedLayerCallbackData());
|
||||
#if 0
|
||||
static int count;
|
||||
char buf[400];
|
||||
sprintf(buf, "wrout%d.png", count++);
|
||||
gfxUtils::WriteAsPNG(target, buf);
|
||||
#endif
|
||||
|
||||
WRImageKey key;
|
||||
{
|
||||
unsigned char* data;
|
||||
IntSize size;
|
||||
int32_t stride;
|
||||
SurfaceFormat format;
|
||||
target->LockBits(&data, &size, &stride, &format);
|
||||
gfx::ByteBuffer buf(size.height * stride, data);
|
||||
WRBridge()->SendAddImage(size.width, size.height, stride, RGBA8, buf, &key);
|
||||
target->ReleaseBits(data);
|
||||
}
|
||||
|
||||
// Since we are creating a stacking context below using the visible region of
|
||||
// this layer, we need to make sure the image display item has coordinates
|
||||
// relative to the visible region.
|
||||
Rect rect = RelativeToVisible(IntRectToRect(bounds.ToUnknownRect()));
|
||||
Rect clip;
|
||||
if (GetClipRect().isSome()) {
|
||||
clip = RelativeToTransformedVisible(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
|
||||
} else {
|
||||
clip = rect;
|
||||
}
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("PaintedLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
|
||||
WRBridge()->SendDPPushImage(toWrRect(rect), toWrRect(clip), Nothing(), key);
|
||||
Manager()->AddImageKeyForDiscard(key);
|
||||
|
||||
Rect relBounds = TransformedVisibleBoundsRelativeToParent();
|
||||
Matrix4x4 transform;// = GetTransform();
|
||||
if (gfxPrefs::LayersDump()) printf_stderr("PaintedLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
|
||||
WRBridge()->SendPopDLBuilder(toWrRect(relBounds), toWrRect(relBounds), transform, FrameMetrics::NULL_SCROLL_ID);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
49
gfx/layers/wr/WebRenderPaintedLayer.h
Normal file
49
gfx/layers/wr/WebRenderPaintedLayer.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 GFX_WEBRENDERPAINTEDLAYER_H
|
||||
#define GFX_WEBRENDERPAINTEDLAYER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "WebRenderLayerManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class WebRenderPaintedLayer : public WebRenderLayer,
|
||||
public PaintedLayer {
|
||||
public:
|
||||
|
||||
explicit WebRenderPaintedLayer(WebRenderLayerManager* aLayerManager)
|
||||
: PaintedLayer(aLayerManager, static_cast<WebRenderLayer*>(this), LayerManager::NONE)
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderPaintedLayer);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderPaintedLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderPaintedLayer);
|
||||
}
|
||||
WebRenderLayerManager* Manager()
|
||||
{
|
||||
return static_cast<WebRenderLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void InvalidateRegion(const nsIntRegion& aRegion) override
|
||||
{
|
||||
mInvalidRegion.Add(aRegion);
|
||||
mValidRegion.Sub(mValidRegion, mInvalidRegion.GetRegion());
|
||||
}
|
||||
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_WEBRENDERPAINTEDLAYER_H
|
||||
155
gfx/layers/wr/WebRenderTypes.h
Normal file
155
gfx/layers/wr/WebRenderTypes.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 GFX_BYTEBUFFER_H
|
||||
#define GFX_BYTEBUFFER_H
|
||||
|
||||
#include "chrome/common/ipc_message_utils.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "webrender.h"
|
||||
|
||||
typedef mozilla::Maybe<WRImageMask> MaybeImageMask;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
struct ByteBuffer
|
||||
{
|
||||
ByteBuffer(size_t aLength, uint8_t* aData)
|
||||
: mLength(aLength)
|
||||
, mData(aData)
|
||||
, mOwned(false)
|
||||
{}
|
||||
|
||||
ByteBuffer()
|
||||
: mLength(0)
|
||||
, mData(nullptr)
|
||||
, mOwned(false)
|
||||
{}
|
||||
|
||||
bool
|
||||
Allocate(size_t aLength)
|
||||
{
|
||||
MOZ_ASSERT(mData == nullptr);
|
||||
mData = (uint8_t*)malloc(aLength);
|
||||
if (!mData) {
|
||||
return false;
|
||||
}
|
||||
mLength = aLength;
|
||||
mOwned = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
~ByteBuffer()
|
||||
{
|
||||
if (mData && mOwned) {
|
||||
free(mData);
|
||||
}
|
||||
}
|
||||
|
||||
size_t mLength;
|
||||
uint8_t* mData;
|
||||
bool mOwned;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::gfx::ByteBuffer>
|
||||
{
|
||||
typedef mozilla::gfx::ByteBuffer paramType;
|
||||
|
||||
static void
|
||||
Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mLength);
|
||||
aMsg->WriteBytes(aParam.mData, aParam.mLength);
|
||||
}
|
||||
|
||||
static bool
|
||||
Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
size_t length;
|
||||
return ReadParam(aMsg, aIter, &length)
|
||||
&& aResult->Allocate(length)
|
||||
&& aMsg->ReadBytesInto(aIter, aResult->mData, length);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<WRImageFormat>
|
||||
: public ContiguousEnumSerializer<
|
||||
WRImageFormat,
|
||||
WRImageFormat::Invalid,
|
||||
WRImageFormat::RGBAF32>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<WRImageKey>
|
||||
{
|
||||
static void
|
||||
Write(Message* aMsg, const WRImageKey& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.a);
|
||||
WriteParam(aMsg, aParam.b);
|
||||
}
|
||||
|
||||
static bool
|
||||
Read(const Message* aMsg, PickleIterator* aIter, WRImageKey* aResult)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, &aResult->a)
|
||||
&& ReadParam(aMsg, aIter, &aResult->b);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<WRRect>
|
||||
{
|
||||
static void
|
||||
Write(Message* aMsg, const WRRect& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.x);
|
||||
WriteParam(aMsg, aParam.y);
|
||||
WriteParam(aMsg, aParam.width);
|
||||
WriteParam(aMsg, aParam.height);
|
||||
}
|
||||
|
||||
static bool
|
||||
Read(const Message* aMsg, PickleIterator* aIter, WRRect* aResult)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, &aResult->x)
|
||||
&& ReadParam(aMsg, aIter, &aResult->y)
|
||||
&& ReadParam(aMsg, aIter, &aResult->width)
|
||||
&& ReadParam(aMsg, aIter, &aResult->height);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<WRImageMask>
|
||||
{
|
||||
static void
|
||||
Write(Message* aMsg, const WRImageMask& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.image);
|
||||
WriteParam(aMsg, aParam.rect);
|
||||
WriteParam(aMsg, aParam.repeat);
|
||||
}
|
||||
|
||||
static bool
|
||||
Read(const Message* aMsg, PickleIterator* aIter, WRImageMask* aResult)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, &aResult->image)
|
||||
&& ReadParam(aMsg, aIter, &aResult->rect)
|
||||
&& ReadParam(aMsg, aIter, &aResult->repeat);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif /* GFX_BYTEBUFFER_H */
|
||||
@@ -24,6 +24,8 @@ DIRS += [
|
||||
'config',
|
||||
]
|
||||
|
||||
EXPORTS += ['webrender/webrender.h']
|
||||
|
||||
if CONFIG['MOZ_ENABLE_SKIA']:
|
||||
DIRS += ['skia']
|
||||
|
||||
|
||||
@@ -2432,6 +2432,12 @@ gfxPlatform::AsyncPanZoomEnabled()
|
||||
if (!BrowserTabsRemoteAutostart()) {
|
||||
return false;
|
||||
}
|
||||
#ifdef MOZ_ENABLE_WEBRENDER
|
||||
// For webrender hacking we have a special pref to disable APZ even with e10s
|
||||
if (!gfxPrefs::APZAllowWithWebRender()) {
|
||||
return false;
|
||||
}
|
||||
#endif // MOZ_ENABLE_WEBRENDER
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
return true;
|
||||
|
||||
@@ -253,6 +253,7 @@ private:
|
||||
// The apz prefs are explained in AsyncPanZoomController.cpp
|
||||
DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true);
|
||||
DECL_GFX_PREF(Live, "apz.allow_immediate_handoff", APZAllowImmediateHandoff, bool, true);
|
||||
DECL_GFX_PREF(Once, "apz.allow_with_webrender", APZAllowWithWebRender, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.allow_zooming", APZAllowZooming, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_angle", APZAxisBreakoutAngle, float, float(M_PI / 8.0) /* 22.5 degrees */);
|
||||
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_threshold", APZAxisBreakoutThreshold, float, 1.0f / 32.0f);
|
||||
|
||||
@@ -620,6 +620,7 @@ pref("layout.event-regions.enabled", false);
|
||||
// gfx/layers/apz/src/AsyncPanZoomController.cpp.
|
||||
pref("apz.allow_checkerboarding", true);
|
||||
pref("apz.allow_immediate_handoff", true);
|
||||
pref("apz.allow_with_webrender", false);
|
||||
pref("apz.allow_zooming", false);
|
||||
|
||||
// Whether to lock touch scrolling to one axis at a time
|
||||
|
||||
Reference in New Issue
Block a user