зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322086 - Handle texture recycling in WebRenderImageLayer r=nical?
This commit is contained in:
Родитель
7383fcbb4a
Коммит
e0f89688a5
|
@ -38,8 +38,8 @@ parent:
|
|||
sync DeleteImage(WRImageKey aImageKey);
|
||||
sync DPBegin(uint32_t aWidth, uint32_t aHeight)
|
||||
returns (bool aOutSuccess);
|
||||
async DPEnd(WebRenderCommand[] commands, OpDestroy[] toDestroy, uint64_t transactionId);
|
||||
sync DPSyncEnd(WebRenderCommand[] commands, OpDestroy[] toDestroy, uint64_t transactionId);
|
||||
async DPEnd(WebRenderCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId);
|
||||
sync DPSyncEnd(WebRenderCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId);
|
||||
sync DPGetSnapshot(PTexture texture, IntRect dirtyRect);
|
||||
async AddExternalImageId(uint64_t aImageId, uint64_t aAsyncContainerId);
|
||||
async RemoveExternalImageId(uint64_t aImageId);
|
||||
|
|
|
@ -55,6 +55,7 @@ WebRenderBridgeChild::DPBegin(uint32_t aWidth, uint32_t aHeight)
|
|||
MOZ_ASSERT(!mDestroyed);
|
||||
MOZ_ASSERT(!mIsInTransaction);
|
||||
bool success = false;
|
||||
UpdateFwdTransactionId();
|
||||
this->SendDPBegin(aWidth, aHeight, &success);
|
||||
if (!success) {
|
||||
return false;
|
||||
|
@ -70,9 +71,9 @@ WebRenderBridgeChild::DPEnd(bool aIsSync, uint64_t aTransactionId)
|
|||
MOZ_ASSERT(!mDestroyed);
|
||||
MOZ_ASSERT(mIsInTransaction);
|
||||
if (aIsSync) {
|
||||
this->SendDPSyncEnd(mCommands, mDestroyedActors, aTransactionId);
|
||||
this->SendDPSyncEnd(mCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId);
|
||||
} else {
|
||||
this->SendDPEnd(mCommands, mDestroyedActors, aTransactionId);
|
||||
this->SendDPEnd(mCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId);
|
||||
}
|
||||
|
||||
mCommands.Clear();
|
||||
|
@ -248,8 +249,7 @@ WebRenderBridgeChild::UseTextures(CompositableClient* aCompositable,
|
|||
|
||||
MarkSyncTransaction();
|
||||
}
|
||||
// XXX Enable recycle
|
||||
//mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
|
||||
GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
|
||||
}
|
||||
AddWebRenderCommand(CompositableOperation(nullptr, aCompositable->GetIPDLActor(),
|
||||
OpUseTexture(textures)));
|
||||
|
@ -266,13 +266,13 @@ WebRenderBridgeChild::UseComponentAlphaTextures(CompositableClient* aCompositabl
|
|||
void
|
||||
WebRenderBridgeChild::UpdateFwdTransactionId()
|
||||
{
|
||||
|
||||
GetCompositorBridgeChild()->UpdateFwdTransactionId();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
WebRenderBridgeChild::GetFwdTransactionId()
|
||||
{
|
||||
return 0;
|
||||
return GetCompositorBridgeChild()->GetFwdTransactionId();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -28,6 +28,33 @@ namespace layers {
|
|||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
class MOZ_STACK_CLASS AutoWebRenderBridgeParentAsyncMessageSender
|
||||
{
|
||||
public:
|
||||
explicit AutoWebRenderBridgeParentAsyncMessageSender(WebRenderBridgeParent* aWebRenderBridgeParent,
|
||||
InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
|
||||
: mWebRenderBridgeParent(aWebRenderBridgeParent)
|
||||
, mActorsToDestroy(aDestroyActors)
|
||||
{
|
||||
mWebRenderBridgeParent->SetAboutToSendAsyncMessages();
|
||||
}
|
||||
|
||||
~AutoWebRenderBridgeParentAsyncMessageSender()
|
||||
{
|
||||
mWebRenderBridgeParent->SendPendingAsyncMessages();
|
||||
if (mActorsToDestroy) {
|
||||
// Destroy the actors after sending the async messages because the latter may contain
|
||||
// references to some actors.
|
||||
for (const auto& op : *mActorsToDestroy) {
|
||||
mWebRenderBridgeParent->DestroyActor(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
WebRenderBridgeParent* mWebRenderBridgeParent;
|
||||
InfallibleTArray<OpDestroy>* mActorsToDestroy;
|
||||
};
|
||||
|
||||
WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompositorBridge,
|
||||
const uint64_t& aPipelineId,
|
||||
widget::CompositorWidget* aWidget,
|
||||
|
@ -167,14 +194,21 @@ WebRenderBridgeParent::RecvDPBegin(const uint32_t& aWidth,
|
|||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPEnd(InfallibleTArray<WebRenderCommand>&& aCommands,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId)
|
||||
{
|
||||
UpdateFwdTransactionId(aFwdTransactionId);
|
||||
|
||||
if (mDestroyed) {
|
||||
for (const auto& op : aToDestroy) {
|
||||
DestroyActor(op);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
// This ensures that destroy operations are always processed. It is not safe
|
||||
// to early-return from RecvDPEnd without doing so.
|
||||
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
|
||||
|
||||
ProcessWebrenderCommands(aCommands);
|
||||
|
||||
// The transaction ID might get reset to 1 if the page gets reloaded, see
|
||||
|
@ -182,24 +216,27 @@ WebRenderBridgeParent::RecvDPEnd(InfallibleTArray<WebRenderCommand>&& aCommands,
|
|||
// Otherwise, it should be continually increasing.
|
||||
MOZ_ASSERT(aTransactionId == 1 || aTransactionId > mPendingTransactionId);
|
||||
mPendingTransactionId = aTransactionId;
|
||||
|
||||
for (const auto& op : aToDestroy) {
|
||||
DestroyActor(op);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDPSyncEnd(InfallibleTArray<WebRenderCommand>&& aCommands,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId)
|
||||
{
|
||||
UpdateFwdTransactionId(aFwdTransactionId);
|
||||
|
||||
if (mDestroyed) {
|
||||
for (const auto& op : aToDestroy) {
|
||||
DestroyActor(op);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
// This ensures that destroy operations are always processed. It is not safe
|
||||
// to early-return from RecvDPEnd without doing so.
|
||||
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
|
||||
|
||||
ProcessWebrenderCommands(aCommands);
|
||||
|
||||
// The transaction ID might get reset to 1 if the page gets reloaded, see
|
||||
|
@ -207,10 +244,6 @@ WebRenderBridgeParent::RecvDPSyncEnd(InfallibleTArray<WebRenderCommand>&& aComma
|
|||
// Otherwise, it should be continually increasing.
|
||||
MOZ_ASSERT(aTransactionId == 1 || aTransactionId > mPendingTransactionId);
|
||||
mPendingTransactionId = aTransactionId;
|
||||
|
||||
for (const auto& op : aToDestroy) {
|
||||
DestroyActor(op);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -498,6 +531,20 @@ WebRenderBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessag
|
|||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::SendPendingAsyncMessages()
|
||||
{
|
||||
MOZ_ASSERT(mCompositorBridge);
|
||||
mCompositorBridge->SendPendingAsyncMessages();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::SetAboutToSendAsyncMessages()
|
||||
{
|
||||
MOZ_ASSERT(mCompositorBridge);
|
||||
mCompositorBridge->SetAboutToSendAsyncMessages();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
|
||||
{
|
||||
|
|
|
@ -66,9 +66,11 @@ public:
|
|||
bool* aOutSuccess) override;
|
||||
mozilla::ipc::IPCResult RecvDPEnd(InfallibleTArray<WebRenderCommand>&& aCommands,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId) override;
|
||||
mozilla::ipc::IPCResult RecvDPSyncEnd(InfallibleTArray<WebRenderCommand>&& aCommands,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId) override;
|
||||
mozilla::ipc::IPCResult RecvDPGetSnapshot(PTextureParent* aTexture,
|
||||
const gfx::IntRect& aRect) override;
|
||||
|
@ -94,17 +96,19 @@ public:
|
|||
void FinishPendingComposite() override { }
|
||||
void CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr) override;
|
||||
|
||||
private:
|
||||
virtual ~WebRenderBridgeParent();
|
||||
|
||||
virtual PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo) override;
|
||||
bool DeallocPCompositableParent(PCompositableParent* aActor) override;
|
||||
|
||||
// CompositableParentManager
|
||||
bool IsSameProcess() const override;
|
||||
base::ProcessId GetChildProcessId() override;
|
||||
void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
|
||||
void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
|
||||
void SendPendingAsyncMessages() override;
|
||||
void SetAboutToSendAsyncMessages() override;
|
||||
|
||||
private:
|
||||
virtual ~WebRenderBridgeParent();
|
||||
|
||||
virtual PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo) override;
|
||||
bool DeallocPCompositableParent(PCompositableParent* aActor) override;
|
||||
|
||||
void DeleteOldImages();
|
||||
void ProcessWebrenderCommands(InfallibleTArray<WebRenderCommand>& commands);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/layers/ImageClient.h"
|
||||
#include "mozilla/layers/TextureClientRecycleAllocator.h"
|
||||
#include "mozilla/layers/TextureWrapperImage.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
|
||||
|
@ -59,41 +60,9 @@ WebRenderImageLayer::RenderLayer()
|
|||
return;
|
||||
}
|
||||
|
||||
gfx::IntSize size = surface->GetSize();
|
||||
|
||||
// XXX Add external image id handling
|
||||
|
||||
// XXX Add texure recycling
|
||||
|
||||
// XXX Add other TextureData supports.
|
||||
// Only BufferTexture is supported now.
|
||||
RefPtr<TextureClient> texture =
|
||||
TextureClient::CreateForRawBufferAccess(WRBridge(),
|
||||
surface->GetFormat(),
|
||||
size,
|
||||
BackendType::SKIA,
|
||||
TextureFlags::DEFAULT);
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(texture->CanExposeDrawTarget());
|
||||
|
||||
TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
return;
|
||||
}
|
||||
RefPtr<DrawTarget> drawTarget = texture->BorrowDrawTarget();
|
||||
if (!drawTarget || !drawTarget->IsValid()) {
|
||||
return;
|
||||
}
|
||||
drawTarget->CopySurface(surface, IntRect(IntPoint(), size), IntPoint());
|
||||
|
||||
if (!mImageContainerForWR) {
|
||||
mImageContainerForWR = LayerManager::CreateImageContainer();
|
||||
}
|
||||
RefPtr<TextureWrapperImage> image =
|
||||
new TextureWrapperImage(texture, IntRect(IntPoint(0, 0), size));
|
||||
mImageContainerForWR->SetCurrentImageInTransaction(image);
|
||||
|
||||
if (!mImageClient) {
|
||||
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
|
||||
|
@ -105,6 +74,36 @@ WebRenderImageLayer::RenderLayer()
|
|||
mImageClient->Connect();
|
||||
}
|
||||
|
||||
gfx::IntSize size = surface->GetSize();
|
||||
|
||||
// XXX Add external image id handling
|
||||
|
||||
RefPtr<TextureClient> texture = mImageClient->GetTextureClientRecycler()
|
||||
->CreateOrRecycle(surface->GetFormat(),
|
||||
size,
|
||||
BackendSelector::Content,
|
||||
TextureFlags::DEFAULT);
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MOZ_ASSERT(texture->CanExposeDrawTarget());
|
||||
{
|
||||
TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
return;
|
||||
}
|
||||
RefPtr<DrawTarget> drawTarget = texture->BorrowDrawTarget();
|
||||
if (!drawTarget || !drawTarget->IsValid()) {
|
||||
return;
|
||||
}
|
||||
drawTarget->CopySurface(surface, IntRect(IntPoint(), size), IntPoint());
|
||||
}
|
||||
RefPtr<TextureWrapperImage> image =
|
||||
new TextureWrapperImage(texture, IntRect(IntPoint(0, 0), size));
|
||||
mImageContainerForWR->SetCurrentImageInTransaction(image);
|
||||
|
||||
if (!mImageClient->UpdateImage(mImageContainerForWR, /* unused */0)) {
|
||||
return;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче