/* -*- 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 "mozilla/layers/CompositableClient.h" #include "mozilla/layers/TextureClient.h" #include "mozilla/layers/TextureClientOGL.h" #include "mozilla/layers/LayerTransactionChild.h" #include "mozilla/layers/CompositableForwarder.h" #include "gfxPlatform.h" #ifdef XP_WIN #include "mozilla/layers/TextureD3D11.h" #include "gfxWindowsPlatform.h" #endif namespace mozilla { namespace layers { CompositableClient::CompositableClient(CompositableForwarder* aForwarder) : mNextTextureID(1) , mCompositableChild(nullptr) , mForwarder(aForwarder) { MOZ_COUNT_CTOR(CompositableClient); } CompositableClient::~CompositableClient() { MOZ_COUNT_DTOR(CompositableClient); Destroy(); MOZ_ASSERT(mTexturesToRemove.size() == 0, "would leak textures pending fore deletion"); } LayersBackend CompositableClient::GetCompositorBackendType() const { return mForwarder->GetCompositorBackendType(); } void CompositableClient::SetIPDLActor(CompositableChild* aChild) { mCompositableChild = aChild; } CompositableChild* CompositableClient::GetIPDLActor() const { return mCompositableChild; } bool CompositableClient::Connect() { if (!GetForwarder() || GetIPDLActor()) { return false; } GetForwarder()->Connect(this); return true; } void CompositableClient::Destroy() { if (!mCompositableChild) { return; } mCompositableChild->Destroy(); mCompositableChild = nullptr; } uint64_t CompositableClient::GetAsyncID() const { if (mCompositableChild) { return mCompositableChild->GetAsyncID(); } return 0; // zero is always an invalid async ID } void CompositableChild::Destroy() { Send__delete__(this); } TemporaryRef CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType) { MOZ_ASSERT(GetForwarder(), "Can't create a texture client if the compositable is not connected to the compositor."); LayersBackend parentBackend = GetForwarder()->GetCompositorBackendType(); RefPtr result; switch (aDeprecatedTextureClientType) { case TEXTURE_SHARED_GL: if (parentBackend == LAYERS_OPENGL) { result = new DeprecatedTextureClientSharedOGL(GetForwarder(), GetTextureInfo()); } break; case TEXTURE_SHARED_GL_EXTERNAL: if (parentBackend == LAYERS_OPENGL) { result = new DeprecatedTextureClientSharedOGLExternal(GetForwarder(), GetTextureInfo()); } break; case TEXTURE_STREAM_GL: if (parentBackend == LAYERS_OPENGL) { result = new DeprecatedTextureClientStreamOGL(GetForwarder(), GetTextureInfo()); } break; case TEXTURE_YCBCR: if (parentBackend == LAYERS_OPENGL || parentBackend == LAYERS_D3D11 || parentBackend == LAYERS_BASIC) { result = new DeprecatedTextureClientShmemYCbCr(GetForwarder(), GetTextureInfo()); } break; case TEXTURE_CONTENT: #ifdef XP_WIN if (parentBackend == LAYERS_D3D11 && gfxWindowsPlatform::GetPlatform()->GetD2DDevice()) { result = new DeprecatedTextureClientD3D11(GetForwarder(), GetTextureInfo()); break; } #endif // fall through to TEXTURE_SHMEM case TEXTURE_SHMEM: result = new DeprecatedTextureClientShmem(GetForwarder(), GetTextureInfo()); break; default: MOZ_ASSERT(false, "Unhandled texture client type"); } // If we couldn't create an appropriate texture client, // then return nullptr so the caller can chose another // type. if (!result) { return nullptr; } MOZ_ASSERT(result->SupportsType(aDeprecatedTextureClientType), "Created the wrong texture client?"); result->SetFlags(GetTextureInfo().mTextureFlags); return result.forget(); } TemporaryRef CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat) { if (gfxPlatform::GetPlatform()->PreferMemoryOverShmem()) { RefPtr result = new MemoryTextureClient(this, aFormat); return result.forget(); } RefPtr result = new ShmemTextureClient(this, aFormat); return result.forget(); } void CompositableClient::AddTextureClient(TextureClient* aClient) { ++mNextTextureID; // 0 is always an invalid ID if (mNextTextureID == 0) { ++mNextTextureID; } aClient->SetID(mNextTextureID); mForwarder->AddTexture(this, aClient); } void CompositableClient::RemoveTextureClient(TextureClient* aClient) { MOZ_ASSERT(aClient); mTexturesToRemove.push_back(aClient->GetID()); aClient->SetID(0); } void CompositableClient::OnTransaction() { for (unsigned i = 0; i < mTexturesToRemove.size(); ++i) { mForwarder->RemoveTexture(this, mTexturesToRemove[i]); } mTexturesToRemove.clear(); } } // namespace layers } // namespace mozilla