1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/ipc/CompositorChild.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,243 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=2 et tw=80 : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "CompositorChild.h" 1.11 +#include <stddef.h> // for size_t 1.12 +#include "ClientLayerManager.h" // for ClientLayerManager 1.13 +#include "base/message_loop.h" // for MessageLoop 1.14 +#include "base/process_util.h" // for OpenProcessHandle 1.15 +#include "base/task.h" // for NewRunnableMethod, etc 1.16 +#include "base/tracked.h" // for FROM_HERE 1.17 +#include "mozilla/layers/LayerTransactionChild.h" 1.18 +#include "mozilla/layers/PLayerTransactionChild.h" 1.19 +#include "mozilla/mozalloc.h" // for operator new, etc 1.20 +#include "nsDebug.h" // for NS_RUNTIMEABORT 1.21 +#include "nsIObserver.h" // for nsIObserver 1.22 +#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc 1.23 +#include "nsTArray.h" // for nsTArray, nsTArray_Impl 1.24 +#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop, etc 1.25 +#include "FrameLayerBuilder.h" 1.26 +#include "mozilla/dom/TabChild.h" 1.27 + 1.28 +using mozilla::layers::LayerTransactionChild; 1.29 + 1.30 +namespace mozilla { 1.31 +namespace layers { 1.32 + 1.33 +/*static*/ CompositorChild* CompositorChild::sCompositor; 1.34 + 1.35 +Atomic<int32_t> CompositableForwarder::sSerialCounter(0); 1.36 + 1.37 +CompositorChild::CompositorChild(ClientLayerManager *aLayerManager) 1.38 + : mLayerManager(aLayerManager) 1.39 +{ 1.40 + MOZ_COUNT_CTOR(CompositorChild); 1.41 +} 1.42 + 1.43 +CompositorChild::~CompositorChild() 1.44 +{ 1.45 + MOZ_COUNT_DTOR(CompositorChild); 1.46 +} 1.47 + 1.48 +void 1.49 +CompositorChild::Destroy() 1.50 +{ 1.51 + mLayerManager->Destroy(); 1.52 + mLayerManager = nullptr; 1.53 + while (size_t len = ManagedPLayerTransactionChild().Length()) { 1.54 + LayerTransactionChild* layers = 1.55 + static_cast<LayerTransactionChild*>(ManagedPLayerTransactionChild()[len - 1]); 1.56 + layers->Destroy(); 1.57 + } 1.58 + SendStop(); 1.59 +} 1.60 + 1.61 +bool 1.62 +CompositorChild::LookupCompositorFrameMetrics(const FrameMetrics::ViewID aId, 1.63 + FrameMetrics& aFrame) 1.64 +{ 1.65 + SharedFrameMetricsData* data = mFrameMetricsTable.Get(aId); 1.66 + if (data) { 1.67 + data->CopyFrameMetrics(&aFrame); 1.68 + return true; 1.69 + } 1.70 + return false; 1.71 +} 1.72 + 1.73 +/*static*/ PCompositorChild* 1.74 +CompositorChild::Create(Transport* aTransport, ProcessId aOtherProcess) 1.75 +{ 1.76 + // There's only one compositor per child process. 1.77 + MOZ_ASSERT(!sCompositor); 1.78 + 1.79 + nsRefPtr<CompositorChild> child(new CompositorChild(nullptr)); 1.80 + ProcessHandle handle; 1.81 + if (!base::OpenProcessHandle(aOtherProcess, &handle)) { 1.82 + // We can't go on without a compositor. 1.83 + NS_RUNTIMEABORT("Couldn't OpenProcessHandle() to parent process."); 1.84 + return nullptr; 1.85 + } 1.86 + if (!child->Open(aTransport, handle, XRE_GetIOMessageLoop(), ipc::ChildSide)) { 1.87 + NS_RUNTIMEABORT("Couldn't Open() Compositor channel."); 1.88 + return nullptr; 1.89 + } 1.90 + // We release this ref in ActorDestroy(). 1.91 + return sCompositor = child.forget().take(); 1.92 +} 1.93 + 1.94 +/*static*/ CompositorChild* 1.95 +CompositorChild::Get() 1.96 +{ 1.97 + // This is only expected to be used in child processes. 1.98 + MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default); 1.99 + return sCompositor; 1.100 +} 1.101 + 1.102 +PLayerTransactionChild* 1.103 +CompositorChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints, 1.104 + const uint64_t& aId, 1.105 + TextureFactoryIdentifier*, 1.106 + bool*) 1.107 +{ 1.108 + LayerTransactionChild* c = new LayerTransactionChild(); 1.109 + c->AddIPDLReference(); 1.110 + return c; 1.111 +} 1.112 + 1.113 +bool 1.114 +CompositorChild::DeallocPLayerTransactionChild(PLayerTransactionChild* actor) 1.115 +{ 1.116 + static_cast<LayerTransactionChild*>(actor)->ReleaseIPDLReference(); 1.117 + return true; 1.118 +} 1.119 + 1.120 +bool 1.121 +CompositorChild::RecvInvalidateAll() 1.122 +{ 1.123 + FrameLayerBuilder::InvalidateAllLayers(mLayerManager); 1.124 + return true; 1.125 +} 1.126 + 1.127 +bool 1.128 +CompositorChild::RecvDidComposite(const uint64_t& aId) 1.129 +{ 1.130 + if (mLayerManager) { 1.131 + MOZ_ASSERT(aId == 0); 1.132 + mLayerManager->DidComposite(); 1.133 + } else if (aId != 0) { 1.134 + dom::TabChild *child = dom::TabChild::GetFrom(aId); 1.135 + if (child) { 1.136 + child->DidComposite(); 1.137 + } 1.138 + } 1.139 + return true; 1.140 +} 1.141 + 1.142 +void 1.143 +CompositorChild::ActorDestroy(ActorDestroyReason aWhy) 1.144 +{ 1.145 + MOZ_ASSERT(sCompositor == this); 1.146 + 1.147 +#ifdef MOZ_B2G 1.148 + // Due to poor lifetime management of gralloc (and possibly shmems) we will 1.149 + // crash at some point in the future when we get destroyed due to abnormal 1.150 + // shutdown. Its better just to crash here. On desktop though, we have a chance 1.151 + // of recovering. 1.152 + if (aWhy == AbnormalShutdown) { 1.153 + NS_RUNTIMEABORT("ActorDestroy by IPC channel failure at CompositorChild"); 1.154 + } 1.155 +#endif 1.156 + if (sCompositor) { 1.157 + sCompositor->Release(); 1.158 + sCompositor = nullptr; 1.159 + } 1.160 + // We don't want to release the ref to sCompositor here, during 1.161 + // cleanup, because that will cause it to be deleted while it's 1.162 + // still being used. So defer the deletion to after it's not in 1.163 + // use. 1.164 + MessageLoop::current()->PostTask( 1.165 + FROM_HERE, 1.166 + NewRunnableMethod(this, &CompositorChild::Release)); 1.167 +} 1.168 + 1.169 +bool 1.170 +CompositorChild::RecvSharedCompositorFrameMetrics( 1.171 + const mozilla::ipc::SharedMemoryBasic::Handle& metrics, 1.172 + const CrossProcessMutexHandle& handle, 1.173 + const uint32_t& aAPZCId) 1.174 +{ 1.175 + SharedFrameMetricsData* data = new SharedFrameMetricsData(metrics, handle, aAPZCId); 1.176 + mFrameMetricsTable.Put(data->GetViewID(), data); 1.177 + return true; 1.178 +} 1.179 + 1.180 +bool 1.181 +CompositorChild::RecvReleaseSharedCompositorFrameMetrics( 1.182 + const ViewID& aId, 1.183 + const uint32_t& aAPZCId) 1.184 +{ 1.185 + SharedFrameMetricsData* data = mFrameMetricsTable.Get(aId); 1.186 + // The SharedFrameMetricsData may have been removed previously if 1.187 + // a SharedFrameMetricsData with the same ViewID but later APZCId had 1.188 + // been store and over wrote it. 1.189 + if (data && (data->GetAPZCId() == aAPZCId)) { 1.190 + mFrameMetricsTable.Remove(aId); 1.191 + } 1.192 + return true; 1.193 +} 1.194 + 1.195 +CompositorChild::SharedFrameMetricsData::SharedFrameMetricsData( 1.196 + const ipc::SharedMemoryBasic::Handle& metrics, 1.197 + const CrossProcessMutexHandle& handle, 1.198 + const uint32_t& aAPZCId) : 1.199 + mBuffer(nullptr), 1.200 + mMutex(nullptr), 1.201 + mAPZCId(aAPZCId) 1.202 +{ 1.203 + mBuffer = new ipc::SharedMemoryBasic(metrics); 1.204 + mBuffer->Map(sizeof(FrameMetrics)); 1.205 + mMutex = new CrossProcessMutex(handle); 1.206 + MOZ_COUNT_CTOR(SharedFrameMetricsData); 1.207 +} 1.208 + 1.209 +CompositorChild::SharedFrameMetricsData::~SharedFrameMetricsData() 1.210 +{ 1.211 + // When the hash table deletes the class, delete 1.212 + // the shared memory and mutex. 1.213 + delete mMutex; 1.214 + delete mBuffer; 1.215 + MOZ_COUNT_DTOR(SharedFrameMetricsData); 1.216 +} 1.217 + 1.218 +void 1.219 +CompositorChild::SharedFrameMetricsData::CopyFrameMetrics(FrameMetrics* aFrame) 1.220 +{ 1.221 + FrameMetrics* frame = static_cast<FrameMetrics*>(mBuffer->memory()); 1.222 + MOZ_ASSERT(frame); 1.223 + mMutex->Lock(); 1.224 + *aFrame = *frame; 1.225 + mMutex->Unlock(); 1.226 +} 1.227 + 1.228 +FrameMetrics::ViewID 1.229 +CompositorChild::SharedFrameMetricsData::GetViewID() 1.230 +{ 1.231 + FrameMetrics* frame = static_cast<FrameMetrics*>(mBuffer->memory()); 1.232 + MOZ_ASSERT(frame); 1.233 + // Not locking to read of mScrollId since it should not change after being 1.234 + // initially set. 1.235 + return frame->GetScrollId(); 1.236 +} 1.237 + 1.238 +uint32_t 1.239 +CompositorChild::SharedFrameMetricsData::GetAPZCId() 1.240 +{ 1.241 + return mAPZCId; 1.242 +} 1.243 + 1.244 +} // namespace layers 1.245 +} // namespace mozilla 1.246 +