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
With CI's NVIDIA GPU, SharedHandle of ID3D11Texture2D of hardware decoded video during no video copy caused rendering problem. When SharedHandle is not used, the rendering problem did not happen. But when video is rendered to WebGL texture, SharedHandle need to be used.
In this case, D3D11TextureIMFSampleImage copies original ID3D11Texture2D to a new ID3D11Texture2D and use a shared handled of the copied texture. And no video copy of future video frames are disabled.
NoCopyNV12Texture is renamed to ZeroCopyNV12Texture to clarify its meaning.
Differential Revision: https://phabricator.services.mozilla.com/D144598
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
OffscreenCanvas::GetOwnerGlobal can return null when the document or
worker thread is closing. We should check for this when we need the
principal hash value. I have not been able to reproduce with the test
case but it is racy because it keeps reloading the document on a loop
with the last action to be create a WebGL context with OffscreenCanvas.
Differential Revision: https://phabricator.services.mozilla.com/D140184
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
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
When DeleteQuery is called, it uses mTarget to determine whether or not
BeginQuery has been called. This is an insufficient condition because
QueryCounter also sets mTarget without calling BeginQuery and occupying
a slot in current query map. This patch fixes the crash by checking if
the slot is empty first.
Differential Revision: https://phabricator.services.mozilla.com/D137070
This patch adds OffscreenCanvas as a texture source for texImage2D,
texSubImage2D and texSubImage2D. This applies to both
WebGLRenderingContext and WebGL2RenderingContext. This was causing
several test failures in the WebGL conformance suite with
OffscreenCanvas.
Differential Revision: https://phabricator.services.mozilla.com/D136924
The intermediate allocation could fail and it was not handled, causing
an infrequent OOM crash. This patch makes it so we just reuse the
surface buffer we have and does the premultiply inline without requiring
an additional allocation.
Differential Revision: https://phabricator.services.mozilla.com/D136410
This patch ensures that our invalidation is more consistent and less
frequent. It no longer queues an invalidation for each draw call. It now
combines the parameter update (e.g. width, height, opacity) with an
invalidation to ensure the contents of the canvas are consistent with
the advertised properties. It also ensures that if an explicit commit
occurs, any pending commits are cancelled.
Differential Revision: https://phabricator.services.mozilla.com/D134655
The swizzling operations were showing up in talos profiles on Linux with
GLX and using OOP WebGL. If DMABuf has been disabled, similar performance
should be observed with EGL as well. This patch combines the necessary
copies, swizzling between RGBA and BGRA, and premultiplication operations
as much as possible for GetFrontBufferSnapshot.
It also has the advantage of unblocking the WebGL thread in the
compositor process sooner since it is a sync IPC call and moving that
work to the caller which would be blocked anyways.
Differential Revision: https://phabricator.services.mozilla.com/D130690
This patch integrates OffscreenCanvasDisplayHelper with
HTMLCanvasElement, OffscreenCanvas and nsDisplayCanvas to allow
asynchronous display of an OffscreenCanvas.
Differential Revision: https://phabricator.services.mozilla.com/D130787
Workers require all runnables to implement nsIDiscardableRunnable. This
is because the worker may want to terminate after going out of scope,
and want to discard any pending events. It should be safe to simply drop
any WebGL related events since we are going to tear down the context /
actors as well.
Also ensure that we record dirty events even without an associated
HTMLCanvasElement so that the OffscreenCanvas is notified properly.
Differential Revision: https://phabricator.services.mozilla.com/D130783
This patch separates out new helper methods that are shared with the
OffscreenCanvas display integration in a later part in this series.
It also standardizes on SupportsWeakPtr/WeakPtr instead of mixing in C++
standard library versions.
Differential Revision: https://phabricator.services.mozilla.com/D130782