tor-browser

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

ISurfaceAllocator.h (9048B)


      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_LAYERS_ISURFACEDEALLOCATOR
      8 #define GFX_LAYERS_ISURFACEDEALLOCATOR
      9 
     10 #include <stddef.h>  // for size_t
     11 #include <stdint.h>  // for uint32_t
     12 #include "gfxTypes.h"
     13 #include "mozilla/dom/ipc/IdType.h"
     14 #include "mozilla/gfx/Point.h"              // for IntSize
     15 #include "nsIMemoryReporter.h"              // for nsIMemoryReporter
     16 #include "mozilla/Atomics.h"                // for Atomic
     17 #include "mozilla/layers/LayersMessages.h"  // for ShmemSection
     18 
     19 namespace mozilla {
     20 namespace ipc {
     21 class Shmem;
     22 class IShmemAllocator;
     23 }  // namespace ipc
     24 namespace gfx {
     25 class DataSourceSurface;
     26 }  // namespace gfx
     27 
     28 namespace layers {
     29 
     30 class CompositableForwarder;
     31 class CompositorBridgeParentBase;
     32 class TextureForwarder;
     33 
     34 class ShmemSectionAllocator;
     35 class LegacySurfaceDescriptorAllocator;
     36 class ClientIPCAllocator;
     37 class HostIPCAllocator;
     38 class LayersIPCChannel;
     39 
     40 enum BufferCapabilities {
     41  DEFAULT_BUFFER_CAPS = 0,
     42  /**
     43   * The allocated buffer must be efficiently mappable as a DataSourceSurface.
     44   */
     45  MAP_AS_IMAGE_SURFACE = 1 << 0,
     46  /**
     47   * The allocated buffer will be used for GL rendering only
     48   */
     49  USING_GL_RENDERING_ONLY = 1 << 1
     50 };
     51 
     52 class SurfaceDescriptor;
     53 
     54 /**
     55 * An interface used to create and destroy surfaces that are shared with the
     56 * Compositor process (using shmem, or other platform specific memory)
     57 *
     58 * Most of the methods here correspond to methods that are implemented by IPDL
     59 * actors without a common polymorphic interface.
     60 * These methods should be only called in the ipdl implementor's thread, unless
     61 * specified otherwise in the implementing class.
     62 */
     63 class ISurfaceAllocator {
     64 public:
     65  MOZ_DECLARE_REFCOUNTED_TYPENAME(ISurfaceAllocator)
     66  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ISurfaceAllocator)
     67 
     68  ISurfaceAllocator() = default;
     69 
     70  // down-casting
     71 
     72  virtual mozilla::ipc::IShmemAllocator* AsShmemAllocator() { return nullptr; }
     73 
     74  virtual ShmemSectionAllocator* AsShmemSectionAllocator() { return nullptr; }
     75 
     76  virtual CompositableForwarder* AsCompositableForwarder() { return nullptr; }
     77 
     78  virtual TextureForwarder* GetTextureForwarder() { return nullptr; }
     79 
     80  virtual ClientIPCAllocator* AsClientAllocator() { return nullptr; }
     81 
     82  virtual HostIPCAllocator* AsHostIPCAllocator() { return nullptr; }
     83 
     84  virtual LegacySurfaceDescriptorAllocator*
     85  AsLegacySurfaceDescriptorAllocator() {
     86    return nullptr;
     87  }
     88 
     89  virtual CompositorBridgeParentBase* AsCompositorBridgeParentBase() {
     90    return nullptr;
     91  }
     92 
     93  // ipc info
     94 
     95  virtual bool IPCOpen() const { return true; }
     96 
     97  virtual bool IsSameProcess() const = 0;
     98 
     99  virtual bool UsesImageBridge() const { return false; }
    100 
    101  virtual bool UsesWebRenderBridge() const { return false; }
    102 
    103  virtual dom::ContentParentId GetContentId() { return dom::ContentParentId(); }
    104 
    105 protected:
    106  void Finalize() {}
    107 
    108  virtual ~ISurfaceAllocator() = default;
    109 };
    110 
    111 /// Methods that are specific to the client/child side.
    112 class ClientIPCAllocator : public ISurfaceAllocator {
    113 public:
    114  ClientIPCAllocator() = default;
    115 
    116  ClientIPCAllocator* AsClientAllocator() override { return this; }
    117 
    118  virtual base::ProcessId GetParentPid() const = 0;
    119 
    120  virtual MessageLoop* GetMessageLoop() const = 0;
    121 
    122  virtual void CancelWaitForNotifyNotUsed(uint64_t aTextureId) = 0;
    123 };
    124 
    125 /// Methods that are specific to the host/parent side.
    126 class HostIPCAllocator : public ISurfaceAllocator {
    127 public:
    128  HostIPCAllocator() = default;
    129 
    130  HostIPCAllocator* AsHostIPCAllocator() override { return this; }
    131 
    132  /**
    133   * Get child side's process Id.
    134   */
    135  virtual base::ProcessId GetChildProcessId() = 0;
    136 
    137  virtual void NotifyNotUsed(PTextureParent* aTexture,
    138                             uint64_t aTransactionId) = 0;
    139 
    140  virtual void SendAsyncMessage(
    141      const nsTArray<AsyncParentMessageData>& aMessage) = 0;
    142 
    143  virtual void SendPendingAsyncMessages();
    144 
    145  virtual void SetAboutToSendAsyncMessages() {
    146    mAboutToSendAsyncMessages = true;
    147  }
    148 
    149  bool IsAboutToSendAsyncMessages() { return mAboutToSendAsyncMessages; }
    150 
    151 protected:
    152  std::vector<AsyncParentMessageData> mPendingAsyncMessage;
    153  bool mAboutToSendAsyncMessages = false;
    154 };
    155 
    156 class ShmemSection {
    157 public:
    158  static Maybe<ShmemSection> FromUntrusted(
    159      const UntrustedShmemSection& aUntrusted);
    160  bool Init(const mozilla::ipc::Shmem& aShm, uint32_t offset, uint32_t size);
    161  UntrustedShmemSection AsUntrusted();
    162 
    163  uint32_t size() const { return mSize; }
    164  uint32_t offset() const { return mOffset; }
    165  const mozilla::ipc::Shmem& shmem() { return mShmem; }
    166 
    167 private:
    168  mozilla::ipc::Shmem mShmem;
    169  uint32_t mOffset;
    170  uint32_t mSize;
    171 };
    172 
    173 /// An allocator that can group allocations in bigger chunks of shared memory.
    174 ///
    175 /// The allocated shmem sections can only be deallocated by the same allocator
    176 /// instance (and only in the child process).
    177 class ShmemSectionAllocator {
    178 public:
    179  virtual bool AllocShmemSection(uint32_t aSize,
    180                                 ShmemSection* aShmemSection) = 0;
    181 
    182  virtual void DeallocShmemSection(ShmemSection& aShmemSection) = 0;
    183 
    184  virtual void MemoryPressure() {}
    185 };
    186 
    187 /// Some old stuff that's still around and used for screenshots.
    188 ///
    189 /// New code should not need this (see TextureClient).
    190 class LegacySurfaceDescriptorAllocator {
    191 public:
    192  virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize,
    193                                      gfxContentType aContent,
    194                                      SurfaceDescriptor* aBuffer) = 0;
    195 
    196  virtual bool AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
    197                                              gfxContentType aContent,
    198                                              uint32_t aCaps,
    199                                              SurfaceDescriptor* aBuffer) = 0;
    200 
    201  virtual void DestroySurfaceDescriptor(SurfaceDescriptor* aSurface) = 0;
    202 };
    203 
    204 bool IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface);
    205 
    206 already_AddRefed<gfx::DataSourceSurface> GetSurfaceForDescriptor(
    207    const SurfaceDescriptor& aDescriptor);
    208 
    209 uint8_t* GetAddressFromDescriptor(const SurfaceDescriptor& aDescriptor);
    210 
    211 void DestroySurfaceDescriptor(mozilla::ipc::IShmemAllocator* aAllocator,
    212                              SurfaceDescriptor* aSurface);
    213 
    214 class GfxMemoryImageReporter final : public nsIMemoryReporter {
    215  ~GfxMemoryImageReporter() = default;
    216 
    217 public:
    218  NS_DECL_ISUPPORTS
    219 
    220  GfxMemoryImageReporter() {
    221 #ifdef DEBUG
    222    // There must be only one instance of this class, due to |sAmount|
    223    // being static.
    224    static bool hasRun = false;
    225    MOZ_ASSERT(!hasRun);
    226    hasRun = true;
    227 #endif
    228  }
    229 
    230  MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
    231  MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
    232 
    233  static void DidAlloc(void* aPointer) {
    234    sAmount += MallocSizeOfOnAlloc(aPointer);
    235  }
    236 
    237  static void WillFree(void* aPointer) {
    238    sAmount -= MallocSizeOfOnFree(aPointer);
    239  }
    240 
    241  NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
    242                            nsISupports* aData, bool aAnonymize) override {
    243    MOZ_COLLECT_REPORT(
    244        "explicit/gfx/heap-textures", KIND_HEAP, UNITS_BYTES, sAmount,
    245        "Heap memory shared between threads by texture clients and hosts.");
    246 
    247    return NS_OK;
    248  }
    249 
    250 private:
    251  // Typically we use |size_t| in memory reporters, but in the past this
    252  // variable has sometimes gone negative due to missing DidAlloc() calls.
    253  // Therefore, we use a signed type so that any such negative values show up
    254  // as negative in about:memory, rather than as enormous positive numbers.
    255  static mozilla::Atomic<ptrdiff_t> sAmount;
    256 };
    257 
    258 /// A simple shmem section allocator that can only allocate small
    259 /// fixed size elements (only intended to be used to store tile
    260 /// copy-on-write locks for now).
    261 class FixedSizeSmallShmemSectionAllocator final : public ShmemSectionAllocator {
    262 public:
    263  NS_DECL_OWNINGTHREAD
    264 
    265  enum AllocationStatus { STATUS_ALLOCATED, STATUS_FREED };
    266 
    267  struct ShmemSectionHeapHeader {
    268    Atomic<uint32_t> mTotalBlocks;
    269    Atomic<uint32_t> mAllocatedBlocks;
    270  };
    271 
    272  struct ShmemSectionHeapAllocation {
    273    Atomic<uint32_t> mStatus;
    274    uint32_t mSize;
    275  };
    276 
    277  explicit FixedSizeSmallShmemSectionAllocator(LayersIPCChannel* aShmProvider);
    278 
    279  ~FixedSizeSmallShmemSectionAllocator();
    280 
    281  bool AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection) override;
    282 
    283  void DeallocShmemSection(ShmemSection& aShmemSection) override;
    284 
    285  void MemoryPressure() override { ShrinkShmemSectionHeap(); }
    286 
    287  // can be called on the compositor process.
    288  static void FreeShmemSection(ShmemSection& aShmemSection);
    289 
    290  void ShrinkShmemSectionHeap();
    291 
    292  bool IPCOpen() const;
    293 
    294 protected:
    295  std::vector<mozilla::ipc::Shmem> mUsedShmems;
    296  LayersIPCChannel* mShmProvider;
    297 };
    298 
    299 }  // namespace layers
    300 }  // namespace mozilla
    301 
    302 #endif