mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 01:35:35 +00:00
Bug 1318113 - Use BufferTexture to return the reftest snapshot r=nical?
This commit is contained in:
parent
0a3554cf97
commit
753708476e
@ -1156,7 +1156,7 @@ CompositorBridgeChild::HandleFatalError(const char* aName, const char* aMsg) con
|
||||
}
|
||||
|
||||
PWebRenderBridgeChild*
|
||||
CompositorBridgeChild::AllocPWebRenderBridgeChild(const uint64_t& aPipelineId)
|
||||
CompositorBridgeChild::AllocPWebRenderBridgeChild(const uint64_t& aPipelineId, TextureFactoryIdentifier*)
|
||||
{
|
||||
WebRenderBridgeChild* child = new WebRenderBridgeChild(aPipelineId);
|
||||
child->AddIPDLReference();
|
||||
|
@ -228,7 +228,7 @@ public:
|
||||
|
||||
void WillEndTransaction();
|
||||
|
||||
PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const uint64_t& aPipelineId) override;
|
||||
PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const uint64_t& aPipelineId, TextureFactoryIdentifier*) override;
|
||||
bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor) override;
|
||||
|
||||
private:
|
||||
|
@ -1556,7 +1556,8 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
|
||||
}
|
||||
|
||||
PWebRenderBridgeParent*
|
||||
CompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId)
|
||||
CompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier)
|
||||
{
|
||||
#ifndef MOZ_ENABLE_WEBRENDER
|
||||
// Extra guard since this in the parent process and we don't want a malicious
|
||||
@ -1575,6 +1576,7 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId)
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
MOZ_ASSERT(sIndirectLayerTrees[aPipelineId].mWRBridge == nullptr);
|
||||
sIndirectLayerTrees[aPipelineId].mWRBridge = mWRBridge;
|
||||
*aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
|
||||
return mWRBridge;
|
||||
}
|
||||
|
||||
|
@ -455,7 +455,8 @@ public:
|
||||
return !!mApzcTreeManager;
|
||||
}
|
||||
|
||||
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const uint64_t& aPipelineId) override;
|
||||
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier) override;
|
||||
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
|
||||
|
||||
private:
|
||||
|
@ -192,7 +192,8 @@ CrossProcessCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
|
||||
}
|
||||
|
||||
PWebRenderBridgeParent*
|
||||
CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId)
|
||||
CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier)
|
||||
{
|
||||
#ifndef MOZ_ENABLE_WEBRENDER
|
||||
// Extra guard since this in the parent process and we don't want a malicious
|
||||
@ -215,7 +216,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t&
|
||||
aPipelineId, nullptr, root->GLContext(), root->WindowState(), root->Compositor());
|
||||
parent->AddRef(); // IPDL reference
|
||||
sIndirectLayerTrees[aPipelineId].mWRBridge = parent;
|
||||
|
||||
*aTextureFactoryIdentifier = parent->Compositor()->GetTextureFactoryIdentifier();
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,8 @@ public:
|
||||
|
||||
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) override;
|
||||
|
||||
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const uint64_t& aPipelineId) override;
|
||||
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier) override;
|
||||
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
|
||||
|
||||
protected:
|
||||
|
@ -231,7 +231,8 @@ parent:
|
||||
sync SyncWithCompositor();
|
||||
|
||||
// The pipelineId is the same as the layersId
|
||||
async PWebRenderBridge(uint64_t pipelineId);
|
||||
sync PWebRenderBridge(uint64_t pipelineId)
|
||||
returns (TextureFactoryIdentifier textureFactoryIdentifier);
|
||||
|
||||
child:
|
||||
// Send back Compositor Frame Metrics from APZCs so tiled layers can
|
||||
|
@ -5,10 +5,12 @@
|
||||
* 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 LayersSurfaces;
|
||||
include "mozilla/GfxMessageUtils.h";
|
||||
|
||||
include WebRenderMessages;
|
||||
include protocol PCompositorBridge;
|
||||
include protocol PTexture;
|
||||
|
||||
using WRImageFormat from "mozilla/gfx/webrender.h";
|
||||
using mozilla::gfx::ByteBuffer from "mozilla/layers/WebRenderTypes.h";
|
||||
@ -32,8 +34,7 @@ parent:
|
||||
returns (bool aOutSuccess);
|
||||
async DPEnd(WebRenderCommand[] commands);
|
||||
sync DPSyncEnd(WebRenderCommand[] commands);
|
||||
sync DPGetSnapshot(uint32_t aWidth, uint32_t aHeight)
|
||||
returns (uint8_t[] aOutImageSnapshot);
|
||||
sync DPGetSnapshot(PTexture texture, IntRect dirtyRect);
|
||||
async AddExternalImageId(uint64_t aImageId, uint64_t aAsyncContainerId);
|
||||
async RemoveExternalImageId(uint64_t aImageId);
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -101,5 +104,23 @@ WebRenderBridgeChild::DeallocExternalImageId(uint64_t aImageId)
|
||||
SendRemoveExternalImageId(aImageId);
|
||||
}
|
||||
|
||||
CompositorBridgeChild*
|
||||
WebRenderBridgeChild::GetCompositorBridgeChild()
|
||||
{
|
||||
return static_cast<CompositorBridgeChild*>(Manager());
|
||||
}
|
||||
|
||||
TextureForwarder*
|
||||
WebRenderBridgeChild::GetTextureForwarder()
|
||||
{
|
||||
return static_cast<TextureForwarder*>(GetCompositorBridgeChild());
|
||||
}
|
||||
|
||||
LayersIPCActor*
|
||||
WebRenderBridgeChild::GetLayersIPCActor()
|
||||
{
|
||||
return static_cast<LayersIPCActor*>(GetCompositorBridgeChild());
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef mozilla_layers_WebRenderBridgeChild_h
|
||||
#define mozilla_layers_WebRenderBridgeChild_h
|
||||
|
||||
#include "mozilla/layers/KnowsCompositor.h"
|
||||
#include "mozilla/layers/PWebRenderBridgeChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -17,7 +18,11 @@ class CompositorWidget;
|
||||
|
||||
namespace layers {
|
||||
|
||||
class CompositorBridgeChild;
|
||||
class TextureForwarder;
|
||||
|
||||
class WebRenderBridgeChild final : public PWebRenderBridgeChild
|
||||
, public KnowsCompositor
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeChild)
|
||||
|
||||
@ -29,6 +34,11 @@ public:
|
||||
bool DPBegin(uint32_t aWidth, uint32_t aHeight);
|
||||
void DPEnd(bool aIsSync = false);
|
||||
|
||||
CompositorBridgeChild* GetCompositorBridgeChild();
|
||||
// KnowsCompositor
|
||||
TextureForwarder* GetTextureForwarder();
|
||||
LayersIPCActor* GetLayersIPCActor();
|
||||
|
||||
uint64_t AllocExternalImageId(uint64_t aAsyncContainerID);
|
||||
void DeallocExternalImageId(uint64_t aImageId);
|
||||
|
||||
|
@ -11,12 +11,16 @@
|
||||
#include "GLContextProvider.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/CompositorVsyncScheduler.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/WebRenderCompositorOGL.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
WebRenderBridgeParent::WebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
widget::CompositorWidget* aWidget,
|
||||
gl::GLContext* aGlContext,
|
||||
@ -207,21 +211,64 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPGetSnapshot(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
InfallibleTArray<uint8_t>* aOutImageSnapshot)
|
||||
WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture,
|
||||
const IntRect& aRect)
|
||||
{
|
||||
if (mDestroyed) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture) {
|
||||
// We kill the content process rather than have it continue with an invalid
|
||||
// snapshot, that may be too harsh and we could decide to return some sort
|
||||
// of error to the child process and let it deal with it...
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
// XXX Add other TextureHost supports.
|
||||
// Only BufferTextureHost is supported now.
|
||||
BufferTextureHost* bufferTexture = texture->AsBufferTextureHost();
|
||||
if (!bufferTexture) {
|
||||
// We kill the content process rather than have it continue with an invalid
|
||||
// snapshot, that may be too harsh and we could decide to return some sort
|
||||
// of error to the child process and let it deal with it...
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(bufferTexture->GetBufferDescriptor().type() == BufferDescriptor::TRGBDescriptor);
|
||||
uint32_t stride = ImageDataSerializer::GetRGBStride(bufferTexture->GetBufferDescriptor().get_RGBDescriptor());
|
||||
RefPtr<DrawTarget> target =
|
||||
Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO,
|
||||
bufferTexture->GetBuffer(),
|
||||
bufferTexture->GetSize(),
|
||||
stride,
|
||||
bufferTexture->GetFormat());
|
||||
MOZ_ASSERT(target);
|
||||
if (!target) {
|
||||
// We kill the content process rather than have it continue with an invalid
|
||||
// snapshot, that may be too harsh and we could decide to return some sort
|
||||
// of error to the child process and let it deal with it...
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mWRState);
|
||||
mGLContext->MakeCurrent();
|
||||
|
||||
uint32_t length = 0;
|
||||
uint32_t capacity = 0;
|
||||
const uint8_t* webrenderSnapshot = wr_readback_buffer(mWRWindowState, aWidth, aHeight, &length, &capacity);
|
||||
const uint8_t* webrenderSnapshot = wr_readback_buffer(mWRWindowState, aRect.width, aRect.height, &length, &capacity);
|
||||
|
||||
aOutImageSnapshot->ReplaceElementsAt(0, aOutImageSnapshot->Length(), webrenderSnapshot, length);
|
||||
// TODO: fixup for proper surface format.
|
||||
RefPtr<DataSourceSurface> snapshot =
|
||||
Factory::CreateWrappingDataSourceSurface(const_cast<uint8_t*>(webrenderSnapshot),
|
||||
aRect.width * 4,
|
||||
IntSize(aRect.width, aRect.height),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
|
||||
Rect floatRect = Rect(0, 0, aRect.width, aRect.height);
|
||||
target->DrawSurface(snapshot, floatRect, floatRect, DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_SOURCE));
|
||||
target->Flush();
|
||||
|
||||
wr_free_buffer(webrenderSnapshot, length, capacity);
|
||||
|
||||
|
@ -63,9 +63,8 @@ public:
|
||||
bool* aOutSuccess) override;
|
||||
mozilla::ipc::IPCResult RecvDPEnd(InfallibleTArray<WebRenderCommand>&& commands) override;
|
||||
mozilla::ipc::IPCResult RecvDPSyncEnd(InfallibleTArray<WebRenderCommand>&& commands) override;
|
||||
mozilla::ipc::IPCResult RecvDPGetSnapshot(const uint32_t& aWidth,
|
||||
const uint32_t& aHeight,
|
||||
InfallibleTArray<uint8_t>* aOutImageSnapshot) override;
|
||||
mozilla::ipc::IPCResult RecvDPGetSnapshot(PTextureParent* aTexture,
|
||||
const gfx::IntRect& aRect) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvAddExternalImageId(const uint64_t& aImageId,
|
||||
const uint64_t& aAsyncContainerId) override;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/layers/APZCTreeManager.h"
|
||||
#include "mozilla/layers/AsyncCompositionManager.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -143,11 +144,14 @@ WebRenderLayerManager::Initialize(PCompositorBridgeChild* aCBChild, uint64_t aLa
|
||||
{
|
||||
MOZ_ASSERT(mWRChild == nullptr);
|
||||
|
||||
PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(aLayersId);
|
||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||
PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(aLayersId,
|
||||
&textureFactoryIdentifier);
|
||||
MOZ_ASSERT(bridge);
|
||||
mWRChild = static_cast<WebRenderBridgeChild*>(bridge);
|
||||
LayoutDeviceIntSize size = mWidget->GetClientSize();
|
||||
WRBridge()->SendCreate(size.width, size.height);
|
||||
WRBridge()->IdentifyTextureHost(textureFactoryIdentifier);
|
||||
}
|
||||
|
||||
void
|
||||
@ -174,7 +178,7 @@ WebRenderLayerManager::GetCompositorBridgeChild()
|
||||
int32_t
|
||||
WebRenderLayerManager::GetMaxTextureSize() const
|
||||
{
|
||||
return 4096;
|
||||
return WRBridge()->GetMaxTextureSize();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -228,20 +232,43 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||
void
|
||||
WebRenderLayerManager::MakeSnapshotIfRequired(LayoutDeviceIntSize aSize)
|
||||
{
|
||||
if (!mTarget) {
|
||||
if (!mTarget || aSize.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> data;
|
||||
WRBridge()->SendDPGetSnapshot(aSize.width, aSize.height, &data);
|
||||
// XXX Add other TextureData supports.
|
||||
// Only BufferTexture is supported now.
|
||||
|
||||
// TODO: fixup for proper surface format.
|
||||
RefPtr<DataSourceSurface> snapshot =
|
||||
Factory::CreateWrappingDataSourceSurface(data.Elements(),
|
||||
aSize.width * 4,
|
||||
IntSize(aSize.width, aSize.height),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
RefPtr<TextureClient> texture =
|
||||
TextureClient::CreateForRawBufferAccess(WRBridge(),
|
||||
SurfaceFormat::B8G8R8A8,
|
||||
aSize.ToUnknownSize(),
|
||||
BackendType::CAIRO,
|
||||
TextureFlags::DEFAULT);
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
texture->InitIPDLActor(WRBridge());
|
||||
if (!texture->GetIPDLActor()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IntRect bounds = ToOutsideIntRect(mTarget->GetClipExtents());
|
||||
if (!WRBridge()->SendDPGetSnapshot(texture->GetIPDLActor(), bounds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TextureClientAutoLock autoLock(texture, OpenMode::OPEN_READ_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
return;
|
||||
}
|
||||
RefPtr<DrawTarget> drawTarget = texture->BorrowDrawTarget();
|
||||
if (!drawTarget || !drawTarget->IsValid()) {
|
||||
return;
|
||||
}
|
||||
RefPtr<SourceSurface> snapshot = drawTarget->Snapshot();
|
||||
/*
|
||||
static int count = 0;
|
||||
char filename[100];
|
||||
@ -250,7 +277,6 @@ WebRenderLayerManager::MakeSnapshotIfRequired(LayoutDeviceIntSize aSize)
|
||||
gfxUtils::WriteAsPNG(snapshot, filename);
|
||||
*/
|
||||
|
||||
IntRect bounds = ToOutsideIntRect(mTarget->GetClipExtents());
|
||||
Rect dst(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
Rect src(0, 0, bounds.width, bounds.height);
|
||||
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
void AddImageKeyForDiscard(WRImageKey);
|
||||
void DiscardImages();
|
||||
|
||||
WebRenderBridgeChild* WRBridge() { return mWRChild; }
|
||||
WebRenderBridgeChild* WRBridge() const { return mWRChild; }
|
||||
|
||||
private:
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user