gfx/layers/ipc/CompositableTransactionParent.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.

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

mercurial