|
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 #include <vector> |
|
20 #include "mozilla/layers/AtomicRefCountedWithFinalize.h" |
|
21 |
|
22 /* |
|
23 * FIXME [bjacob] *** PURE CRAZYNESS WARNING *** |
|
24 * |
|
25 * This #define is actually needed here, because subclasses of ISurfaceAllocator, |
|
26 * namely ShadowLayerForwarder, will or will not override AllocGrallocBuffer |
|
27 * depending on whether MOZ_HAVE_SURFACEDESCRIPTORGRALLOC is defined. |
|
28 */ |
|
29 #ifdef MOZ_WIDGET_GONK |
|
30 #define MOZ_HAVE_SURFACEDESCRIPTORGRALLOC |
|
31 #endif |
|
32 |
|
33 class gfxSharedImageSurface; |
|
34 |
|
35 namespace base { |
|
36 class Thread; |
|
37 } |
|
38 |
|
39 namespace mozilla { |
|
40 namespace ipc { |
|
41 class Shmem; |
|
42 } |
|
43 namespace gfx { |
|
44 class DataSourceSurface; |
|
45 } |
|
46 |
|
47 namespace layers { |
|
48 |
|
49 class PGrallocBufferChild; |
|
50 class MaybeMagicGrallocBufferHandle; |
|
51 class MemoryTextureClient; |
|
52 class MemoryTextureHost; |
|
53 |
|
54 enum BufferCapabilities { |
|
55 DEFAULT_BUFFER_CAPS = 0, |
|
56 /** |
|
57 * The allocated buffer must be efficiently mappable as a |
|
58 * gfxImageSurface. |
|
59 */ |
|
60 MAP_AS_IMAGE_SURFACE = 1 << 0, |
|
61 /** |
|
62 * The allocated buffer will be used for GL rendering only |
|
63 */ |
|
64 USING_GL_RENDERING_ONLY = 1 << 1 |
|
65 }; |
|
66 |
|
67 class SurfaceDescriptor; |
|
68 |
|
69 |
|
70 mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType(); |
|
71 bool IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface); |
|
72 bool IsSurfaceDescriptorOwned(const SurfaceDescriptor& aDescriptor); |
|
73 bool ReleaseOwnedSurfaceDescriptor(const SurfaceDescriptor& aDescriptor); |
|
74 |
|
75 TemporaryRef<gfx::DrawTarget> GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend); |
|
76 TemporaryRef<gfx::DataSourceSurface> GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor); |
|
77 /** |
|
78 * An interface used to create and destroy surfaces that are shared with the |
|
79 * Compositor process (using shmem, or gralloc, or other platform specific memory) |
|
80 * |
|
81 * Most of the methods here correspond to methods that are implemented by IPDL |
|
82 * actors without a common polymorphic interface. |
|
83 * These methods should be only called in the ipdl implementor's thread, unless |
|
84 * specified otherwise in the implementing class. |
|
85 */ |
|
86 class ISurfaceAllocator : public AtomicRefCountedWithFinalize<ISurfaceAllocator> |
|
87 { |
|
88 public: |
|
89 MOZ_DECLARE_REFCOUNTED_TYPENAME(ISurfaceAllocator) |
|
90 ISurfaceAllocator() {} |
|
91 |
|
92 void Finalize(); |
|
93 |
|
94 /** |
|
95 * Returns the type of backend that is used off the main thread. |
|
96 * We only don't allow changing the backend type at runtime so this value can |
|
97 * be queried once and will not change until Gecko is restarted. |
|
98 * |
|
99 * XXX - With e10s this may not be true anymore. we can have accelerated widgets |
|
100 * and non-accelerated widgets (small popups, etc.) |
|
101 */ |
|
102 virtual LayersBackend GetCompositorBackendType() const = 0; |
|
103 |
|
104 /** |
|
105 * Allocate shared memory that can be accessed by only one process at a time. |
|
106 * Ownership of this memory is passed when the memory is sent in an IPDL |
|
107 * message. |
|
108 */ |
|
109 virtual bool AllocShmem(size_t aSize, |
|
110 mozilla::ipc::SharedMemory::SharedMemoryType aType, |
|
111 mozilla::ipc::Shmem* aShmem) = 0; |
|
112 |
|
113 /** |
|
114 * Allocate shared memory that can be accessed by both processes at the |
|
115 * same time. Safety is left for the user of the memory to care about. |
|
116 */ |
|
117 virtual bool AllocUnsafeShmem(size_t aSize, |
|
118 mozilla::ipc::SharedMemory::SharedMemoryType aType, |
|
119 mozilla::ipc::Shmem* aShmem) = 0; |
|
120 |
|
121 /** |
|
122 * Allocate memory in shared memory that can always be accessed by both |
|
123 * processes at a time. Safety is left for the user of the memory to care |
|
124 * about. |
|
125 */ |
|
126 bool AllocShmemSection(size_t aSize, |
|
127 mozilla::layers::ShmemSection* aShmemSection); |
|
128 |
|
129 /** |
|
130 * Deallocates a shmem section. |
|
131 */ |
|
132 void FreeShmemSection(mozilla::layers::ShmemSection& aShmemSection); |
|
133 |
|
134 /** |
|
135 * Deallocate memory allocated by either AllocShmem or AllocUnsafeShmem. |
|
136 */ |
|
137 virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) = 0; |
|
138 |
|
139 // was AllocBuffer |
|
140 virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize, |
|
141 gfxContentType aContent, |
|
142 SurfaceDescriptor* aBuffer); |
|
143 |
|
144 // was AllocBufferWithCaps |
|
145 virtual bool AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize, |
|
146 gfxContentType aContent, |
|
147 uint32_t aCaps, |
|
148 SurfaceDescriptor* aBuffer); |
|
149 |
|
150 /** |
|
151 * Returns the maximum texture size supported by the compositor. |
|
152 */ |
|
153 virtual int32_t GetMaxTextureSize() const { return INT32_MAX; } |
|
154 |
|
155 virtual void DestroySharedSurface(SurfaceDescriptor* aSurface); |
|
156 |
|
157 // method that does the actual allocation work |
|
158 virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize, |
|
159 uint32_t aFormat, |
|
160 uint32_t aUsage, |
|
161 MaybeMagicGrallocBufferHandle* aHandle) |
|
162 { |
|
163 return nullptr; |
|
164 } |
|
165 |
|
166 virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) |
|
167 { |
|
168 NS_RUNTIMEABORT("should not be called"); |
|
169 } |
|
170 |
|
171 virtual bool IPCOpen() const { return true; } |
|
172 virtual bool IsSameProcess() const = 0; |
|
173 |
|
174 // Returns true if aSurface wraps a Shmem. |
|
175 static bool IsShmem(SurfaceDescriptor* aSurface); |
|
176 |
|
177 protected: |
|
178 |
|
179 virtual bool IsOnCompositorSide() const = 0; |
|
180 |
|
181 virtual ~ISurfaceAllocator(); |
|
182 |
|
183 void ShrinkShmemSectionHeap(); |
|
184 |
|
185 // This is used to implement an extremely simple & naive heap allocator. |
|
186 std::vector<mozilla::ipc::Shmem> mUsedShmems; |
|
187 |
|
188 friend class AtomicRefCountedWithFinalize<ISurfaceAllocator>; |
|
189 }; |
|
190 |
|
191 class GfxMemoryImageReporter MOZ_FINAL : public nsIMemoryReporter |
|
192 { |
|
193 public: |
|
194 NS_DECL_ISUPPORTS |
|
195 |
|
196 GfxMemoryImageReporter() |
|
197 { |
|
198 #ifdef DEBUG |
|
199 // There must be only one instance of this class, due to |sAmount| |
|
200 // being static. |
|
201 static bool hasRun = false; |
|
202 MOZ_ASSERT(!hasRun); |
|
203 hasRun = true; |
|
204 #endif |
|
205 } |
|
206 |
|
207 MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc) |
|
208 MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree) |
|
209 |
|
210 static void DidAlloc(void* aPointer) |
|
211 { |
|
212 sAmount += MallocSizeOfOnAlloc(aPointer); |
|
213 } |
|
214 |
|
215 static void WillFree(void* aPointer) |
|
216 { |
|
217 sAmount -= MallocSizeOfOnFree(aPointer); |
|
218 } |
|
219 |
|
220 NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, |
|
221 nsISupports* aData) |
|
222 { |
|
223 return MOZ_COLLECT_REPORT( |
|
224 "explicit/gfx/heap-textures", KIND_HEAP, UNITS_BYTES, sAmount, |
|
225 "Heap memory shared between threads by texture clients and hosts."); |
|
226 } |
|
227 |
|
228 private: |
|
229 static mozilla::Atomic<size_t> sAmount; |
|
230 }; |
|
231 |
|
232 } // namespace |
|
233 } // namespace |
|
234 |
|
235 #endif |