tor-browser

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

IpcResourceUpdateQueue.h (7342B)


      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 GFX_WR_IPCRESOURCEUPDATEQUEUE_H
      8 #define GFX_WR_IPCRESOURCEUPDATEQUEUE_H
      9 
     10 #include "mozilla/layers/WebRenderMessages.h"
     11 #include "mozilla/layers/RefCountedShmem.h"
     12 #include "mozilla/layers/TextureClient.h"
     13 #include "mozilla/webrender/WebRenderTypes.h"
     14 
     15 namespace mozilla {
     16 namespace ipc {
     17 class IShmemAllocator;
     18 }
     19 namespace layers {
     20 class TextureClient;
     21 class WebRenderBridgeChild;
     22 }  // namespace layers
     23 
     24 namespace wr {
     25 
     26 /// ShmSegmentsWriter pushes bytes in a sequence of fixed size shmems for small
     27 /// allocations and creates dedicated shmems for large allocations.
     28 class ShmSegmentsWriter {
     29 public:
     30  ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator,
     31                    size_t aChunkSize);
     32  ~ShmSegmentsWriter();
     33 
     34  ShmSegmentsWriter(ShmSegmentsWriter&& aOther) noexcept;
     35  ShmSegmentsWriter& operator=(ShmSegmentsWriter&& aOther) noexcept;
     36 
     37  ShmSegmentsWriter(const ShmSegmentsWriter& aOther) = delete;
     38  ShmSegmentsWriter& operator=(const ShmSegmentsWriter& aOther) = delete;
     39 
     40  layers::OffsetRange Write(Range<uint8_t> aBytes);
     41 
     42  template <typename T>
     43  layers::OffsetRange WriteAsBytes(Range<T> aValues) {
     44    return Write(Range<uint8_t>((uint8_t*)aValues.begin().get(),
     45                                aValues.length() * sizeof(T)));
     46  }
     47 
     48  void Flush(nsTArray<layers::RefCountedShmem>& aSmallAllocs,
     49             nsTArray<mozilla::ipc::Shmem>& aLargeAllocs);
     50 
     51  void Clear();
     52  bool IsEmpty() const;
     53 
     54  layers::WebRenderBridgeChild* WrBridge() const { return mShmAllocator; }
     55  size_t ChunkSize() const { return mChunkSize; }
     56 
     57 protected:
     58  bool AllocChunk();
     59  layers::OffsetRange AllocLargeChunk(size_t aSize);
     60 
     61  nsTArray<layers::RefCountedShmem> mSmallAllocs;
     62  nsTArray<mozilla::ipc::Shmem> mLargeAllocs;
     63  layers::WebRenderBridgeChild* mShmAllocator;
     64  size_t mCursor;
     65  size_t mChunkSize;
     66 };
     67 
     68 class ShmSegmentsReader {
     69 public:
     70  ShmSegmentsReader(const nsTArray<layers::RefCountedShmem>& aSmallShmems,
     71                    const nsTArray<mozilla::ipc::Shmem>& aLargeShmems);
     72 
     73  bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
     74 
     75  // Get a read pointer, if possible, directly into the shm. If the range has
     76  // been broken up into multiple chunks that can't be represented by a single
     77  // range, nothing will be returned to indicate failure.
     78  Maybe<Range<uint8_t>> GetReadPointer(const layers::OffsetRange& aRange);
     79 
     80  // Get a read pointer, if possible, directly into the shm. Otherwise, copy
     81  // it into the Vec and return a pointer to that contiguous memory instead.
     82  // If all fails, return nothing.
     83  Maybe<Range<uint8_t>> GetReadPointerOrCopy(const layers::OffsetRange& aRange,
     84                                             wr::Vec<uint8_t>& aInto) {
     85    if (Maybe<Range<uint8_t>> ptr = GetReadPointer(aRange)) {
     86      return ptr;
     87    } else {
     88      size_t initialLength = aInto.Length();
     89      if (Read(aRange, aInto)) {
     90        return Some(Range<uint8_t>(aInto.Data() + initialLength,
     91                                   aInto.Length() - initialLength));
     92      } else {
     93        return Nothing();
     94      }
     95    }
     96  }
     97 
     98 protected:
     99  bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
    100 
    101  Maybe<Range<uint8_t>> GetReadPointerLarge(const layers::OffsetRange& aRange);
    102 
    103  const nsTArray<layers::RefCountedShmem>& mSmallAllocs;
    104  const nsTArray<mozilla::ipc::Shmem>& mLargeAllocs;
    105  size_t mChunkSize;
    106 };
    107 
    108 class IpcResourceUpdateQueue {
    109 public:
    110  // Because we are using shmems, the size should be a multiple of the page
    111  // size. Each shmem has two guard pages, and the minimum shmem size (at least
    112  // one Windows) is 64k which is already quite large for a lot of the resources
    113  // we use here. The RefCountedShmem type used to allocate the chunks keeps a
    114  // 16 bytes header in the buffer which we account for here as well. So we pick
    115  // 64k - 2 * 4k - 16 = 57328 bytes as the default alloc size.
    116  explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator,
    117                                  size_t aChunkSize = 57328);
    118 
    119  IpcResourceUpdateQueue(IpcResourceUpdateQueue&& aOther) noexcept;
    120  IpcResourceUpdateQueue& operator=(IpcResourceUpdateQueue&& aOther) noexcept;
    121 
    122  IpcResourceUpdateQueue(const IpcResourceUpdateQueue& aOther) = delete;
    123  IpcResourceUpdateQueue& operator=(const IpcResourceUpdateQueue& aOther) =
    124      delete;
    125 
    126  // Moves over everything but the subqueues
    127  void ReplaceResources(IpcResourceUpdateQueue&& aOther);
    128 
    129  bool AddImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor,
    130                Range<uint8_t> aBytes);
    131 
    132  bool AddBlobImage(wr::BlobImageKey aKey, const ImageDescriptor& aDescriptor,
    133                    Range<uint8_t> aBytes, ImageIntRect aVisibleRect);
    134 
    135  void AddSnapshotImage(wr::SnapshotImageKey aKey);
    136 
    137  void AddSharedExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey);
    138 
    139  void PushExternalImageForTexture(wr::ExternalImageId aExtId,
    140                                   wr::ImageKey aKey,
    141                                   layers::TextureClient* aTexture,
    142                                   bool aIsUpdate);
    143 
    144  bool UpdateImageBuffer(wr::ImageKey aKey, const ImageDescriptor& aDescriptor,
    145                         Range<uint8_t> aBytes);
    146 
    147  bool UpdateBlobImage(wr::BlobImageKey aKey,
    148                       const ImageDescriptor& aDescriptor,
    149                       Range<uint8_t> aBytes, ImageIntRect aVisibleRect,
    150                       ImageIntRect aDirtyRect);
    151 
    152  void UpdateSharedExternalImage(ExternalImageId aExtID, ImageKey aKey,
    153                                 ImageIntRect aDirtyRect);
    154 
    155  void SetBlobImageVisibleArea(BlobImageKey aKey, const ImageIntRect& aArea);
    156 
    157  void DeleteImage(wr::ImageKey aKey);
    158 
    159  void DeleteBlobImage(wr::BlobImageKey aKey);
    160 
    161  void DeleteSnapshotImage(wr::SnapshotImageKey aKey);
    162 
    163  bool AddRawFont(wr::FontKey aKey, Range<uint8_t> aBytes, uint32_t aIndex);
    164 
    165  bool AddFontDescriptor(wr::FontKey aKey, Range<uint8_t> aBytes,
    166                         uint32_t aIndex);
    167 
    168  void DeleteFont(wr::FontKey aKey);
    169 
    170  void AddFontInstance(wr::FontInstanceKey aKey, wr::FontKey aFontKey,
    171                       float aGlyphSize,
    172                       const wr::FontInstanceOptions* aOptions,
    173                       const wr::FontInstancePlatformOptions* aPlatformOptions,
    174                       Range<const gfx::FontVariation> aVariations);
    175 
    176  void DeleteFontInstance(wr::FontInstanceKey aKey);
    177 
    178  void Clear();
    179 
    180  void Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
    181             nsTArray<layers::RefCountedShmem>& aSmallAllocs,
    182             nsTArray<mozilla::ipc::Shmem>& aLargeAllocs);
    183 
    184  bool IsEmpty() const;
    185 
    186  static void ReleaseShmems(mozilla::ipc::IProtocol*,
    187                            nsTArray<layers::RefCountedShmem>& aShms);
    188  static void ReleaseShmems(mozilla::ipc::IProtocol*,
    189                            nsTArray<mozilla::ipc::Shmem>& aShms);
    190 
    191 protected:
    192  ShmSegmentsWriter mWriter;
    193  nsTArray<layers::OpUpdateResource> mUpdates;
    194 };
    195 
    196 }  // namespace wr
    197 }  // namespace mozilla
    198 
    199 #endif