Bug 1527181 - Add webgl.auto-flush:true. r=lsalzman

* webgl.auto-flush (default: true) enqueues a runnable to flush pending
  webgl commands after each draw.
* webgl.auto-flush.gl (default: false) causes this auto-flush to also
  call glFlush.

This is probably not useful for pure RAF-based apps, since they run
RAF();Present(); back-to-back. For other cases though, this should
improve latency and may reduce jank.

Differential Revision: https://phabricator.services.mozilla.com/D123031
This commit is contained in:
Jeff Gilbert 2021-08-19 21:22:04 +00:00
Родитель 94466e43ee
Коммит 3acae77e09
3 изменённых файлов: 48 добавлений и 4 удалений

Просмотреть файл

@ -360,7 +360,7 @@ void ClientWebGLContext::Present(WebGLFramebufferJS* const xrFb,
if (!xrFb) {
mIsCanvasDirty = false;
}
CancelAutoFlush();
Run<RPROC(Present)>(xrFb ? xrFb->mId : 0, type, webvr);
}
@ -2705,12 +2705,14 @@ void ClientWebGLContext::DepthRange(GLclampf zNear, GLclampf zFar) {
Run<RPROC(DepthRange)>(zNear, zFar);
}
void ClientWebGLContext::Flush() {
void ClientWebGLContext::Flush(const bool flushGl) {
const FuncScope funcScope(*this, "flush");
const auto notLost = mNotLost;
if (IsContextLost()) return;
Run<RPROC(Flush)>();
if (flushGl) {
Run<RPROC(Flush)>();
}
if (notLost->inProcess) return;
const auto& child = mNotLost->outOfProcess;

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/StaticPrefs_webgl.h"
#include "WebGLFormats.h"
#include "WebGLStrongTypes.h"
#include "WebGLTypes.h"
@ -1012,12 +1013,43 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
void DoReadPixels(const webgl::ReadPixelsDesc&, Range<uint8_t>) const;
uvec2 DrawingBufferSize();
// -
bool mAutoFlushPending = false;
void AutoEnqueueFlush() {
if (MOZ_LIKELY(mAutoFlushPending)) return;
mAutoFlushPending = true;
const auto weak = WeakPtr<ClientWebGLContext>(this);
const auto DeferredFlush = [weak]() {
const auto strong = RefPtr<ClientWebGLContext>(weak);
if (!strong) return;
if (!strong->mAutoFlushPending) return;
strong->mAutoFlushPending = false;
if (!StaticPrefs::webgl_auto_flush()) return;
const bool flushGl = StaticPrefs::webgl_auto_flush_gl();
strong->Flush(flushGl);
};
already_AddRefed<mozilla::Runnable> runnable = NS_NewRunnableFunction(
"enqueue Event_webglcontextrestored", DeferredFlush);
NS_DispatchToCurrentThread(std::move(runnable));
}
void CancelAutoFlush() { mAutoFlushPending = false; }
// -
void AfterDrawCall() {
if (!mNotLost) return;
const auto& state = State();
if (!state.mBoundDrawFb) {
MarkCanvasDirty();
}
AutoEnqueueFlush();
}
// -------------------------------------------------------------------------
@ -1251,7 +1283,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
void DepthRange(GLclampf zNear, GLclampf zFar);
void Flush();
void Flush(bool flushGl = true);
void Finish();

Просмотреть файл

@ -11431,6 +11431,16 @@
value: false
mirror: always
- name: webgl.auto-flush
type: RelaxedAtomicBool
value: true
mirror: always
- name: webgl.auto-flush.gl
type: RelaxedAtomicBool
value: false
mirror: always
- name: webgl.can-lose-context-in-foreground
type: RelaxedAtomicBool
value: true