Bug 1845697 - Always enable IPC congestion check in WebGLChild::FlushPendingCmds() r=jgilbert,gfx-reviewers,lsalzman

IPC congestion check was added by Bug 1839314. It is enabled only when async remote texture is enabled and after first ClientWebGLContext::GetFrontBuffer() call. There were cases that it does not work like the followings.
- ClientWebGLContext::GetFrontBuffer() was not called during IPC congestion.
- When gfx::gfxVars::WebglOopAsyncPresentForceSync() = true.

When the IPC congestion happened, it caused ouf of file descriptor on Linux. Then it is better always to enable the IPC congestion check in WebGLChild::FlushPendingCmds().

Differential Revision: https://phabricator.services.mozilla.com/D184917
This commit is contained in:
sotaro
2023-08-01 00:18:12 +00:00
parent e838a5923e
commit 31ad5bf633
3 changed files with 54 additions and 57 deletions

View File

@@ -535,29 +535,19 @@ Maybe<layers::SurfaceDescriptor> ClientWebGLContext::GetFrontBuffer(
child->FlushPendingCmds(); child->FlushPendingCmds();
Maybe<layers::SurfaceDescriptor> ret; Maybe<layers::SurfaceDescriptor> ret;
auto& info = child->GetFlushedCmdInfo();
// If valid remote texture data was set for async present, then use it. // If valid remote texture data was set for async present, then use it.
const auto& ownerId = fb ? fb->mRemoteTextureOwnerId : mRemoteTextureOwnerId; const auto& ownerId = fb ? fb->mRemoteTextureOwnerId : mRemoteTextureOwnerId;
const auto& textureId = fb ? fb->mLastRemoteTextureId : mLastRemoteTextureId; const auto& textureId = fb ? fb->mLastRemoteTextureId : mLastRemoteTextureId;
auto& needsSync = fb ? fb->mNeedsRemoteTextureSync : mNeedsRemoteTextureSync; auto& needsSync = fb ? fb->mNeedsRemoteTextureSync : mNeedsRemoteTextureSync;
if (ownerId && textureId) { if (ownerId && textureId) {
auto& info = child->GetFlushedCmdInfo();
if (!gfx::gfxVars::WebglOopAsyncPresentForceSync() &&
info.flushesSinceLastCongestionCheck.isNothing()) {
// Enabling checking of increase of flush cmds.
info.flushesSinceLastCongestionCheck = Some(0);
}
const auto tooManyFlushes = 10; const auto tooManyFlushes = 10;
if (info.flushesSinceLastCongestionCheck.isSome()) {
// If there are many flushed cmds, force synchronous IPC to avoid too many // If there are many flushed cmds, force synchronous IPC to avoid too many
// pending ipc messages. // pending ipc messages.
if (info.flushesSinceLastCongestionCheck.ref() > tooManyFlushes) { if (info.flushesSinceLastCongestionCheck > tooManyFlushes) {
needsSync = true; needsSync = true;
} }
// Reset flushesSinceLastCongestionCheck
info.flushesSinceLastCongestionCheck = Some(0);
info.congestionCheckGeneration++;
}
if (XRE_IsParentProcess() || if (XRE_IsParentProcess() ||
gfx::gfxVars::WebglOopAsyncPresentForceSync() || needsSync) { gfx::gfxVars::WebglOopAsyncPresentForceSync() || needsSync) {
needsSync = false; needsSync = false;
@@ -565,11 +555,19 @@ Maybe<layers::SurfaceDescriptor> ClientWebGLContext::GetFrontBuffer(
// will continue to use the remote texture descriptor after. // will continue to use the remote texture descriptor after.
(void)child->SendGetFrontBuffer(fb ? fb->mId : 0, vr, &ret); (void)child->SendGetFrontBuffer(fb ? fb->mId : 0, vr, &ret);
} }
// Reset flushesSinceLastCongestionCheck
info.flushesSinceLastCongestionCheck = 0;
info.congestionCheckGeneration++;
return Some(layers::SurfaceDescriptorRemoteTexture(*textureId, *ownerId)); return Some(layers::SurfaceDescriptorRemoteTexture(*textureId, *ownerId));
} }
if (!child->SendGetFrontBuffer(fb ? fb->mId : 0, vr, &ret)) return {}; if (!child->SendGetFrontBuffer(fb ? fb->mId : 0, vr, &ret)) return {};
// Reset flushesSinceLastCongestionCheck
info.flushesSinceLastCongestionCheck = 0;
info.congestionCheckGeneration++;
return ret; return ret;
} }

View File

@@ -74,8 +74,9 @@ void WebGLChild::FlushPendingCmds() {
mFlushedCmdInfo.flushes += 1; mFlushedCmdInfo.flushes += 1;
mFlushedCmdInfo.flushedCmdBytes += byteSize; mFlushedCmdInfo.flushedCmdBytes += byteSize;
mFlushedCmdInfo.overhead += mPendingCmdsAlignmentOverhead; mFlushedCmdInfo.overhead += mPendingCmdsAlignmentOverhead;
if (mFlushedCmdInfo.flushesSinceLastCongestionCheck.isSome()) {
mFlushedCmdInfo.flushesSinceLastCongestionCheck.ref() += 1; // Handle flushesSinceLastCongestionCheck
mFlushedCmdInfo.flushesSinceLastCongestionCheck += 1;
const auto startCongestionCheck = 20; const auto startCongestionCheck = 20;
const auto maybeIPCMessageCongestion = 70; const auto maybeIPCMessageCongestion = 70;
const auto eventTarget = GetCurrentSerialEventTarget(); const auto eventTarget = GetCurrentSerialEventTarget();
@@ -96,26 +97,24 @@ void WebGLChild::FlushPendingCmds() {
// messages. // messages.
// Due to the async nature of the async ping, it is possible for the flush // Due to the async nature of the async ping, it is possible for the flush
// check to exceed maybeIPCMessageCongestion, but that it it still bounded. // check to exceed maybeIPCMessageCongestion, but that it it still bounded.
if (mFlushedCmdInfo.flushesSinceLastCongestionCheck.ref() == if (mFlushedCmdInfo.flushesSinceLastCongestionCheck == startCongestionCheck) {
startCongestionCheck) {
SendPing()->Then(eventTarget, __func__, [self, generation]() { SendPing()->Then(eventTarget, __func__, [self, generation]() {
if (generation == self->mFlushedCmdInfo.congestionCheckGeneration) { if (generation == self->mFlushedCmdInfo.congestionCheckGeneration) {
// Confirmed IPC messages congestion does not happen. // Confirmed IPC messages congestion does not happen.
// Reset flushesSinceLastCongestionCheck for next congestion check. // Reset flushesSinceLastCongestionCheck for next congestion check.
self->mFlushedCmdInfo.flushesSinceLastCongestionCheck = Some(0); self->mFlushedCmdInfo.flushesSinceLastCongestionCheck = 0;
self->mFlushedCmdInfo.congestionCheckGeneration++; self->mFlushedCmdInfo.congestionCheckGeneration++;
} }
}); });
} else if (mFlushedCmdInfo.flushesSinceLastCongestionCheck.ref() > } else if (mFlushedCmdInfo.flushesSinceLastCongestionCheck >
maybeIPCMessageCongestion) { maybeIPCMessageCongestion) {
// IPC messages congestion might happen, send sync SyncPing for flushing // IPC messages congestion might happen, send sync SyncPing for flushing
// pending messages. // pending messages.
SendSyncPing(); SendSyncPing();
// Reset flushesSinceLastCongestionCheck for next congestion check. // Reset flushesSinceLastCongestionCheck for next congestion check.
mFlushedCmdInfo.flushesSinceLastCongestionCheck = Some(0); mFlushedCmdInfo.flushesSinceLastCongestionCheck = 0;
mFlushedCmdInfo.congestionCheckGeneration++; mFlushedCmdInfo.congestionCheckGeneration++;
} }
}
if (gl::GLContext::ShouldSpew()) { if (gl::GLContext::ShouldSpew()) {
const auto overheadRatio = float(mPendingCmdsAlignmentOverhead) / const auto overheadRatio = float(mPendingCmdsAlignmentOverhead) /

View File

@@ -22,8 +22,8 @@ namespace dom {
struct FlushedCmdInfo final { struct FlushedCmdInfo final {
size_t flushes = 0; size_t flushes = 0;
// Store a number of flushes since last IPC congestion check. // Store a number of flushes since last IPC congestion check.
// It is reset to Some(0), when current IPC congestion check is done. // It is reset to 0, when current IPC congestion check is done.
Maybe<size_t> flushesSinceLastCongestionCheck; size_t flushesSinceLastCongestionCheck = 0;
// Incremented for each IPC congestion check. // Incremented for each IPC congestion check.
size_t congestionCheckGeneration = 0; size_t congestionCheckGeneration = 0;
size_t flushedCmdBytes = 0; size_t flushedCmdBytes = 0;