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