gfx/layers/ipc/ImageBridgeParent.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* vim: set ts=2 sw=2 et tw=80: */
     2 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     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 "ImageBridgeParent.h"
     8 #include <stdint.h>                     // for uint64_t, uint32_t
     9 #include "CompositableHost.h"           // for CompositableParent, Create
    10 #include "base/message_loop.h"          // for MessageLoop
    11 #include "base/process.h"               // for ProcessHandle
    12 #include "base/process_util.h"          // for OpenProcessHandle
    13 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
    14 #include "base/tracked.h"               // for FROM_HERE
    15 #include "mozilla/gfx/Point.h"          // for IntSize
    16 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
    17 #include "mozilla/ipc/ProtocolUtils.h"
    18 #include "mozilla/ipc/Transport.h"      // for Transport
    19 #include "mozilla/layers/CompositableTransactionParent.h"
    20 #include "mozilla/layers/CompositorParent.h"  // for CompositorParent
    21 #include "mozilla/layers/LayerManagerComposite.h"
    22 #include "mozilla/layers/LayersMessages.h"  // for EditReply
    23 #include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferParent
    24 #include "mozilla/layers/PCompositableParent.h"
    25 #include "mozilla/layers/PImageBridgeParent.h"
    26 #include "mozilla/layers/Compositor.h"
    27 #include "mozilla/mozalloc.h"           // for operator new, etc
    28 #include "nsAutoPtr.h"                  // for nsRefPtr
    29 #include "nsDebug.h"                    // for NS_RUNTIMEABORT, etc
    30 #include "nsISupportsImpl.h"            // for ImageBridgeParent::Release, etc
    31 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
    32 #include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
    33 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop
    34 #include "mozilla/layers/TextureHost.h"
    35 #include "nsThreadUtils.h"
    37 using namespace mozilla::ipc;
    38 using namespace mozilla::gfx;
    40 namespace mozilla {
    41 namespace layers {
    43 class PGrallocBufferParent;
    45 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport)
    46   : mMessageLoop(aLoop)
    47   , mTransport(aTransport)
    48 {
    49   // creates the map only if it has not been created already, so it is safe
    50   // with several bridges
    51   CompositableMap::Create();
    52 }
    54 ImageBridgeParent::~ImageBridgeParent()
    55 {
    56   if (mTransport) {
    57     XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
    58                                      new DeleteTask<Transport>(mTransport));
    59   }
    60 }
    62 LayersBackend
    63 ImageBridgeParent::GetCompositorBackendType() const
    64 {
    65   return Compositor::GetBackend();
    66 }
    68 void
    69 ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
    70 {
    71   MessageLoop::current()->PostTask(
    72     FROM_HERE,
    73     NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));
    74 }
    76 bool
    77 ImageBridgeParent::RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply)
    78 {
    79   // If we don't actually have a compositor, then don't bother
    80   // creating any textures.
    81   if (Compositor::GetBackend() == LayersBackend::LAYERS_NONE) {
    82     return true;
    83   }
    85   // Clear fence handles used in previsou transaction.
    86   ClearPrevFenceHandles();
    88   EditReplyVector replyv;
    89   for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
    90     if (!ReceiveCompositableUpdate(aEdits[i], replyv)) {
    91       return false;
    92     }
    93   }
    95   aReply->SetCapacity(replyv.size());
    96   if (replyv.size() > 0) {
    97     aReply->AppendElements(&replyv.front(), replyv.size());
    98   }
   100   // Ensure that any pending operations involving back and front
   101   // buffers have completed, so that neither process stomps on the
   102   // other's buffer contents.
   103   LayerManagerComposite::PlatformSyncBeforeReplyUpdate();
   105   return true;
   106 }
   108 bool
   109 ImageBridgeParent::RecvUpdateNoSwap(const EditArray& aEdits)
   110 {
   111   InfallibleTArray<EditReply> noReplies;
   112   bool success = RecvUpdate(aEdits, &noReplies);
   113   NS_ABORT_IF_FALSE(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits");
   114   return success;
   115 }
   117 static void
   118 ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
   119                                   Transport* aTransport,
   120                                   base::ProcessHandle aOtherProcess)
   121 {
   122   aBridge->Open(aTransport, aOtherProcess, XRE_GetIOMessageLoop(), ipc::ParentSide);
   123 }
   125 /*static*/ PImageBridgeParent*
   126 ImageBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
   127 {
   128   base::ProcessHandle processHandle;
   129   if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
   130     return nullptr;
   131   }
   133   MessageLoop* loop = CompositorParent::CompositorLoop();
   134   nsRefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport);
   135   bridge->mSelfRef = bridge;
   136   loop->PostTask(FROM_HERE,
   137                  NewRunnableFunction(ConnectImageBridgeInParentProcess,
   138                                      bridge.get(), aTransport, processHandle));
   139   return bridge.get();
   140 }
   142 bool ImageBridgeParent::RecvWillStop()
   143 {
   144   // If there is any texture still alive we have to force it to deallocate the
   145   // device data (GL textures, etc.) now because shortly after SenStop() returns
   146   // on the child side the widget will be destroyed along with it's associated
   147   // GL context.
   148   InfallibleTArray<PTextureParent*> textures;
   149   ManagedPTextureParent(textures);
   150   for (unsigned int i = 0; i < textures.Length(); ++i) {
   151     RefPtr<TextureHost> tex = TextureHost::AsTextureHost(textures[i]);
   152     tex->DeallocateDeviceData();
   153   }
   154   return true;
   155 }
   157 bool ImageBridgeParent::RecvStop()
   158 {
   159   // Nothing to do. This message just serves as synchronization between the
   160   // child and parent threads during shutdown.
   161   return true;
   162 }
   164 static  uint64_t GenImageContainerID() {
   165   static uint64_t sNextImageID = 1;
   167   ++sNextImageID;
   168   return sNextImageID;
   169 }
   171 PGrallocBufferParent*
   172 ImageBridgeParent::AllocPGrallocBufferParent(const IntSize& aSize,
   173                                              const uint32_t& aFormat,
   174                                              const uint32_t& aUsage,
   175                                              MaybeMagicGrallocBufferHandle* aOutHandle)
   176 {
   177 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
   178   return GrallocBufferActor::Create(aSize, aFormat, aUsage, aOutHandle);
   179 #else
   180   NS_RUNTIMEABORT("No gralloc buffers for you");
   181   return nullptr;
   182 #endif
   183 }
   185 bool
   186 ImageBridgeParent::DeallocPGrallocBufferParent(PGrallocBufferParent* actor)
   187 {
   188 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
   189   delete actor;
   190   return true;
   191 #else
   192   NS_RUNTIMEABORT("Um, how did we get here?");
   193   return false;
   194 #endif
   195 }
   197 PCompositableParent*
   198 ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo,
   199                                             uint64_t* aID)
   200 {
   201   uint64_t id = GenImageContainerID();
   202   *aID = id;
   203   return CompositableHost::CreateIPDLActor(this, aInfo, id);
   204 }
   206 bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
   207 {
   208   return CompositableHost::DestroyIPDLActor(aActor);
   209 }
   211 PTextureParent*
   212 ImageBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
   213                                        const TextureFlags& aFlags)
   214 {
   215   return TextureHost::CreateIPDLActor(this, aSharedData, aFlags);
   216 }
   218 bool
   219 ImageBridgeParent::DeallocPTextureParent(PTextureParent* actor)
   220 {
   221   return TextureHost::DestroyIPDLActor(actor);
   222 }
   224 MessageLoop * ImageBridgeParent::GetMessageLoop() {
   225   return mMessageLoop;
   226 }
   228 class ReleaseRunnable : public nsRunnable
   229 {
   230 public:
   231   ReleaseRunnable(ImageBridgeParent* aRef)
   232     : mRef(aRef)
   233   {
   234   }
   236   NS_IMETHOD Run()
   237   {
   238     mRef->Release();
   239     return NS_OK;
   240   }
   242 private:
   243   ImageBridgeParent* mRef;
   244 };
   246 void
   247 ImageBridgeParent::DeferredDestroy()
   248 {
   249   ImageBridgeParent* self;
   250   mSelfRef.forget(&self);
   252   nsCOMPtr<nsIRunnable> runnable = new ReleaseRunnable(self);
   253   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
   254 }
   256 IToplevelProtocol*
   257 ImageBridgeParent::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
   258                                  base::ProcessHandle aPeerProcess,
   259                                  mozilla::ipc::ProtocolCloneContext* aCtx)
   260 {
   261   for (unsigned int i = 0; i < aFds.Length(); i++) {
   262     if (aFds[i].protocolId() == unsigned(GetProtocolId())) {
   263       Transport* transport = OpenDescriptor(aFds[i].fd(),
   264                                             Transport::MODE_SERVER);
   265       PImageBridgeParent* bridge = Create(transport, base::GetProcId(aPeerProcess));
   266       bridge->CloneManagees(this, aCtx);
   267       bridge->IToplevelProtocol::SetTransport(transport);
   268       return bridge;
   269     }
   270   }
   271   return nullptr;
   272 }
   274 bool ImageBridgeParent::IsSameProcess() const
   275 {
   276   return OtherProcess() == ipc::kInvalidProcessHandle;
   277 }
   279 } // layers
   280 } // mozilla

mercurial