2022-06-29 12:32:29 +03:00
|
|
|
/* -*- 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 "mozilla/layers/RemoteTextureMap.h"
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2022-12-23 23:41:02 +03:00
|
|
|
#include "CompositableHost.h"
|
2022-12-07 05:24:57 +03:00
|
|
|
#include "mozilla/gfx/gfxVars.h"
|
2022-06-29 12:32:29 +03:00
|
|
|
#include "mozilla/layers/AsyncImagePipelineManager.h"
|
|
|
|
#include "mozilla/layers/BufferTexture.h"
|
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
2022-12-23 23:41:02 +03:00
|
|
|
#include "mozilla/layers/ImageDataSerializer.h"
|
2022-09-07 03:58:34 +03:00
|
|
|
#include "mozilla/layers/RemoteTextureHostWrapper.h"
|
2022-06-29 12:32:29 +03:00
|
|
|
#include "mozilla/layers/WebRenderTextureHost.h"
|
2022-09-07 03:58:34 +03:00
|
|
|
#include "mozilla/StaticPrefs_webgl.h"
|
2022-12-07 05:24:57 +03:00
|
|
|
#include "mozilla/webrender/RenderThread.h"
|
2022-06-29 12:32:29 +03:00
|
|
|
#include "SharedSurface.h"
|
|
|
|
|
|
|
|
namespace mozilla::layers {
|
|
|
|
|
|
|
|
RemoteTextureOwnerClient::RemoteTextureOwnerClient(
|
|
|
|
const base::ProcessId aForPid)
|
|
|
|
: mForPid(aForPid) {}
|
|
|
|
|
|
|
|
RemoteTextureOwnerClient::~RemoteTextureOwnerClient() = default;
|
|
|
|
|
|
|
|
bool RemoteTextureOwnerClient::IsRegistered(
|
|
|
|
const RemoteTextureOwnerId aOwnerId) {
|
|
|
|
auto it = mOwnerIds.find(aOwnerId);
|
|
|
|
if (it == mOwnerIds.end()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteTextureOwnerClient::RegisterTextureOwner(
|
2022-12-23 23:41:02 +03:00
|
|
|
const RemoteTextureOwnerId aOwnerId, bool aIsSyncMode) {
|
2022-06-29 12:32:29 +03:00
|
|
|
MOZ_ASSERT(mOwnerIds.find(aOwnerId) == mOwnerIds.end());
|
|
|
|
mOwnerIds.emplace(aOwnerId);
|
2022-12-23 23:41:02 +03:00
|
|
|
RemoteTextureMap::Get()->RegisterTextureOwner(aOwnerId, mForPid, aIsSyncMode);
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteTextureOwnerClient::UnregisterTextureOwner(
|
|
|
|
const RemoteTextureOwnerId aOwnerId) {
|
|
|
|
auto it = mOwnerIds.find(aOwnerId);
|
|
|
|
if (it == mOwnerIds.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mOwnerIds.erase(it);
|
|
|
|
RemoteTextureMap::Get()->UnregisterTextureOwner(aOwnerId, mForPid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteTextureOwnerClient::UnregisterAllTextureOwners() {
|
|
|
|
if (!mOwnerIds.empty()) {
|
|
|
|
RemoteTextureMap::Get()->UnregisterTextureOwners(mOwnerIds, mForPid);
|
|
|
|
mOwnerIds.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-12 09:56:19 +03:00
|
|
|
void RemoteTextureOwnerClient::PushTexture(
|
2022-06-29 12:32:29 +03:00
|
|
|
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId,
|
|
|
|
UniquePtr<TextureData>&& aTextureData,
|
|
|
|
const std::shared_ptr<gl::SharedSurface>& aSharedSurface) {
|
|
|
|
MOZ_ASSERT(IsRegistered(aOwnerId));
|
2023-01-12 01:23:01 +03:00
|
|
|
|
|
|
|
RefPtr<TextureHost> textureHost = RemoteTextureMap::CreateRemoteTexture(
|
|
|
|
aTextureData.get(), TextureFlags::DEFAULT);
|
|
|
|
if (!textureHost) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoteTextureMap::Get()->PushTexture(aTextureId, aOwnerId, mForPid,
|
|
|
|
std::move(aTextureData), textureHost,
|
|
|
|
aSharedSurface);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteTextureOwnerClient::PushDummyTexture(
|
|
|
|
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId) {
|
|
|
|
MOZ_ASSERT(IsRegistered(aOwnerId));
|
|
|
|
|
|
|
|
auto flags = TextureFlags::DEALLOCATE_CLIENT | TextureFlags::REMOTE_TEXTURE |
|
|
|
|
TextureFlags::DUMMY_TEXTURE;
|
|
|
|
auto* rawData = BufferTextureData::Create(
|
|
|
|
gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8A8, gfx::BackendType::SKIA,
|
|
|
|
LayersBackend::LAYERS_WR, flags, ALLOC_DEFAULT, nullptr);
|
|
|
|
if (!rawData) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto textureData = UniquePtr<TextureData>(rawData);
|
|
|
|
|
|
|
|
RefPtr<TextureHost> textureHost = RemoteTextureMap::CreateRemoteTexture(
|
|
|
|
textureData.get(), TextureFlags::DUMMY_TEXTURE);
|
|
|
|
if (!textureHost) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-12 09:56:19 +03:00
|
|
|
RemoteTextureMap::Get()->PushTexture(aTextureId, aOwnerId, mForPid,
|
2023-01-12 01:23:01 +03:00
|
|
|
std::move(textureData), textureHost,
|
|
|
|
/* aSharedSurface */ nullptr);
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
2022-12-23 23:41:02 +03:00
|
|
|
void RemoteTextureOwnerClient::GetLatestBufferSnapshot(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, const ipc::Shmem& aDestShmem,
|
|
|
|
const gfx::IntSize& aSize) {
|
|
|
|
MOZ_ASSERT(IsRegistered(aOwnerId));
|
|
|
|
RemoteTextureMap::Get()->GetLatestBufferSnapshot(aOwnerId, mForPid,
|
|
|
|
aDestShmem, aSize);
|
|
|
|
}
|
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
UniquePtr<TextureData>
|
|
|
|
RemoteTextureOwnerClient::CreateOrRecycleBufferTextureData(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, gfx::IntSize aSize,
|
|
|
|
gfx::SurfaceFormat aFormat) {
|
2022-09-07 03:58:34 +03:00
|
|
|
auto texture = RemoteTextureMap::Get()->GetRecycledBufferTextureData(
|
|
|
|
aOwnerId, mForPid, aSize, aFormat);
|
2022-06-29 12:32:29 +03:00
|
|
|
if (texture) {
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
|
2022-07-12 09:56:21 +03:00
|
|
|
auto flags = TextureFlags::DEALLOCATE_CLIENT | TextureFlags::REMOTE_TEXTURE;
|
|
|
|
auto* data = BufferTextureData::Create(aSize, aFormat, gfx::BackendType::SKIA,
|
|
|
|
LayersBackend::LAYERS_WR, flags,
|
|
|
|
ALLOC_DEFAULT, nullptr);
|
2022-06-29 12:32:29 +03:00
|
|
|
return UniquePtr<TextureData>(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<gl::SharedSurface>
|
|
|
|
RemoteTextureOwnerClient::GetRecycledSharedSurface(
|
|
|
|
const RemoteTextureOwnerId aOwnerId) {
|
|
|
|
return RemoteTextureMap::Get()->RemoteTextureMap::GetRecycledSharedSurface(
|
|
|
|
aOwnerId, mForPid);
|
|
|
|
}
|
|
|
|
|
|
|
|
StaticAutoPtr<RemoteTextureMap> RemoteTextureMap::sInstance;
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
void RemoteTextureMap::Init() {
|
|
|
|
MOZ_ASSERT(!sInstance);
|
|
|
|
sInstance = new RemoteTextureMap();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
void RemoteTextureMap::Shutdown() {
|
|
|
|
if (sInstance) {
|
|
|
|
sInstance = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
RemoteTextureMap::RemoteTextureMap() : mMonitor("D3D11TextureMap::mMonitor") {}
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
RemoteTextureMap::~RemoteTextureMap() = default;
|
|
|
|
|
2022-07-12 09:56:19 +03:00
|
|
|
void RemoteTextureMap::PushTexture(
|
2022-06-29 12:32:29 +03:00
|
|
|
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId,
|
|
|
|
const base::ProcessId aForPid, UniquePtr<TextureData>&& aTextureData,
|
2023-01-12 01:23:01 +03:00
|
|
|
RefPtr<TextureHost>& aTextureHost,
|
2022-06-29 12:32:29 +03:00
|
|
|
const std::shared_ptr<gl::SharedSurface>& aSharedSurface) {
|
2023-01-12 01:23:01 +03:00
|
|
|
MOZ_RELEASE_ASSERT(aTextureHost);
|
2022-09-07 03:58:34 +03:00
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
std::vector<std::function<void(const RemoteTextureInfo&)>>
|
2023-04-06 08:27:08 +03:00
|
|
|
renderingReadyCallbacks; // Call outside the monitor
|
2022-06-29 12:32:29 +03:00
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
|
|
|
if (!owner) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-12-23 23:41:02 +03:00
|
|
|
const auto key = std::pair(aForPid, aOwnerId);
|
|
|
|
auto it = mRemoteTexturePushListeners.find(key);
|
|
|
|
// Notify a new texture if callback is requested
|
|
|
|
if (it != mRemoteTexturePushListeners.end()) {
|
|
|
|
RefPtr<CompositableHost> compositableHost = it->second;
|
|
|
|
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
|
|
|
"RemoteTextureMap::PushTexture::Runnable",
|
|
|
|
[compositableHost, aTextureId, aOwnerId, aForPid]() {
|
|
|
|
compositableHost->NotifyPushTexture(aTextureId, aOwnerId, aForPid);
|
|
|
|
});
|
|
|
|
CompositorThread()->Dispatch(runnable.forget());
|
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
auto textureData = MakeUnique<TextureDataHolder>(
|
2023-01-12 01:23:01 +03:00
|
|
|
aTextureId, aTextureHost, std::move(aTextureData), aSharedSurface);
|
2022-09-07 03:58:34 +03:00
|
|
|
|
|
|
|
MOZ_ASSERT(owner->mLatestTextureId < aTextureId);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
owner->mWaitingTextureDataHolders.push_back(std::move(textureData));
|
|
|
|
|
2022-12-23 23:41:02 +03:00
|
|
|
if (!owner->mIsSyncMode) {
|
2023-04-06 08:27:08 +03:00
|
|
|
renderingReadyCallbacks =
|
|
|
|
GetRenderingReadyCallbacks(lock, owner, aTextureId);
|
2022-12-07 05:24:57 +03:00
|
|
|
// Update mAsyncRemoteTextureHost for async mode.
|
|
|
|
// This happens when PushTexture() with RemoteTextureId is called after
|
|
|
|
// GetRemoteTextureForDisplayList() with the RemoteTextureId.
|
|
|
|
const auto key = std::pair(aForPid, aTextureId);
|
|
|
|
auto it = mRemoteTextureHostWrapperHolders.find(key);
|
|
|
|
if (it != mRemoteTextureHostWrapperHolders.end()) {
|
|
|
|
MOZ_ASSERT(!it->second->mAsyncRemoteTextureHost);
|
2023-01-12 01:23:01 +03:00
|
|
|
it->second->mAsyncRemoteTextureHost = aTextureHost;
|
2023-04-06 08:27:08 +03:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(renderingReadyCallbacks.empty());
|
2022-12-07 05:24:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mMonitor.Notify();
|
2022-09-07 03:58:34 +03:00
|
|
|
|
|
|
|
// Drop obsoleted remote textures.
|
|
|
|
while (!owner->mUsingTextureDataHolders.empty()) {
|
|
|
|
auto& front = owner->mUsingTextureDataHolders.front();
|
|
|
|
// When compositable ref of TextureHost becomes 0, the TextureHost is not
|
|
|
|
// used by WebRender anymore.
|
|
|
|
if (front->mTextureHost &&
|
|
|
|
front->mTextureHost->NumCompositableRefs() == 0) {
|
|
|
|
// Recycle gl::SharedSurface
|
|
|
|
if (front->mSharedSurface) {
|
|
|
|
owner->mRecycledSharedSurfaces.push(front->mSharedSurface);
|
|
|
|
front->mSharedSurface = nullptr;
|
|
|
|
}
|
|
|
|
// Recycle BufferTextureData
|
2023-01-12 01:23:01 +03:00
|
|
|
if (!(front->mTextureHost->GetFlags() & TextureFlags::DUMMY_TEXTURE) &&
|
|
|
|
(front->mTextureData &&
|
|
|
|
front->mTextureData->AsBufferTextureData())) {
|
2022-09-07 03:58:34 +03:00
|
|
|
owner->mRecycledTextures.push(std::move(front->mTextureData));
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
2022-09-08 17:27:44 +03:00
|
|
|
owner->mUsingTextureDataHolders.pop_front();
|
2022-09-07 03:58:34 +03:00
|
|
|
} else if (front->mTextureHost &&
|
|
|
|
front->mTextureHost->NumCompositableRefs() >= 0) {
|
|
|
|
// Remote texture is still in use by WebRender.
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
2022-09-08 17:27:44 +03:00
|
|
|
owner->mUsingTextureDataHolders.pop_front();
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-06 08:27:08 +03:00
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
const auto info = RemoteTextureInfo(aTextureId, aOwnerId, aForPid);
|
2023-04-06 08:27:08 +03:00
|
|
|
for (auto& callback : renderingReadyCallbacks) {
|
2023-04-14 00:38:24 +03:00
|
|
|
callback(info);
|
2023-04-06 08:27:08 +03:00
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
2022-12-23 23:41:02 +03:00
|
|
|
void RemoteTextureMap::GetLatestBufferSnapshot(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
|
|
|
const ipc::Shmem& aDestShmem, const gfx::IntSize& aSize) {
|
|
|
|
// The compositable ref of remote texture should be updated in mMonitor lock.
|
|
|
|
CompositableTextureHostRef textureHostRef;
|
|
|
|
RefPtr<TextureHost> releasingTexture; // Release outside the monitor
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mMonitor);
|
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
|
|
|
if (!owner) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get latest TextureHost of remote Texture.
|
|
|
|
if (owner->mWaitingTextureDataHolders.empty() &&
|
|
|
|
!owner->mLatestTextureHost) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
TextureHost* textureHost =
|
|
|
|
!owner->mWaitingTextureDataHolders.empty()
|
|
|
|
? owner->mWaitingTextureDataHolders.back()->mTextureHost
|
|
|
|
: owner->mLatestTextureHost;
|
|
|
|
if (!textureHost->AsBufferTextureHost()) {
|
|
|
|
// Only BufferTextureHost is supported for now.
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (textureHost->GetSize() != aSize) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (textureHost->GetFormat() != gfx::SurfaceFormat::R8G8B8A8 &&
|
|
|
|
textureHost->GetFormat() != gfx::SurfaceFormat::B8G8R8A8) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Increment compositable ref to prevent that TextureHost is removed during
|
|
|
|
// memcpy.
|
|
|
|
textureHostRef = textureHost;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!textureHostRef) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto* bufferTextureHost = textureHostRef->AsBufferTextureHost();
|
|
|
|
if (bufferTextureHost) {
|
|
|
|
uint32_t stride = ImageDataSerializer::ComputeRGBStride(
|
|
|
|
bufferTextureHost->GetFormat(), aSize.width);
|
|
|
|
uint32_t bufferSize = stride * aSize.height;
|
|
|
|
uint8_t* dst = aDestShmem.get<uint8_t>();
|
|
|
|
uint8_t* src = bufferTextureHost->GetBuffer();
|
|
|
|
|
|
|
|
MOZ_ASSERT(bufferSize <= aDestShmem.Size<uint8_t>());
|
|
|
|
memcpy(dst, src, bufferSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mMonitor);
|
|
|
|
// Release compositable ref in mMonitor lock, but release RefPtr outside the
|
|
|
|
// monitor
|
|
|
|
releasingTexture = textureHostRef;
|
|
|
|
textureHostRef = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
void RemoteTextureMap::RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId,
|
2022-12-23 23:41:02 +03:00
|
|
|
const base::ProcessId aForPid,
|
|
|
|
bool aIsSyncMode) {
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
const auto key = std::pair(aForPid, aOwnerId);
|
|
|
|
auto it = mTextureOwners.find(key);
|
|
|
|
if (it != mTextureOwners.end()) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto owner = MakeUnique<TextureOwner>();
|
2022-12-23 23:41:02 +03:00
|
|
|
owner->mIsSyncMode = aIsSyncMode;
|
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
mTextureOwners.emplace(key, std::move(owner));
|
|
|
|
}
|
|
|
|
|
2022-09-08 17:27:44 +03:00
|
|
|
void RemoteTextureMap::KeepTextureDataAliveForTextureHostIfNecessary(
|
2022-12-07 05:24:57 +03:00
|
|
|
const MonitorAutoLock& aProofOfLock,
|
2022-09-08 17:27:44 +03:00
|
|
|
std::deque<UniquePtr<TextureDataHolder>>& aHolders) {
|
|
|
|
for (auto& holder : aHolders) {
|
|
|
|
// If remote texture of TextureHost still exist, keep
|
|
|
|
// gl::SharedSurface/TextureData alive while the TextureHost is alive.
|
|
|
|
if (holder->mTextureHost &&
|
|
|
|
holder->mTextureHost->NumCompositableRefs() >= 0) {
|
|
|
|
RefPtr<nsISerialEventTarget> eventTarget =
|
|
|
|
MessageLoop::current()->SerialEventTarget();
|
|
|
|
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
|
|
|
"RemoteTextureMap::UnregisterTextureOwner::Runnable",
|
|
|
|
[data = std::move(holder->mTextureData),
|
|
|
|
surface = std::move(holder->mSharedSurface)]() {});
|
|
|
|
|
|
|
|
auto destroyedCallback = [eventTarget = std::move(eventTarget),
|
|
|
|
runnable = std::move(runnable)]() mutable {
|
|
|
|
eventTarget->Dispatch(runnable.forget());
|
|
|
|
};
|
|
|
|
|
|
|
|
holder->mTextureHost->SetDestroyedCallback(destroyedCallback);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
void RemoteTextureMap::UnregisterTextureOwner(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid) {
|
2022-12-07 05:24:57 +03:00
|
|
|
UniquePtr<TextureOwner> releasingOwner; // Release outside the monitor
|
2023-04-06 08:27:08 +03:00
|
|
|
std::vector<RefPtr<TextureHost>>
|
|
|
|
releasingTextures; // Release outside the monitor
|
2023-04-14 00:38:24 +03:00
|
|
|
std::vector<std::function<void(const RemoteTextureInfo&)>>
|
2023-04-06 08:27:08 +03:00
|
|
|
renderingReadyCallbacks; // Call outside the monitor
|
2022-06-29 12:32:29 +03:00
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
const auto key = std::pair(aForPid, aOwnerId);
|
|
|
|
auto it = mTextureOwners.find(key);
|
|
|
|
if (it == mTextureOwners.end()) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
2022-09-08 17:27:44 +03:00
|
|
|
|
2022-09-12 06:49:02 +03:00
|
|
|
if (it->second->mLatestTextureHost) {
|
2022-12-07 05:24:57 +03:00
|
|
|
// Release CompositableRef in mMonitor
|
2023-04-06 08:27:08 +03:00
|
|
|
releasingTextures.emplace_back(it->second->mLatestTextureHost);
|
2022-09-12 06:49:02 +03:00
|
|
|
it->second->mLatestTextureHost = nullptr;
|
|
|
|
}
|
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
if (it->second->mLatestRenderedTextureHost) {
|
|
|
|
// Release CompositableRef in mMonitor
|
|
|
|
releasingTextures.emplace_back(it->second->mLatestRenderedTextureHost);
|
|
|
|
it->second->mLatestRenderedTextureHost = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
renderingReadyCallbacks =
|
|
|
|
GetAllRenderingReadyCallbacks(lock, it->second.get());
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
KeepTextureDataAliveForTextureHostIfNecessary(
|
|
|
|
lock, it->second->mWaitingTextureDataHolders);
|
|
|
|
|
2022-09-08 17:27:44 +03:00
|
|
|
KeepTextureDataAliveForTextureHostIfNecessary(
|
|
|
|
lock, it->second->mUsingTextureDataHolders);
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
releasingOwner = std::move(it->second);
|
2022-06-29 12:32:29 +03:00
|
|
|
mTextureOwners.erase(it);
|
2022-12-07 05:24:57 +03:00
|
|
|
|
|
|
|
mMonitor.Notify();
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
2023-04-06 08:27:08 +03:00
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
const auto info =
|
|
|
|
RemoteTextureInfo(RemoteTextureId{0}, RemoteTextureOwnerId{0}, 0);
|
2023-04-06 08:27:08 +03:00
|
|
|
for (auto& callback : renderingReadyCallbacks) {
|
2023-04-14 00:38:24 +03:00
|
|
|
callback(info);
|
2023-04-06 08:27:08 +03:00
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteTextureMap::UnregisterTextureOwners(
|
|
|
|
const std::unordered_set<RemoteTextureOwnerId,
|
|
|
|
RemoteTextureOwnerId::HashFn>& aOwnerIds,
|
|
|
|
const base::ProcessId aForPid) {
|
2022-09-07 03:58:34 +03:00
|
|
|
std::vector<UniquePtr<TextureOwner>>
|
2022-12-07 05:24:57 +03:00
|
|
|
releasingOwners; // Release outside the monitor
|
2022-09-12 06:49:02 +03:00
|
|
|
std::vector<RefPtr<TextureHost>>
|
2022-12-07 05:24:57 +03:00
|
|
|
releasingTextures; // Release outside the monitor
|
2023-04-14 00:38:24 +03:00
|
|
|
std::vector<std::function<void(const RemoteTextureInfo&)>>
|
2023-04-06 08:27:08 +03:00
|
|
|
renderingReadyCallbacks; // Call outside the monitor
|
2022-06-29 12:32:29 +03:00
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
for (auto id : aOwnerIds) {
|
|
|
|
const auto key = std::pair(aForPid, id);
|
|
|
|
auto it = mTextureOwners.find(key);
|
|
|
|
if (it == mTextureOwners.end()) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
continue;
|
|
|
|
}
|
2022-09-08 17:27:44 +03:00
|
|
|
|
2022-09-12 06:49:02 +03:00
|
|
|
if (it->second->mLatestTextureHost) {
|
2022-12-07 05:24:57 +03:00
|
|
|
// Release CompositableRef in mMonitor
|
2022-09-12 06:49:02 +03:00
|
|
|
releasingTextures.emplace_back(it->second->mLatestTextureHost);
|
|
|
|
it->second->mLatestTextureHost = nullptr;
|
|
|
|
}
|
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
if (it->second->mLatestRenderedTextureHost) {
|
|
|
|
// Release CompositableRef in mMonitor
|
|
|
|
releasingTextures.emplace_back(it->second->mLatestRenderedTextureHost);
|
|
|
|
it->second->mLatestRenderedTextureHost = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
renderingReadyCallbacks =
|
|
|
|
GetAllRenderingReadyCallbacks(lock, it->second.get());
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
KeepTextureDataAliveForTextureHostIfNecessary(
|
|
|
|
lock, it->second->mWaitingTextureDataHolders);
|
|
|
|
|
2022-09-08 17:27:44 +03:00
|
|
|
KeepTextureDataAliveForTextureHostIfNecessary(
|
|
|
|
lock, it->second->mUsingTextureDataHolders);
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
releasingOwners.push_back(std::move(it->second));
|
2022-06-29 12:32:29 +03:00
|
|
|
mTextureOwners.erase(it);
|
|
|
|
}
|
2022-12-07 05:24:57 +03:00
|
|
|
|
|
|
|
mMonitor.Notify();
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
2023-04-06 08:27:08 +03:00
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
const auto info =
|
|
|
|
RemoteTextureInfo(RemoteTextureId{0}, RemoteTextureOwnerId{0}, 0);
|
2023-04-06 08:27:08 +03:00
|
|
|
for (auto& callback : renderingReadyCallbacks) {
|
2023-04-14 00:38:24 +03:00
|
|
|
callback(info);
|
2023-04-06 08:27:08 +03:00
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
/* static */
|
2022-06-29 12:32:29 +03:00
|
|
|
RefPtr<TextureHost> RemoteTextureMap::CreateRemoteTexture(
|
2023-01-12 01:23:01 +03:00
|
|
|
TextureData* aTextureData, TextureFlags aTextureFlags) {
|
2022-06-29 12:32:29 +03:00
|
|
|
SurfaceDescriptor desc;
|
2022-09-07 03:58:34 +03:00
|
|
|
DebugOnly<bool> ret = aTextureData->Serialize(desc);
|
2022-06-29 12:32:29 +03:00
|
|
|
MOZ_ASSERT(ret);
|
2023-01-12 01:23:01 +03:00
|
|
|
TextureFlags flags = aTextureFlags | TextureFlags::REMOTE_TEXTURE |
|
|
|
|
TextureFlags::DEALLOCATE_CLIENT;
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
Maybe<wr::ExternalImageId> externalImageId = Nothing();
|
2022-06-29 12:32:29 +03:00
|
|
|
RefPtr<TextureHost> textureHost =
|
|
|
|
TextureHost::Create(desc, null_t(), nullptr, LayersBackend::LAYERS_WR,
|
|
|
|
flags, externalImageId);
|
|
|
|
MOZ_ASSERT(textureHost);
|
|
|
|
if (!textureHost) {
|
|
|
|
gfxCriticalNoteOnce << "Failed to create remote texture";
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
textureHost->EnsureRenderTexture(Nothing());
|
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
return textureHost;
|
|
|
|
}
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
void RemoteTextureMap::UpdateTexture(const MonitorAutoLock& aProofOfLock,
|
2022-09-07 03:58:34 +03:00
|
|
|
RemoteTextureMap::TextureOwner* aOwner,
|
|
|
|
const RemoteTextureId aTextureId) {
|
2022-06-29 12:32:29 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2022-09-07 03:58:34 +03:00
|
|
|
MOZ_ASSERT(aOwner);
|
|
|
|
MOZ_ASSERT(aTextureId >= aOwner->mLatestTextureId);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
if (aTextureId == aOwner->mLatestTextureId) {
|
|
|
|
// No need to update texture.
|
|
|
|
return;
|
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
// Move remote textures to mUsingTextureDataHolders.
|
|
|
|
while (!aOwner->mWaitingTextureDataHolders.empty()) {
|
|
|
|
auto& front = aOwner->mWaitingTextureDataHolders.front();
|
|
|
|
if (aTextureId < front->mTextureId) {
|
|
|
|
break;
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
2022-09-07 03:58:34 +03:00
|
|
|
MOZ_RELEASE_ASSERT(front->mTextureHost);
|
|
|
|
aOwner->mLatestTextureHost = front->mTextureHost;
|
|
|
|
aOwner->mLatestTextureId = front->mTextureId;
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
UniquePtr<TextureDataHolder> holder = std::move(front);
|
2022-12-07 05:24:57 +03:00
|
|
|
aOwner->mWaitingTextureDataHolders.pop_front();
|
2022-09-08 17:27:44 +03:00
|
|
|
aOwner->mUsingTextureDataHolders.push_back(std::move(holder));
|
2022-09-07 03:58:34 +03:00
|
|
|
}
|
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
std::vector<std::function<void(const RemoteTextureInfo&)>>
|
2023-04-06 08:27:08 +03:00
|
|
|
RemoteTextureMap::GetRenderingReadyCallbacks(
|
|
|
|
const MonitorAutoLock& aProofOfLock, RemoteTextureMap::TextureOwner* aOwner,
|
|
|
|
const RemoteTextureId aTextureId) {
|
|
|
|
MOZ_ASSERT(aOwner);
|
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
std::vector<std::function<void(const RemoteTextureInfo&)>> functions;
|
2023-04-06 08:27:08 +03:00
|
|
|
|
|
|
|
while (!aOwner->mRenderingReadyCallbackHolders.empty()) {
|
|
|
|
auto& front = aOwner->mRenderingReadyCallbackHolders.front();
|
|
|
|
if (aTextureId < front->mTextureId) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (front->mCallback) {
|
|
|
|
functions.push_back(std::move(front->mCallback));
|
|
|
|
}
|
|
|
|
aOwner->mRenderingReadyCallbackHolders.pop_front();
|
|
|
|
}
|
|
|
|
|
|
|
|
return functions;
|
|
|
|
}
|
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
std::vector<std::function<void(const RemoteTextureInfo&)>>
|
2023-04-06 08:27:08 +03:00
|
|
|
RemoteTextureMap::GetAllRenderingReadyCallbacks(
|
|
|
|
const MonitorAutoLock& aProofOfLock,
|
|
|
|
RemoteTextureMap::TextureOwner* aOwner) {
|
|
|
|
auto functions =
|
|
|
|
GetRenderingReadyCallbacks(aProofOfLock, aOwner, RemoteTextureId::Max());
|
|
|
|
MOZ_ASSERT(aOwner->mRenderingReadyCallbackHolders.empty());
|
|
|
|
|
|
|
|
return functions;
|
|
|
|
}
|
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
bool RemoteTextureMap::GetRemoteTextureForDisplayList(
|
|
|
|
RemoteTextureHostWrapper* aTextureHostWrapper,
|
|
|
|
std::function<void(const RemoteTextureInfo&)>&& aReadyCallback) {
|
2022-09-07 03:58:34 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
MOZ_ASSERT(aTextureHostWrapper);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
if (aTextureHostWrapper->IsReadyForRendering()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
const auto& textureId = aTextureHostWrapper->mTextureId;
|
|
|
|
const auto& ownerId = aTextureHostWrapper->mOwnerId;
|
|
|
|
const auto& forPid = aTextureHostWrapper->mForPid;
|
|
|
|
const auto& size = aTextureHostWrapper->mSize;
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
RefPtr<TextureHost> textureHost;
|
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-09-07 03:58:34 +03:00
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, ownerId, forPid);
|
|
|
|
if (!owner) {
|
2023-04-14 00:38:24 +03:00
|
|
|
return false;
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
UpdateTexture(lock, owner, textureId);
|
|
|
|
|
2023-01-12 01:23:01 +03:00
|
|
|
if (owner->mLatestTextureHost &&
|
|
|
|
(owner->mLatestTextureHost->GetFlags() & TextureFlags::DUMMY_TEXTURE)) {
|
|
|
|
// Remote texture allocation was failed.
|
2023-04-14 00:38:24 +03:00
|
|
|
return false;
|
2023-01-12 01:23:01 +03:00
|
|
|
}
|
|
|
|
|
2023-04-14 00:38:24 +03:00
|
|
|
bool syncMode = owner->mIsSyncMode || bool(aReadyCallback);
|
|
|
|
|
|
|
|
if (syncMode) {
|
2022-09-07 03:58:34 +03:00
|
|
|
// remote texture sync ipc
|
|
|
|
if (textureId == owner->mLatestTextureId) {
|
|
|
|
MOZ_ASSERT(owner->mLatestTextureHost);
|
|
|
|
MOZ_ASSERT(owner->mLatestTextureHost->GetSize() == size);
|
2022-11-05 07:14:31 +03:00
|
|
|
if (owner->mLatestTextureHost->GetSize() != size) {
|
|
|
|
gfxCriticalNoteOnce << "unexpected remote texture size: "
|
|
|
|
<< owner->mLatestTextureHost->GetSize()
|
|
|
|
<< " expected: " << size;
|
|
|
|
}
|
2022-09-07 03:58:34 +03:00
|
|
|
textureHost = owner->mLatestTextureHost;
|
|
|
|
} else {
|
2023-04-14 00:38:24 +03:00
|
|
|
if (aReadyCallback) {
|
|
|
|
auto callbackHolder = MakeUnique<RenderingReadyCallbackHolder>(
|
|
|
|
textureId, std::move(aReadyCallback));
|
|
|
|
owner->mRenderingReadyCallbackHolders.push_back(
|
|
|
|
std::move(callbackHolder));
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
}
|
2022-09-07 03:58:34 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// remote texture async ipc
|
2022-12-07 05:24:57 +03:00
|
|
|
if (owner->mLatestTextureHost) {
|
|
|
|
if (owner->mLatestTextureHost->GetSize() == size) {
|
|
|
|
textureHost = owner->mLatestTextureHost;
|
|
|
|
} else {
|
|
|
|
gfxCriticalNoteOnce << "unexpected remote texture size: "
|
|
|
|
<< owner->mLatestTextureHost->GetSize()
|
|
|
|
<< " expected: " << size;
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
gfxCriticalNoteOnce << "remote texture does not exist";
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update mAsyncRemoteTextureHost for async mode
|
|
|
|
if (textureId == owner->mLatestTextureId) {
|
|
|
|
const auto key = std::pair(forPid, textureId);
|
|
|
|
auto it = mRemoteTextureHostWrapperHolders.find(key);
|
|
|
|
if (it != mRemoteTextureHostWrapperHolders.end() &&
|
|
|
|
!it->second->mAsyncRemoteTextureHost) {
|
|
|
|
it->second->mAsyncRemoteTextureHost = owner->mLatestTextureHost;
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(it->second->mAsyncRemoteTextureHost ==
|
|
|
|
owner->mLatestTextureHost);
|
|
|
|
}
|
2022-09-07 03:58:34 +03:00
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
if (textureHost) {
|
2023-04-14 00:38:24 +03:00
|
|
|
aTextureHostWrapper->SetRemoteTextureHostForDisplayList(lock, textureHost,
|
|
|
|
syncMode);
|
2022-09-07 03:58:34 +03:00
|
|
|
aTextureHostWrapper->ApplyTextureFlagsToRemoteTexture();
|
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
2023-04-14 00:38:24 +03:00
|
|
|
|
|
|
|
return false;
|
2022-09-07 03:58:34 +03:00
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
wr::MaybeExternalImageId RemoteTextureMap::GetExternalImageIdOfRemoteTexture(
|
2022-12-07 05:24:57 +03:00
|
|
|
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId,
|
|
|
|
const base::ProcessId aForPid) {
|
|
|
|
MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
|
|
|
|
MonitorAutoLock lock(mMonitor);
|
|
|
|
|
|
|
|
const auto key = std::pair(aForPid, aTextureId);
|
|
|
|
auto it = mRemoteTextureHostWrapperHolders.find(key);
|
|
|
|
if (it == mRemoteTextureHostWrapperHolders.end()) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return Nothing();
|
|
|
|
}
|
2023-04-06 08:27:08 +03:00
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
TextureHost* remoteTexture = it->second->mAsyncRemoteTextureHost;
|
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
|
|
|
if (!owner) {
|
|
|
|
if (!remoteTexture) {
|
|
|
|
// This could happen with IPC abnormal shutdown
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
return remoteTexture->GetMaybeExternalImageId();
|
|
|
|
}
|
2023-04-11 06:04:02 +03:00
|
|
|
|
|
|
|
if (remoteTexture &&
|
|
|
|
remoteTexture->GetFlags() & TextureFlags::DUMMY_TEXTURE) {
|
|
|
|
// Remote texture allocation was failed.
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(!(remoteTexture &&
|
|
|
|
remoteTexture->GetFlags() & TextureFlags::DUMMY_TEXTURE));
|
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
MOZ_ASSERT(owner);
|
2022-12-07 05:24:57 +03:00
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
if (!remoteTexture) {
|
|
|
|
// Use mLatestRenderedTextureHost for rendering. Remote texture of
|
|
|
|
// aTextureId does not exist.
|
|
|
|
remoteTexture = owner->mLatestRenderedTextureHost;
|
2022-12-07 05:24:57 +03:00
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
gfxCriticalNoteOnce << "remote texture for rendering does not exist id:"
|
|
|
|
<< uint64_t(aTextureId);
|
|
|
|
} else {
|
|
|
|
// Update mLatestRenderedTextureHost
|
|
|
|
owner->mLatestRenderedTextureHost = remoteTexture;
|
2022-12-07 05:24:57 +03:00
|
|
|
}
|
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
if (!remoteTexture) {
|
2023-01-12 01:23:01 +03:00
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
return remoteTexture->GetMaybeExternalImageId();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteTextureMap::ReleaseRemoteTextureHostForDisplayList(
|
2022-09-07 03:58:34 +03:00
|
|
|
RemoteTextureHostWrapper* aTextureHostWrapper) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
MOZ_ASSERT(aTextureHostWrapper);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
RefPtr<TextureHost> releasingTexture; // Release outside the mutex
|
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
|
|
|
releasingTexture =
|
|
|
|
aTextureHostWrapper->GetRemoteTextureHostForDisplayList(lock);
|
2022-12-23 23:41:02 +03:00
|
|
|
aTextureHostWrapper->ClearRemoteTextureHostForDisplayList(lock);
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
RefPtr<TextureHost> RemoteTextureMap::GetOrCreateRemoteTextureHostWrapper(
|
|
|
|
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId,
|
|
|
|
const base::ProcessId aForPid, const gfx::IntSize aSize,
|
|
|
|
const TextureFlags aFlags) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
const auto key = std::pair(aForPid, aTextureId);
|
2022-12-07 05:24:57 +03:00
|
|
|
auto it = mRemoteTextureHostWrapperHolders.find(key);
|
|
|
|
if (it != mRemoteTextureHostWrapperHolders.end()) {
|
|
|
|
return it->second->mRemoteTextureHostWrapper;
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
auto wrapper = RemoteTextureHostWrapper::Create(aTextureId, aOwnerId, aForPid,
|
|
|
|
aSize, aFlags);
|
|
|
|
auto wrapperHolder = MakeUnique<RemoteTextureHostWrapperHolder>(wrapper);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
mRemoteTextureHostWrapperHolders.emplace(key, std::move(wrapperHolder));
|
|
|
|
|
|
|
|
return wrapper;
|
2022-09-07 03:58:34 +03:00
|
|
|
}
|
2022-06-29 12:32:29 +03:00
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
void RemoteTextureMap::UnregisterRemoteTextureHostWrapper(
|
|
|
|
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId,
|
|
|
|
const base::ProcessId aForPid) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
std::vector<RefPtr<TextureHost>>
|
|
|
|
releasingTextures; // Release outside the monitor
|
2022-09-07 03:58:34 +03:00
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-09-07 03:58:34 +03:00
|
|
|
|
|
|
|
const auto key = std::pair(aForPid, aTextureId);
|
2022-12-07 05:24:57 +03:00
|
|
|
auto it = mRemoteTextureHostWrapperHolders.find(key);
|
|
|
|
if (it == mRemoteTextureHostWrapperHolders.end()) {
|
2022-09-07 03:58:34 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
return;
|
|
|
|
}
|
2022-12-07 05:24:57 +03:00
|
|
|
releasingTextures.emplace_back(it->second->mRemoteTextureHostWrapper);
|
|
|
|
if (it->second->mAsyncRemoteTextureHost) {
|
|
|
|
releasingTextures.emplace_back(it->second->mAsyncRemoteTextureHost);
|
|
|
|
}
|
|
|
|
|
|
|
|
mRemoteTextureHostWrapperHolders.erase(it);
|
|
|
|
mMonitor.Notify();
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-23 23:41:02 +03:00
|
|
|
void RemoteTextureMap::RegisterRemoteTexturePushListener(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
|
|
|
CompositableHost* aListener) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
|
|
|
|
RefPtr<CompositableHost>
|
|
|
|
releasingCompositableHost; // Release outside the monitor
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mMonitor);
|
|
|
|
|
|
|
|
const auto key = std::pair(aForPid, aOwnerId);
|
|
|
|
auto it = mRemoteTexturePushListeners.find(key);
|
|
|
|
// Remove obsoleted CompositableHost.
|
|
|
|
if (it != mRemoteTexturePushListeners.end()) {
|
|
|
|
releasingCompositableHost = std::move(it->second);
|
|
|
|
mRemoteTexturePushListeners.erase(it);
|
|
|
|
}
|
|
|
|
mRemoteTexturePushListeners.emplace(key, aListener);
|
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
|
|
|
if (!owner) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (owner->mWaitingTextureDataHolders.empty() &&
|
|
|
|
!owner->mLatestTextureHost) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get latest RemoteTextureId.
|
|
|
|
auto textureId = !owner->mWaitingTextureDataHolders.empty()
|
|
|
|
? owner->mWaitingTextureDataHolders.back()->mTextureId
|
|
|
|
: owner->mLatestTextureId;
|
|
|
|
|
|
|
|
// Notify the RemoteTextureId to callback
|
|
|
|
RefPtr<CompositableHost> compositableHost = aListener;
|
|
|
|
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
|
|
|
"RemoteTextureMap::RegisterRemoteTexturePushListener::Runnable",
|
|
|
|
[compositableHost, textureId, aOwnerId, aForPid]() {
|
|
|
|
compositableHost->NotifyPushTexture(textureId, aOwnerId, aForPid);
|
|
|
|
});
|
|
|
|
CompositorThread()->Dispatch(runnable.forget());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteTextureMap::UnregisterRemoteTexturePushListener(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
|
|
|
CompositableHost* aListener) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
|
|
|
|
RefPtr<CompositableHost>
|
|
|
|
releasingCompositableHost; // Release outside the monitor
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mMonitor);
|
|
|
|
|
|
|
|
const auto key = std::pair(aForPid, aOwnerId);
|
|
|
|
auto it = mRemoteTexturePushListeners.find(key);
|
|
|
|
if (it == mRemoteTexturePushListeners.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (aListener != it->second) {
|
|
|
|
// aListener was alredy obsoleted.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
releasingCompositableHost = std::move(it->second);
|
|
|
|
mRemoteTexturePushListeners.erase(it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
bool RemoteTextureMap::CheckRemoteTextureReady(
|
2023-04-14 00:38:24 +03:00
|
|
|
const RemoteTextureInfo& aInfo,
|
|
|
|
std::function<void(const RemoteTextureInfo&)>&& aCallback) {
|
2023-04-06 08:27:08 +03:00
|
|
|
MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
|
|
|
|
|
|
|
|
MonitorAutoLock lock(mMonitor);
|
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, aInfo.mOwnerId, aInfo.mForPid);
|
|
|
|
if (!owner) {
|
|
|
|
// Owner is already removed.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto key = std::pair(aInfo.mForPid, aInfo.mTextureId);
|
|
|
|
auto it = mRemoteTextureHostWrapperHolders.find(key);
|
|
|
|
if (it == mRemoteTextureHostWrapperHolders.end()) {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
gfxCriticalNoteOnce << "Remote texture does not exist id:"
|
|
|
|
<< uint64_t(aInfo.mTextureId);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (it->second->mAsyncRemoteTextureHost) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(!it->second->mAsyncRemoteTextureHost);
|
|
|
|
|
|
|
|
// Check if RemoteTextureId is as expected.
|
|
|
|
if (!owner->mRenderingReadyCallbackHolders.empty()) {
|
|
|
|
auto& front = owner->mRenderingReadyCallbackHolders.front();
|
|
|
|
MOZ_RELEASE_ASSERT(aInfo.mTextureId >= front->mTextureId);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto callbackHolder = MakeUnique<RenderingReadyCallbackHolder>(
|
|
|
|
aInfo.mTextureId, std::move(aCallback));
|
|
|
|
owner->mRenderingReadyCallbackHolders.push_back(std::move(callbackHolder));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
UniquePtr<TextureData> RemoteTextureMap::GetRecycledBufferTextureData(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
|
|
|
gfx::IntSize aSize, gfx::SurfaceFormat aFormat) {
|
2022-09-07 03:58:34 +03:00
|
|
|
std::stack<UniquePtr<TextureData>>
|
2022-12-07 05:24:57 +03:00
|
|
|
releasingTextures; // Release outside the monitor
|
2022-06-29 12:32:29 +03:00
|
|
|
UniquePtr<TextureData> texture;
|
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
|
|
|
if (!owner) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (owner->mRecycledTextures.empty()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!owner->mRecycledTextures.empty()) {
|
|
|
|
auto& top = owner->mRecycledTextures.top();
|
|
|
|
auto* bufferTexture = top->AsBufferTextureData();
|
2023-01-12 01:23:01 +03:00
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
if (bufferTexture && bufferTexture->GetSize() == aSize &&
|
|
|
|
bufferTexture->GetFormat() == aFormat) {
|
|
|
|
texture = std::move(top);
|
|
|
|
owner->mRecycledTextures.pop();
|
|
|
|
} else {
|
2022-09-07 03:58:34 +03:00
|
|
|
// If size or format are different, release all textures.
|
|
|
|
owner->mRecycledTextures.swap(releasingTextures);
|
2022-06-29 12:32:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<gl::SharedSurface> RemoteTextureMap::GetRecycledSharedSurface(
|
|
|
|
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid) {
|
|
|
|
std::shared_ptr<gl::SharedSurface> sharedSurface;
|
|
|
|
{
|
2022-12-07 05:24:57 +03:00
|
|
|
MonitorAutoLock lock(mMonitor);
|
2022-06-29 12:32:29 +03:00
|
|
|
|
|
|
|
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
|
|
|
if (!owner) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (owner->mRecycledSharedSurfaces.empty()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!owner->mRecycledSharedSurfaces.empty()) {
|
2023-01-05 08:47:15 +03:00
|
|
|
sharedSurface = owner->mRecycledSharedSurfaces.front();
|
2022-06-29 12:32:29 +03:00
|
|
|
owner->mRecycledSharedSurfaces.pop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sharedSurface;
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoteTextureMap::TextureOwner* RemoteTextureMap::GetTextureOwner(
|
2022-12-07 05:24:57 +03:00
|
|
|
const MonitorAutoLock& aProofOfLock, const RemoteTextureOwnerId aOwnerId,
|
2022-06-29 12:32:29 +03:00
|
|
|
const base::ProcessId aForPid) {
|
|
|
|
const auto key = std::pair(aForPid, aOwnerId);
|
|
|
|
auto it = mTextureOwners.find(key);
|
|
|
|
if (it == mTextureOwners.end()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return it->second.get();
|
|
|
|
}
|
|
|
|
|
2022-09-07 03:58:34 +03:00
|
|
|
RemoteTextureMap::TextureDataHolder::TextureDataHolder(
|
|
|
|
const RemoteTextureId aTextureId, RefPtr<TextureHost> aTextureHost,
|
|
|
|
UniquePtr<TextureData>&& aTextureData,
|
|
|
|
const std::shared_ptr<gl::SharedSurface>& aSharedSurface)
|
2022-06-29 12:32:29 +03:00
|
|
|
: mTextureId(aTextureId),
|
2022-09-07 03:58:34 +03:00
|
|
|
mTextureHost(aTextureHost),
|
2022-06-29 12:32:29 +03:00
|
|
|
mTextureData(std::move(aTextureData)),
|
|
|
|
mSharedSurface(aSharedSurface) {}
|
|
|
|
|
2023-04-06 08:27:08 +03:00
|
|
|
RemoteTextureMap::RenderingReadyCallbackHolder::RenderingReadyCallbackHolder(
|
2023-04-14 00:38:24 +03:00
|
|
|
const RemoteTextureId aTextureId,
|
|
|
|
std::function<void(const RemoteTextureInfo&)>&& aCallback)
|
2023-04-06 08:27:08 +03:00
|
|
|
: mTextureId(aTextureId), mCallback(aCallback) {}
|
|
|
|
|
2022-12-07 05:24:57 +03:00
|
|
|
RemoteTextureMap::RemoteTextureHostWrapperHolder::
|
|
|
|
RemoteTextureHostWrapperHolder(
|
|
|
|
RefPtr<TextureHost> aRemoteTextureHostWrapper)
|
|
|
|
: mRemoteTextureHostWrapper(aRemoteTextureHostWrapper) {}
|
|
|
|
|
2022-06-29 12:32:29 +03:00
|
|
|
} // namespace mozilla::layers
|