Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/ipc/UiCompositorControllerParent.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
#include "UiCompositorControllerParent.h"
7
8
#if defined(MOZ_WIDGET_ANDROID)
9
#include "apz/src/APZCTreeManager.h"
10
#endif
11
#include "mozilla/layers/Compositor.h"
12
#include "mozilla/layers/CompositorBridgeParent.h"
13
#include "mozilla/layers/CompositorThread.h"
14
#include "mozilla/layers/LayerManagerComposite.h"
15
#include "mozilla/gfx/Types.h"
16
#include "mozilla/Move.h"
17
#include "mozilla/Unused.h"
18
19
namespace mozilla {
20
namespace layers {
21
22
typedef CompositorBridgeParent::LayerTreeState LayerTreeState;
23
24
/* static */ RefPtr<UiCompositorControllerParent>
25
UiCompositorControllerParent::GetFromRootLayerTreeId(const LayersId& aRootLayerTreeId)
26
0
{
27
0
  RefPtr<UiCompositorControllerParent> controller;
28
0
  CompositorBridgeParent::CallWithIndirectShadowTree(aRootLayerTreeId,
29
0
    [&](LayerTreeState& aState) -> void {
30
0
      controller = aState.mUiControllerParent;
31
0
    });
32
0
  return controller;
33
0
}
34
35
/* static */ RefPtr<UiCompositorControllerParent>
36
UiCompositorControllerParent::Start(const LayersId& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint)
37
0
{
38
0
  RefPtr<UiCompositorControllerParent> parent = new UiCompositorControllerParent(aRootLayerTreeId);
39
0
40
0
  RefPtr<Runnable> task =
41
0
    NewRunnableMethod<Endpoint<PUiCompositorControllerParent>&&>(
42
0
      "layers::UiCompositorControllerParent::Open",
43
0
      parent,
44
0
      &UiCompositorControllerParent::Open,
45
0
      std::move(aEndpoint));
46
0
  CompositorThreadHolder::Loop()->PostTask(task.forget());
47
0
48
0
  return parent;
49
0
}
50
51
mozilla::ipc::IPCResult
52
UiCompositorControllerParent::RecvPause()
53
0
{
54
0
  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
55
0
  if (parent) {
56
0
    parent->PauseComposition();
57
0
  }
58
0
  return IPC_OK();
59
0
}
60
61
mozilla::ipc::IPCResult
62
UiCompositorControllerParent::RecvResume()
63
0
{
64
0
  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
65
0
  if (parent) {
66
0
    parent->ResumeComposition();
67
0
  }
68
0
  return IPC_OK();
69
0
}
70
71
mozilla::ipc::IPCResult
72
UiCompositorControllerParent::RecvResumeAndResize(const int32_t& aWidth,
73
                                                  const int32_t& aHeight)
74
0
{
75
0
  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
76
0
  if (parent) {
77
0
    // Front-end expects a first paint callback upon resume/resize.
78
0
    parent->ForceIsFirstPaint();
79
0
    parent->ResumeCompositionAndResize(aWidth, aHeight);
80
0
  }
81
0
  return IPC_OK();
82
0
}
83
84
mozilla::ipc::IPCResult
85
UiCompositorControllerParent::RecvInvalidateAndRender()
86
0
{
87
0
  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
88
0
  if (parent) {
89
0
    parent->Invalidate();
90
0
    parent->ScheduleComposition();
91
0
  }
92
0
  return IPC_OK();
93
0
}
94
95
mozilla::ipc::IPCResult
96
UiCompositorControllerParent::RecvMaxToolbarHeight(const int32_t& aHeight)
97
0
{
98
0
  mMaxToolbarHeight = aHeight;
99
#if defined(MOZ_WIDGET_ANDROID)
100
  if (mAnimator) {
101
    mAnimator->SetMaxToolbarHeight(mMaxToolbarHeight);
102
  }
103
#endif // defined(MOZ_WIDGET_ANDROID)
104
105
0
  return IPC_OK();
106
0
}
107
108
mozilla::ipc::IPCResult
109
UiCompositorControllerParent::RecvPinned(const bool& aPinned, const int32_t& aReason)
110
0
{
111
#if defined(MOZ_WIDGET_ANDROID)
112
  if (mAnimator) {
113
    mAnimator->SetPinned(aPinned, aReason);
114
  }
115
#endif // defined(MOZ_WIDGET_ANDROID)
116
117
0
  return IPC_OK();
118
0
}
119
120
mozilla::ipc::IPCResult
121
UiCompositorControllerParent::RecvToolbarAnimatorMessageFromUI(const int32_t& aMessage)
122
0
{
123
#if defined(MOZ_WIDGET_ANDROID)
124
  if (mAnimator) {
125
    mAnimator->ToolbarAnimatorMessageFromUI(aMessage);
126
  }
127
#endif // defined(MOZ_WIDGET_ANDROID)
128
129
0
  return IPC_OK();
130
0
}
131
132
mozilla::ipc::IPCResult
133
UiCompositorControllerParent::RecvDefaultClearColor(const uint32_t& aColor)
134
0
{
135
0
  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
136
0
137
0
  if (state && state->mLayerManager) {
138
0
    Compositor* compositor = state->mLayerManager->GetCompositor();
139
0
    if (compositor) {
140
0
      // Android Color is ARGB which is apparently unusual.
141
0
      compositor->SetDefaultClearColor(gfx::Color::UnusualFromARGB(aColor));
142
0
    }
143
0
  }
144
0
145
0
  return IPC_OK();
146
0
}
147
148
mozilla::ipc::IPCResult
149
UiCompositorControllerParent::RecvRequestScreenPixels()
150
0
{
151
#if defined(MOZ_WIDGET_ANDROID)
152
  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
153
154
  if (state && state->mLayerManager && state->mParent) {
155
    state->mLayerManager->RequestScreenPixels(this);
156
    state->mParent->Invalidate();
157
    state->mParent->ScheduleComposition();
158
  }
159
#endif // defined(MOZ_WIDGET_ANDROID)
160
161
0
  return IPC_OK();
162
0
}
163
164
mozilla::ipc::IPCResult
165
UiCompositorControllerParent::RecvEnableLayerUpdateNotifications(const bool& aEnable)
166
0
{
167
#if defined(MOZ_WIDGET_ANDROID)
168
  if (mAnimator) {
169
    mAnimator->EnableLayersUpdateNotifications(aEnable);
170
  }
171
#endif // defined(MOZ_WIDGET_ANDROID)
172
173
0
  return IPC_OK();
174
0
}
175
176
mozilla::ipc::IPCResult
177
UiCompositorControllerParent::RecvToolbarPixelsToCompositor(Shmem&& aMem, const ScreenIntSize& aSize)
178
0
{
179
#if defined(MOZ_WIDGET_ANDROID)
180
  if (mAnimator) {
181
    // By adopting the Shmem, the animator is responsible for deallocating.
182
    mAnimator->AdoptToolbarPixels(std::move(aMem), aSize);
183
  } else {
184
    DeallocShmem(aMem);
185
  }
186
#endif // defined(MOZ_WIDGET_ANDROID)
187
188
0
  return IPC_OK();
189
0
}
190
191
void
192
UiCompositorControllerParent::ActorDestroy(ActorDestroyReason aWhy)
193
0
{
194
0
}
195
196
void
197
UiCompositorControllerParent::DeallocPUiCompositorControllerParent()
198
0
{
199
0
  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
200
0
  Shutdown();
201
0
  Release(); // For AddRef in Initialize()
202
0
}
203
204
#if defined(MOZ_WIDGET_ANDROID)
205
void
206
UiCompositorControllerParent::RegisterAndroidDynamicToolbarAnimator(AndroidDynamicToolbarAnimator* aAnimator)
207
{
208
  MOZ_ASSERT(!mAnimator);
209
  mAnimator = aAnimator;
210
  if (mAnimator) {
211
    mAnimator->SetMaxToolbarHeight(mMaxToolbarHeight);
212
  }
213
}
214
#endif // defined(MOZ_WIDGET_ANDROID)
215
216
void
217
UiCompositorControllerParent::ToolbarAnimatorMessageFromCompositor(int32_t aMessage)
218
0
{
219
0
  // This function can be call from ether compositor or controller thread.
220
0
  if (!CompositorThreadHolder::IsInCompositorThread()) {
221
0
    CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod<int32_t>(
222
0
      "layers::UiCompositorControllerParent::"
223
0
      "ToolbarAnimatorMessageFromCompositor",
224
0
      this,
225
0
      &UiCompositorControllerParent::ToolbarAnimatorMessageFromCompositor,
226
0
      aMessage));
227
0
    return;
228
0
  }
229
0
230
0
  Unused << SendToolbarAnimatorMessageFromCompositor(aMessage);
231
0
}
232
233
bool
234
UiCompositorControllerParent::AllocPixelBuffer(const int32_t aSize, ipc::Shmem* aMem)
235
0
{
236
0
  MOZ_ASSERT(aSize > 0);
237
0
  return AllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, aMem);
238
0
}
239
240
UiCompositorControllerParent::UiCompositorControllerParent(const LayersId& aRootLayerTreeId)
241
  : mRootLayerTreeId(aRootLayerTreeId)
242
  , mMaxToolbarHeight(0)
243
0
{
244
0
  MOZ_COUNT_CTOR(UiCompositorControllerParent);
245
0
}
246
247
UiCompositorControllerParent::~UiCompositorControllerParent()
248
0
{
249
0
  MOZ_COUNT_DTOR(UiCompositorControllerParent);
250
0
}
251
252
void
253
UiCompositorControllerParent::InitializeForSameProcess()
254
0
{
255
0
  // This function is called by UiCompositorControllerChild in the main thread.
256
0
  // So dispatch to the compositor thread to Initialize.
257
0
  if (!CompositorThreadHolder::IsInCompositorThread()) {
258
0
    CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod(
259
0
      "layers::UiCompositorControllerParent::InitializeForSameProcess",
260
0
      this,
261
0
      &UiCompositorControllerParent::InitializeForSameProcess));
262
0
    return;
263
0
  }
264
0
265
0
  Initialize();
266
0
}
267
268
void
269
UiCompositorControllerParent::InitializeForOutOfProcess()
270
0
{
271
0
  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
272
0
  Initialize();
273
0
}
274
275
void
276
UiCompositorControllerParent::Initialize()
277
0
{
278
0
  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
279
0
  AddRef();
280
0
  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
281
0
  MOZ_ASSERT(state);
282
0
  MOZ_ASSERT(state->mParent);
283
0
  state->mUiControllerParent = this;
284
#if defined(MOZ_WIDGET_ANDROID)
285
  AndroidDynamicToolbarAnimator* animator = state->mParent->GetAndroidDynamicToolbarAnimator();
286
  // It is possible the compositor has already started shutting down and
287
  // the AndroidDynamicToolbarAnimator could be a nullptr.
288
  if (animator) {
289
    animator->Initialize(mRootLayerTreeId);
290
  }
291
#endif
292
}
293
294
void
295
UiCompositorControllerParent::Open(Endpoint<PUiCompositorControllerParent>&& aEndpoint)
296
0
{
297
0
  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
298
0
  if (!aEndpoint.Bind(this)) {
299
0
    // We can't recover from this.
300
0
    MOZ_CRASH("Failed to bind UiCompositorControllerParent to endpoint");
301
0
  }
302
0
  InitializeForOutOfProcess();
303
0
}
304
305
void
306
UiCompositorControllerParent::Shutdown()
307
0
{
308
0
  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
309
#if defined(MOZ_WIDGET_ANDROID)
310
  if (mAnimator) {
311
    mAnimator->Shutdown();
312
  }
313
#endif // defined(MOZ_WIDGET_ANDROID)
314
  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
315
0
  if (state) {
316
0
    state->mUiControllerParent = nullptr;
317
0
  }
318
0
}
319
320
} // namespace layers
321
} // namespace mozilla