CompositableClient.cpp (5225B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/layers/CompositableClient.h" 8 9 #include <stdint.h> // for uint64_t, uint32_t 10 11 #include "gfxPlatform.h" // for gfxPlatform 12 #include "mozilla/layers/CompositableForwarder.h" 13 #include "mozilla/layers/ImageBridgeChild.h" 14 #include "mozilla/layers/TextureClient.h" // for TextureClient, etc 15 #include "mozilla/layers/TextureClientOGL.h" 16 #include "mozilla/layers/TextureClientRecycleAllocator.h" 17 #include "mozilla/mozalloc.h" // for operator delete, etc 18 #ifdef XP_WIN 19 # include "gfxWindowsPlatform.h" // for gfxWindowsPlatform 20 # include "mozilla/layers/TextureD3D11.h" 21 #endif 22 #include "IPDLActor.h" 23 #include "gfxUtils.h" 24 25 namespace mozilla { 26 namespace layers { 27 28 using namespace mozilla::gfx; 29 30 void CompositableClient::InitIPDL(const CompositableHandle& aHandle) { 31 MOZ_ASSERT(aHandle); 32 33 mForwarder->AssertInForwarderThread(); 34 35 mHandle = aHandle; 36 mIsAsync |= !NS_IsMainThread(); 37 // By simply taking the lock on mTextureClientRecycler we force memory barrier 38 // on mHandle and mIsAsync which makes them behave as Atomic as they are only 39 // ever set in this method. 40 auto l = mTextureClientRecycler.Lock(); 41 } 42 43 CompositableClient::CompositableClient(CompositableForwarder* aForwarder, 44 TextureFlags aTextureFlags) 45 : mForwarder(aForwarder), 46 mTextureFlags(aTextureFlags), 47 mTextureClientRecycler("CompositableClient::mTextureClientRecycler"), 48 mIsAsync(false) {} 49 50 CompositableClient::~CompositableClient() { Destroy(); } 51 52 LayersBackend CompositableClient::GetCompositorBackendType() const { 53 return mForwarder->GetCompositorBackendType(); 54 } 55 56 bool CompositableClient::Connect(ImageContainer* aImageContainer) { 57 MOZ_ASSERT(!mHandle); 58 if (!GetForwarder() || mHandle) { 59 return false; 60 } 61 62 GetForwarder()->AssertInForwarderThread(); 63 GetForwarder()->Connect(this, aImageContainer); 64 return true; 65 } 66 67 bool CompositableClient::IsConnected() const { 68 // CanSend() is only reliable in the same thread as the IPDL channel. 69 mForwarder->AssertInForwarderThread(); 70 return !!mHandle; 71 } 72 73 void CompositableClient::Destroy() { 74 auto l = mTextureClientRecycler.Lock(); 75 if (*l) { 76 (*l)->Destroy(); 77 } 78 79 if (mHandle) { 80 mForwarder->ReleaseCompositable(mHandle); 81 mHandle = CompositableHandle(); 82 } 83 } 84 85 CompositableHandle CompositableClient::GetAsyncHandle() const { 86 if (mIsAsync) { 87 return mHandle; 88 } 89 return CompositableHandle(); 90 } 91 92 already_AddRefed<TextureClient> CompositableClient::CreateBufferTextureClient( 93 gfx::SurfaceFormat aFormat, gfx::IntSize aSize, 94 gfx::BackendType aMoz2DBackend, TextureFlags aTextureFlags) { 95 return TextureClient::CreateForRawBufferAccess(GetForwarder(), aFormat, aSize, 96 aMoz2DBackend, 97 aTextureFlags | mTextureFlags); 98 } 99 100 already_AddRefed<TextureClient> 101 CompositableClient::CreateTextureClientForDrawing( 102 gfx::SurfaceFormat aFormat, gfx::IntSize aSize, BackendSelector aSelector, 103 TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags) { 104 return TextureClient::CreateForDrawing( 105 GetForwarder(), aFormat, aSize, aSelector, aTextureFlags | mTextureFlags, 106 aAllocFlags); 107 } 108 109 bool CompositableClient::AddTextureClient(TextureClient* aClient) { 110 if (!aClient) { 111 return false; 112 } 113 aClient->SetAddedToCompositableClient(); 114 return aClient->InitIPDLActor(mForwarder); 115 } 116 117 void CompositableClient::ClearCachedResources() { 118 auto l = mTextureClientRecycler.Lock(); 119 if (*l) { 120 (*l)->ShrinkToMinimumSize(); 121 } 122 } 123 124 void CompositableClient::HandleMemoryPressure() { 125 auto l = mTextureClientRecycler.Lock(); 126 if (*l) { 127 (*l)->ShrinkToMinimumSize(); 128 } 129 } 130 131 void CompositableClient::RemoveTexture(TextureClient* aTexture) { 132 mForwarder->RemoveTextureFromCompositable(this, aTexture); 133 } 134 135 TextureClientRecycleAllocator* CompositableClient::GetTextureClientRecycler() { 136 auto l = mTextureClientRecycler.Lock(); 137 if (*l) { 138 return *l; 139 } 140 141 if (!mForwarder || !mForwarder->GetTextureForwarder()) { 142 return nullptr; 143 } 144 145 *l = new layers::TextureClientRecycleAllocator(mForwarder); 146 return *l; 147 } 148 149 void CompositableClient::DumpTextureClient(std::stringstream& aStream, 150 TextureClient* aTexture, 151 TextureDumpMode aCompress) { 152 if (!aTexture) { 153 return; 154 } 155 RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface(); 156 if (!dSurf) { 157 return; 158 } 159 if (aCompress == TextureDumpMode::Compress) { 160 aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); 161 } else { 162 aStream << gfxUtils::GetAsDataURI(dSurf).get(); 163 } 164 } 165 166 AutoRemoveTexture::~AutoRemoveTexture() { 167 if (mCompositable && mTexture && mCompositable->IsConnected()) { 168 mCompositable->RemoveTexture(mTexture); 169 } 170 } 171 172 } // namespace layers 173 } // namespace mozilla