gecko-dev/gfx/layers/TextureWrapperImage.h
Andrew Osmond 4d74abb189 Bug 1877429 - Prevent offscreen canvas2d updates from racing with compositing. r=gfx-reviewers,lsalzman
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
2024-02-07 20:25:52 +00:00

40 lines
1.3 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 GFX_LAYERS_TEXTUREWRAPPINGIMAGE_H_
#define GFX_LAYERS_TEXTUREWRAPPINGIMAGE_H_
#include "mozilla/RefPtr.h"
#include "ImageContainer.h"
#include "mozilla/layers/TextureClient.h"
namespace mozilla {
namespace layers {
// Wraps a TextureClient into an Image. This may only be used on the main
// thread, and only with TextureClients that support BorrowDrawTarget().
class TextureWrapperImage final : public Image {
public:
TextureWrapperImage(TextureClient* aClient, const gfx::IntRect& aPictureRect);
virtual ~TextureWrapperImage();
gfx::IntSize GetSize() const override;
gfx::IntRect GetPictureRect() const override;
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
TextureClient* GetTextureClient(KnowsCompositor* aKnowsCompositor) override;
void OnPrepareForwardToHost() override;
void OnAbandonForwardToHost() override;
private:
gfx::IntRect mPictureRect;
RefPtr<TextureClient> mTextureClient;
};
} // namespace layers
} // namespace mozilla
#endif // GFX_LAYERS_TEXTUREWRAPPINGIMAGE_H_