It is disabled in this patch via the gfx.canvas.remote.allow-offscreen
pref. A follow up patch will enable this by default.
Differential Revision: https://phabricator.services.mozilla.com/D189532
When OffscreenCanvas::CommitFrameToCompositor uses the non-remote
texture canvas path with Skia, it uses ImageBridgeChild for compositing.
When ImageContainer::SetCurrentImages is called, there was an
intermediate state where the relevant textures were not yet marked as
read only for the compositor's consumption, because the event to do so
was dispatched asynchronously to the ImageBridgeChild thread. If the
owning thread of the canvas (main or DOM worker) ran immediately after
CommitFrameToCompositor, then we could run into texture reuse since
nothing marked the texture yet as being used for compositing. This had
the end result of sometimes displaying back buffer textures currently
being used for drawing on the display pipeline.
This patch makes it so that we mark OffscreenCanvas textures as read
only for the compositor before dispatching, and releasing the lock
either when we swap the images in the ImageContainer (winning the race
with ImageBridgeChild), or after the compositor has finished with it
(losing the race, if any, with ImageBridgeChild).
Additionally, to handle better the case where we run out of buffers, we
need to implement ImageBridgeChild::SyncWithCompositor, to be analogous
to how WebRenderBridgeChild::SyncWithCompositor works. We achieve this
by calling from ImageBridgeChild back into the appropriate
WebRenderBridgeChild based on the window ID associated with the canvas,
It also adds a new pref, gfx.offscreencanvas.shared-provider, which
allows one to switch between PersistentBufferProviderShared and Basic.
The latter of which is used if we fallback from using shared buffers if
it takes too long to get the shared buffers back from the compositor.
Differential Revision: https://phabricator.services.mozilla.com/D200991
If a path builder is left in place after a drawing command, and then user then
sets up new transforms before beginning a new path, the old path will get spuriously
transformed every time the transform is changed, even though it will never be used.
We want to delay actually transforming the path until we need to read from it or
write to it.
Differential Revision: https://phabricator.services.mozilla.com/D198672
EnsureTarget() is called in many places in the code without checking the result, so
in error cases, like processing path builder commands, it can lead to EnsureTarget()
generating an error to the log on every single invocation, with some users noticing
thousands upon thousands of errors being generated.
One notice of this error should be sufficient, given that this is a shutdown error.
Differential Revision: https://phabricator.services.mozilla.com/D197440
Because we cannot control the ordering of shutdown notification from
WorkerRef, we need to choose one centralized point to begin shutdown of
the main thread or the owning DOM worker. Since there are other objects
owned by CanvasManagerChild, we also switch to a ThreadSafeWorkerRef.
Differential Revision: https://phabricator.services.mozilla.com/D195120
It is disabled in this patch via the gfx.canvas.remote.allow-offscreen
pref. A follow up patch will enable this by default.
Differential Revision: https://phabricator.services.mozilla.com/D189532
Because we cannot control the ordering of shutdown notification from
WorkerRef, we need to choose one centralized point to begin shutdown of
the main thread or the owning DOM worker. Since there are other objects
owned by CanvasManagerChild, we also switch to a ThreadSafeWorkerRef.
Differential Revision: https://phabricator.services.mozilla.com/D195120
This adds the necessary infrastructure for CanvasTranslator to allocate DrawTargetWebgl
instead of just allocating TextureData, and to use RemoteTextureMap to handle sending
the DrawTargetWebgl frames to the compositor.
This optimizes snapshot transport to use fewer copies to and from shmems when we know
the snapshot contents can be sourced from a shmem.
This adds a blocking mechanism separate from deactivation so that existing DrawTargetWebgls
can continue processing events while denying further ones from being created in the event
that allocating further DrawTargetWebgls might cause problems, but so that we don't disrupt
canvases that are already in flight.
PersistentBufferProviderAccelerated still remains the buffer provider for the new setup,
but just allocates a single RecordedTextureData internally. Since DrawTargetWebgl already
does its own swap chain management internally, we do not want to use the multiple texture
client strategy that PersistentBufferProviderShared does.
This adds a fallback mechanism such that if DrawTargetWebgl allocation fails, a TextureData
is allocated instead that still sends results to RemoteTextureMap. This has the advantage
that we don't need to synchronously block in the content process to verify if acceleration
succeeded, as the costs of such blocking are rather extreme and we must still produce the
rendered frame to ensure the user sees the correct result if the speculative acceleration
failed. It then notifies the content process asynchronously via the refresh mechanism to
try to recreate a non-accelerated buffer provider when it is ready.
There is one additional hitch in RemoteTextureMap that we need to add a mechanism to deal
with the setup of the RemoteTextureOwner. When display list building initially needs to get
the remote texture, the RemoteTextureOwner might not exist yet. In this case, we need to add
a block to ensure we wait for that to occur so that we do not render an erroneous result.
Previously, this block was handled in ClientWebGLContext. Since that is no longer used,
the block must be reinstated somewhere else until a non-blocking mechanism for display list
building to proceed with a stub texture host wrapper can be implemented.
Currently this leaves the gfx.canvas.remote and gfx.canvas.accelerated prefs as separate
toggles rather than trying to lump everything into one mechanism. While this may be desirable
in the future, currently Direct2D remote canvas is a separate acceleration mechanism that
needs to co-exist with the WebGL acceleration, and so being able to toggle both on or off
for testing is desirable.
Differential Revision: https://phabricator.services.mozilla.com/D194352
This adds the necessary infrastructure for CanvasTranslator to allocate DrawTargetWebgl
instead of just allocating TextureData, and to use RemoteTextureMap to handle sending
the DrawTargetWebgl frames to the compositor.
This optimizes snapshot transport to use fewer copies to and from shmems when we know
the snapshot contents can be sourced from a shmem.
This adds a blocking mechanism separate from deactivation so that existing DrawTargetWebgls
can continue processing events while denying further ones from being created in the event
that allocating further DrawTargetWebgls might cause problems, but so that we don't disrupt
canvases that are already in flight.
PersistentBufferProviderAccelerated still remains the buffer provider for the new setup,
but just allocates a single RecordedTextureData internally. Since DrawTargetWebgl already
does its own swap chain management internally, we do not want to use the multiple texture
client strategy that PersistentBufferProviderShared does.
This adds a fallback mechanism such that if DrawTargetWebgl allocation fails, a TextureData
is allocated instead that still sends results to RemoteTextureMap. This has the advantage
that we don't need to synchronously block in the content process to verify if acceleration
succeeded, as the costs of such blocking are rather extreme and we must still produce the
rendered frame to ensure the user sees the correct result if the speculative acceleration
failed. It then notifies the content process asynchronously via the refresh mechanism to
try to recreate a non-accelerated buffer provider when it is ready.
There is one additional hitch in RemoteTextureMap that we need to add a mechanism to deal
with the setup of the RemoteTextureOwner. When display list building initially needs to get
the remote texture, the RemoteTextureOwner might not exist yet. In this case, we need to add
a block to ensure we wait for that to occur so that we do not render an erroneous result.
Previously, this block was handled in ClientWebGLContext. Since that is no longer used,
the block must be reinstated somewhere else until a non-blocking mechanism for display list
building to proceed with a stub texture host wrapper can be implemented.
Currently this leaves the gfx.canvas.remote and gfx.canvas.accelerated prefs as separate
toggles rather than trying to lump everything into one mechanism. While this may be desirable
in the future, currently Direct2D remote canvas is a separate acceleration mechanism that
needs to co-exist with the WebGL acceleration, and so being able to toggle both on or off
for testing is desirable.
Differential Revision: https://phabricator.services.mozilla.com/D194352
This adds the necessary infrastructure for CanvasTranslator to allocate DrawTargetWebgl
instead of just allocating TextureData, and to use RemoteTextureMap to handle sending
the DrawTargetWebgl frames to the compositor.
This optimizes snapshot transport to use fewer copies to and from shmems when we know
the snapshot contents can be sourced from a shmem.
This adds a blocking mechanism separate from deactivation so that existing DrawTargetWebgls
can continue processing events while denying further ones from being created in the event
that allocating further DrawTargetWebgls might cause problems, but so that we don't disrupt
canvases that are already in flight.
PersistentBufferProviderAccelerated still remains the buffer provider for the new setup,
but just allocates a single RecordedTextureData internally. Since DrawTargetWebgl already
does its own swap chain management internally, we do not want to use the multiple texture
client strategy that PersistentBufferProviderShared does.
This adds a fallback mechanism such that if DrawTargetWebgl allocation fails, a TextureData
is allocated instead that still sends results to RemoteTextureMap. This has the advantage
that we don't need to synchronously block in the content process to verify if acceleration
succeeded, as the costs of such blocking are rather extreme and we must still produce the
rendered frame to ensure the user sees the correct result if the speculative acceleration
failed. It then notifies the content process asynchronously via the refresh mechanism to
try to recreate a non-accelerated buffer provider when it is ready.
There is one additional hitch in RemoteTextureMap that we need to add a mechanism to deal
with the setup of the RemoteTextureOwner. When display list building initially needs to get
the remote texture, the RemoteTextureOwner might not exist yet. In this case, we need to add
a block to ensure we wait for that to occur so that we do not render an erroneous result.
Previously, this block was handled in ClientWebGLContext. Since that is no longer used,
the block must be reinstated somewhere else until a non-blocking mechanism for display list
building to proceed with a stub texture host wrapper can be implemented.
Currently this leaves the gfx.canvas.remote and gfx.canvas.accelerated prefs as separate
toggles rather than trying to lump everything into one mechanism. While this may be desirable
in the future, currently Direct2D remote canvas is a separate acceleration mechanism that
needs to co-exist with the WebGL acceleration, and so being able to toggle both on or off
for testing is desirable.
Differential Revision: https://phabricator.services.mozilla.com/D194352
With OffscreenCanvas, mCanvasElement may be null, so we need to check
for that case when deciding whether or not we need to use ExtractSubrect
when calling DrawImage.
Differential Revision: https://phabricator.services.mozilla.com/D188877