summaryrefslogtreecommitdiffstats
path: root/gfx/layers/ipc/CompositorBridgeChild.h
blob: 7e0a4799fef6fe89431b0114e2767714c81a90e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_layers_CompositorBridgeChild_h
#define mozilla_layers_CompositorBridgeChild_h

#include "base/basictypes.h"     // for DISALLOW_EVIL_CONSTRUCTORS
#include "mozilla/Assertions.h"  // for MOZ_ASSERT_HELPER2
#include "mozilla/Attributes.h"  // for override
#include "mozilla/Monitor.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/PCompositorBridgeChild.h"
#include "mozilla/layers/TextureForwarder.h"  // for TextureForwarder
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsClassHashtable.h"  // for nsClassHashtable
#include "nsCOMPtr.h"          // for nsCOMPtr
#include "nsHashKeys.h"        // for nsUint64HashKey
#include "nsISupportsImpl.h"   // for NS_INLINE_DECL_REFCOUNTING
#include "nsIWeakReferenceUtils.h"

#include <unordered_map>

namespace mozilla {

namespace dom {
class BrowserChild;
}  // namespace dom

namespace widget {
class CompositorWidget;
}  // namespace widget

namespace layers {

using mozilla::dom::BrowserChild;

class IAPZCTreeManager;
class APZCTreeManagerChild;
class CanvasChild;
class CompositorBridgeParent;
class CompositorManagerChild;
class CompositorOptions;
class WebRenderLayerManager;
class TextureClient;
class TextureClientPool;
struct FrameMetrics;
struct FwdTransactionCounter;

class CompositorBridgeChild final : public PCompositorBridgeChild,
                                    public TextureForwarder {
  typedef nsTArray<AsyncParentMessageData> AsyncParentMessageArray;

  friend class PCompositorBridgeChild;

 public:
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorBridgeChild, override);

  explicit CompositorBridgeChild(CompositorManagerChild* aManager);

  /**
   * Initialize the singleton compositor bridge for a content process.
   */
  void InitForContent(uint32_t aNamespace);

  void InitForWidget(uint64_t aProcessToken,
                     WebRenderLayerManager* aLayerManager, uint32_t aNamespace);

  void Destroy();

  static CompositorBridgeChild* Get();

  // Returns whether the compositor is in the GPU process (false if in the UI
  // process). This may only be called on the main thread.
  static bool CompositorIsInGPUProcess();

  mozilla::ipc::IPCResult RecvDidComposite(
      const LayersId& aId, const nsTArray<TransactionId>& aTransactionIds,
      const TimeStamp& aCompositeStart, const TimeStamp& aCompositeEnd);

  mozilla::ipc::IPCResult RecvNotifyFrameStats(
      nsTArray<FrameStats>&& aFrameStats);

  mozilla::ipc::IPCResult RecvNotifyJankedAnimations(
      const LayersId& aLayersId, nsTArray<uint64_t>&& aJankedAnimations);

  PTextureChild* AllocPTextureChild(
      const SurfaceDescriptor& aSharedData, ReadLockDescriptor& aReadLock,
      const LayersBackend& aLayersBackend, const TextureFlags& aFlags,
      const LayersId& aId, const uint64_t& aSerial,
      const wr::MaybeExternalImageId& aExternalImageId);

  bool DeallocPTextureChild(PTextureChild* actor);

  mozilla::ipc::IPCResult RecvParentAsyncMessages(
      nsTArray<AsyncParentMessageData>&& aMessages);
  PTextureChild* CreateTexture(
      const SurfaceDescriptor& aSharedData, ReadLockDescriptor&& aReadLock,
      LayersBackend aLayersBackend, TextureFlags aFlags,
      const dom::ContentParentId& aContentId, uint64_t aSerial,
      wr::MaybeExternalImageId& aExternalImageId) override;

  already_AddRefed<CanvasChild> GetCanvasChild() final;

  void EndCanvasTransaction();

  /**
   * Release resources until they are next required.
   */
  void ClearCachedResources();

  // Beware that these methods don't override their super-class equivalent
  // (which are not virtual), they just overload them. All of these Send*
  // methods just add a sanity check (that it is not too late send a message)
  // and forward the call to the super-class's equivalent method. This means
  // that it is correct to call directly the super-class methods, but you won't
  // get the extra safety provided here.
  bool SendWillClose();
  bool SendPause();
  bool SendResume();
  bool SendResumeAsync();
  bool SendAdoptChild(const LayersId& id);
  bool SendFlushRendering(const wr::RenderReasons& aReasons);
  bool SendStartFrameTimeRecording(const int32_t& bufferSize,
                                   uint32_t* startIndex);
  bool SendStopFrameTimeRecording(const uint32_t& startIndex,
                                  nsTArray<float>* intervals);
  bool IsSameProcess() const override;

  bool IPCOpen() const override { return mCanSend; }

  bool IsPaused() const { return mPaused; }

  static void ShutDown();

  FwdTransactionCounter& GetFwdTransactionCounter();

  /**
   * Hold TextureClient ref until end of usage on host side if
   * TextureFlags::RECYCLE is set. Host side's usage is checked via
   * CompositableRef.
   */
  void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);

  /**
   * Notify id of Texture When host side end its use. Transaction id is used to
   * make sure if there is no newer usage.
   */
  void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);

  void CancelWaitForNotifyNotUsed(uint64_t aTextureId) override;

  FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator() override;

  nsISerialEventTarget* GetThread() const override { return mThread; }

  base::ProcessId GetParentPid() const override { return OtherPid(); }

  bool AllocUnsafeShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override;
  bool AllocShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override;
  bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;

  PCompositorWidgetChild* AllocPCompositorWidgetChild(
      const CompositorWidgetInitData& aInitData);
  bool DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor);

  PAPZCTreeManagerChild* AllocPAPZCTreeManagerChild(const LayersId& aLayersId);
  bool DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor);

  PAPZChild* AllocPAPZChild(const LayersId& aLayersId);
  bool DeallocPAPZChild(PAPZChild* aActor);

  PWebRenderBridgeChild* AllocPWebRenderBridgeChild(
      const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize&,
      const WindowKind&);
  bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor);

  wr::MaybeExternalImageId GetNextExternalImageId() override;

  wr::PipelineId GetNextPipelineId();

 private:
  // Private destructor, to discourage deletion outside of Release():
  virtual ~CompositorBridgeChild();

  // Must only be called from the paint thread. If the main thread is delaying
  // IPC messages, this forwards all such delayed IPC messages to the I/O thread
  // and resumes IPC.
  void ResumeIPCAfterAsyncPaint();

  void PrepareFinalDestroy();
  void AfterDestroy();

  void ActorDestroy(ActorDestroyReason aWhy) override;

  mozilla::ipc::IPCResult RecvObserveLayersUpdate(const LayersId& aLayersId,
                                                  const bool& aActive);

  mozilla::ipc::IPCResult RecvCompositorOptionsChanged(
      const LayersId& aLayersId, const CompositorOptions& aNewOptions);

  uint64_t GetNextResourceId();

  RefPtr<CompositorManagerChild> mCompositorManager;

  RefPtr<WebRenderLayerManager> mLayerManager;

  uint32_t mIdNamespace;
  uint32_t mResourceId;

  // When not multi-process, hold a reference to the CompositorBridgeParent to
  // keep it alive. This reference should be null in multi-process.
  RefPtr<CompositorBridgeParent> mCompositorBridgeParent;

  DISALLOW_EVIL_CONSTRUCTORS(CompositorBridgeChild);

  // True until the beginning of the two-step shutdown sequence of this actor.
  bool mCanSend;

  // False until the actor is destroyed.
  bool mActorDestroyed;

  bool mPaused;

  /**
   * Hold TextureClients refs until end of their usages on host side.
   * It defer calling of TextureClient recycle callback.
   */
  std::unordered_map<uint64_t, RefPtr<TextureClient>>
      mTexturesWaitingNotifyNotUsed;

  nsCOMPtr<nsISerialEventTarget> mThread;

  AutoTArray<RefPtr<TextureClientPool>, 2> mTexturePools;

  uint64_t mProcessToken;

  FixedSizeSmallShmemSectionAllocator* mSectionAllocator;

  // TextureClients that must be kept alive during async painting. This
  // is only accessed on the main thread.
  nsTArray<RefPtr<TextureClient>> mTextureClientsForAsyncPaint;

  RefPtr<CanvasChild> mCanvasChild;
};

}  // namespace layers
}  // namespace mozilla

#endif  // mozilla_layers_CompositorBrigedChild_h