Files
tubestation/gfx/layers/wr/RenderRootStateManager.h
Lee Salzman 51030f7ed6 Bug 1511493 - Ensure PushGlyphs uses the current transaction's IpcResourceUpdateQueue. r=emilio
WebRenderBridgeChild::GetFontKeyForScaledFont can currently cause a IpcResourceUpdateQueue race.
If we're in the middle of a transaction building a blob image, GetFontKeyForScaledFont is called
in the blob image building code using the transaction's IpcResourceUpdateQueue as expected, such
that resource updates are sent out when the transaction is finalized.

However, TextDrawTarget calls into PushGlyphs without passing along its IpcResourceUpdateQueue,
calling GetFontKeyForScaledFont without it, and causing it to immediately send out the resource
update.

So if a blob image uses a font key and submits a resource update, but a display list is built
after that also using the font key within the transaction, the display list will fail to send
the resource update because it thinks the blob image already did, even though the blob image
transaction has not yet been finalized.

The simple fix is to just pass IpcResourceUpdateQueue from TextDrawTarget into PushGlyphs, thus
ensuring the resource updates are properly ordered.

Differential Revision: https://phabricator.services.mozilla.com/D140438
2022-03-05 23:35:16 +00:00

98 lines
3.7 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_RENDERROOTSTATEMANAGER_H
#define GFX_RENDERROOTSTATEMANAGER_H
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/layers/IpcResourceUpdateQueue.h"
#include "mozilla/layers/SharedSurfacesChild.h"
#include "mozilla/layers/WebRenderCommandBuilder.h"
#include "nsTHashSet.h"
namespace mozilla {
namespace layers {
class RenderRootStateManager {
typedef nsTHashSet<RefPtr<WebRenderUserData>> WebRenderUserDataRefTable;
public:
void AddRef();
void Release();
RenderRootStateManager() : mLayerManager(nullptr), mDestroyed(false) {}
void Destroy();
bool IsDestroyed() { return mDestroyed; }
wr::IpcResourceUpdateQueue& AsyncResourceUpdates();
WebRenderBridgeChild* WrBridge() const;
WebRenderCommandBuilder& CommandBuilder();
WebRenderUserDataRefTable* GetWebRenderUserDataTable();
WebRenderLayerManager* LayerManager() { return mLayerManager; }
void AddImageKeyForDiscard(wr::ImageKey key);
void AddBlobImageKeyForDiscard(wr::BlobImageKey key);
void DiscardImagesInTransaction(wr::IpcResourceUpdateQueue& aResources);
void DiscardLocalImages();
void ClearCachedResources();
// Methods to manage the compositor animation ids. Active animations are still
// going, and when they end we discard them and remove them from the active
// list.
void AddActiveCompositorAnimationId(uint64_t aId);
void AddCompositorAnimationsIdForDiscard(uint64_t aId);
void DiscardCompositorAnimations();
void RegisterAsyncAnimation(const wr::ImageKey& aKey,
SharedSurfacesAnimation* aAnimation);
void DeregisterAsyncAnimation(const wr::ImageKey& aKey);
void ClearAsyncAnimations();
void WrReleasedImages(const nsTArray<wr::ExternalImageKeyPair>& aPairs);
void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineId,
const CompositableHandle& aHandle,
CompositableHandleOwner aOwner);
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);
/// Release TextureClient that is bounded to ImageKey.
/// It is used for recycling TextureClient.
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
Maybe<wr::FontInstanceKey> GetFontKeyForScaledFont(
gfx::ScaledFont* aScaledFont, wr::IpcResourceUpdateQueue& aResources);
Maybe<wr::FontKey> GetFontKeyForUnscaledFont(
gfx::UnscaledFont* aUnscaledFont, wr::IpcResourceUpdateQueue& aResources);
void FlushAsyncResourceUpdates();
private:
WebRenderLayerManager* mLayerManager;
Maybe<wr::IpcResourceUpdateQueue> mAsyncResourceUpdates;
nsTArray<wr::ImageKey> mImageKeysToDelete;
nsTArray<wr::BlobImageKey> mBlobImageKeysToDelete;
std::unordered_map<uint64_t, RefPtr<SharedSurfacesAnimation>>
mAsyncAnimations;
// Set of compositor animation ids for which there are active animations (as
// of the last transaction) on the compositor side.
std::unordered_set<uint64_t> mActiveCompositorAnimationIds;
// Compositor animation ids for animations that are done now and that we want
// the compositor to discard information for.
nsTArray<uint64_t> mDiscardedCompositorAnimationsIds;
bool mDestroyed;
friend class WebRenderLayerManager;
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_RENDERROOTSTATEMANAGER_H */