Name of Singleton is commonly used in gecko.
Name of SharedGL is confusing. It looks like "shared context", but it is not. The GL context is actually a singleton GLContext that is used by all WebRender. Each window creates one EGLSurface for each window. EGLSurface is switched for each window rendering.
Differential Revision: https://phabricator.services.mozilla.com/D108714
This requires us to plumb CompositorCapabilities to support the extra field.
This is complicated by the fact that since it is a Rust struct, it has no
default constructor that can pass through to C++ via bindings, so every
one of our RenderCompositors was forced to manually initialize fields. To
get around this brittle footgun, instead the structure is initialized on
the Rust side, and RenderCompositor's are encouraged to only change fields
that actually diverge from the defaults as passed in via pointer.
Finally, we can then do what we need to do, which is just to send the
ForceRedraw message that needs to happen based on what we know about
CompositorCapabilities.
Differential Revision: https://phabricator.services.mozilla.com/D106246
This requires us to plumb CompositorCapabilities to support the extra field.
This is complicated by the fact that since it is a Rust struct, it has no
default constructor that can pass through to C++ via bindings, so every
one of our RenderCompositors was forced to manually initialize fields. To
get around this brittle footgun, instead the structure is initialized on
the Rust side, and RenderCompositor's are encouraged to only change fields
that actually diverge from the defaults as passed in via pointer.
Finally, we can then do what we need to do, which is just to send the
ForceRedraw message that needs to happen based on what we know about
CompositorCapabilities.
Differential Revision: https://phabricator.services.mozilla.com/D106246
Currently we query the backbuffer age in
RenderCompositor::BeginFrame(). Querying the age on android requires
the driver to dequeue a new backbuffer. By doing this right at the
start of the frame, we may cause the driver to block until a buffer is
ready.
We don't actually need the buffer age until part way through
rendering, in Renderer::composite_simple(), by which point there is a
better chance the buffer is available. So move the query to there instead.
Differential Revision: https://phabricator.services.mozilla.com/D92950
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
Add a trait PartialPresentCompositor with a function get_buffer_age(),
and allow gecko to pass an implementation to webrender during
initialization. This allows webrender to query the age of the current
backbuffer during compositing.
Make webrender track the previous 2 frame's dirty rects, rather than
just the previous 1 frame's, allowing it to calculate the total damage
rect for buffer ages of up to 3. If the age is greater than 3, treat
the entire buffer as invalid. Also handle special cases of ages 0 and
1, 0 meaning the entire buffer is invalid, and 1 meaning the entire
buffer is valid. Make gecko stop requesting a full render for buffer
ages other than 2, as webrender can now handle these cases itself.
Differential Revision: https://phabricator.services.mozilla.com/D91202
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
Add a trait PartialPresentCompositor with a function get_buffer_age(),
and allow gecko to pass an implementation to webrender during
initialization. This allows webrender to query the age of the current
backbuffer during compositing.
Make webrender track the previous 2 frame's dirty rects, rather than
just the previous 1 frame's, allowing it to calculate the total damage
rect for buffer ages of up to 3. If the age is greater than 3, treat
the entire buffer as invalid. Also handle special cases of ages 0 and
1, 0 meaning the entire buffer is invalid, and 1 meaning the entire
buffer is valid. Make gecko stop requesting a full render for buffer
ages other than 2, as webrender can now handle these cases itself.
Differential Revision: https://phabricator.services.mozilla.com/D91202
Webrender provides dirty rects with a top-left origin, whereas EGL
requires bottom-left. We also clamp the region to the framebuffer size
prior to passing it to EGL. There was a bug in this calculation when
the dirty rect had a negative y-offset and a height greater than the
framebuffer's height. This was causing too little of the screen to be
updated in some circumstances, resulting in stale content.
Note that this is only an issue when
gfx.webrender.max-partial-present-rects != 0.
Differential Revision: https://phabricator.services.mozilla.com/D91714
This largely reverts D81868, only keeping what's needed to make SwapBuffersWithDamage
work, and also adds BufferAge support to RenderCompositorOGL.
Differential Revision: https://phabricator.services.mozilla.com/D85565
RenderCompositorOGL currently has many responsibilities including supporting
OpenGL compositor for Linux, whole-window compositing for Mac NativeLayerCA,
and per-cache-tile compositing for Mac NativeLayerCA. With the addition of
support for SWGL, this becomes even further complicated.
It becomes advantageous to separate out RenderCompositorOGL specifically as
only the basic OpenGL compositing case, as that naturally yields a simple and
isolated RenderCompositor.
What is left over becomes RenderCompositorNative, a basis for implementing
NativeLayer-based RenderCompositors. To cleanly isolate state and details of
when HW compositing or SW compositing is being used, these are further split
off into RCNativeOGL and RCNativeSWGL versions that deal with specific
isolated details of OpenGL and SWGL respectively.
RCNativeOGL deals with just setting up OpenGL FBOs for NativeLayers.
RCNativeSWGL's new task is just to deal mapping NativeLayers and providing
SWGL FBOs for them without involving OpenGL.
Differential Revision: https://phabricator.services.mozilla.com/D80270
RenderCompositors for SWGL that wish to provide accelerated compositing need to
subvert the existing Bind/Unbind hooks in the WR compositor. These compositors
need to keep track of their HW tiles without actually binding an OpenGL FBO
for WR to render picture cache tiles. SWGL needs to intervene and get a backing
buffer for tile from the RenderCompositor so that it can create a SWGL FBO for
WR to render the picture cache tile to.
To that end, this adds MapTile/UnmapTile as a replacement for Bind/Unbind for
those scenarios. This is done in a way that it affects only the WrCompositor of
webrender_bindings without actually altering WR's Compositor interface. This is
beneficial because WR does not have to understand the details of SWGL
integration and also so as not to complicate other users of WR such as Servo
who are not currently utilizing SWGL at all.
RenderCompositorOGL is initially modified to use these hooks in this patch. It
later became more convenient to restructure that in a follow-up patch.
Differential Revision: https://phabricator.services.mozilla.com/D80269
This moves the clipping responsibility into the layer. It also brings back
assertions that make sure that no invalid content reaches the screen.
On the layer side I'm renaming validRect to displayRect, because at the time
NextSurface* is called, that rect is not yet valid.
This implementation also allows having valid content outside of the display
rect. So, for example, if you grow and shrink the display rect multiple times
but most of the outer parts are transparent, in theory this allows you to paint
the transparent pixels only once rather than every time the display rect
expands.
Differential Revision: https://phabricator.services.mozilla.com/D79842
Bug 1632096 added the capability to shared gl context with WebRender. This bug extends the support to non shared gl context.
Differential Revision: https://phabricator.services.mozilla.com/D72579
For Draw (non-native) and CA modes, we include the per-tile
valid rect in the clip rect from the surface.
For DC (non-virtual) mode, a per-tile clip rect is set on the
visual for each tile, separate from the overall clip rect that
is set on the surface visual.
For DC (virtual) mode, the Trim API is used to remove pixels
in the virtual tile area that are outside the valid / clipped
region.
Note: Although the valid rect is now applied in the native
compositors, it's currently only based on the overall picture
cache bounding rect. Thus, with this patch there isn't any
noticeable performance improvement. Once this lands and is
working correctly, the follow up patch to calculate a smaller
valid region per-tile is a small amount of work.
Differential Revision: https://phabricator.services.mozilla.com/D61424
This fixes RenderCompositorOGL::DestroySurface to update mTotalPixelCount as needed when there are still tiles in the surface that's getting removed.
I'm also adding a few asserts and performing some minor cleanup.
Differential Revision: https://phabricator.services.mozilla.com/D58518
This will allow use of the DirectComposition virtual surface API. If
it turns out that some pages recreate surfaces a lot due to opacity
changing, we can add some extra logic to avoid recreating surfaces
as often, and making use of per-tile opacity in some cases.
Differential Revision: https://phabricator.services.mozilla.com/D57592
This makes it more similar to how SwapBuffers was used.
This patch also makes us call glFlush directly when using native layers, rather than going through the misleadingly-named GLContext::SwapBuffers method.
Differential Revision: https://phabricator.services.mozilla.com/D57062
There are multiple SurfacePools: Main thread painting and the non-WebRender compositors create a new pool per window, and WebRender creates one shared pool across all windows. The non-WebRender users set the pool size limit to zero, i.e. no recycling across paints. This preserves the pre-existing behavior.
WebRender's pool size is configurable with the gfx.webrender.compositor.surface-pool-size pref.
Every window holds on to a SurfacePoolHandle. A SurfacePoolHandle has an owning reference to the pool, via a surface pool wrapper. Once all handles are gone, the surface pool goes away, too.
The SurfacePool holds on to IOSurfaces and MozFramebuffers. Both are created on demand, independently, but are associated with each other.
A given NativeLayer uses only one surface pool handle during its lifetime. The native layer no longer influences which GLContext its framebuffers are created for; the GL context is now managed by the surface pool handle.
As a result, a NativeLayer can no longer change which GLContext its framebuffers are created by.
So in the future, if we ever need to migrate a window frome one GLContext to another, we will need to recreate the NativeLayers inside it. I think that's ok.
Differential Revision: https://phabricator.services.mozilla.com/D54859