gfx/layers/ipc/CompositorChild.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
    20 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
    21 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop, etc
    22 #include "FrameLayerBuilder.h"
    23 #include "mozilla/dom/TabChild.h"
    25 using mozilla::layers::LayerTransactionChild;
    27 namespace mozilla {
    28 namespace layers {
    30 /*static*/ CompositorChild* CompositorChild::sCompositor;
    32 Atomic<int32_t> CompositableForwarder::sSerialCounter(0);
    34 CompositorChild::CompositorChild(ClientLayerManager *aLayerManager)
    35   : mLayerManager(aLayerManager)
    36 {
    37   MOZ_COUNT_CTOR(CompositorChild);
    38 }
    40 CompositorChild::~CompositorChild()
    41 {
    42   MOZ_COUNT_DTOR(CompositorChild);
    43 }
    45 void
    46 CompositorChild::Destroy()
    47 {
    48   mLayerManager->Destroy();
    49   mLayerManager = nullptr;
    50   while (size_t len = ManagedPLayerTransactionChild().Length()) {
    51     LayerTransactionChild* layers =
    52       static_cast<LayerTransactionChild*>(ManagedPLayerTransactionChild()[len - 1]);
    53     layers->Destroy();
    54   }
    55   SendStop();
    56 }
    58 bool
    59 CompositorChild::LookupCompositorFrameMetrics(const FrameMetrics::ViewID aId,
    60                                               FrameMetrics& aFrame)
    61 {
    62   SharedFrameMetricsData* data = mFrameMetricsTable.Get(aId);
    63   if (data) {
    64     data->CopyFrameMetrics(&aFrame);
    65     return true;
    66   }
    67   return false;
    68 }
    70 /*static*/ PCompositorChild*
    71 CompositorChild::Create(Transport* aTransport, ProcessId aOtherProcess)
    72 {
    73   // There's only one compositor per child process.
    74   MOZ_ASSERT(!sCompositor);
    76   nsRefPtr<CompositorChild> child(new CompositorChild(nullptr));
    77   ProcessHandle handle;
    78   if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
    79     // We can't go on without a compositor.
    80     NS_RUNTIMEABORT("Couldn't OpenProcessHandle() to parent process.");
    81     return nullptr;
    82   }
    83   if (!child->Open(aTransport, handle, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
    84     NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
    85     return nullptr;
    86   }
    87   // We release this ref in ActorDestroy().
    88   return sCompositor = child.forget().take();
    89 }
    91 /*static*/ CompositorChild*
    92 CompositorChild::Get()
    93 {
    94   // This is only expected to be used in child processes.
    95   MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
    96   return sCompositor;
    97 }
    99 PLayerTransactionChild*
   100 CompositorChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
   101                                              const uint64_t& aId,
   102                                              TextureFactoryIdentifier*,
   103                                              bool*)
   104 {
   105   LayerTransactionChild* c = new LayerTransactionChild();
   106   c->AddIPDLReference();
   107   return c;
   108 }
   110 bool
   111 CompositorChild::DeallocPLayerTransactionChild(PLayerTransactionChild* actor)
   112 {
   113   static_cast<LayerTransactionChild*>(actor)->ReleaseIPDLReference();
   114   return true;
   115 }
   117 bool
   118 CompositorChild::RecvInvalidateAll()
   119 {
   120   FrameLayerBuilder::InvalidateAllLayers(mLayerManager);
   121   return true;
   122 }
   124 bool
   125 CompositorChild::RecvDidComposite(const uint64_t& aId)
   126 {
   127   if (mLayerManager) {
   128     MOZ_ASSERT(aId == 0);
   129     mLayerManager->DidComposite();
   130   } else if (aId != 0) {
   131     dom::TabChild *child = dom::TabChild::GetFrom(aId);
   132     if (child) {
   133       child->DidComposite();
   134     }
   135   }
   136   return true;
   137 }
   139 void
   140 CompositorChild::ActorDestroy(ActorDestroyReason aWhy)
   141 {
   142   MOZ_ASSERT(sCompositor == this);
   144 #ifdef MOZ_B2G
   145   // Due to poor lifetime management of gralloc (and possibly shmems) we will
   146   // crash at some point in the future when we get destroyed due to abnormal
   147   // shutdown. Its better just to crash here. On desktop though, we have a chance
   148   // of recovering.
   149   if (aWhy == AbnormalShutdown) {
   150     NS_RUNTIMEABORT("ActorDestroy by IPC channel failure at CompositorChild");
   151   }
   152 #endif
   153   if (sCompositor) {
   154     sCompositor->Release();
   155     sCompositor = nullptr;
   156   }
   157   // We don't want to release the ref to sCompositor here, during
   158   // cleanup, because that will cause it to be deleted while it's
   159   // still being used.  So defer the deletion to after it's not in
   160   // use.
   161   MessageLoop::current()->PostTask(
   162     FROM_HERE,
   163     NewRunnableMethod(this, &CompositorChild::Release));
   164 }
   166 bool
   167 CompositorChild::RecvSharedCompositorFrameMetrics(
   168     const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
   169     const CrossProcessMutexHandle& handle,
   170     const uint32_t& aAPZCId)
   171 {
   172   SharedFrameMetricsData* data = new SharedFrameMetricsData(metrics, handle, aAPZCId);
   173   mFrameMetricsTable.Put(data->GetViewID(), data);
   174   return true;
   175 }
   177 bool
   178 CompositorChild::RecvReleaseSharedCompositorFrameMetrics(
   179     const ViewID& aId,
   180     const uint32_t& aAPZCId)
   181 {
   182   SharedFrameMetricsData* data = mFrameMetricsTable.Get(aId);
   183   // The SharedFrameMetricsData may have been removed previously if
   184   // a SharedFrameMetricsData with the same ViewID but later APZCId had
   185   // been store and over wrote it.
   186   if (data && (data->GetAPZCId() == aAPZCId)) {
   187     mFrameMetricsTable.Remove(aId);
   188   }
   189   return true;
   190 }
   192 CompositorChild::SharedFrameMetricsData::SharedFrameMetricsData(
   193     const ipc::SharedMemoryBasic::Handle& metrics,
   194     const CrossProcessMutexHandle& handle,
   195     const uint32_t& aAPZCId) :
   196     mBuffer(nullptr),
   197     mMutex(nullptr),
   198     mAPZCId(aAPZCId)
   199 {
   200   mBuffer = new ipc::SharedMemoryBasic(metrics);
   201   mBuffer->Map(sizeof(FrameMetrics));
   202   mMutex = new CrossProcessMutex(handle);
   203   MOZ_COUNT_CTOR(SharedFrameMetricsData);
   204 }
   206 CompositorChild::SharedFrameMetricsData::~SharedFrameMetricsData()
   207 {
   208   // When the hash table deletes the class, delete
   209   // the shared memory and mutex.
   210   delete mMutex;
   211   delete mBuffer;
   212   MOZ_COUNT_DTOR(SharedFrameMetricsData);
   213 }
   215 void
   216 CompositorChild::SharedFrameMetricsData::CopyFrameMetrics(FrameMetrics* aFrame)
   217 {
   218   FrameMetrics* frame = static_cast<FrameMetrics*>(mBuffer->memory());
   219   MOZ_ASSERT(frame);
   220   mMutex->Lock();
   221   *aFrame = *frame;
   222   mMutex->Unlock();
   223 }
   225 FrameMetrics::ViewID
   226 CompositorChild::SharedFrameMetricsData::GetViewID()
   227 {
   228   FrameMetrics* frame = static_cast<FrameMetrics*>(mBuffer->memory());
   229   MOZ_ASSERT(frame);
   230   // Not locking to read of mScrollId since it should not change after being
   231   // initially set.
   232   return frame->GetScrollId();
   233 }
   235 uint32_t
   236 CompositorChild::SharedFrameMetricsData::GetAPZCId()
   237 {
   238   return mAPZCId;
   239 }
   241 } // namespace layers
   242 } // namespace mozilla

mercurial