1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/composite/CompositableHost.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,295 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "CompositableHost.h" 1.10 +#include <map> // for _Rb_tree_iterator, map, etc 1.11 +#include <utility> // for pair 1.12 +#include "ContentHost.h" // for ContentHostDoubleBuffered, etc 1.13 +#include "Effects.h" // for EffectMask, Effect, etc 1.14 +#include "ImageHost.h" // for ImageHostBuffered, etc 1.15 +#include "TiledContentHost.h" // for TiledContentHost 1.16 +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor 1.17 +#include "mozilla/layers/TextureHost.h" // for TextureHost, etc 1.18 +#include "nsAutoPtr.h" // for nsRefPtr 1.19 +#include "nsDebug.h" // for NS_WARNING 1.20 +#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc 1.21 +#include "gfxPlatform.h" // for gfxPlatform 1.22 + 1.23 +namespace mozilla { 1.24 +namespace layers { 1.25 + 1.26 +class Compositor; 1.27 + 1.28 +/** 1.29 + * IPDL actor used by CompositableHost to match with its corresponding 1.30 + * CompositableClient on the content side. 1.31 + * 1.32 + * CompositableParent is owned by the IPDL system. It's deletion is triggered 1.33 + * by either the CompositableChild's deletion, or by the IPDL communication 1.34 + * goind down. 1.35 + */ 1.36 +class CompositableParent : public PCompositableParent 1.37 +{ 1.38 +public: 1.39 + CompositableParent(CompositableParentManager* aMgr, 1.40 + const TextureInfo& aTextureInfo, 1.41 + uint64_t aID = 0) 1.42 + { 1.43 + MOZ_COUNT_CTOR(CompositableParent); 1.44 + mHost = CompositableHost::Create(aTextureInfo); 1.45 + mHost->SetAsyncID(aID); 1.46 + if (aID) { 1.47 + CompositableMap::Set(aID, this); 1.48 + } 1.49 + } 1.50 + 1.51 + ~CompositableParent() 1.52 + { 1.53 + MOZ_COUNT_DTOR(CompositableParent); 1.54 + CompositableMap::Erase(mHost->GetAsyncID()); 1.55 + } 1.56 + 1.57 + virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE 1.58 + { 1.59 + if (mHost) { 1.60 + mHost->Detach(nullptr, CompositableHost::FORCE_DETACH); 1.61 + } 1.62 + } 1.63 + 1.64 + RefPtr<CompositableHost> mHost; 1.65 +}; 1.66 + 1.67 +CompositableHost::CompositableHost(const TextureInfo& aTextureInfo) 1.68 + : mTextureInfo(aTextureInfo) 1.69 + , mAsyncID(0) 1.70 + , mCompositorID(0) 1.71 + , mCompositor(nullptr) 1.72 + , mLayer(nullptr) 1.73 + , mFlashCounter(0) 1.74 + , mAttached(false) 1.75 + , mKeepAttached(false) 1.76 +{ 1.77 + MOZ_COUNT_CTOR(CompositableHost); 1.78 +} 1.79 + 1.80 +CompositableHost::~CompositableHost() 1.81 +{ 1.82 + MOZ_COUNT_DTOR(CompositableHost); 1.83 + if (mBackendData) { 1.84 + mBackendData->ClearData(); 1.85 + } 1.86 +} 1.87 + 1.88 +PCompositableParent* 1.89 +CompositableHost::CreateIPDLActor(CompositableParentManager* aMgr, 1.90 + const TextureInfo& aTextureInfo, 1.91 + uint64_t aID) 1.92 +{ 1.93 + return new CompositableParent(aMgr, aTextureInfo, aID); 1.94 +} 1.95 + 1.96 +bool 1.97 +CompositableHost::DestroyIPDLActor(PCompositableParent* aActor) 1.98 +{ 1.99 + delete aActor; 1.100 + return true; 1.101 +} 1.102 + 1.103 +CompositableHost* 1.104 +CompositableHost::FromIPDLActor(PCompositableParent* aActor) 1.105 +{ 1.106 + MOZ_ASSERT(aActor); 1.107 + return static_cast<CompositableParent*>(aActor)->mHost; 1.108 +} 1.109 + 1.110 +void 1.111 +CompositableHost::UseTextureHost(TextureHost* aTexture) 1.112 +{ 1.113 + if (!aTexture) { 1.114 + return; 1.115 + } 1.116 + aTexture->SetCompositor(GetCompositor()); 1.117 + aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); 1.118 +} 1.119 + 1.120 +void 1.121 +CompositableHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack, 1.122 + TextureHost* aTextureOnWhite) 1.123 +{ 1.124 + MOZ_ASSERT(aTextureOnBlack && aTextureOnWhite); 1.125 + aTextureOnBlack->SetCompositor(GetCompositor()); 1.126 + aTextureOnBlack->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); 1.127 + aTextureOnWhite->SetCompositor(GetCompositor()); 1.128 + aTextureOnWhite->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); 1.129 +} 1.130 + 1.131 +void 1.132 +CompositableHost::RemoveTextureHost(TextureHost* aTexture) 1.133 +{ 1.134 + // Clear strong refrence to CompositableBackendSpecificData 1.135 + aTexture->SetCompositableBackendSpecificData(nullptr); 1.136 +} 1.137 + 1.138 +void 1.139 +CompositableHost::SetCompositor(Compositor* aCompositor) 1.140 +{ 1.141 + mCompositor = aCompositor; 1.142 +} 1.143 + 1.144 +bool 1.145 +CompositableHost::AddMaskEffect(EffectChain& aEffects, 1.146 + const gfx::Matrix4x4& aTransform, 1.147 + bool aIs3D) 1.148 +{ 1.149 + RefPtr<TextureSource> source; 1.150 + RefPtr<TextureHost> host = GetAsTextureHost(); 1.151 + if (host && host->Lock()) { 1.152 + source = host->GetTextureSources(); 1.153 + } 1.154 + 1.155 + if (!source) { 1.156 + NS_WARNING("Using compositable with no texture host as mask layer"); 1.157 + return false; 1.158 + } 1.159 + 1.160 + RefPtr<EffectMask> effect = new EffectMask(source, 1.161 + source->GetSize(), 1.162 + aTransform); 1.163 + effect->mIs3D = aIs3D; 1.164 + aEffects.mSecondaryEffects[EFFECT_MASK] = effect; 1.165 + return true; 1.166 +} 1.167 + 1.168 +void 1.169 +CompositableHost::RemoveMaskEffect() 1.170 +{ 1.171 + RefPtr<TextureHost> host = GetAsTextureHost(); 1.172 + if (host) { 1.173 + host->Unlock(); 1.174 + } 1.175 +} 1.176 + 1.177 +// implemented in TextureHostOGL.cpp 1.178 +TemporaryRef<CompositableBackendSpecificData> CreateCompositableBackendSpecificDataOGL(); 1.179 + 1.180 +/* static */ TemporaryRef<CompositableHost> 1.181 +CompositableHost::Create(const TextureInfo& aTextureInfo) 1.182 +{ 1.183 + RefPtr<CompositableHost> result; 1.184 + switch (aTextureInfo.mCompositableType) { 1.185 + case BUFFER_BRIDGE: 1.186 + NS_ERROR("Cannot create an image bridge compositable this way"); 1.187 + break; 1.188 + case BUFFER_CONTENT_INC: 1.189 + result = new ContentHostIncremental(aTextureInfo); 1.190 + break; 1.191 + case BUFFER_TILED: 1.192 + case BUFFER_SIMPLE_TILED: 1.193 + result = new TiledContentHost(aTextureInfo); 1.194 + break; 1.195 + case COMPOSITABLE_IMAGE: 1.196 + result = new ImageHost(aTextureInfo); 1.197 + break; 1.198 + case COMPOSITABLE_CONTENT_SINGLE: 1.199 + result = new ContentHostSingleBuffered(aTextureInfo); 1.200 + break; 1.201 + case COMPOSITABLE_CONTENT_DOUBLE: 1.202 + result = new ContentHostDoubleBuffered(aTextureInfo); 1.203 + break; 1.204 + default: 1.205 + NS_ERROR("Unknown CompositableType"); 1.206 + } 1.207 + // We know that Tiled buffers don't use the compositable backend-specific 1.208 + // data, so don't bother creating it. 1.209 + if (result && aTextureInfo.mCompositableType != BUFFER_TILED) { 1.210 + RefPtr<CompositableBackendSpecificData> data = CreateCompositableBackendSpecificDataOGL(); 1.211 + result->SetCompositableBackendSpecificData(data); 1.212 + } 1.213 + return result; 1.214 +} 1.215 + 1.216 +#ifdef MOZ_DUMP_PAINTING 1.217 +void 1.218 +CompositableHost::DumpTextureHost(FILE* aFile, TextureHost* aTexture) 1.219 +{ 1.220 + if (!aTexture) { 1.221 + return; 1.222 + } 1.223 + RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface(); 1.224 + if (!dSurf) { 1.225 + return; 1.226 + } 1.227 + gfxPlatform *platform = gfxPlatform::GetPlatform(); 1.228 + RefPtr<gfx::DrawTarget> dt = platform->CreateDrawTargetForData(dSurf->GetData(), 1.229 + dSurf->GetSize(), 1.230 + dSurf->Stride(), 1.231 + dSurf->GetFormat()); 1.232 + nsRefPtr<gfxASurface> surf = platform->GetThebesSurfaceForDrawTarget(dt); 1.233 + if (!surf) { 1.234 + return; 1.235 + } 1.236 + surf->DumpAsDataURL(aFile ? aFile : stderr); 1.237 +} 1.238 +#endif 1.239 + 1.240 +namespace CompositableMap { 1.241 + 1.242 +typedef std::map<uint64_t, PCompositableParent*> CompositableMap_t; 1.243 +static CompositableMap_t* sCompositableMap = nullptr; 1.244 +bool IsCreated() { 1.245 + return sCompositableMap != nullptr; 1.246 +} 1.247 +PCompositableParent* Get(uint64_t aID) 1.248 +{ 1.249 + if (!IsCreated() || aID == 0) { 1.250 + return nullptr; 1.251 + } 1.252 + CompositableMap_t::iterator it = sCompositableMap->find(aID); 1.253 + if (it == sCompositableMap->end()) { 1.254 + return nullptr; 1.255 + } 1.256 + return it->second; 1.257 +} 1.258 +void Set(uint64_t aID, PCompositableParent* aParent) 1.259 +{ 1.260 + if (!IsCreated() || aID == 0) { 1.261 + return; 1.262 + } 1.263 + (*sCompositableMap)[aID] = aParent; 1.264 +} 1.265 +void Erase(uint64_t aID) 1.266 +{ 1.267 + if (!IsCreated() || aID == 0) { 1.268 + return; 1.269 + } 1.270 + CompositableMap_t::iterator it = sCompositableMap->find(aID); 1.271 + if (it != sCompositableMap->end()) { 1.272 + sCompositableMap->erase(it); 1.273 + } 1.274 +} 1.275 +void Clear() 1.276 +{ 1.277 + if (!IsCreated()) { 1.278 + return; 1.279 + } 1.280 + sCompositableMap->clear(); 1.281 +} 1.282 +void Create() 1.283 +{ 1.284 + if (sCompositableMap == nullptr) { 1.285 + sCompositableMap = new CompositableMap_t; 1.286 + } 1.287 +} 1.288 +void Destroy() 1.289 +{ 1.290 + Clear(); 1.291 + delete sCompositableMap; 1.292 + sCompositableMap = nullptr; 1.293 +} 1.294 + 1.295 +} // namespace CompositableMap 1.296 + 1.297 +} // namespace layers 1.298 +} // namespace mozilla