diff -r 000000000000 -r 6474c204b198 gfx/layers/composite/CompositableHost.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/layers/composite/CompositableHost.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,295 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CompositableHost.h" +#include // for _Rb_tree_iterator, map, etc +#include // for pair +#include "ContentHost.h" // for ContentHostDoubleBuffered, etc +#include "Effects.h" // for EffectMask, Effect, etc +#include "ImageHost.h" // for ImageHostBuffered, etc +#include "TiledContentHost.h" // for TiledContentHost +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor +#include "mozilla/layers/TextureHost.h" // for TextureHost, etc +#include "nsAutoPtr.h" // for nsRefPtr +#include "nsDebug.h" // for NS_WARNING +#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc +#include "gfxPlatform.h" // for gfxPlatform + +namespace mozilla { +namespace layers { + +class Compositor; + +/** + * IPDL actor used by CompositableHost to match with its corresponding + * CompositableClient on the content side. + * + * CompositableParent is owned by the IPDL system. It's deletion is triggered + * by either the CompositableChild's deletion, or by the IPDL communication + * goind down. + */ +class CompositableParent : public PCompositableParent +{ +public: + CompositableParent(CompositableParentManager* aMgr, + const TextureInfo& aTextureInfo, + uint64_t aID = 0) + { + MOZ_COUNT_CTOR(CompositableParent); + mHost = CompositableHost::Create(aTextureInfo); + mHost->SetAsyncID(aID); + if (aID) { + CompositableMap::Set(aID, this); + } + } + + ~CompositableParent() + { + MOZ_COUNT_DTOR(CompositableParent); + CompositableMap::Erase(mHost->GetAsyncID()); + } + + virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE + { + if (mHost) { + mHost->Detach(nullptr, CompositableHost::FORCE_DETACH); + } + } + + RefPtr mHost; +}; + +CompositableHost::CompositableHost(const TextureInfo& aTextureInfo) + : mTextureInfo(aTextureInfo) + , mAsyncID(0) + , mCompositorID(0) + , mCompositor(nullptr) + , mLayer(nullptr) + , mFlashCounter(0) + , mAttached(false) + , mKeepAttached(false) +{ + MOZ_COUNT_CTOR(CompositableHost); +} + +CompositableHost::~CompositableHost() +{ + MOZ_COUNT_DTOR(CompositableHost); + if (mBackendData) { + mBackendData->ClearData(); + } +} + +PCompositableParent* +CompositableHost::CreateIPDLActor(CompositableParentManager* aMgr, + const TextureInfo& aTextureInfo, + uint64_t aID) +{ + return new CompositableParent(aMgr, aTextureInfo, aID); +} + +bool +CompositableHost::DestroyIPDLActor(PCompositableParent* aActor) +{ + delete aActor; + return true; +} + +CompositableHost* +CompositableHost::FromIPDLActor(PCompositableParent* aActor) +{ + MOZ_ASSERT(aActor); + return static_cast(aActor)->mHost; +} + +void +CompositableHost::UseTextureHost(TextureHost* aTexture) +{ + if (!aTexture) { + return; + } + aTexture->SetCompositor(GetCompositor()); + aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); +} + +void +CompositableHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack, + TextureHost* aTextureOnWhite) +{ + MOZ_ASSERT(aTextureOnBlack && aTextureOnWhite); + aTextureOnBlack->SetCompositor(GetCompositor()); + aTextureOnBlack->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); + aTextureOnWhite->SetCompositor(GetCompositor()); + aTextureOnWhite->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); +} + +void +CompositableHost::RemoveTextureHost(TextureHost* aTexture) +{ + // Clear strong refrence to CompositableBackendSpecificData + aTexture->SetCompositableBackendSpecificData(nullptr); +} + +void +CompositableHost::SetCompositor(Compositor* aCompositor) +{ + mCompositor = aCompositor; +} + +bool +CompositableHost::AddMaskEffect(EffectChain& aEffects, + const gfx::Matrix4x4& aTransform, + bool aIs3D) +{ + RefPtr source; + RefPtr host = GetAsTextureHost(); + if (host && host->Lock()) { + source = host->GetTextureSources(); + } + + if (!source) { + NS_WARNING("Using compositable with no texture host as mask layer"); + return false; + } + + RefPtr effect = new EffectMask(source, + source->GetSize(), + aTransform); + effect->mIs3D = aIs3D; + aEffects.mSecondaryEffects[EFFECT_MASK] = effect; + return true; +} + +void +CompositableHost::RemoveMaskEffect() +{ + RefPtr host = GetAsTextureHost(); + if (host) { + host->Unlock(); + } +} + +// implemented in TextureHostOGL.cpp +TemporaryRef CreateCompositableBackendSpecificDataOGL(); + +/* static */ TemporaryRef +CompositableHost::Create(const TextureInfo& aTextureInfo) +{ + RefPtr result; + switch (aTextureInfo.mCompositableType) { + case BUFFER_BRIDGE: + NS_ERROR("Cannot create an image bridge compositable this way"); + break; + case BUFFER_CONTENT_INC: + result = new ContentHostIncremental(aTextureInfo); + break; + case BUFFER_TILED: + case BUFFER_SIMPLE_TILED: + result = new TiledContentHost(aTextureInfo); + break; + case COMPOSITABLE_IMAGE: + result = new ImageHost(aTextureInfo); + break; + case COMPOSITABLE_CONTENT_SINGLE: + result = new ContentHostSingleBuffered(aTextureInfo); + break; + case COMPOSITABLE_CONTENT_DOUBLE: + result = new ContentHostDoubleBuffered(aTextureInfo); + break; + default: + NS_ERROR("Unknown CompositableType"); + } + // We know that Tiled buffers don't use the compositable backend-specific + // data, so don't bother creating it. + if (result && aTextureInfo.mCompositableType != BUFFER_TILED) { + RefPtr data = CreateCompositableBackendSpecificDataOGL(); + result->SetCompositableBackendSpecificData(data); + } + return result; +} + +#ifdef MOZ_DUMP_PAINTING +void +CompositableHost::DumpTextureHost(FILE* aFile, TextureHost* aTexture) +{ + if (!aTexture) { + return; + } + RefPtr dSurf = aTexture->GetAsSurface(); + if (!dSurf) { + return; + } + gfxPlatform *platform = gfxPlatform::GetPlatform(); + RefPtr dt = platform->CreateDrawTargetForData(dSurf->GetData(), + dSurf->GetSize(), + dSurf->Stride(), + dSurf->GetFormat()); + nsRefPtr surf = platform->GetThebesSurfaceForDrawTarget(dt); + if (!surf) { + return; + } + surf->DumpAsDataURL(aFile ? aFile : stderr); +} +#endif + +namespace CompositableMap { + +typedef std::map CompositableMap_t; +static CompositableMap_t* sCompositableMap = nullptr; +bool IsCreated() { + return sCompositableMap != nullptr; +} +PCompositableParent* Get(uint64_t aID) +{ + if (!IsCreated() || aID == 0) { + return nullptr; + } + CompositableMap_t::iterator it = sCompositableMap->find(aID); + if (it == sCompositableMap->end()) { + return nullptr; + } + return it->second; +} +void Set(uint64_t aID, PCompositableParent* aParent) +{ + if (!IsCreated() || aID == 0) { + return; + } + (*sCompositableMap)[aID] = aParent; +} +void Erase(uint64_t aID) +{ + if (!IsCreated() || aID == 0) { + return; + } + CompositableMap_t::iterator it = sCompositableMap->find(aID); + if (it != sCompositableMap->end()) { + sCompositableMap->erase(it); + } +} +void Clear() +{ + if (!IsCreated()) { + return; + } + sCompositableMap->clear(); +} +void Create() +{ + if (sCompositableMap == nullptr) { + sCompositableMap = new CompositableMap_t; + } +} +void Destroy() +{ + Clear(); + delete sCompositableMap; + sCompositableMap = nullptr; +} + +} // namespace CompositableMap + +} // namespace layers +} // namespace mozilla