Coverage Report

Created: 2018-09-25 14:53

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