зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1677165 - Add support for partial present to GLX. r=kvark,jgilbert
This adds support for GLX_EXT_buffer_age if available to minimize how much must be redrawn when using GLX. Differential Revision: https://phabricator.services.mozilla.com/D93098
This commit is contained in:
Родитель
e2b0a11bac
Коммит
ca9f3b661d
|
@ -3381,6 +3381,12 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
|
|||
*/
|
||||
virtual void SetDamage(const nsIntRegion& aDamageRegion) {}
|
||||
|
||||
/**
|
||||
* Get the buffer age. If it returns 0, that indicates the buffer state is
|
||||
* unknown and the entire frame should be redrawn.
|
||||
*/
|
||||
virtual GLint GetBufferAge() const { return 0; }
|
||||
|
||||
/**
|
||||
* Defines a two-dimensional texture image for context target surface
|
||||
*/
|
||||
|
|
|
@ -90,6 +90,8 @@ class GLContextEGL final : public GLContext {
|
|||
|
||||
virtual void SetDamage(const nsIntRegion& aDamageRegion) override;
|
||||
|
||||
GLint GetBufferAge() const override;
|
||||
|
||||
virtual void GetWSIInfo(nsCString* const out) const override;
|
||||
|
||||
// hold a reference to the given surface
|
||||
|
@ -100,7 +102,6 @@ class GLContextEGL final : public GLContext {
|
|||
|
||||
bool HasExtBufferAge() const;
|
||||
bool HasKhrPartialUpdate() const;
|
||||
EGLint GetBufferAge() const;
|
||||
|
||||
bool BindTex2DOffscreen(GLContext* aOffscreen);
|
||||
void UnbindTex2DOffscreen(GLContext* aOffscreen);
|
||||
|
|
|
@ -53,6 +53,8 @@ class GLContextGLX : public GLContext {
|
|||
|
||||
bool SwapBuffers() override;
|
||||
|
||||
GLint GetBufferAge() const override;
|
||||
|
||||
void GetWSIInfo(nsCString* const out) const override;
|
||||
|
||||
// Overrides the current GLXDrawable backing the context and makes the
|
||||
|
|
|
@ -606,7 +606,7 @@ bool GLContextEGL::HasKhrPartialUpdate() const {
|
|||
return mEgl->IsExtensionSupported(EGLExtension::KHR_partial_update);
|
||||
}
|
||||
|
||||
EGLint GLContextEGL::GetBufferAge() const {
|
||||
GLint GLContextEGL::GetBufferAge() const {
|
||||
EGLSurface surface =
|
||||
mSurfaceOverride != EGL_NO_SURFACE ? mSurfaceOverride : mSurface;
|
||||
|
||||
|
|
|
@ -171,6 +171,9 @@ bool GLXLibrary::EnsureInitialized() {
|
|||
const SymLoadStruct symbols_swapcontrol[] = {SYMBOL(SwapIntervalEXT),
|
||||
END_OF_SYMBOLS};
|
||||
|
||||
const SymLoadStruct symbols_querydrawable[] = {SYMBOL(QueryDrawable),
|
||||
END_OF_SYMBOLS};
|
||||
|
||||
const auto fnLoadSymbols = [&](const SymLoadStruct* symbols) {
|
||||
if (pfnLoader.LoadSymbols(symbols)) return true;
|
||||
|
||||
|
@ -217,6 +220,11 @@ bool GLXLibrary::EnsureInitialized() {
|
|||
"swaps.");
|
||||
}
|
||||
|
||||
if (HasExtension(extensionsStr, "GLX_EXT_buffer_age") &&
|
||||
fnLoadSymbols(symbols_querydrawable)) {
|
||||
mHasBufferAge = true;
|
||||
}
|
||||
|
||||
mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
|
||||
mIsNVIDIA =
|
||||
serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation");
|
||||
|
@ -619,6 +627,21 @@ bool GLContextGLX::SwapBuffers() {
|
|||
return true;
|
||||
}
|
||||
|
||||
GLint GLContextGLX::GetBufferAge() const {
|
||||
if (!sGLXLibrary.SupportsBufferAge()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLuint result = 0;
|
||||
mGLX->fQueryDrawable(mDisplay, mDrawable, LOCAL_GLX_BACK_BUFFER_AGE_EXT,
|
||||
&result);
|
||||
if (result > INT32_MAX) {
|
||||
// If the result can't fit, just assume the buffer cannot be reused.
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void GLContextGLX::GetWSIInfo(nsCString* const out) const {
|
||||
Display* display = DefaultXDisplay();
|
||||
int screen = DefaultScreen(display);
|
||||
|
|
|
@ -154,6 +154,10 @@ class GLXLibrary final {
|
|||
int interval) const
|
||||
VOID_WRAP(fSwapIntervalEXT(dpy, drawable, interval))
|
||||
|
||||
int fQueryDrawable(Display* dpy, GLXDrawable drawable, int attribute,
|
||||
unsigned int* value) const
|
||||
WRAP(fQueryDrawable(dpy, drawable, attribute, value))
|
||||
|
||||
#undef WRAP
|
||||
#undef VOID_WRAP
|
||||
#undef BEFORE_CALL
|
||||
|
@ -176,6 +180,10 @@ class GLXLibrary final {
|
|||
bool SupportsTextureFromPixmap(gfxASurface* aSurface);
|
||||
bool SupportsVideoSync();
|
||||
bool SupportsSwapControl() const { return bool(mSymbols.fSwapIntervalEXT); }
|
||||
bool SupportsBufferAge() const {
|
||||
MOZ_ASSERT(mInitialized);
|
||||
return mHasBufferAge;
|
||||
}
|
||||
bool IsATI() { return mIsATI; }
|
||||
bool IsMesa() { return mClientIsMesa; }
|
||||
|
||||
|
@ -214,6 +222,7 @@ class GLXLibrary final {
|
|||
int(GLAPIENTRY* fGetVideoSyncSGI)(unsigned int*);
|
||||
int(GLAPIENTRY* fWaitVideoSyncSGI)(int, int, unsigned int*);
|
||||
void(GLAPIENTRY* fSwapIntervalEXT)(Display*, GLXDrawable, int);
|
||||
int(GLAPIENTRY* fQueryDrawable)(Display*, GLXDrawable, int, unsigned int*);
|
||||
} mSymbols = {};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -229,6 +238,7 @@ class GLXLibrary final {
|
|||
bool mHasVideoMemoryPurge = false;
|
||||
bool mHasCreateContextAttribs = false;
|
||||
bool mHasVideoSync = false;
|
||||
bool mHasBufferAge = false;
|
||||
bool mIsATI = false;
|
||||
bool mIsNVIDIA = false;
|
||||
bool mClientIsMesa = false;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "GLContextEGL.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "mozilla/StaticPrefs_gfx.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/BuildConstants.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
|
@ -244,7 +245,11 @@ bool RenderCompositorEGL::ShouldDrawPreviousPartialPresentRegions() {
|
|||
}
|
||||
|
||||
size_t RenderCompositorEGL::GetBufferAge() const {
|
||||
return gl::GLContextEGL::Cast(gl())->GetBufferAge();
|
||||
if (!StaticPrefs::
|
||||
gfx_webrender_allow_partial_present_buffer_age_AtStartup()) {
|
||||
return 0;
|
||||
}
|
||||
return gl()->GetBufferAge();
|
||||
}
|
||||
|
||||
void RenderCompositorEGL::SetBufferDamageRegion(const wr::DeviceIntRect* aRects,
|
||||
|
|
|
@ -104,13 +104,13 @@ CompositorCapabilities RenderCompositorOGL::GetCompositorCapabilities() {
|
|||
}
|
||||
|
||||
uint32_t RenderCompositorOGL::GetMaxPartialPresentRects() {
|
||||
return mIsEGL ? gfx::gfxVars::WebRenderMaxPartialPresentRects() : 0;
|
||||
return gfx::gfxVars::WebRenderMaxPartialPresentRects();
|
||||
}
|
||||
|
||||
bool RenderCompositorOGL::RequestFullRender() { return false; }
|
||||
|
||||
bool RenderCompositorOGL::UsePartialPresent() {
|
||||
return mIsEGL && gfx::gfxVars::WebRenderMaxPartialPresentRects() > 0;
|
||||
return gfx::gfxVars::WebRenderMaxPartialPresentRects() > 0;
|
||||
}
|
||||
|
||||
bool RenderCompositorOGL::ShouldDrawPreviousPartialPresentRegions() {
|
||||
|
@ -118,10 +118,11 @@ bool RenderCompositorOGL::ShouldDrawPreviousPartialPresentRegions() {
|
|||
}
|
||||
|
||||
size_t RenderCompositorOGL::GetBufferAge() const {
|
||||
if (mIsEGL) {
|
||||
return gl::GLContextEGL::Cast(gl())->GetBufferAge();
|
||||
if (!StaticPrefs::
|
||||
gfx_webrender_allow_partial_present_buffer_age_AtStartup()) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return gl()->GetBufferAge();
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
|
|
|
@ -4569,6 +4569,8 @@
|
|||
value: 25
|
||||
mirror: once
|
||||
|
||||
# Number of damage rects we can give to the compositor for a new frame with
|
||||
# partial present. This controls whether partial present is used or not.
|
||||
- name: gfx.webrender.max-partial-present-rects
|
||||
type: uint32_t
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
|
||||
|
@ -4578,6 +4580,14 @@
|
|||
#endif
|
||||
mirror: once
|
||||
|
||||
# Whether or not we can reuse the buffer contents using the GL buffer age
|
||||
# extension, if supported by the platform. This requires partial present
|
||||
# to be used.
|
||||
- name: gfx.webrender.allow-partial-present-buffer-age
|
||||
type: bool
|
||||
value: true
|
||||
mirror: once
|
||||
|
||||
- name: gfx.webrender.enable-gpu-markers
|
||||
type: bool
|
||||
#ifdef DEBUG
|
||||
|
|
Загрузка…
Ссылка в новой задаче