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