Bug 1826280 - Add RemoteTexture async waiting capability r=gfx-reviewers,lsalzman

RenderThread::PushPendingRemoteTexture() notifies pending RemoteTextures to RenderThread. And RemoteTextureMap::CheckRemoteTextureReady() is used for checking if a RemoteTexture is ready. If the RemoteTexture is not ready during the function call, callback will be called when the RemoteTexture becomes ready.

RemoteTextureMap::GetExternalImageIdOfRemoteTextureSync() is changed to RemoteTextureMap::GetExternalImageIdOfRemoteTexture() and wait of RemoteTexture ready in the function is removed. The wait of RemoteTexture ready is done by the callback of the CheckRemoteTextureReady().

Differential Revision: https://phabricator.services.mozilla.com/D174732
This commit is contained in:
sotaro 2023-04-06 05:27:08 +00:00
parent f91604fab5
commit 8c971ce95e
11 changed files with 362 additions and 36 deletions

View file

@ -337,6 +337,8 @@ struct RemoteTextureId {
static RemoteTextureId GetNext();
static constexpr RemoteTextureId Max() { return RemoteTextureId{UINT64_MAX}; }
bool IsValid() const { return mId != 0; }
// Allow explicit cast to a uint64_t for now

View file

@ -165,6 +165,8 @@ void RemoteTextureMap::PushTexture(
const std::shared_ptr<gl::SharedSurface>& aSharedSurface) {
MOZ_RELEASE_ASSERT(aTextureHost);
std::vector<std::function<void(void)>>
renderingReadyCallbacks; // Call outside the monitor
{
MonitorAutoLock lock(mMonitor);
@ -195,6 +197,8 @@ void RemoteTextureMap::PushTexture(
owner->mWaitingTextureDataHolders.push_back(std::move(textureData));
if (!owner->mIsSyncMode) {
renderingReadyCallbacks =
GetRenderingReadyCallbacks(lock, owner, aTextureId);
// Update mAsyncRemoteTextureHost for async mode.
// This happens when PushTexture() with RemoteTextureId is called after
// GetRemoteTextureForDisplayList() with the RemoteTextureId.
@ -203,6 +207,8 @@ void RemoteTextureMap::PushTexture(
if (it != mRemoteTextureHostWrapperHolders.end()) {
MOZ_ASSERT(!it->second->mAsyncRemoteTextureHost);
it->second->mAsyncRemoteTextureHost = aTextureHost;
} else {
MOZ_ASSERT(renderingReadyCallbacks.empty());
}
}
@ -237,6 +243,10 @@ void RemoteTextureMap::PushTexture(
}
}
}
for (auto& callback : renderingReadyCallbacks) {
callback();
}
}
void RemoteTextureMap::GetLatestBufferSnapshot(
@ -352,7 +362,10 @@ void RemoteTextureMap::KeepTextureDataAliveForTextureHostIfNecessary(
void RemoteTextureMap::UnregisterTextureOwner(
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid) {
UniquePtr<TextureOwner> releasingOwner; // Release outside the monitor
RefPtr<TextureHost> releasingTexture; // Release outside the monitor
std::vector<RefPtr<TextureHost>>
releasingTextures; // Release outside the monitor
std::vector<std::function<void(void)>>
renderingReadyCallbacks; // Call outside the monitor
{
MonitorAutoLock lock(mMonitor);
@ -365,10 +378,19 @@ void RemoteTextureMap::UnregisterTextureOwner(
if (it->second->mLatestTextureHost) {
// Release CompositableRef in mMonitor
releasingTexture = it->second->mLatestTextureHost;
releasingTextures.emplace_back(it->second->mLatestTextureHost);
it->second->mLatestTextureHost = nullptr;
}
if (it->second->mLatestRenderedTextureHost) {
// Release CompositableRef in mMonitor
releasingTextures.emplace_back(it->second->mLatestRenderedTextureHost);
it->second->mLatestRenderedTextureHost = nullptr;
}
renderingReadyCallbacks =
GetAllRenderingReadyCallbacks(lock, it->second.get());
KeepTextureDataAliveForTextureHostIfNecessary(
lock, it->second->mWaitingTextureDataHolders);
@ -380,6 +402,10 @@ void RemoteTextureMap::UnregisterTextureOwner(
mMonitor.Notify();
}
for (auto& callback : renderingReadyCallbacks) {
callback();
}
}
void RemoteTextureMap::UnregisterTextureOwners(
@ -390,6 +416,8 @@ void RemoteTextureMap::UnregisterTextureOwners(
releasingOwners; // Release outside the monitor
std::vector<RefPtr<TextureHost>>
releasingTextures; // Release outside the monitor
std::vector<std::function<void(void)>>
renderingReadyCallbacks; // Call outside the monitor
{
MonitorAutoLock lock(mMonitor);
@ -407,6 +435,15 @@ void RemoteTextureMap::UnregisterTextureOwners(
it->second->mLatestTextureHost = nullptr;
}
if (it->second->mLatestRenderedTextureHost) {
// Release CompositableRef in mMonitor
releasingTextures.emplace_back(it->second->mLatestRenderedTextureHost);
it->second->mLatestRenderedTextureHost = nullptr;
}
renderingReadyCallbacks =
GetAllRenderingReadyCallbacks(lock, it->second.get());
KeepTextureDataAliveForTextureHostIfNecessary(
lock, it->second->mWaitingTextureDataHolders);
@ -419,6 +456,10 @@ void RemoteTextureMap::UnregisterTextureOwners(
mMonitor.Notify();
}
for (auto& callback : renderingReadyCallbacks) {
callback();
}
}
/* static */
@ -473,6 +514,39 @@ void RemoteTextureMap::UpdateTexture(const MonitorAutoLock& aProofOfLock,
}
}
std::vector<std::function<void(void)>>
RemoteTextureMap::GetRenderingReadyCallbacks(
const MonitorAutoLock& aProofOfLock, RemoteTextureMap::TextureOwner* aOwner,
const RemoteTextureId aTextureId) {
MOZ_ASSERT(aOwner);
std::vector<std::function<void(void)>> functions;
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;
}
std::vector<std::function<void(void)>>
RemoteTextureMap::GetAllRenderingReadyCallbacks(
const MonitorAutoLock& aProofOfLock,
RemoteTextureMap::TextureOwner* aOwner) {
auto functions =
GetRenderingReadyCallbacks(aProofOfLock, aOwner, RemoteTextureId::Max());
MOZ_ASSERT(aOwner->mRenderingReadyCallbackHolders.empty());
return functions;
}
void RemoteTextureMap::GetRemoteTextureForDisplayList(
RemoteTextureHostWrapper* aTextureHostWrapper) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
@ -552,25 +626,27 @@ void RemoteTextureMap::GetRemoteTextureForDisplayList(
}
}
wr::MaybeExternalImageId
RemoteTextureMap::GetExternalImageIdOfRemoteTextureSync(
wr::MaybeExternalImageId RemoteTextureMap::GetExternalImageIdOfRemoteTexture(
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId,
const base::ProcessId aForPid) {
MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
MonitorAutoLock lock(mMonitor);
const TimeDuration timeout = TimeDuration::FromMilliseconds(10000);
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();
}
TextureHost* remoteTexture = it->second->mAsyncRemoteTextureHost;
if (remoteTexture->GetFlags() & TextureFlags::DUMMY_TEXTURE) {
// Remote texture allocation was failed.
return Nothing();
}
MOZ_ASSERT(!(remoteTexture->GetFlags() & TextureFlags::DUMMY_TEXTURE));
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
// When owner is alreay unregistered, remote texture will not be pushed.
if (!owner) {
if (!remoteTexture) {
// This could happen with IPC abnormal shutdown
@ -578,33 +654,22 @@ RemoteTextureMap::GetExternalImageIdOfRemoteTextureSync(
}
return remoteTexture->GetMaybeExternalImageId();
}
MOZ_ASSERT(owner);
while (!remoteTexture) {
CVStatus status = mMonitor.Wait(timeout);
if (status == CVStatus::Timeout) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return Nothing();
}
auto it = mRemoteTextureHostWrapperHolders.find(key);
if (it == mRemoteTextureHostWrapperHolders.end()) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return Nothing();
}
remoteTexture = it->second->mAsyncRemoteTextureHost;
if (!remoteTexture) {
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
// When owner is alreay unregistered, remote texture will not be pushed.
if (!owner) {
// This could happen with IPC abnormal shutdown
return Nothing();
}
}
// Use mLatestRenderedTextureHost for rendering. Remote texture of
// aTextureId does not exist.
remoteTexture = owner->mLatestRenderedTextureHost;
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;
}
if (remoteTexture->GetFlags() & TextureFlags::DUMMY_TEXTURE) {
// Remote texture allocation was failed.
if (!remoteTexture) {
return Nothing();
}
@ -741,6 +806,45 @@ void RemoteTextureMap::UnregisterRemoteTexturePushListener(
}
}
bool RemoteTextureMap::CheckRemoteTextureReady(
const RemoteTextureInfo& aInfo, std::function<void(void)>&& aCallback) {
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;
}
UniquePtr<TextureData> RemoteTextureMap::GetRecycledBufferTextureData(
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat) {
@ -819,6 +923,10 @@ RemoteTextureMap::TextureDataHolder::TextureDataHolder(
mTextureData(std::move(aTextureData)),
mSharedSurface(aSharedSurface) {}
RemoteTextureMap::RenderingReadyCallbackHolder::RenderingReadyCallbackHolder(
const RemoteTextureId aTextureId, std::function<void(void)>&& aCallback)
: mTextureId(aTextureId), mCallback(aCallback) {}
RemoteTextureMap::RemoteTextureHostWrapperHolder::
RemoteTextureHostWrapperHolder(
RefPtr<TextureHost> aRemoteTextureHostWrapper)

View file

@ -42,6 +42,21 @@ class RemoteTextureHostWrapper;
class TextureData;
class TextureHost;
struct RemoteTextureInfo {
RemoteTextureInfo(const RemoteTextureId aTextureId,
const RemoteTextureOwnerId aOwnerId,
const base::ProcessId aForPid)
: mTextureId(aTextureId), mOwnerId(aOwnerId), mForPid(aForPid) {}
const RemoteTextureId mTextureId;
const RemoteTextureOwnerId mOwnerId;
const base::ProcessId mForPid;
};
struct RemoteTextureInfoList {
std::queue<RemoteTextureInfo> mList;
};
/**
* A class provides API for remote texture owners.
*/
@ -129,8 +144,7 @@ class RemoteTextureMap {
RemoteTextureHostWrapper* aTextureHostWrapper);
// Get ExternalImageId of remote texture for WebRender rendering.
// This synchronously waits until remote texture becomes ready.
wr::MaybeExternalImageId GetExternalImageIdOfRemoteTextureSync(
wr::MaybeExternalImageId GetExternalImageIdOfRemoteTexture(
const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId,
const base::ProcessId aForPid);
@ -154,6 +168,9 @@ class RemoteTextureMap {
const base::ProcessId aForPid,
CompositableHost* aListener);
bool CheckRemoteTextureReady(const RemoteTextureInfo& aInfo,
std::function<void(void)>&& aCallback);
UniquePtr<TextureData> GetRecycledBufferTextureData(
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
@ -184,6 +201,15 @@ class RemoteTextureMap {
std::shared_ptr<gl::SharedSurface> mSharedSurface;
};
struct RenderingReadyCallbackHolder {
RenderingReadyCallbackHolder(const RemoteTextureId aTextureId,
std::function<void(void)>&& aCallback);
const RemoteTextureId mTextureId;
// callback of async RemoteTexture ready
std::function<void(void)> mCallback;
};
struct TextureOwner {
bool mIsSyncMode = true;
// Holds TextureDataHolders that wait to be used for building wr display
@ -191,8 +217,13 @@ class RemoteTextureMap {
std::deque<UniquePtr<TextureDataHolder>> mWaitingTextureDataHolders;
// Holds TextureDataHolders that are used for building wr display list.
std::deque<UniquePtr<TextureDataHolder>> mUsingTextureDataHolders;
// Holds async RemoteTexture ready callbacks.
std::deque<UniquePtr<RenderingReadyCallbackHolder>>
mRenderingReadyCallbackHolders;
RemoteTextureId mLatestTextureId = {0};
CompositableTextureHostRef mLatestTextureHost;
CompositableTextureHostRef mLatestRenderedTextureHost;
std::stack<UniquePtr<TextureData>> mRecycledTextures;
std::queue<std::shared_ptr<gl::SharedSurface>> mRecycledSharedSurfaces;
};
@ -213,6 +244,14 @@ class RemoteTextureMap {
RemoteTextureMap::TextureOwner* aOwner,
const RemoteTextureId aTextureId);
std::vector<std::function<void(void)>> GetRenderingReadyCallbacks(
const MonitorAutoLock& aProofOfLock,
RemoteTextureMap::TextureOwner* aOwner, const RemoteTextureId aTextureId);
std::vector<std::function<void(void)>> GetAllRenderingReadyCallbacks(
const MonitorAutoLock& aProofOfLock,
RemoteTextureMap::TextureOwner* aOwner);
void KeepTextureDataAliveForTextureHostIfNecessary(
const MonitorAutoLock& aProofOfLock,
std::deque<UniquePtr<TextureDataHolder>>& aHolders);

View file

@ -191,6 +191,10 @@ bool RemoteTextureHostWrapper::CheckIsReadyForRendering() {
return !!mRemoteTextureForDisplayList;
}
bool RemoteTextureHostWrapper::IsReadyForRendering() {
return !!mRemoteTextureForDisplayList;
}
void RemoteTextureHostWrapper::ApplyTextureFlagsToRemoteTexture() {
if (!mRemoteTextureForDisplayList) {
return;

View file

@ -82,6 +82,8 @@ class RemoteTextureHostWrapper : public TextureHost {
bool CheckIsReadyForRendering();
bool IsReadyForRendering();
void ApplyTextureFlagsToRemoteTexture();
const RemoteTextureId mTextureId;

View file

@ -13,9 +13,11 @@
#include "gfxEnv.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/RemoteTextureHostWrapper.h"
#include "mozilla/layers/SharedSurfacesParent.h"
#include "mozilla/layers/WebRenderImageHost.h"
#include "mozilla/layers/WebRenderTextureHost.h"
#include "mozilla/StaticPrefs_webgl.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -744,6 +746,45 @@ wr::Epoch AsyncImagePipelineManager::GetNextImageEpoch() {
return mAsyncImageEpoch;
}
UniquePtr<RemoteTextureInfoList>
AsyncImagePipelineManager::GetPendingRemoteTextures() {
if (!gfx::gfxVars::UseCanvasRenderThread() ||
!StaticPrefs::webgl_out_of_process_async_present() ||
gfx::gfxVars::WebglOopAsyncPresentForceSync()) {
return nullptr;
}
// async remote texture is enabled
MOZ_ASSERT(gfx::gfxVars::UseCanvasRenderThread());
MOZ_ASSERT(StaticPrefs::webgl_out_of_process_async_present());
MOZ_ASSERT(!gfx::gfxVars::WebglOopAsyncPresentForceSync());
auto list = MakeUnique<RemoteTextureInfoList>();
for (const auto& entry : mAsyncImagePipelines) {
AsyncImagePipeline* pipeline = entry.GetWeak();
if (!pipeline->mImageHost->GetCurrentTextureHost()) {
continue;
}
auto* wrapper = pipeline->mImageHost->GetCurrentTextureHost()
->AsRemoteTextureHostWrapper();
if (!wrapper || !wrapper->IsReadyForRendering()) {
continue;
}
list->mList.emplace(wrapper->mTextureId, wrapper->mOwnerId,
wrapper->mForPid);
}
if (list->mList.empty()) {
return nullptr;
}
return list;
}
AsyncImagePipelineManager::WebRenderPipelineInfoHolder::
WebRenderPipelineInfoHolder(RefPtr<const wr::WebRenderPipelineInfo>&& aInfo,
ipc::FileDescriptor&& aFenceFd)

View file

@ -12,6 +12,7 @@
#include "CompositableHost.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/layers/RemoteTextureMap.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/Maybe.h"
#include "mozilla/webrender/WebRenderAPI.h"
@ -129,6 +130,8 @@ class AsyncImagePipelineManager final {
void SetWillGenerateFrame();
bool GetAndResetWillGenerateFrame();
UniquePtr<RemoteTextureInfoList> GetPendingRemoteTextures();
static wr::ExternalImageId GetNextExternalImageId();
private:

View file

@ -2273,6 +2273,29 @@ TimeDuration WebRenderBridgeParent::GetVsyncInterval() const {
return TimeDuration();
}
class SchedulePendingRemoteTextures : public wr::NotificationHandler {
public:
SchedulePendingRemoteTextures(
wr::WindowId aWindowId,
UniquePtr<RemoteTextureInfoList>&& aPendingRemoteTextures)
: mWindowId(aWindowId),
mPendingRemoteTextures(std::move(aPendingRemoteTextures)) {}
virtual void Notify(wr::Checkpoint aCheckpoint) override {
if (aCheckpoint == wr::Checkpoint::FrameBuilt) {
wr::RenderThread::Get()->PushPendingRemoteTexture(
mWindowId, std::move(mPendingRemoteTextures));
} else {
MOZ_ASSERT(aCheckpoint == wr::Checkpoint::TransactionDropped);
}
}
protected:
wr::WindowId mWindowId;
UniquePtr<RemoteTextureInfoList> mPendingRemoteTextures;
};
void WebRenderBridgeParent::MaybeGenerateFrame(VsyncId aId,
bool aForceGenerateFrame,
wr::RenderReasons aReasons) {
@ -2346,6 +2369,14 @@ void WebRenderBridgeParent::MaybeGenerateFrame(VsyncId aId,
SetOMTASampleTime();
SetAPZSampleTime();
auto pendingTextures = mAsyncImageManager->GetPendingRemoteTextures();
if (pendingTextures) {
MOZ_ASSERT(!pendingTextures->mList.empty());
fastTxn.Notify(wr::Checkpoint::FrameBuilt,
MakeUnique<SchedulePendingRemoteTextures>(
mApi->GetId(), std::move(pendingTextures)));
}
#if defined(ENABLE_FRAME_LATENCY_LOG)
auto startTime = TimeStamp::Now();
mApi->SetFrameStartTime(startTime);

View file

@ -57,7 +57,7 @@ void RenderTextureHostWrapper::EnsureRemoteTexture() const {
}
auto externalImageId =
layers::RemoteTextureMap::Get()->GetExternalImageIdOfRemoteTextureSync(
layers::RemoteTextureMap::Get()->GetExternalImageIdOfRemoteTexture(
*mTextureId, *mOwnerId, *mForPid);
if (externalImageId.isNothing()) {
// This could happen with IPC abnormal shutdown

View file

@ -26,6 +26,7 @@
#include "mozilla/layers/SurfacePool.h"
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/PerfStats.h"
#include "mozilla/StaticPrefs_webgl.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h"
#include "mozilla/webrender/RendererOGL.h"
@ -384,6 +385,56 @@ size_t RenderThread::ActiveRendererCount() const {
return num_active;
}
void RenderThread::PushPendingRemoteTexture(
wr::WindowId aWindowId,
UniquePtr<layers::RemoteTextureInfoList>&& aPendingRemoteTextures) {
auto windows = mWindowInfos.Lock();
auto it = windows->find(AsUint64(aWindowId));
if (it == windows->end()) {
MOZ_ASSERT(false);
return;
}
WindowInfo* info = it->second.get();
info->mPendingWrNotifierEvents.emplace(WrNotifierEvent::PendingRemoteTextures(
std::move(aPendingRemoteTextures)));
}
bool RenderThread::CheckIsRemoteTextureReady(
WrWindowId aWindowId, layers::RemoteTextureInfoList* aList) {
MOZ_ASSERT(aList);
MOZ_ASSERT(gfx::gfxVars::UseCanvasRenderThread());
MOZ_ASSERT(StaticPrefs::webgl_out_of_process_async_present());
MOZ_ASSERT(!gfx::gfxVars::WebglOopAsyncPresentForceSync());
auto callback = [windowId = aWindowId]() {
RefPtr<nsIRunnable> runnable = NewRunnableMethod<WrWindowId>(
"RenderThread::HandleWrNotifierEvents", RenderThread::Get(),
&RenderThread::HandleWrNotifierEvents, windowId);
RenderThread::Get()->PostRunnable(runnable.forget());
};
bool isReady = true;
while (!aList->mList.empty() && isReady) {
auto& front = aList->mList.front();
isReady &= layers::RemoteTextureMap::Get()->CheckRemoteTextureReady(
front, callback);
if (isReady) {
aList->mList.pop();
}
}
{
auto windows = mWindowInfos.Lock();
auto it = windows->find(AsUint64(aWindowId));
MOZ_RELEASE_ASSERT(it != windows->end());
WindowInfo* info = it->second.get();
info->mIsWaitingRemoteTextureReady = !isReady;
}
return isReady;
}
void RenderThread::WrNotifierEvent_WakeUp(WrWindowId aWindowId,
bool aCompositeNeeded) {
auto windows = mWindowInfos.Lock();
@ -454,6 +505,11 @@ void RenderThread::PostWrNotifierEvents(WrWindowId aWindowId,
return;
}
// Waitig callback from RemoteTextureMap
if (aInfo->mIsWaitingRemoteTextureReady) {
return;
}
// Runnable has not been triggered yet.
RefPtr<nsIRunnable> runnable = NewRunnableMethod<WrWindowId>(
"RenderThread::HandleWrNotifierEvents", this,
@ -503,6 +559,13 @@ void RenderThread::HandleWrNotifierEvents(WrWindowId aWindowId) {
case WrNotifierEvent::Tag::ExternalEvent:
WrNotifierEvent_HandleExternalEvent(aWindowId, front.ExternalEvent());
break;
case WrNotifierEvent::Tag::PendingRemoteTextures:
bool isReady =
CheckIsRemoteTextureReady(aWindowId, front.RemoteTextureInfoList());
if (!isReady) {
return;
}
break;
}
events->pop();
}

View file

@ -21,6 +21,7 @@
#include "mozilla/UniquePtr.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/layers/CompositionRecorder.h"
#include "mozilla/layers/RemoteTextureMap.h"
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/VsyncDispatcher.h"
@ -235,6 +236,10 @@ class RenderThread final {
void DecPendingFrameBuildCount(wr::WindowId aWindowId);
void DecPendingFrameCount(wr::WindowId aWindowId);
void PushPendingRemoteTexture(
wr::WindowId aWindowId,
UniquePtr<layers::RemoteTextureInfoList>&& aPendingRemoteTextures);
// RenderNotifier implementation
void WrNotifierEvent_WakeUp(WrWindowId aWindowId, bool aCompositeNeeded);
void WrNotifierEvent_NewFrameReady(WrWindowId aWindowId,
@ -314,6 +319,7 @@ class RenderThread final {
WakeUp,
NewFrameReady,
ExternalEvent,
PendingRemoteTextures,
};
const Tag mTag;
@ -329,14 +335,22 @@ class RenderThread final {
mPublishId(aPublishId) {
MOZ_ASSERT(mTag == Tag::NewFrameReady);
}
WrNotifierEvent(const Tag aTag, UniquePtr<RendererEvent> aRendererEvent)
WrNotifierEvent(const Tag aTag, UniquePtr<RendererEvent>&& aRendererEvent)
: mTag(aTag), mRendererEvent(std::move(aRendererEvent)) {
MOZ_ASSERT(mTag == Tag::ExternalEvent);
}
WrNotifierEvent(
const Tag aTag,
UniquePtr<layers::RemoteTextureInfoList>&& aPendingRemoteTextures)
: mTag(aTag),
mPendingRemoteTextures(std::move(aPendingRemoteTextures)) {
MOZ_ASSERT(mTag == Tag::PendingRemoteTextures);
}
const bool mCompositeNeeded = false;
UniquePtr<RendererEvent> mRendererEvent;
const FramePublishId mPublishId = FramePublishId::INVALID;
UniquePtr<RendererEvent> mRendererEvent;
UniquePtr<layers::RemoteTextureInfoList> mPendingRemoteTextures;
public:
static WrNotifierEvent WakeUp(const bool aCompositeNeeded) {
@ -349,10 +363,16 @@ class RenderThread final {
}
static WrNotifierEvent ExternalEvent(
UniquePtr<RendererEvent> aRendererEvent) {
UniquePtr<RendererEvent>&& aRendererEvent) {
return WrNotifierEvent(Tag::ExternalEvent, std::move(aRendererEvent));
}
static WrNotifierEvent PendingRemoteTextures(
UniquePtr<layers::RemoteTextureInfoList>&& aPendingRemoteTextures) {
return WrNotifierEvent(Tag::PendingRemoteTextures,
std::move(aPendingRemoteTextures));
}
bool CompositeNeeded() {
if (mTag == Tag::WakeUp || mTag == Tag::NewFrameReady) {
return mCompositeNeeded;
@ -369,11 +389,21 @@ class RenderThread final {
}
UniquePtr<RendererEvent> ExternalEvent() {
if (mTag == Tag::ExternalEvent) {
MOZ_ASSERT(mRendererEvent);
return std::move(mRendererEvent);
}
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return nullptr;
}
layers::RemoteTextureInfoList* RemoteTextureInfoList() {
if (mTag == Tag::PendingRemoteTextures) {
MOZ_ASSERT(mPendingRemoteTextures);
return mPendingRemoteTextures.get();
}
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return nullptr;
}
};
explicit RenderThread(RefPtr<nsIThread> aThread);
@ -412,6 +442,8 @@ class RenderThread final {
FramePublishId aPublishId);
void WrNotifierEvent_HandleExternalEvent(
wr::WindowId aWindowId, UniquePtr<RendererEvent> aRendererEvent);
bool CheckIsRemoteTextureReady(WrWindowId aWindowId,
layers::RemoteTextureInfoList* aList);
~RenderThread();
@ -446,6 +478,7 @@ class RenderThread final {
bool mIsDestroyed = false;
RefPtr<nsIRunnable> mWrNotifierEventsRunnable;
std::queue<WrNotifierEvent> mPendingWrNotifierEvents;
bool mIsWaitingRemoteTextureReady = false;
};
DataMutex<std::unordered_map<uint64_t, UniquePtr<WindowInfo>>> mWindowInfos;