There were cases that a lot of cmds messages were sent by WebGLChild::FlushPendingCmds() without calling ClientWebGLContext::GetFrontBuffer(). And the IPC messages were waiting to be handled by WebGLParent, since OpenGL handling could take longer. Then there were cases that pending IPC messages were accumulated and it caused out of file descriptor on Linux. The sync IPC could reduce the pending IPC messages if there are a lot of cmds flashes.
async Ping is used for checking if IPC message is congested at WebGLParent. If a count of flushes since last congestion check reaches maybeIPCMessageCongestion, we think that IPC message is congested at WebGLParent. Then send sync SyncPing message to flush pending IPC messages.
Differential Revision: https://phabricator.services.mozilla.com/D181484
Enabling async remote texture removes sync IPC PWebGLChild::SendGetFrontBuffer(). With the change, there are cases that pending IPC messages are accumulated and it caused out of file descriptor. The sync IPC SendGetFrontBuffer() could reduce the pending IPC messages if there are a lot of cmds flashes.
Differential Revision: https://phabricator.services.mozilla.com/D181033
This patch moves ShouldResistFingerprinting() and add a RFPTarget as
input argument. We will use this function to check if canvas
fingerprinting protection is enabled.
We also modify the caller to pass the right RFPTarget for Canvas image
data extraction prompt. Note that, we need to set the default argument
for the function to known because it's used for WebGL fingerprinting
protection too. However, We don't cut over this part in this patch and
will do it in a future bug.
Differential Revision: https://phabricator.services.mozilla.com/D175608
DrawTargetWebgl renders a path by uploading vertex data to the back of
a large VBO using glBufferSubData then issuing a draw call, orphaning
the buffer when it becomes full. This results in many glBufferSubData
calls being interleaved with draw calls. On Mali GPUs this causes
severe performance issues as the driver is unable to determine that
any pending draw calls do not reference the updated region of the
buffer, and therefore must create a copy of the buffer for each
update.
However, since *we* know that we never overwrite a region that is
referenced by a submitted draw call, we can force the driver to avoid
making these copies. We do so by adding a new function
UnsynchronizedBufferSubData(), which acts like BufferSubData so long
as this rule is followed. Internally, this uses glMapBufferRange with
GL_MAP_UNSYNCHRONIZED_BIT, allowing the driver to omit the extraneous
copies.
Differential Revision: https://phabricator.services.mozilla.com/D174685
This updates the version wpf-gpu-raster which adds support for
GPUs/drivers that use truncation instead of rounding when converting
vertices to fixed point.
It also adds the GL vendor to InitContextResult so that we can detect
AMD on macOS and tell wpf-gpu-raster that truncation is going to happen.
Differential Revision: https://phabricator.services.mozilla.com/D167503
The remote texture is processed asynchronously, but the WebGL rendering results are rendered synchronously with WebRender transaction by WebRender.
Async remote texture support is enabled only when CanvasRenderThread is used. This is to simplify implementation.
In async mode, remote texture of current RemoteTextureId might not be created yet when WebRenderImageHost::UseRemoteTexture() is called. In this case, RemoteTextureHostWrapper uses its own external image ID, otherwise the RemoteTextureHostWrapper uses compatible old remote texture for creating wr display list. RenderTextureHostWrapper calls RemoteTextureMap::GetExternalImageIdOfRemoteTextureSync() before is ussage. The GetExternalImageIdOfRemoteTextureSync() synchronously waits until remote texture becomes ready. The wait works since WebGL IPC handling is always done in CanvasRenderThread in async mode.
PWebGLChild::SendGetFrontBuffer() triggers sync IPC. It is called to ensure the compatible remote texture in RemoteTextureMap during RemoteTextureMap::GetRemoteTextureForDisplayList() call.
Differential Revision: https://phabricator.services.mozilla.com/D162971
The remote texture is processed asynchronously, but the WebGL rendering results are rendered synchronously with WebRender transaction by WebRender.
Async remote texture support is enabled only when CanvasRenderThread is used. This is to simplify implementation.
In async mode, remote texture of current RemoteTextureId might not be created yet when WebRenderImageHost::UseRemoteTexture() is called. In this case, RemoteTextureHostWrapper uses its own external image ID, otherwise the RemoteTextureHostWrapper uses compatible old remote texture for creating wr display list. RenderTextureHostWrapper calls RemoteTextureMap::GetExternalImageIdOfRemoteTextureSync() before is ussage. The GetExternalImageIdOfRemoteTextureSync() synchronously waits until remote texture becomes ready. The wait works since WebGL IPC handling is always done in CanvasRenderThread in async mode.
PWebGLChild::SendGetFrontBuffer() triggers sync IPC. It is called to ensure the compatible remote texture in RemoteTextureMap during RemoteTextureMap::GetRemoteTextureForDisplayList() call.
Differential Revision: https://phabricator.services.mozilla.com/D162971
This adds a path vertex buffer where triangle list output from WGR is stored.
Each PathCacheEntry can potentially reference a range of vertexes in this buffer
corresponding to triangles for that entry. When this buffer is full, it gets
orphaned and clears corresponding cache entries, so that it can start anew.
Differential Revision: https://phabricator.services.mozilla.com/D161479
This adds a path vertex buffer where triangle list output from WGR is stored.
Each PathCacheEntry can potentially reference a range of vertexes in this buffer
corresponding to triangles for that entry. When this buffer is full, it gets
orphaned and clears corresponding cache entries, so that it can start anew.
Differential Revision: https://phabricator.services.mozilla.com/D161479
There was still a timing that hit the assert. When ClientWebGLContext::Event_webglcontextrestored() was called just before ClientWebGLContext::UpdateWebRenderCanvasData() the assert was failed.
Differential Revision: https://phabricator.services.mozilla.com/D161243
When rendering large and/or fullscreen Canvas2Ds, excessive time can be spent
in calls to TexImage/ReadPixels copying into and out of Shmems to the separate
buffer for DrawTargetSkia. To alleviate this, we can make the DrawTargetSkia
directly wrap the Shmem, so that calls to TexImage/ReadPixels then directly
read or write to this without any separate copy. We modify RawTexImage to use
the IPDL SendTexImage path so that Shmems can be sent via SurfaceDescriptor.
Since SendTexImage is nominally async (which is beneficial), we rely on a
call to GetError later to verify that the Shmem processing is completely before
we further modify the DrawTargetSkia. We further add a ReadPixelsIntoShmem IPDL
call to allow sending the Shmem in the other direction directly.
Differential Revision: https://phabricator.services.mozilla.com/D151286
When rendering large and/or fullscreen Canvas2Ds, excessive time can be spent
in calls to TexImage/ReadPixels copying into and out of Shmems to the separate
buffer for DrawTargetSkia. To alleviate this, we can make the DrawTargetSkia
directly wrap the Shmem, so that calls to TexImage/ReadPixels then directly
read or write to this without any separate copy. We modify RawTexImage to use
the IPDL SendTexImage path so that Shmems can be sent via SurfaceDescriptor.
Since SendTexImage is nominally async (which is beneficial), we rely on a
call to GetError later to verify that the Shmem processing is completely before
we further modify the DrawTargetSkia. We further add a ReadPixelsIntoShmem IPDL
call to allow sending the Shmem in the other direction directly.
Differential Revision: https://phabricator.services.mozilla.com/D151286
When rendering large and/or fullscreen Canvas2Ds, excessive time can be spent
in calls to TexImage/ReadPixels copying into and out of Shmems to the separate
buffer for DrawTargetSkia. To alleviate this, we can make the DrawTargetSkia
directly wrap the Shmem, so that calls to TexImage/ReadPixels then directly
read or write to this without any separate copy. We modify RawTexImage to use
the IPDL SendTexImage path so that Shmems can be sent via SurfaceDescriptor.
Since SendTexImage is nominally async (which is beneficial), we rely on a
call to GetError later to verify that the Shmem processing is completely before
we further modify the DrawTargetSkia. We further add a ReadPixelsIntoShmem IPDL
call to allow sending the Shmem in the other direction directly.
Differential Revision: https://phabricator.services.mozilla.com/D151286
Currently CopyToSwapChain creates spurious copies of the back buffer when SharedSurfaces aren't exportable (= ToSurfaceDescriptor returns Nothing from SharedSurface_Basic). These then later get read back into a CPU memory buffer when PresentFrontBufferToCompositor is used to send the buffer to RemoteTextureMap. This has associated performance and memory costs.
Conceptually, we want Present/CopyToSwapChain to just do the right thing and automatically push buffers to RemoteTextureMap, rather than secondarily needing a hidden call to PresentFrontBufferToCompositor. Then we can get rid of the need to create front buffers whose only purpose is to shuttle data to PresentFrontBufferToCompositor which then shuttles it RemoteTextureMap.
This patch achieves this by refactoring the guts of PresentFrontBufferToCompositor into Present/CopyToSwapChain. The remote texture ids are sent along inside SwapChainOptions if async present is enabled. Those remote texture ids are cached in ClientWebGLContext so that GetFrontBuffer can return them without any subsequent need for an IPDL call.
On the parent side, CopyToSwapChain will now notice if async present is to be used and if a SurfaceFactory does not generate SharedSurfaces that can be exported. In that case it cuts out the middle man and reads from the WebGLFramebuffer's back buffer directly into a CPU buffer to send to RemoteTextureMap.
This also adds a forceAsyncPresent option to SwapChainOptions so that in the future we can have a separate pref for Accelerated Canvas2D that will allow enabling async present independent of the global WebGL pref.
Differential Revision: https://phabricator.services.mozilla.com/D150720
The async front buffer posting is going to be enabled by another bug.
Async IPC was added for async front buffer posting for out-of-process WebGL.
Client does not use TextureClient for storing SurfaceDescriptor.
It works basically same way as to in-process WebGL around nsDisplayCanvas, WebRenderCanvasData, WebRenderCommandBuilder and WebRenderBridgeParent.
SharedSurfaces of SurfaceDescriptorD3D10 are kept alive during their usage. It is for keeping a shread handle valid.
Copied data buffers of SharedShurface_Basics are kept alive during their usage. It is for keeping RenderBufferTextureHost valid.
Differential Revision: https://phabricator.services.mozilla.com/D150197
The async front buffer posting is going to be enabled by another bug.
Async IPC was added for async front buffer posting for out-of-process WebGL.
Client does not use TextureClient for storing SurfaceDescriptor.
It works basically same way as to in-process WebGL around nsDisplayCanvas, WebRenderCanvasData, WebRenderCommandBuilder and WebRenderBridgeParent.
SharedSurfaces of SurfaceDescriptorD3D10 are kept alive during their usage. It is for keeping a shread handle valid.
Copied data buffers of SharedShurface_Basics are kept alive during their usage. It is for keeping RenderBufferTextureHost valid.
Differential Revision: https://phabricator.services.mozilla.com/D150197
bug 1733732 decreased the size of the display port on Android. When you scroll to the bottom of the page, the canvas leaves the display port. It triggers to destroy WebRenderCanvasData and WebRenderCanvasRendererAsync. And then RenderAndroidSurfaceTextureHost::NotifyNotUsed() is called and RenderAndroidSurfaceTextureHost is destroyed.
Then if scrolling makes the canvas into the display port again, WebRenderCanvasData, WebRenderCanvasRendererAsync and RenderAndroidSurfaceTextureHost are recreated again. But there is no rendering update at SharedSurface_SurfaceTexture. Since the page does WebGL rendering only once during page load.
It caused the problem to RenderAndroidSurfaceTextureHost. RenderAndroidSurfaceTextureHost::NotifyNotUsed() returns SurfaceTexture's buffer to client side. For using SurfaceTexture again in RenderAndroidSurfaceTextureHost, Client side needs to do re-rendering to SurfaceTexture. But SharedSurface_SurfaceTexture did nothing in this case.
To address the problem, we could hold layers::CanvasRenderer in ClientWebGLContext::mNotLost. If WebRenderCanvasRendererAsync is kept alive, RenderAndroidSurfaceTextureHost::NotifyNotUsed() and destruction of WebRenderCanvasRendererAsync do not happen.
Then if WebRenderCanvasData is re-created, the stored WebRenderCanvasRendererAsync is set in the new WebRenderCanvasData in ClientWebGLContext::UpdateWebRenderCanvasData().
Differential Revision: https://phabricator.services.mozilla.com/D143811
We use webgl::RaiiShmem in a few places to read in pixel buffers from a
call to the compositor process. Shmems might fail to be mapped into our
process, probably due to virtual memory constraints, and we should check
for that condition.
Depends on D136355
Differential Revision: https://phabricator.services.mozilla.com/D136365
For use within accelerated Canvas2D, it is expedient to have a variant of Present
that explicitly acknowledges that there is a copy from a supplied WebGL framebuffer
into the swap chain back buffer, as is usually the case when remoting, so that it
can be relied upon for format conversions or other concerns. This allows Present
to remain simple and assume rendering happened directly to the back buffer, without
need of a copy.
This backs out some of the earlier changes to Present in 1754130 in favor of
separating the new copy behavior into an explicit CopyToSwapChain interface,
which supports a format swizzle that is useful for converting between Canvas2D
and WebGL swap chain formats. The behavior of CopyToSwapChain, as noted,
assumes that there is a supplied WebGL framebuffer that must be copied to the
swap chain back buffer before any compositing should occur.
Differential Revision: https://phabricator.services.mozilla.com/D138954
* Accept that finding an explicit unpack for a given stride might fail.
* Directly use the logic from the GLES spec for unpacking stride calculations.
* Use structuredSrcSize member.
* Calc explicit unpack based on dstStride, not srcStride.
Differential Revision: https://phabricator.services.mozilla.com/D136052
Most of the support for presenting a WebGLFramebuffer to a swap chain existed as part of the
mechanism for opaque WebXR framebuffer support. However, such "opaque" framebuffer are meant
to be opaque in the sense that their attachments can't be inspected or changed, which does
not provide the requisite level of control for efficiently implementing Canvas2D snapshots.
To this end, the existing Present mechanism is slightly extended to allow presenting to the
swap chain already present in WebGLFramebuffer without the existence of a corresponding
MozFramebuffer.
This also fixes a bug in that AsWebgl() was no longer being utilized in CanvasRenderer, such
that a new mechanism that routed GetFrontBuffer() was needed to fix the code rot.
There are also some efforts to remove a couple redundant copies I noticed in profiles along
the way.
Differential Revision: https://phabricator.services.mozilla.com/D138119