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/webrender/WebRenderTypes.h"
13 
14 namespace mozilla {
15 namespace ipc {
16 class IShmemAllocator;
17 }
18 namespace wr {
19 
20 /// ShmSegmentsWriter pushes bytes in a sequence of fixed size shmems for small
21 /// allocations and creates dedicated shmems for large allocations.
22 class ShmSegmentsWriter {
23  public:
24   ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator,
25                     size_t aChunkSize);
26   ~ShmSegmentsWriter();
27 
28   layers::OffsetRange Write(Range<uint8_t> aBytes);
29 
30   template <typename T>
WriteAsBytes(Range<T> aValues)31   layers::OffsetRange WriteAsBytes(Range<T> aValues) {
32     return Write(Range<uint8_t>((uint8_t*)aValues.begin().get(),
33                                 aValues.length() * sizeof(T)));
34   }
35 
36   void Flush(nsTArray<layers::RefCountedShmem>& aSmallAllocs,
37              nsTArray<ipc::Shmem>& aLargeAllocs);
38 
39   void Clear();
40   bool IsEmpty() const;
41 
42  protected:
43   bool AllocChunk();
44   layers::OffsetRange AllocLargeChunk(size_t aSize);
45 
46   nsTArray<layers::RefCountedShmem> mSmallAllocs;
47   nsTArray<ipc::Shmem> mLargeAllocs;
48   layers::WebRenderBridgeChild* mShmAllocator;
49   size_t mCursor;
50   size_t mChunkSize;
51 };
52 
53 class ShmSegmentsReader {
54  public:
55   ShmSegmentsReader(const nsTArray<layers::RefCountedShmem>& aSmallShmems,
56                     const nsTArray<ipc::Shmem>& aLargeShmems);
57 
58   bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
59 
60  protected:
61   bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
62 
63   const nsTArray<layers::RefCountedShmem>& mSmallAllocs;
64   const nsTArray<ipc::Shmem>& mLargeAllocs;
65   size_t mChunkSize;
66 };
67 
68 class IpcResourceUpdateQueue {
69  public:
70   // Because we are using shmems, the size should be a multiple of the page
71   // size. Each shmem has two guard pages, and the minimum shmem size (at least
72   // one Windows) is 64k which is already quite large for a lot of the resources
73   // we use here. The RefCountedShmem type used to allocate the chunks keeps a
74   // 16 bytes header in the buffer which we account for here as well. So we pick
75   // 64k - 2 * 4k - 16 = 57328 bytes as the default alloc size.
76   explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator,
77                                   size_t aChunkSize = 57328);
78 
79   bool AddImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor,
80                 Range<uint8_t> aBytes);
81 
82   bool AddBlobImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor,
83                     Range<uint8_t> aBytes);
84 
85   void AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey);
86 
87   bool UpdateImageBuffer(wr::ImageKey aKey, const ImageDescriptor& aDescriptor,
88                          Range<uint8_t> aBytes);
89 
90   bool UpdateBlobImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor,
91                        Range<uint8_t> aBytes, ImageIntRect aDirtyRect);
92 
93   void UpdateExternalImage(ImageKey aKey, const ImageDescriptor& aDescriptor,
94                            ExternalImageId aExtID,
95                            wr::WrExternalImageBufferType aBufferType,
96                            uint8_t aChannelIndex = 0);
97 
98   void DeleteImage(wr::ImageKey aKey);
99 
100   bool AddRawFont(wr::FontKey aKey, Range<uint8_t> aBytes, uint32_t aIndex);
101 
102   bool AddFontDescriptor(wr::FontKey aKey, Range<uint8_t> aBytes,
103                          uint32_t aIndex);
104 
105   void DeleteFont(wr::FontKey aKey);
106 
107   void AddFontInstance(wr::FontInstanceKey aKey, wr::FontKey aFontKey,
108                        float aGlyphSize,
109                        const wr::FontInstanceOptions* aOptions,
110                        const wr::FontInstancePlatformOptions* aPlatformOptions,
111                        Range<const gfx::FontVariation> aVariations);
112 
113   void DeleteFontInstance(wr::FontInstanceKey aKey);
114 
115   void Clear();
116 
117   void Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
118              nsTArray<layers::RefCountedShmem>& aSmallAllocs,
119              nsTArray<ipc::Shmem>& aLargeAllocs);
120 
121   bool IsEmpty() const;
122 
123   static void ReleaseShmems(ipc::IProtocol*,
124                             nsTArray<layers::RefCountedShmem>& aShmems);
125   static void ReleaseShmems(ipc::IProtocol*, nsTArray<ipc::Shmem>& aShmems);
126 
127  protected:
128   ShmSegmentsWriter mWriter;
129   nsTArray<layers::OpUpdateResource> mUpdates;
130 };
131 
132 }  // namespace wr
133 }  // namespace mozilla
134 
135 #endif
136