diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /gfx/layers/client/TextureRecorded.cpp | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/layers/client/TextureRecorded.cpp')
-rw-r--r-- | gfx/layers/client/TextureRecorded.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/gfx/layers/client/TextureRecorded.cpp b/gfx/layers/client/TextureRecorded.cpp new file mode 100644 index 0000000000..3a88a6addd --- /dev/null +++ b/gfx/layers/client/TextureRecorded.cpp @@ -0,0 +1,122 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 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 "TextureRecorded.h" + +#include "RecordedCanvasEventImpl.h" + +namespace mozilla { +namespace layers { + +// The texture ID is used in the GPU process both to lookup the real texture in +// the canvas threads and to lookup the SurfaceDescriptor for that texture in +// the compositor thread. It is therefore important that the ID is unique (per +// recording process), otherwise an old descriptor can be picked up. This means +// we can't use the pointer in the recording process as an ID like we do for +// other objects. +static int64_t sNextRecordedTextureId = 0; + +RecordedTextureData::RecordedTextureData( + already_AddRefed<CanvasChild> aCanvasChild, gfx::IntSize aSize, + gfx::SurfaceFormat aFormat, TextureType aTextureType) + : mCanvasChild(aCanvasChild), mSize(aSize), mFormat(aFormat) { + mCanvasChild->EnsureRecorder(aTextureType); +} + +RecordedTextureData::~RecordedTextureData() { + // We need the translator to drop its reference for the DrawTarget first, + // because the TextureData might need to destroy its DrawTarget within a lock. + mDT = nullptr; + mCanvasChild->RecordEvent(RecordedTextureDestruction(mTextureId)); +} + +void RecordedTextureData::FillInfo(TextureData::Info& aInfo) const { + aInfo.size = mSize; + aInfo.format = mFormat; + aInfo.supportsMoz2D = true; + aInfo.hasSynchronization = true; +} + +bool RecordedTextureData::Lock(OpenMode aMode) { + mCanvasChild->EnsureBeginTransaction(); + if (!mDT) { + mTextureId = sNextRecordedTextureId++; + mCanvasChild->RecordEvent(RecordedNextTextureId(mTextureId)); + mDT = mCanvasChild->CreateDrawTarget(mSize, mFormat); + if (!mDT) { + return false; + } + + // We lock the TextureData when we create it to get the remote DrawTarget. + mCanvasChild->OnTextureWriteLock(); + mLockedMode = aMode; + return true; + } + + mCanvasChild->RecordEvent(RecordedTextureLock(mTextureId, aMode)); + if (aMode & OpenMode::OPEN_WRITE) { + mCanvasChild->OnTextureWriteLock(); + } + mLockedMode = aMode; + return true; +} + +void RecordedTextureData::Unlock() { + if ((mLockedMode == OpenMode::OPEN_READ_WRITE) && + mCanvasChild->ShouldCacheDataSurface()) { + mSnapshot = mDT->Snapshot(); + mDT->DetachAllSnapshots(); + mCanvasChild->RecordEvent(RecordedCacheDataSurface(mSnapshot.get())); + } + + mCanvasChild->RecordEvent(RecordedTextureUnlock(mTextureId)); + mLockedMode = OpenMode::OPEN_NONE; +} + +already_AddRefed<gfx::DrawTarget> RecordedTextureData::BorrowDrawTarget() { + mSnapshot = nullptr; + return do_AddRef(mDT); +} + +void RecordedTextureData::EndDraw() { + MOZ_ASSERT(mDT->hasOneRef()); + MOZ_ASSERT(mLockedMode == OpenMode::OPEN_READ_WRITE); + + if (mCanvasChild->ShouldCacheDataSurface()) { + mSnapshot = mDT->Snapshot(); + mCanvasChild->RecordEvent(RecordedCacheDataSurface(mSnapshot.get())); + } +} + +already_AddRefed<gfx::SourceSurface> RecordedTextureData::BorrowSnapshot() { + MOZ_ASSERT(mDT); + + if (mSnapshot) { + return mCanvasChild->WrapSurface(mSnapshot); + } + + return mCanvasChild->WrapSurface(mDT->Snapshot()); +} + +void RecordedTextureData::Deallocate(LayersIPCChannel* aAllocator) {} + +bool RecordedTextureData::Serialize(SurfaceDescriptor& aDescriptor) { + aDescriptor = SurfaceDescriptorRecorded(mTextureId); + return true; +} + +void RecordedTextureData::OnForwardedToHost() { + mCanvasChild->OnTextureForwarded(); +} + +TextureFlags RecordedTextureData::GetTextureFlags() const { + // With WebRender, resource open happens asynchronously on RenderThread. + // Use WAIT_HOST_USAGE_END to keep TextureClient alive during host side usage. + return TextureFlags::WAIT_HOST_USAGE_END; +} + +} // namespace layers +} // namespace mozilla |