tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AsyncImagePipelineManager.h (11708B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H
      8 #define MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H
      9 
     10 #include <vector>
     11 
     12 #include "CompositableHost.h"
     13 #include "mozilla/gfx/Point.h"
     14 #include "mozilla/layers/RemoteTextureMap.h"
     15 #include "mozilla/layers/TextureHost.h"
     16 #include "mozilla/Maybe.h"
     17 #include "mozilla/webrender/WebRenderAPI.h"
     18 #include "mozilla/webrender/WebRenderTypes.h"
     19 #include "nsClassHashtable.h"
     20 
     21 namespace mozilla {
     22 
     23 namespace wr {
     24 class DisplayListBuilder;
     25 class RenderTextureHostUsageInfo;
     26 class WebRenderAPI;
     27 class WebRenderPipelineInfo;
     28 }  // namespace wr
     29 
     30 namespace layers {
     31 
     32 class CompositableHost;
     33 class CompositorVsyncScheduler;
     34 class Fence;
     35 class WebRenderImageHost;
     36 class WebRenderTextureHost;
     37 
     38 class AsyncImagePipelineManager final {
     39 public:
     40  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager)
     41 
     42  explicit AsyncImagePipelineManager(RefPtr<wr::WebRenderAPI>&& aApi,
     43                                     bool aUseCompositorWnd);
     44 
     45 protected:
     46  ~AsyncImagePipelineManager();
     47 
     48 public:
     49  void Destroy();
     50 
     51  bool UseCompositorWnd() const { return mUseCompositorWnd; }
     52 
     53  void AddPipeline(const wr::PipelineId& aPipelineId,
     54                   WebRenderBridgeParent* aWrBridge);
     55  void RemovePipeline(const wr::PipelineId& aPipelineId,
     56                      const wr::Epoch& aEpoch);
     57  WebRenderBridgeParent* GetWrBridge(const wr::PipelineId& aPipelineId);
     58 
     59  void HoldExternalImage(const wr::PipelineId& aPipelineId,
     60                         const wr::Epoch& aEpoch, TextureHost* aTexture);
     61  void HoldExternalImage(const wr::PipelineId& aPipelineId,
     62                         const wr::Epoch& aEpoch,
     63                         const wr::ExternalImageId& aImageId);
     64 
     65  // This is called from the Renderer thread to notify this class about the
     66  // pipelines in the most recently completed update.
     67  // @param aInfo PipelineInfo for the update
     68  // @param aLatestFrameId RenderedFrameId if a frame has been submitted for
     69  //                       rendering, invalid if not
     70  // @param aLastCompletedFrameId RenderedFrameId for the last completed frame
     71  void NotifyPipelinesUpdated(RefPtr<const wr::WebRenderPipelineInfo> aInfo,
     72                              wr::RenderedFrameId aLatestFrameId,
     73                              wr::RenderedFrameId aLastCompletedFrameId,
     74                              RefPtr<Fence>&& aFence);
     75 
     76  // This is run on the compositor thread to process mRenderSubmittedUpdates. We
     77  // make this public because we need to invoke it from other places.
     78  void ProcessPipelineUpdates();
     79 
     80  TimeStamp GetCompositionTime() const { return mCompositionTime; }
     81  CompositionOpportunityId GetCompositionOpportunityId() const {
     82    return mCompositionOpportunityId;
     83  }
     84 
     85  void SetCompositionInfo(TimeStamp aTimeStamp,
     86                          CompositionOpportunityId aCompositionOpportunityId) {
     87    mCompositionTime = aTimeStamp;
     88    mCompositionOpportunityId = aCompositionOpportunityId;
     89    if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() &&
     90        mCompositionTime >= mCompositeUntilTime) {
     91      mCompositeUntilTime = TimeStamp();
     92    }
     93  }
     94  void CompositeUntil(TimeStamp aTimeStamp) {
     95    if (mCompositeUntilTime.IsNull() || mCompositeUntilTime < aTimeStamp) {
     96      mCompositeUntilTime = aTimeStamp;
     97    }
     98  }
     99  TimeStamp GetCompositeUntilTime() const { return mCompositeUntilTime; }
    100 
    101  void AddAsyncImagePipeline(const wr::PipelineId& aPipelineId,
    102                             WebRenderImageHost* aImageHost);
    103  void RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId,
    104                                AsyncImagePipelineOps* aPendingOps,
    105                                wr::TransactionBuilder& aTxn);
    106 
    107  void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId,
    108                                const LayoutDeviceRect& aScBounds,
    109                                wr::WrRotation aRotation,
    110                                const wr::ImageRendering& aFilter,
    111                                const wr::MixBlendMode& aMixBlendMode);
    112  void ApplyAsyncImagesOfImageBridge(wr::TransactionBuilder& aSceneBuilderTxn,
    113                                     wr::TransactionBuilder& aFastTxn);
    114  void ApplyAsyncImageForPipeline(
    115      const wr::PipelineId& aPipelineId, wr::TransactionBuilder& aTxn,
    116      wr::TransactionBuilder& aTxnForImageBridge,
    117      AsyncImagePipelineOps* aPendingOps,
    118      RemoteTextureInfoList* aPendingRemoteTextures);
    119 
    120  void ApplyAsyncImageForPipeline(const wr::PipelineId& aPipelineId,
    121                                  TextureHost* aTexture,
    122                                  wr::TransactionBuilder& aTxn);
    123 
    124  void SetEmptyDisplayList(const wr::PipelineId& aPipelineId,
    125                           wr::TransactionBuilder& aTxn,
    126                           wr::TransactionBuilder& aTxnForImageBridge);
    127 
    128  void AppendImageCompositeNotification(
    129      const ImageCompositeNotificationInfo& aNotification) {
    130    mImageCompositeNotifications.AppendElement(aNotification);
    131  }
    132 
    133  void FlushImageNotifications(
    134      nsTArray<ImageCompositeNotificationInfo>* aNotifications) {
    135    aNotifications->AppendElements(std::move(mImageCompositeNotifications));
    136  }
    137 
    138  void SetWillGenerateFrame();
    139  bool GetAndResetWillGenerateFrame();
    140 
    141  static wr::ExternalImageId GetNextExternalImageId();
    142 
    143  void SetTextureFactoryIdentifier(
    144      const TextureFactoryIdentifier& aTextureFactoryIdentifier) {
    145    mTextureFactoryIdentifier = aTextureFactoryIdentifier;
    146  }
    147 
    148  TextureFactoryIdentifier GetTextureFactoryIdentifier() const {
    149    return mTextureFactoryIdentifier;
    150  }
    151 
    152 private:
    153  void ProcessPipelineRendered(const wr::PipelineId& aPipelineId,
    154                               const wr::Epoch& aEpoch,
    155                               wr::RenderedFrameId aRenderedFrameId);
    156  void ProcessPipelineRemoved(const wr::RemovedPipeline& aRemovedPipeline,
    157                              wr::RenderedFrameId aRenderedFrameId);
    158 
    159  wr::Epoch GetNextImageEpoch();
    160  uint32_t GetNextResourceId() { return ++mResourceId; }
    161  wr::IdNamespace GetNamespace() { return mIdNamespace; }
    162  wr::ImageKey GenerateImageKey() {
    163    wr::ImageKey key;
    164    key.mNamespace = GetNamespace();
    165    key.mHandle = GetNextResourceId();
    166    return key;
    167  }
    168 
    169  struct ForwardingTextureHost {
    170    ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
    171        : mEpoch(aEpoch), mTexture(aTexture) {}
    172    wr::Epoch mEpoch;
    173    CompositableTextureHostRef mTexture;
    174  };
    175 
    176  struct ForwardingExternalImage {
    177    ForwardingExternalImage(const wr::Epoch& aEpoch,
    178                            const wr::ExternalImageId& aImageId)
    179        : mEpoch(aEpoch), mImageId(aImageId) {}
    180    ~ForwardingExternalImage();
    181    wr::Epoch mEpoch;
    182    wr::ExternalImageId mImageId;
    183  };
    184 
    185  struct PipelineTexturesHolder {
    186    // Holds forwarding WebRenderTextureHosts.
    187    std::vector<ForwardingTextureHost> mTextureHostsUntilRenderSubmitted;
    188    // TextureHosts that must be held until rendering has completed. UniquePtr
    189    // is used to make the entries movable, ideally ForwardingTextureHost would
    190    // be fully movable.
    191    std::vector<UniquePtr<ForwardingTextureHost>>
    192        mTextureHostsUntilRenderCompleted;
    193    std::vector<UniquePtr<ForwardingExternalImage>> mExternalImages;
    194    Maybe<wr::Epoch> mDestroyedEpoch;
    195    WebRenderBridgeParent* MOZ_NON_OWNING_REF mWrBridge = nullptr;
    196  };
    197 
    198  struct AsyncImagePipeline {
    199    AsyncImagePipeline(wr::PipelineId aPipelineId,
    200                       layers::WebRenderBackend aBackend,
    201                       WebRenderImageHost* aImageHost);
    202    void Update(const LayoutDeviceRect& aScBounds, wr::WrRotation aRotation,
    203                const wr::ImageRendering& aFilter,
    204                const wr::MixBlendMode& aMixBlendMode) {
    205      mIsChanged |= !mScBounds.IsEqualEdges(aScBounds) ||
    206                    mRotation != aRotation || mFilter != aFilter ||
    207                    mMixBlendMode != aMixBlendMode;
    208      mScBounds = aScBounds;
    209      mRotation = aRotation;
    210      mFilter = aFilter;
    211      mMixBlendMode = aMixBlendMode;
    212    }
    213 
    214    bool mInitialised;
    215    bool mIsChanged;
    216    bool mUseExternalImage;
    217    LayoutDeviceRect mScBounds;
    218    wr::WrRotation mRotation;
    219    wr::ImageRendering mFilter;
    220    wr::MixBlendMode mMixBlendMode;
    221    const RefPtr<WebRenderImageHost> mImageHost;
    222    CompositableTextureHostRef mCurrentTexture;
    223    nsTArray<wr::ImageKey> mKeys;
    224    wr::DisplayListBuilder mDLBuilder;
    225    bool mVideoOverlayDisabled = false;
    226  };
    227 
    228  void ApplyAsyncImageForPipeline(const wr::Epoch& aEpoch,
    229                                  const wr::PipelineId& aPipelineId,
    230                                  AsyncImagePipeline* aPipeline,
    231                                  TextureHost* aTexture,
    232                                  wr::TransactionBuilder& aSceneBuilderTxn,
    233                                  wr::TransactionBuilder& aMaybeFastTxn);
    234  Maybe<TextureHost::ResourceUpdateOp> UpdateImageKeys(
    235      const wr::Epoch& aEpoch, const wr::PipelineId& aPipelineId,
    236      AsyncImagePipeline* aPipeline, TextureHost* aTexture,
    237      nsTArray<wr::ImageKey>& aKeys, wr::TransactionBuilder& aSceneBuilderTxn,
    238      wr::TransactionBuilder& aMaybeFastTxn);
    239  Maybe<TextureHost::ResourceUpdateOp> UpdateWithoutExternalImage(
    240      TextureHost* aTexture, wr::ImageKey aKey, TextureHost::ResourceUpdateOp,
    241      wr::TransactionBuilder& aTxn);
    242 
    243  void CheckForTextureHostsNotUsedByGPU();
    244 
    245  RefPtr<wr::WebRenderAPI> mApi;
    246  bool mUseCompositorWnd;
    247  TextureFactoryIdentifier mTextureFactoryIdentifier;
    248 
    249  const wr::IdNamespace mIdNamespace;
    250  const bool mUseTripleBuffering;
    251  uint32_t mResourceId;
    252 
    253  nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder>
    254      mPipelineTexturesHolders;
    255  nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines;
    256  wr::Epoch mAsyncImageEpoch;
    257  bool mWillGenerateFrame;
    258  bool mDestroyed;
    259 
    260 #ifdef XP_WIN
    261  bool mUseWebRenderDCompVideoHwOverlayWin;
    262  bool mUseWebRenderDCompVideoSwOverlayWin;
    263  bool mUseWebRenderDCompositionTextureOverlayWin;
    264 #endif
    265 
    266  // Render time for the current composition.
    267  TimeStamp mCompositionTime;
    268 
    269  // CompositionOpportunityId of the current composition.
    270  CompositionOpportunityId mCompositionOpportunityId;
    271 
    272  // When nonnull, during rendering, some compositable indicated that it will
    273  // change its rendering at this time. In order not to miss it, we composite
    274  // on every vsync until this time occurs (this is the latest such time).
    275  TimeStamp mCompositeUntilTime;
    276 
    277  nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications;
    278 
    279  struct WebRenderPipelineInfoHolder {
    280    WebRenderPipelineInfoHolder(RefPtr<const wr::WebRenderPipelineInfo>&& aInfo,
    281                                RefPtr<Fence>&& aFence);
    282    ~WebRenderPipelineInfoHolder();
    283    WebRenderPipelineInfoHolder(WebRenderPipelineInfoHolder&&) = default;
    284    RefPtr<const wr::WebRenderPipelineInfo> mInfo;
    285    RefPtr<Fence> mFence;
    286  };
    287 
    288  std::vector<std::pair<wr::RenderedFrameId, WebRenderPipelineInfoHolder>>
    289      mRenderSubmittedUpdates;
    290  Mutex mRenderSubmittedUpdatesLock MOZ_UNANNOTATED;
    291 
    292  Atomic<uint64_t> mLastCompletedFrameId;
    293  std::vector<std::pair<wr::RenderedFrameId,
    294                        std::vector<UniquePtr<ForwardingTextureHost>>>>
    295      mTexturesInUseByGPU;
    296  RefPtr<Fence> mReadFence;
    297 };
    298 
    299 }  // namespace layers
    300 }  // namespace mozilla
    301 
    302 #endif /* MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H */