Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/ipc/UiCompositorControllerChild.cpp
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
#include "mozilla/layers/UiCompositorControllerChild.h"
8
9
#include "mozilla/dom/ContentChild.h"
10
#include "mozilla/layers/CompositorThread.h"
11
#include "mozilla/layers/UiCompositorControllerMessageTypes.h"
12
#include "mozilla/layers/UiCompositorControllerParent.h"
13
#include "mozilla/gfx/GPUProcessManager.h"
14
#include "mozilla/StaticPtr.h"
15
#include "nsBaseWidget.h"
16
#include "nsThreadUtils.h"
17
18
#if defined(MOZ_WIDGET_ANDROID)
19
#include "mozilla/widget/AndroidUiThread.h"
20
21
static RefPtr<nsThread>
22
GetUiThread()
23
{
24
  return mozilla::GetAndroidUiThread();
25
}
26
#else
27
static RefPtr<nsThread>
28
GetUiThread()
29
0
{
30
0
  MOZ_CRASH("Platform does not support UiCompositorController");
31
0
  return nullptr;
32
0
}
33
#endif // defined(MOZ_WIDGET_ANDROID)
34
35
static bool
36
IsOnUiThread()
37
0
{
38
0
  return GetUiThread()->SerialEventTarget()->IsOnCurrentThread();
39
0
}
40
41
namespace mozilla {
42
namespace layers {
43
44
45
// public:
46
/* static */ RefPtr<UiCompositorControllerChild>
47
UiCompositorControllerChild::CreateForSameProcess(const LayersId& aRootLayerTreeId)
48
0
{
49
0
  RefPtr<UiCompositorControllerChild> child = new UiCompositorControllerChild(0);
50
0
  child->mParent = new UiCompositorControllerParent(aRootLayerTreeId);
51
0
  GetUiThread()->Dispatch(
52
0
    NewRunnableMethod("layers::UiCompositorControllerChild::OpenForSameProcess",
53
0
                      child,
54
0
                      &UiCompositorControllerChild::OpenForSameProcess),
55
0
    nsIThread::DISPATCH_NORMAL);
56
0
  return child;
57
0
}
58
59
/* static */ RefPtr<UiCompositorControllerChild>
60
UiCompositorControllerChild::CreateForGPUProcess(const uint64_t& aProcessToken,
61
                                                 Endpoint<PUiCompositorControllerChild>&& aEndpoint)
62
0
{
63
0
  RefPtr<UiCompositorControllerChild> child = new UiCompositorControllerChild(aProcessToken);
64
0
65
0
  RefPtr<nsIRunnable> task =
66
0
    NewRunnableMethod<Endpoint<PUiCompositorControllerChild>&&>(
67
0
      "layers::UiCompositorControllerChild::OpenForGPUProcess",
68
0
      child,
69
0
      &UiCompositorControllerChild::OpenForGPUProcess,
70
0
      std::move(aEndpoint));
71
0
72
0
  GetUiThread()->Dispatch(task.forget(), nsIThread::DISPATCH_NORMAL);
73
0
  return child;
74
0
}
75
76
bool
77
UiCompositorControllerChild::Pause()
78
0
{
79
0
  if (!mIsOpen) {
80
0
    return false;
81
0
  }
82
0
  return SendPause();
83
0
}
84
85
bool
86
UiCompositorControllerChild::Resume()
87
0
{
88
0
  if (!mIsOpen) {
89
0
    return false;
90
0
  }
91
0
  return SendResume();
92
0
}
93
94
bool
95
UiCompositorControllerChild::ResumeAndResize(const int32_t& aWidth, const int32_t& aHeight)
96
0
{
97
0
  if (!mIsOpen) {
98
0
    mResize = Some(gfx::IntSize(aWidth, aHeight));
99
0
    // Since we are caching these values, pretend the call succeeded.
100
0
    return true;
101
0
  }
102
0
  return SendResumeAndResize(aWidth, aHeight);
103
0
}
104
105
bool
106
UiCompositorControllerChild::InvalidateAndRender()
107
0
{
108
0
  if (!mIsOpen) {
109
0
    return false;
110
0
  }
111
0
  return SendInvalidateAndRender();
112
0
}
113
114
bool
115
UiCompositorControllerChild::SetMaxToolbarHeight(const int32_t& aHeight)
116
0
{
117
0
  if (!mIsOpen) {
118
0
    mMaxToolbarHeight = Some(aHeight);
119
0
    // Since we are caching this value, pretend the call succeeded.
120
0
    return true;
121
0
  }
122
0
  return SendMaxToolbarHeight(aHeight);
123
0
}
124
125
bool
126
UiCompositorControllerChild::SetPinned(const bool& aPinned, const int32_t& aReason)
127
0
{
128
0
  if (!mIsOpen) {
129
0
    return false;
130
0
  }
131
0
  return SendPinned(aPinned, aReason);
132
0
}
133
134
bool
135
UiCompositorControllerChild::ToolbarAnimatorMessageFromUI(const int32_t& aMessage)
136
0
{
137
0
  if (!mIsOpen) {
138
0
    return false;
139
0
  }
140
0
141
0
  if (aMessage == IS_COMPOSITOR_CONTROLLER_OPEN) {
142
0
    RecvToolbarAnimatorMessageFromCompositor(COMPOSITOR_CONTROLLER_OPEN);
143
0
    return true;
144
0
  }
145
0
146
0
  return SendToolbarAnimatorMessageFromUI(aMessage);
147
0
}
148
149
bool
150
UiCompositorControllerChild::SetDefaultClearColor(const uint32_t& aColor)
151
0
{
152
0
  if (!mIsOpen) {
153
0
    mDefaultClearColor = Some(aColor);
154
0
    // Since we are caching this value, pretend the call succeeded.
155
0
    return true;
156
0
  }
157
0
158
0
  return SendDefaultClearColor(aColor);
159
0
}
160
161
bool
162
UiCompositorControllerChild::RequestScreenPixels()
163
0
{
164
0
  if (!mIsOpen) {
165
0
    return false;
166
0
  }
167
0
168
0
  return SendRequestScreenPixels();
169
0
}
170
171
bool
172
UiCompositorControllerChild::EnableLayerUpdateNotifications(const bool& aEnable)
173
0
{
174
0
  if (!mIsOpen) {
175
0
    mLayerUpdateEnabled = Some(aEnable);
176
0
    // Since we are caching this value, pretend the call succeeded.
177
0
    return true;
178
0
  }
179
0
180
0
  return SendEnableLayerUpdateNotifications(aEnable);
181
0
}
182
183
bool
184
UiCompositorControllerChild::ToolbarPixelsToCompositor(Shmem& aMem, const ScreenIntSize& aSize)
185
0
{
186
0
  if (!mIsOpen) {
187
0
    return false;
188
0
  }
189
0
190
0
  return SendToolbarPixelsToCompositor(aMem, aSize);
191
0
}
192
193
void
194
UiCompositorControllerChild::Destroy()
195
0
{
196
0
  if (!IsOnUiThread()) {
197
0
    GetUiThread()->Dispatch(
198
0
      NewRunnableMethod("layers::UiCompositorControllerChild::Destroy",
199
0
                        this,
200
0
                        &UiCompositorControllerChild::Destroy),
201
0
      nsIThread::DISPATCH_SYNC);
202
0
    return;
203
0
  }
204
0
205
0
  if (mIsOpen) {
206
0
    // Close the underlying IPC channel.
207
0
    PUiCompositorControllerChild::Close();
208
0
    mIsOpen = false;
209
0
  }
210
0
}
211
212
void
213
UiCompositorControllerChild::SetBaseWidget(nsBaseWidget* aWidget)
214
0
{
215
0
  mWidget = aWidget;
216
0
}
217
218
bool
219
UiCompositorControllerChild::AllocPixelBuffer(const int32_t aSize, Shmem* aMem)
220
0
{
221
0
  MOZ_ASSERT(aSize > 0);
222
0
  return AllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, aMem);
223
0
}
224
225
bool
226
UiCompositorControllerChild::DeallocPixelBuffer(Shmem& aMem)
227
0
{
228
0
  return DeallocShmem(aMem);
229
0
}
230
231
// protected:
232
void
233
UiCompositorControllerChild::ActorDestroy(ActorDestroyReason aWhy)
234
0
{
235
0
  mIsOpen = false;
236
0
  mParent = nullptr;
237
0
238
0
  if (mProcessToken) {
239
0
    gfx::GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
240
0
    mProcessToken = 0;
241
0
  }
242
0
}
243
244
void
245
UiCompositorControllerChild::DeallocPUiCompositorControllerChild()
246
0
{
247
0
  if (mParent) {
248
0
    mParent = nullptr;
249
0
  }
250
0
  Release();
251
0
}
252
253
void
254
UiCompositorControllerChild::ProcessingError(Result aCode, const char* aReason)
255
0
{
256
0
  MOZ_RELEASE_ASSERT(aCode == MsgDropped, "Processing error in UiCompositorControllerChild");
257
0
}
258
259
void
260
UiCompositorControllerChild::HandleFatalError(const char* aMsg) const
261
0
{
262
0
  dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherPid());
263
0
}
264
265
mozilla::ipc::IPCResult
266
UiCompositorControllerChild::RecvToolbarAnimatorMessageFromCompositor(const int32_t& aMessage)
267
0
{
268
#if defined(MOZ_WIDGET_ANDROID)
269
  if (mWidget) {
270
    mWidget->RecvToolbarAnimatorMessageFromCompositor(aMessage);
271
  }
272
#endif // defined(MOZ_WIDGET_ANDROID)
273
274
0
  return IPC_OK();
275
0
}
276
277
mozilla::ipc::IPCResult
278
UiCompositorControllerChild::RecvRootFrameMetrics(const ScreenPoint& aScrollOffset, const CSSToScreenScale& aZoom)
279
0
{
280
#if defined(MOZ_WIDGET_ANDROID)
281
  if (mWidget) {
282
    mWidget->UpdateRootFrameMetrics(aScrollOffset, aZoom);
283
  }
284
#endif // defined(MOZ_WIDGET_ANDROID)
285
286
0
  return IPC_OK();
287
0
}
288
289
mozilla::ipc::IPCResult
290
UiCompositorControllerChild::RecvScreenPixels(ipc::Shmem&& aMem, const ScreenIntSize& aSize)
291
0
{
292
#if defined(MOZ_WIDGET_ANDROID)
293
  if (mWidget) {
294
    mWidget->RecvScreenPixels(std::move(aMem), aSize);
295
  }
296
#endif // defined(MOZ_WIDGET_ANDROID)
297
298
0
  return IPC_OK();
299
0
}
300
301
// private:
302
UiCompositorControllerChild::UiCompositorControllerChild(const uint64_t& aProcessToken)
303
 : mIsOpen(false)
304
 , mProcessToken(aProcessToken)
305
 , mWidget(nullptr)
306
0
{
307
0
}
308
309
UiCompositorControllerChild::~UiCompositorControllerChild()
310
0
{
311
0
}
312
313
void
314
UiCompositorControllerChild::OpenForSameProcess()
315
0
{
316
0
  MOZ_ASSERT(IsOnUiThread());
317
0
318
0
  mIsOpen = Open(mParent->GetIPCChannel(),
319
0
                 mozilla::layers::CompositorThreadHolder::Loop(),
320
0
                 mozilla::ipc::ChildSide);
321
0
322
0
  if (!mIsOpen) {
323
0
    mParent = nullptr;
324
0
    return;
325
0
  }
326
0
327
0
  mParent->InitializeForSameProcess();
328
0
  AddRef();
329
0
  SendCachedValues();
330
0
  // Let Ui thread know the connection is open;
331
0
  RecvToolbarAnimatorMessageFromCompositor(COMPOSITOR_CONTROLLER_OPEN);
332
0
}
333
334
void
335
UiCompositorControllerChild::OpenForGPUProcess(Endpoint<PUiCompositorControllerChild>&& aEndpoint)
336
0
{
337
0
  MOZ_ASSERT(IsOnUiThread());
338
0
339
0
  mIsOpen = aEndpoint.Bind(this);
340
0
341
0
  if (!mIsOpen) {
342
0
    // The GPU Process Manager might be gone if we receive ActorDestroy very
343
0
    // late in shutdown.
344
0
    if (gfx::GPUProcessManager* gpm = gfx::GPUProcessManager::Get()) {
345
0
      gpm->NotifyRemoteActorDestroyed(mProcessToken);
346
0
    }
347
0
    return;
348
0
  }
349
0
350
0
  AddRef();
351
0
  SendCachedValues();
352
0
  // Let Ui thread know the connection is open;
353
0
  RecvToolbarAnimatorMessageFromCompositor(COMPOSITOR_CONTROLLER_OPEN);
354
0
}
355
356
void
357
UiCompositorControllerChild::SendCachedValues()
358
0
{
359
0
  MOZ_ASSERT(mIsOpen);
360
0
  if (mResize) {
361
0
    SendResumeAndResize(mResize.ref().width, mResize.ref().height);
362
0
    mResize.reset();
363
0
  }
364
0
  if (mMaxToolbarHeight) {
365
0
    SendMaxToolbarHeight(mMaxToolbarHeight.ref());
366
0
    mMaxToolbarHeight.reset();
367
0
  }
368
0
  if (mDefaultClearColor) {
369
0
    SendDefaultClearColor(mDefaultClearColor.ref());
370
0
    mDefaultClearColor.reset();
371
0
  }
372
0
  if (mLayerUpdateEnabled) {
373
0
    SendEnableLayerUpdateNotifications(mLayerUpdateEnabled.ref());
374
0
    mLayerUpdateEnabled.reset();
375
0
  }
376
0
}
377
378
} // namespace layers
379
} // namespace mozilla