LCOV - code coverage report
Current view: top level - gfx/layers/ipc - CompositableTransactionParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 70 143 49.0 %
Date: 2017-07-14 16:53:18 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * vim: sw=2 ts=8 et :
       3             :  */
       4             : /* This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : #include "CompositableTransactionParent.h"
       9             : #include "CompositableHost.h"           // for CompositableParent, etc
      10             : #include "CompositorBridgeParent.h"     // for CompositorBridgeParent
      11             : #include "GLContext.h"                  // for GLContext
      12             : #include "Layers.h"                     // for Layer
      13             : #include "RenderTrace.h"                // for RenderTraceInvalidateEnd, etc
      14             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
      15             : #include "mozilla/RefPtr.h"             // for RefPtr
      16             : #include "mozilla/layers/CompositorTypes.h"
      17             : #include "mozilla/layers/ContentHost.h"  // for ContentHostBase
      18             : #include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
      19             : #include "mozilla/layers/LayerManagerComposite.h"
      20             : #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
      21             : #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
      22             : #include "mozilla/layers/TextureHost.h"  // for TextureHost
      23             : #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
      24             : #include "mozilla/layers/TiledContentHost.h"
      25             : #include "mozilla/layers/PaintedLayerComposite.h"
      26             : #include "mozilla/mozalloc.h"           // for operator delete
      27             : #include "mozilla/Unused.h"
      28             : #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
      29             : #include "nsRegion.h"                   // for nsIntRegion
      30             : 
      31             : namespace mozilla {
      32             : namespace layers {
      33             : 
      34             : class ClientTiledLayerBuffer;
      35             : class Compositor;
      36             : 
      37             : // This function can in some cases fail and return false without it being a bug.
      38             : // This can theoretically happen if the ImageBridge sends frames before
      39             : // we created the layer tree. Since we can't enforce that the layer
      40             : // tree is already created before ImageBridge operates, there isn't much
      41             : // we can do about it, but in practice it is very rare.
      42             : // Typically when a tab with a video is dragged from a window to another,
      43             : // there can be a short time when the video is still sending frames
      44             : // asynchonously while the layer tree is not reconstructed. It's not a
      45             : // big deal.
      46             : // Note that Layers transactions do not need to call this because they always
      47             : // schedule the composition, in LayerManagerComposite::EndTransaction.
      48             : static bool
      49           0 : ScheduleComposition(CompositableHost* aCompositable)
      50             : {
      51           0 :   uint64_t id = aCompositable->GetCompositorBridgeID();
      52           0 :   if (!id) {
      53           0 :     return false;
      54             :   }
      55           0 :   CompositorBridgeParent* cp = CompositorBridgeParent::GetCompositorBridgeParent(id);
      56           0 :   if (!cp) {
      57           0 :     return false;
      58             :   }
      59           0 :   cp->ScheduleComposition();
      60           0 :   return true;
      61             : }
      62             : 
      63             : bool
      64          66 : CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit)
      65             : {
      66             :   // Ignore all operations on compositables created on stale compositors. We
      67             :   // return true because the child is unable to handle errors.
      68         132 :   RefPtr<CompositableHost> compositable = FindCompositable(aEdit.compositable());
      69          66 :   if (!compositable) {
      70           0 :     return false;
      71             :   }
      72          66 :   if (TextureSourceProvider* provider = compositable->GetTextureSourceProvider()) {
      73          66 :     if (!provider->IsValid()) {
      74           0 :       return false;
      75             :     }
      76             :   }
      77             : 
      78          66 :   switch (aEdit.detail().type()) {
      79             :     case CompositableOperationDetail::TOpPaintTextureRegion: {
      80          33 :       MOZ_LAYERS_LOG(("[ParentSide] Paint PaintedLayer"));
      81             : 
      82          33 :       const OpPaintTextureRegion& op = aEdit.detail().get_OpPaintTextureRegion();
      83          33 :       Layer* layer = compositable->GetLayer();
      84          33 :       if (!layer || layer->GetType() != Layer::TYPE_PAINTED) {
      85           0 :         return false;
      86             :       }
      87          33 :       PaintedLayerComposite* thebes = static_cast<PaintedLayerComposite*>(layer);
      88             : 
      89          33 :       const ThebesBufferData& bufferData = op.bufferData();
      90             : 
      91          33 :       RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());
      92             : 
      93          66 :       if (!compositable->UpdateThebes(bufferData,
      94             :                                       op.updatedRegion(),
      95          33 :                                       thebes->GetValidRegion()))
      96             :       {
      97           0 :         return false;
      98             :       }
      99             : 
     100          33 :       RenderTraceInvalidateEnd(thebes, "FF00FF");
     101          33 :       break;
     102             :     }
     103             :     case CompositableOperationDetail::TOpUseTiledLayerBuffer: {
     104           0 :       MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer"));
     105           0 :       const OpUseTiledLayerBuffer& op = aEdit.detail().get_OpUseTiledLayerBuffer();
     106           0 :       TiledContentHost* tiledHost = compositable->AsTiledContentHost();
     107             : 
     108           0 :       NS_ASSERTION(tiledHost, "The compositable is not tiled");
     109             : 
     110           0 :       const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor();
     111             : 
     112           0 :       bool success = tiledHost->UseTiledLayerBuffer(this, tileDesc);
     113             : 
     114           0 :       const InfallibleTArray<TileDescriptor>& tileDescriptors = tileDesc.tiles();
     115           0 :       for (size_t i = 0; i < tileDescriptors.Length(); i++) {
     116           0 :         const TileDescriptor& tileDesc = tileDescriptors[i];
     117           0 :         if (tileDesc.type() != TileDescriptor::TTexturedTileDescriptor) {
     118           0 :           continue;
     119             :         }
     120           0 :         const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor();
     121           0 :         RefPtr<TextureHost> texture = TextureHost::AsTextureHost(texturedDesc.textureParent());
     122           0 :         if (texture) {
     123           0 :           texture->SetLastFwdTransactionId(mFwdTransactionId);
     124             :           // Make sure that each texture was handled by the compositable
     125             :           // because the recycling logic depends on it.
     126           0 :           MOZ_ASSERT(texture->NumCompositableRefs() > 0);
     127             :         }
     128           0 :         if (texturedDesc.textureOnWhite().type() == MaybeTexture::TPTextureParent) {
     129           0 :           texture = TextureHost::AsTextureHost(texturedDesc.textureOnWhite().get_PTextureParent());
     130           0 :           if (texture) {
     131           0 :             texture->SetLastFwdTransactionId(mFwdTransactionId);
     132             :             // Make sure that each texture was handled by the compositable
     133             :             // because the recycling logic depends on it.
     134           0 :             MOZ_ASSERT(texture->NumCompositableRefs() > 0);
     135             :           }
     136             :         }
     137             :       }
     138           0 :       if (!success) {
     139           0 :         return false;
     140             :       }
     141           0 :       break;
     142             :     }
     143             :     case CompositableOperationDetail::TOpRemoveTexture: {
     144           0 :       const OpRemoveTexture& op = aEdit.detail().get_OpRemoveTexture();
     145             : 
     146           0 :       RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
     147             : 
     148           0 :       MOZ_ASSERT(tex.get());
     149           0 :       compositable->RemoveTextureHost(tex);
     150           0 :       break;
     151             :     }
     152             :     case CompositableOperationDetail::TOpUseTexture: {
     153          33 :       const OpUseTexture& op = aEdit.detail().get_OpUseTexture();
     154             : 
     155          66 :       AutoTArray<CompositableHost::TimedTexture,4> textures;
     156          66 :       for (auto& timedTexture : op.textures()) {
     157          33 :         CompositableHost::TimedTexture* t = textures.AppendElement();
     158             :         t->mTexture =
     159          33 :             TextureHost::AsTextureHost(timedTexture.textureParent());
     160          33 :         MOZ_ASSERT(t->mTexture);
     161          33 :         t->mTimeStamp = timedTexture.timeStamp();
     162          33 :         t->mPictureRect = timedTexture.picture();
     163          33 :         t->mFrameID = timedTexture.frameID();
     164          33 :         t->mProducerID = timedTexture.producerID();
     165          33 :         t->mTexture->SetReadLock(FindReadLock(timedTexture.sharedLock()));
     166             :       }
     167          33 :       if (textures.Length() > 0) {
     168          33 :         compositable->UseTextureHost(textures);
     169             : 
     170          66 :         for (auto& timedTexture : op.textures()) {
     171          66 :           RefPtr<TextureHost> texture = TextureHost::AsTextureHost(timedTexture.textureParent());
     172          33 :           if (texture) {
     173          33 :             texture->SetLastFwdTransactionId(mFwdTransactionId);
     174             :             // Make sure that each texture was handled by the compositable
     175             :             // because the recycling logic depends on it.
     176          33 :             MOZ_ASSERT(texture->NumCompositableRefs() > 0);
     177             :           }
     178             :         }
     179             :       }
     180             : 
     181          33 :       if (UsesImageBridge() && compositable->GetLayer()) {
     182           0 :         ScheduleComposition(compositable);
     183             :       }
     184          33 :       break;
     185             :     }
     186             :     case CompositableOperationDetail::TOpUseComponentAlphaTextures: {
     187           0 :       const OpUseComponentAlphaTextures& op = aEdit.detail().get_OpUseComponentAlphaTextures();
     188           0 :       RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent());
     189           0 :       RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());
     190           0 :       texOnBlack->SetReadLock(FindReadLock(op.sharedLockBlack()));
     191           0 :       texOnWhite->SetReadLock(FindReadLock(op.sharedLockWhite()));
     192             : 
     193           0 :       MOZ_ASSERT(texOnBlack && texOnWhite);
     194           0 :       compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);
     195             : 
     196           0 :       if (texOnBlack) {
     197           0 :         texOnBlack->SetLastFwdTransactionId(mFwdTransactionId);
     198             :         // Make sure that each texture was handled by the compositable
     199             :         // because the recycling logic depends on it.
     200           0 :         MOZ_ASSERT(texOnBlack->NumCompositableRefs() > 0);
     201             :       }
     202             : 
     203           0 :       if (texOnWhite) {
     204           0 :         texOnWhite->SetLastFwdTransactionId(mFwdTransactionId);
     205             :         // Make sure that each texture was handled by the compositable
     206             :         // because the recycling logic depends on it.
     207           0 :         MOZ_ASSERT(texOnWhite->NumCompositableRefs() > 0);
     208             :       }
     209             : 
     210           0 :       if (UsesImageBridge()) {
     211           0 :         ScheduleComposition(compositable);
     212             :       }
     213           0 :       break;
     214             :     }
     215             :     default: {
     216           0 :       MOZ_ASSERT(false, "bad type");
     217             :     }
     218             :   }
     219             : 
     220          66 :   return true;
     221             : }
     222             : 
     223             : void
     224           2 : CompositableParentManager::DestroyActor(const OpDestroy& aOp)
     225             : {
     226           2 :   switch (aOp.type()) {
     227             :     case OpDestroy::TPTextureParent: {
     228           2 :       auto actor = aOp.get_PTextureParent();
     229           2 :       TextureHost::ReceivedDestroy(actor);
     230           2 :       break;
     231             :     }
     232             :     case OpDestroy::TCompositableHandle: {
     233           0 :       ReleaseCompositable(aOp.get_CompositableHandle());
     234           0 :       break;
     235             :     }
     236             :     default: {
     237           0 :       MOZ_ASSERT(false, "unsupported type");
     238             :     }
     239             :   }
     240           2 : }
     241             : 
     242             : RefPtr<CompositableHost>
     243          22 : CompositableParentManager::AddCompositable(const CompositableHandle& aHandle,
     244             :                                            const TextureInfo& aInfo)
     245             : {
     246          22 :   if (mCompositables.find(aHandle.Value()) != mCompositables.end()) {
     247           0 :     NS_ERROR("Client should not allocate duplicate handles");
     248           0 :     return nullptr;
     249             :   }
     250          22 :   if (!aHandle) {
     251           0 :     NS_ERROR("Client should not allocate 0 as a handle");
     252           0 :     return nullptr;
     253             :   }
     254             : 
     255          44 :   RefPtr<CompositableHost> host = CompositableHost::Create(aInfo);
     256          22 :   if (!host) {
     257           0 :     return nullptr;
     258             :   }
     259             : 
     260          22 :   mCompositables[aHandle.Value()] = host;
     261          22 :   return host;
     262             : }
     263             : 
     264             : RefPtr<CompositableHost>
     265          88 : CompositableParentManager::FindCompositable(const CompositableHandle& aHandle)
     266             : {
     267          88 :   auto iter = mCompositables.find(aHandle.Value());
     268          88 :   if (iter == mCompositables.end()) {
     269           0 :     return nullptr;
     270             :   }
     271          88 :   return iter->second;
     272             : }
     273             : 
     274             : void
     275          19 : CompositableParentManager::ReleaseCompositable(const CompositableHandle& aHandle)
     276             : {
     277          19 :   auto iter = mCompositables.find(aHandle.Value());
     278          19 :   if (iter == mCompositables.end()) {
     279           0 :     return;
     280             :   }
     281             : 
     282          38 :   RefPtr<CompositableHost> host = iter->second;
     283          19 :   mCompositables.erase(iter);
     284             : 
     285          19 :   host->Detach(nullptr, CompositableHost::FORCE_DETACH);
     286             : }
     287             : 
     288             : bool
     289          24 : CompositableParentManager::AddReadLocks(ReadLockArray&& aReadLocks)
     290             : {
     291          57 :   for (ReadLockInit& r : aReadLocks) {
     292          33 :     if (mReadLocks.find(r.handle().Value()) != mReadLocks.end()) {
     293           0 :       NS_ERROR("Duplicate read lock handle!");
     294           0 :       return false;
     295             :     }
     296          33 :     mReadLocks[r.handle().Value()] = TextureReadLock::Deserialize(r.sharedLock(), this);
     297             :   }
     298          24 :   return true;
     299             : }
     300             : 
     301             : TextureReadLock*
     302          33 : CompositableParentManager::FindReadLock(const ReadLockHandle& aHandle)
     303             : {
     304          33 :   auto iter = mReadLocks.find(aHandle.Value());
     305          33 :   if (iter == mReadLocks.end()) {
     306           0 :     return nullptr;
     307             :   }
     308          33 :   return iter->second.get();
     309             : }
     310             : 
     311             : } // namespace layers
     312             : } // namespace mozilla
     313             : 

Generated by: LCOV version 1.13