1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/ipc/CompositableTransactionParent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,274 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=8 et : 1.6 + */ 1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#include "CompositableTransactionParent.h" 1.12 +#include "CompositableHost.h" // for CompositableParent, etc 1.13 +#include "CompositorParent.h" // for CompositorParent 1.14 +#include "GLContext.h" // for GLContext 1.15 +#include "Layers.h" // for Layer 1.16 +#include "RenderTrace.h" // for RenderTraceInvalidateEnd, etc 1.17 +#include "TiledLayerBuffer.h" // for TiledLayerComposer 1.18 +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 1.19 +#include "mozilla/RefPtr.h" // for RefPtr 1.20 +#include "mozilla/layers/CompositorTypes.h" 1.21 +#include "mozilla/layers/ContentHost.h" // for ContentHostBase 1.22 +#include "mozilla/layers/LayerManagerComposite.h" 1.23 +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor 1.24 +#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG 1.25 +#include "mozilla/layers/TextureHost.h" // for TextureHost 1.26 +#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL 1.27 +#include "mozilla/layers/ThebesLayerComposite.h" 1.28 +#include "mozilla/mozalloc.h" // for operator delete 1.29 +#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION 1.30 +#include "nsRegion.h" // for nsIntRegion 1.31 + 1.32 +namespace mozilla { 1.33 +namespace layers { 1.34 + 1.35 +class ClientTiledLayerBuffer; 1.36 +class Compositor; 1.37 + 1.38 +template<typename Op> 1.39 +CompositableHost* AsCompositable(const Op& op) 1.40 +{ 1.41 + return CompositableHost::FromIPDLActor(op.compositableParent()); 1.42 +} 1.43 + 1.44 +// This function can in some cases fail and return false without it being a bug. 1.45 +// This can theoretically happen if the ImageBridge sends frames before 1.46 +// we created the layer tree. Since we can't enforce that the layer 1.47 +// tree is already created before ImageBridge operates, there isn't much 1.48 +// we can do about it, but in practice it is very rare. 1.49 +// Typically when a tab with a video is dragged from a window to another, 1.50 +// there can be a short time when the video is still sending frames 1.51 +// asynchonously while the layer tree is not reconstructed. It's not a 1.52 +// big deal. 1.53 +// Note that Layers transactions do not need to call this because they always 1.54 +// schedule the composition, in LayerManagerComposite::EndTransaction. 1.55 +template<typename T> 1.56 +bool ScheduleComposition(const T& op) 1.57 +{ 1.58 + CompositableHost* comp = AsCompositable(op); 1.59 + uint64_t id = comp->GetCompositorID(); 1.60 + if (!comp || !id) { 1.61 + return false; 1.62 + } 1.63 + CompositorParent* cp = CompositorParent::GetCompositor(id); 1.64 + if (!cp) { 1.65 + return false; 1.66 + } 1.67 + cp->ScheduleComposition(); 1.68 + return true; 1.69 +} 1.70 + 1.71 +bool 1.72 +CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit, 1.73 + EditReplyVector& replyv) 1.74 +{ 1.75 + switch (aEdit.type()) { 1.76 + case CompositableOperation::TOpCreatedIncrementalTexture: { 1.77 + MOZ_LAYERS_LOG(("[ParentSide] Created texture")); 1.78 + const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture(); 1.79 + CompositableHost* compositable = AsCompositable(op); 1.80 + 1.81 + bool success = 1.82 + compositable->CreatedIncrementalTexture(this, 1.83 + op.textureInfo(), 1.84 + op.bufferRect()); 1.85 + if (!success) { 1.86 + return false; 1.87 + } 1.88 + break; 1.89 + } 1.90 + case CompositableOperation::TOpPaintTextureRegion: { 1.91 + MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); 1.92 + 1.93 + const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion(); 1.94 + CompositableHost* compositable = AsCompositable(op); 1.95 + Layer* layer = compositable->GetLayer(); 1.96 + if (!layer || layer->GetType() != Layer::TYPE_THEBES) { 1.97 + return false; 1.98 + } 1.99 + ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer); 1.100 + 1.101 + const ThebesBufferData& bufferData = op.bufferData(); 1.102 + 1.103 + RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds()); 1.104 + 1.105 + nsIntRegion frontUpdatedRegion; 1.106 + if (!compositable->UpdateThebes(bufferData, 1.107 + op.updatedRegion(), 1.108 + thebes->GetValidRegion(), 1.109 + &frontUpdatedRegion)) 1.110 + { 1.111 + return false; 1.112 + } 1.113 + replyv.push_back( 1.114 + OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion)); 1.115 + 1.116 + RenderTraceInvalidateEnd(thebes, "FF00FF"); 1.117 + // return texure data to client if necessary 1.118 + ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); 1.119 + break; 1.120 + } 1.121 + case CompositableOperation::TOpPaintTextureIncremental: { 1.122 + MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); 1.123 + 1.124 + const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental(); 1.125 + 1.126 + CompositableHost* compositable = AsCompositable(op); 1.127 + 1.128 + SurfaceDescriptor desc = op.image(); 1.129 + 1.130 + compositable->UpdateIncremental(op.textureId(), 1.131 + desc, 1.132 + op.updatedRegion(), 1.133 + op.bufferRect(), 1.134 + op.bufferRotation()); 1.135 + break; 1.136 + } 1.137 + case CompositableOperation::TOpUpdatePictureRect: { 1.138 + const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect(); 1.139 + CompositableHost* compositable = AsCompositable(op); 1.140 + MOZ_ASSERT(compositable); 1.141 + compositable->SetPictureRect(op.picture()); 1.142 + break; 1.143 + } 1.144 + case CompositableOperation::TOpUseTiledLayerBuffer: { 1.145 + MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); 1.146 + const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); 1.147 + CompositableHost* compositable = AsCompositable(op); 1.148 + 1.149 + TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer(); 1.150 + NS_ASSERTION(tileComposer, "compositable is not a tile composer"); 1.151 + 1.152 + const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); 1.153 + tileComposer->UseTiledLayerBuffer(this, tileDesc); 1.154 + break; 1.155 + } 1.156 + case CompositableOperation::TOpRemoveTexture: { 1.157 + const OpRemoveTexture& op = aEdit.get_OpRemoveTexture(); 1.158 + CompositableHost* compositable = AsCompositable(op); 1.159 + RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); 1.160 + 1.161 + MOZ_ASSERT(tex.get()); 1.162 + compositable->RemoveTextureHost(tex); 1.163 + // return texure data to client if necessary 1.164 + ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); 1.165 + break; 1.166 + } 1.167 + case CompositableOperation::TOpUseTexture: { 1.168 + const OpUseTexture& op = aEdit.get_OpUseTexture(); 1.169 + CompositableHost* compositable = AsCompositable(op); 1.170 + RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); 1.171 + 1.172 + MOZ_ASSERT(tex.get()); 1.173 + compositable->UseTextureHost(tex); 1.174 + 1.175 + if (IsAsync()) { 1.176 + ScheduleComposition(op); 1.177 + // Async layer updates don't trigger invalidation, manually tell the layer 1.178 + // that its content have changed. 1.179 + if (compositable->GetLayer()) { 1.180 + compositable->GetLayer()->SetInvalidRectToVisibleRegion(); 1.181 + } 1.182 + } 1.183 + // return texure data to client if necessary 1.184 + ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); 1.185 + break; 1.186 + } 1.187 + case CompositableOperation::TOpUseComponentAlphaTextures: { 1.188 + const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures(); 1.189 + CompositableHost* compositable = AsCompositable(op); 1.190 + RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent()); 1.191 + RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent()); 1.192 + 1.193 + MOZ_ASSERT(texOnBlack && texOnWhite); 1.194 + compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite); 1.195 + 1.196 + if (IsAsync()) { 1.197 + ScheduleComposition(op); 1.198 + } 1.199 + // return texure data to client if necessary 1.200 + ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); 1.201 + break; 1.202 + } 1.203 + case CompositableOperation::TOpUpdateTexture: { 1.204 + const OpUpdateTexture& op = aEdit.get_OpUpdateTexture(); 1.205 + RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent()); 1.206 + MOZ_ASSERT(texture); 1.207 + 1.208 + texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion 1.209 + ? &op.region().get_nsIntRegion() 1.210 + : nullptr); // no region means invalidate the entire surface 1.211 + break; 1.212 + } 1.213 + 1.214 + default: { 1.215 + MOZ_ASSERT(false, "bad type"); 1.216 + } 1.217 + } 1.218 + 1.219 + return true; 1.220 +} 1.221 + 1.222 +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 1.223 +void 1.224 +CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable, 1.225 + EditReplyVector& replyv, 1.226 + PCompositableParent* aParent) 1.227 +{ 1.228 + if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) { 1.229 + return; 1.230 + } 1.231 + 1.232 + const std::vector< RefPtr<TextureHost> > textureList = 1.233 + aCompositable->GetCompositableBackendSpecificData()->GetPendingReleaseFenceTextureList(); 1.234 + // Return pending Texture data 1.235 + for (size_t i = 0; i < textureList.size(); i++) { 1.236 + // File descriptor number is limited to 4 per IPC message. 1.237 + // See Bug 986253 1.238 + if (mPrevFenceHandles.size() >= 4) { 1.239 + break; 1.240 + } 1.241 + TextureHostOGL* hostOGL = textureList[i]->AsHostOGL(); 1.242 + PTextureParent* actor = textureList[i]->GetIPDLActor(); 1.243 + if (!hostOGL || !actor) { 1.244 + continue; 1.245 + } 1.246 + android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence(); 1.247 + if (fence.get() && fence->isValid()) { 1.248 + FenceHandle handle = FenceHandle(fence); 1.249 + replyv.push_back(ReturnReleaseFence(aParent, nullptr, actor, nullptr, handle)); 1.250 + // Hold fence handle to prevent fence's file descriptor is closed before IPC happens. 1.251 + mPrevFenceHandles.push_back(handle); 1.252 + } 1.253 + } 1.254 + aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList(); 1.255 +} 1.256 +#else 1.257 +void 1.258 +CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable, 1.259 + EditReplyVector& replyv, 1.260 + PCompositableParent* aParent) 1.261 +{ 1.262 + if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) { 1.263 + return; 1.264 + } 1.265 + aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList(); 1.266 +} 1.267 +#endif 1.268 + 1.269 +void 1.270 +CompositableParentManager::ClearPrevFenceHandles() 1.271 +{ 1.272 + mPrevFenceHandles.clear(); 1.273 +} 1.274 + 1.275 +} // namespace 1.276 +} // namespace 1.277 +