1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=2 et 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/. */
7 #include "CompositorChild.h"
8 #include <stddef.h> // for size_t
9 #include "ClientLayerManager.h" // for ClientLayerManager
10 #include "base/message_loop.h" // for MessageLoop
11 #include "base/process_util.h" // for OpenProcessHandle
12 #include "base/task.h" // for NewRunnableMethod, etc
13 #include "base/tracked.h" // for FROM_HERE
14 #include "mozilla/layers/LayerTransactionChild.h"
15 #include "mozilla/layers/PLayerTransactionChild.h"
16 #include "mozilla/mozalloc.h" // for operator new, etc
17 #include "nsDebug.h" // for NS_RUNTIMEABORT
18 #include "nsIObserver.h" // for nsIObserver
19 #include "nsTArray.h" // for nsTArray, nsTArray_Impl
20 #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
21 #include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop, etc
22 #include "FrameLayerBuilder.h"
24 using mozilla::layers::LayerTransactionChild
;
29 /*static*/ CompositorChild
* CompositorChild::sCompositor
;
31 CompositorChild::CompositorChild(ClientLayerManager
*aLayerManager
)
32 : mLayerManager(aLayerManager
)
34 MOZ_COUNT_CTOR(CompositorChild
);
37 CompositorChild::~CompositorChild()
39 MOZ_COUNT_DTOR(CompositorChild
);
43 CompositorChild::Destroy()
45 mLayerManager
->Destroy();
46 mLayerManager
= nullptr;
47 while (size_t len
= ManagedPLayerTransactionChild().Length()) {
48 LayerTransactionChild
* layers
=
49 static_cast<LayerTransactionChild
*>(ManagedPLayerTransactionChild()[len
- 1]);
55 /*static*/ PCompositorChild
*
56 CompositorChild::Create(Transport
* aTransport
, ProcessId aOtherProcess
)
58 // There's only one compositor per child process.
59 MOZ_ASSERT(!sCompositor
);
61 nsRefPtr
<CompositorChild
> child(new CompositorChild(nullptr));
63 if (!base::OpenProcessHandle(aOtherProcess
, &handle
)) {
64 // We can't go on without a compositor.
65 NS_RUNTIMEABORT("Couldn't OpenProcessHandle() to parent process.");
68 if (!child
->Open(aTransport
, handle
, XRE_GetIOMessageLoop(), ipc::ChildSide
)) {
69 NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
72 // We release this ref in ActorDestroy().
73 return sCompositor
= child
.forget().get();
76 /*static*/ PCompositorChild
*
77 CompositorChild::Get()
79 // This is only expected to be used in child processes.
80 MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default
);
84 PLayerTransactionChild
*
85 CompositorChild::AllocPLayerTransactionChild(const nsTArray
<LayersBackend
>& aBackendHints
,
87 TextureFactoryIdentifier
*,
90 return new LayerTransactionChild();
94 CompositorChild::DeallocPLayerTransactionChild(PLayerTransactionChild
* actor
)
101 CompositorChild::RecvInvalidateAll()
103 FrameLayerBuilder::InvalidateAllLayers(mLayerManager
);
108 CompositorChild::ActorDestroy(ActorDestroyReason aWhy
)
110 MOZ_ASSERT(sCompositor
== this);
113 // Due to poor lifetime management of gralloc (and possibly shmems) we will
114 // crash at some point in the future when we get destroyed due to abnormal
115 // shutdown. Its better just to crash here. On desktop though, we have a chance
117 if (aWhy
== AbnormalShutdown
) {
118 NS_RUNTIMEABORT("ActorDestroy by IPC channel failure at CompositorChild");
122 sCompositor
= nullptr;
123 // We don't want to release the ref to sCompositor here, during
124 // cleanup, because that will cause it to be deleted while it's
125 // still being used. So defer the deletion to after it's not in
127 MessageLoop::current()->PostTask(
129 NewRunnableMethod(this, &CompositorChild::Release
));
133 } // namespace layers
134 } // namespace mozilla