gecko-dev/gfx/gl/GLContextEGL.h
Jamie Nicol 7adec85b80 Bug 1575765 - Implement KHR_partial_update for webrender. r=sotaro,jgilbert
KHR_partial_update allows us to avoid rerendering the entire
backbuffer every frame, and instead only render what has changed on
the current frame, as well as the difference between the current
backbuffer and the current frontbuffer. It works similarily to
EXT_buffer_age, which we already support, with the additional
requirement that we must call eglSetDamageRegion each frame before
rendering to the backbuffer.

Modify GLContextEGL::GetBufferAge() so that it queries the age if
either EXT_buffer_age or KHR_partial_update are available. This will
now automatically be queried by webrender through the
PartialPresentCompositor trait. Add a new function to that trait,
set_buffer_damage_region(), whose RenderCompositorEGL implementation
calls eglSetDamageRegion(). Call this from composite_simple(), once
the damage rect has been calculated but before rendering to the
backbuffer.

Additionally, change both RenderCompositorEGL and
RenderCompositorOGL's implementations of
ShouldDrawPreviousPartialPresentRegions() to unconditionally return
true, rather than checking for the existence of EXT_buffer_age (or
adding a new check for KHR_partial_update). The lack of these
extensions does not mean that webrender is able to skip rendering
previous frames' damage. Rather the opposite, it means we cannot
render *only* the previous frames' damage, and must instead always
render the entire buffer.

Differential Revision: https://phabricator.services.mozilla.com/D91203
2020-10-02 10:23:56 +00:00

174 lines
5.0 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GLCONTEXTEGL_H_
#define GLCONTEXTEGL_H_
#include "GLContext.h"
#include "GLLibraryEGL.h"
#include "nsRegion.h"
#include <memory>
class gfxASurface;
namespace mozilla {
namespace layers {
class SurfaceTextureImage;
} // namespace layers
namespace widget {
class CompositorWidget;
} // namespace widget
namespace gl {
RefPtr<GLLibraryEGL> DefaultEglLibrary(nsACString* const out_failureId);
inline std::shared_ptr<EglDisplay> DefaultEglDisplay(
nsACString* const out_failureId) {
const auto lib = DefaultEglLibrary(out_failureId);
if (!lib) {
return nullptr;
}
return lib->DefaultDisplay(out_failureId);
}
// -
class GLContextEGL final : public GLContext {
friend class TextureImageEGL;
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEGL, override)
static RefPtr<GLContextEGL> CreateGLContext(
std::shared_ptr<EglDisplay>, const GLContextDesc&, EGLConfig config,
EGLSurface surface, const bool useGles, nsACString* const out_failureId);
private:
GLContextEGL(std::shared_ptr<EglDisplay>, const GLContextDesc&,
EGLConfig config, EGLSurface surface, EGLContext context);
~GLContextEGL();
public:
virtual GLContextType GetContextType() const override {
return GLContextType::EGL;
}
static GLContextEGL* Cast(GLContext* gl) {
MOZ_ASSERT(gl->GetContextType() == GLContextType::EGL);
return static_cast<GLContextEGL*>(gl);
}
bool Init() override;
virtual bool IsDoubleBuffered() const override { return mIsDoubleBuffered; }
void SetIsDoubleBuffered(bool aIsDB) { mIsDoubleBuffered = aIsDB; }
virtual bool IsANGLE() const override { return mEgl->mLib->IsANGLE(); }
virtual bool IsWARP() const override { return mEgl->mIsWARP; }
virtual bool BindTexImage() override;
virtual bool ReleaseTexImage() override;
void SetEGLSurfaceOverride(EGLSurface surf);
EGLSurface GetEGLSurfaceOverride() { return mSurfaceOverride; }
virtual bool MakeCurrentImpl() const override;
virtual bool IsCurrentImpl() const override;
virtual bool RenewSurface(widget::CompositorWidget* aWidget) override;
virtual void ReleaseSurface() override;
Maybe<SymbolLoader> GetSymbolLoader() const override;
virtual bool SwapBuffers() override;
virtual void SetDamage(const nsIntRegion& aDamageRegion) override;
virtual void GetWSIInfo(nsCString* const out) const override;
// hold a reference to the given surface
// for the lifetime of this context.
void HoldSurface(gfxASurface* aSurf);
EGLSurface GetEGLSurface() const { return mSurface; }
bool HasExtBufferAge() const;
bool HasKhrPartialUpdate() const;
EGLint GetBufferAge() const;
bool BindTex2DOffscreen(GLContext* aOffscreen);
void UnbindTex2DOffscreen(GLContext* aOffscreen);
void BindOffscreenFramebuffer();
void Destroy();
static RefPtr<GLContextEGL> CreateEGLPBufferOffscreenContext(
std::shared_ptr<EglDisplay>, const GLContextCreateDesc&,
const gfx::IntSize& size, nsACString* const out_FailureId);
static RefPtr<GLContextEGL> CreateEGLPBufferOffscreenContextImpl(
std::shared_ptr<EglDisplay>, const GLContextCreateDesc&,
const gfx::IntSize& size, bool aUseGles, nsACString* const out_FailureId);
static EGLSurface CreateEGLSurfaceForCompositorWidget(
widget::CompositorWidget* aCompositorWidget, const EGLConfig aConfig);
#ifdef MOZ_X11
static bool FindVisual(bool aUseWebRender, bool useAlpha,
int* const out_visualId);
#endif
protected:
friend class GLContextProviderEGL;
friend class GLContextEGLFactory;
virtual void OnMarkDestroyed() override;
public:
const std::shared_ptr<EglDisplay> mEgl;
const EGLConfig mConfig;
const EGLContext mContext;
protected:
EGLSurface mSurface;
const EGLSurface mFallbackSurface;
EGLSurface mSurfaceOverride = EGL_NO_SURFACE;
RefPtr<gfxASurface> mThebesSurface;
bool mBound = false;
bool mIsPBuffer = false;
bool mIsDoubleBuffered = false;
bool mCanBindToTexture = false;
bool mShareWithEGLImage = false;
bool mOwnsContext = true;
nsIntRegion mDamageRegion;
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(
EglDisplay&, EGLConfig, EGLenum bindToTextureFormat,
gfx::IntSize& pbsize);
static EGLSurface CreateWaylandBufferSurface(EglDisplay&, EGLConfig,
gfx::IntSize& pbsize);
public:
EGLSurface CreateCompatibleSurface(void* aWindow) const;
};
// -
// aVisual is used in Linux only to exactly match window and framebuffer
// visuals on NVIDIA drivers (Bug 1478454).
bool CreateConfig(EglDisplay&, EGLConfig* aConfig, int32_t depth,
bool aEnableDepthBuffer, bool aUseGles, int aVisual = 0);
} // namespace gl
} // namespace mozilla
#endif // GLCONTEXTEGL_H_