forked from mirrors/gecko-dev
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:
parent
f91604fab5
commit
8c971ce95e
11 changed files with 362 additions and 36 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -191,6 +191,10 @@ bool RemoteTextureHostWrapper::CheckIsReadyForRendering() {
|
|||
return !!mRemoteTextureForDisplayList;
|
||||
}
|
||||
|
||||
bool RemoteTextureHostWrapper::IsReadyForRendering() {
|
||||
return !!mRemoteTextureForDisplayList;
|
||||
}
|
||||
|
||||
void RemoteTextureHostWrapper::ApplyTextureFlagsToRemoteTexture() {
|
||||
if (!mRemoteTextureForDisplayList) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ class RemoteTextureHostWrapper : public TextureHost {
|
|||
|
||||
bool CheckIsReadyForRendering();
|
||||
|
||||
bool IsReadyForRendering();
|
||||
|
||||
void ApplyTextureFlagsToRemoteTexture();
|
||||
|
||||
const RemoteTextureId mTextureId;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue