gfx/layers/ipc/CompositableTransactionParent.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     8 #include "CompositableTransactionParent.h"
     9 #include "CompositableHost.h"           // for CompositableParent, etc
    10 #include "CompositorParent.h"           // for CompositorParent
    11 #include "GLContext.h"                  // for GLContext
    12 #include "Layers.h"                     // for Layer
    13 #include "RenderTrace.h"                // for RenderTraceInvalidateEnd, etc
    14 #include "TiledLayerBuffer.h"           // for TiledLayerComposer
    15 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    16 #include "mozilla/RefPtr.h"             // for RefPtr
    17 #include "mozilla/layers/CompositorTypes.h"
    18 #include "mozilla/layers/ContentHost.h"  // for ContentHostBase
    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/ThebesLayerComposite.h"
    25 #include "mozilla/mozalloc.h"           // for operator delete
    26 #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
    27 #include "nsRegion.h"                   // for nsIntRegion
    29 namespace mozilla {
    30 namespace layers {
    32 class ClientTiledLayerBuffer;
    33 class Compositor;
    35 template<typename Op>
    36 CompositableHost* AsCompositable(const Op& op)
    37 {
    38   return CompositableHost::FromIPDLActor(op.compositableParent());
    39 }
    41 // This function can in some cases fail and return false without it being a bug.
    42 // This can theoretically happen if the ImageBridge sends frames before
    43 // we created the layer tree. Since we can't enforce that the layer
    44 // tree is already created before ImageBridge operates, there isn't much
    45 // we can do about it, but in practice it is very rare.
    46 // Typically when a tab with a video is dragged from a window to another,
    47 // there can be a short time when the video is still sending frames
    48 // asynchonously while the layer tree is not reconstructed. It's not a
    49 // big deal.
    50 // Note that Layers transactions do not need to call this because they always
    51 // schedule the composition, in LayerManagerComposite::EndTransaction.
    52 template<typename T>
    53 bool ScheduleComposition(const T& op)
    54 {
    55   CompositableHost* comp = AsCompositable(op);
    56   uint64_t id = comp->GetCompositorID();
    57   if (!comp || !id) {
    58     return false;
    59   }
    60   CompositorParent* cp = CompositorParent::GetCompositor(id);
    61   if (!cp) {
    62     return false;
    63   }
    64   cp->ScheduleComposition();
    65   return true;
    66 }
    68 bool
    69 CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
    70                                                      EditReplyVector& replyv)
    71 {
    72   switch (aEdit.type()) {
    73     case CompositableOperation::TOpCreatedIncrementalTexture: {
    74       MOZ_LAYERS_LOG(("[ParentSide] Created texture"));
    75       const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture();
    76       CompositableHost* compositable = AsCompositable(op);
    78       bool success =
    79         compositable->CreatedIncrementalTexture(this,
    80                                                 op.textureInfo(),
    81                                                 op.bufferRect());
    82       if (!success) {
    83         return false;
    84       }
    85       break;
    86     }
    87     case CompositableOperation::TOpPaintTextureRegion: {
    88       MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));
    90       const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion();
    91       CompositableHost* compositable = AsCompositable(op);
    92       Layer* layer = compositable->GetLayer();
    93       if (!layer || layer->GetType() != Layer::TYPE_THEBES) {
    94         return false;
    95       }
    96       ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer);
    98       const ThebesBufferData& bufferData = op.bufferData();
   100       RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());
   102       nsIntRegion frontUpdatedRegion;
   103       if (!compositable->UpdateThebes(bufferData,
   104                                       op.updatedRegion(),
   105                                       thebes->GetValidRegion(),
   106                                       &frontUpdatedRegion))
   107       {
   108         return false;
   109       }
   110       replyv.push_back(
   111         OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion));
   113       RenderTraceInvalidateEnd(thebes, "FF00FF");
   114       // return texure data to client if necessary
   115       ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
   116       break;
   117     }
   118     case CompositableOperation::TOpPaintTextureIncremental: {
   119       MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));
   121       const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental();
   123       CompositableHost* compositable = AsCompositable(op);
   125       SurfaceDescriptor desc = op.image();
   127       compositable->UpdateIncremental(op.textureId(),
   128                                       desc,
   129                                       op.updatedRegion(),
   130                                       op.bufferRect(),
   131                                       op.bufferRotation());
   132       break;
   133     }
   134     case CompositableOperation::TOpUpdatePictureRect: {
   135       const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect();
   136       CompositableHost* compositable = AsCompositable(op);
   137       MOZ_ASSERT(compositable);
   138       compositable->SetPictureRect(op.picture());
   139       break;
   140     }
   141     case CompositableOperation::TOpUseTiledLayerBuffer: {
   142       MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer"));
   143       const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer();
   144       CompositableHost* compositable = AsCompositable(op);
   146       TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer();
   147       NS_ASSERTION(tileComposer, "compositable is not a tile composer");
   149       const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor();
   150       tileComposer->UseTiledLayerBuffer(this, tileDesc);
   151       break;
   152     }
   153     case CompositableOperation::TOpRemoveTexture: {
   154       const OpRemoveTexture& op = aEdit.get_OpRemoveTexture();
   155       CompositableHost* compositable = AsCompositable(op);
   156       RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
   158       MOZ_ASSERT(tex.get());
   159       compositable->RemoveTextureHost(tex);
   160       // return texure data to client if necessary
   161       ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
   162       break;
   163     }
   164     case CompositableOperation::TOpUseTexture: {
   165       const OpUseTexture& op = aEdit.get_OpUseTexture();
   166       CompositableHost* compositable = AsCompositable(op);
   167       RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
   169       MOZ_ASSERT(tex.get());
   170       compositable->UseTextureHost(tex);
   172       if (IsAsync()) {
   173         ScheduleComposition(op);
   174         // Async layer updates don't trigger invalidation, manually tell the layer
   175         // that its content have changed.
   176         if (compositable->GetLayer()) {
   177           compositable->GetLayer()->SetInvalidRectToVisibleRegion();
   178         }
   179       }
   180       // return texure data to client if necessary
   181       ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
   182       break;
   183     }
   184     case CompositableOperation::TOpUseComponentAlphaTextures: {
   185       const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures();
   186       CompositableHost* compositable = AsCompositable(op);
   187       RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent());
   188       RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());
   190       MOZ_ASSERT(texOnBlack && texOnWhite);
   191       compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);
   193       if (IsAsync()) {
   194         ScheduleComposition(op);
   195       }
   196       // return texure data to client if necessary
   197       ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
   198       break;
   199     }
   200     case CompositableOperation::TOpUpdateTexture: {
   201       const OpUpdateTexture& op = aEdit.get_OpUpdateTexture();
   202       RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent());
   203       MOZ_ASSERT(texture);
   205       texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion
   206                        ? &op.region().get_nsIntRegion()
   207                        : nullptr); // no region means invalidate the entire surface
   208       break;
   209     }
   211     default: {
   212       MOZ_ASSERT(false, "bad type");
   213     }
   214   }
   216   return true;
   217 }
   219 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   220 void
   221 CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable,
   222                                                         EditReplyVector& replyv,
   223                                                         PCompositableParent* aParent)
   224 {
   225   if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
   226     return;
   227   }
   229   const std::vector< RefPtr<TextureHost> > textureList =
   230         aCompositable->GetCompositableBackendSpecificData()->GetPendingReleaseFenceTextureList();
   231   // Return pending Texture data
   232   for (size_t i = 0; i < textureList.size(); i++) {
   233     // File descriptor number is limited to 4 per IPC message.
   234     // See Bug 986253
   235     if (mPrevFenceHandles.size() >= 4) {
   236       break;
   237     }
   238     TextureHostOGL* hostOGL = textureList[i]->AsHostOGL();
   239     PTextureParent* actor = textureList[i]->GetIPDLActor();
   240     if (!hostOGL || !actor) {
   241       continue;
   242     }
   243     android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
   244     if (fence.get() && fence->isValid()) {
   245       FenceHandle handle = FenceHandle(fence);
   246       replyv.push_back(ReturnReleaseFence(aParent, nullptr, actor, nullptr, handle));
   247       // Hold fence handle to prevent fence's file descriptor is closed before IPC happens.
   248       mPrevFenceHandles.push_back(handle);
   249     }
   250   }
   251   aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
   252 }
   253 #else
   254 void
   255 CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable,
   256                                                        EditReplyVector& replyv,
   257                                                        PCompositableParent* aParent)
   258 {
   259   if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
   260     return;
   261   }
   262   aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
   263 }
   264 #endif
   266 void
   267 CompositableParentManager::ClearPrevFenceHandles()
   268 {
   269   mPrevFenceHandles.clear();
   270 }
   272 } // namespace
   273 } // namespace

mercurial