/src/mozilla-central/gfx/layers/client/CompositableClient.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include <stdint.h> // for uint64_t, uint32_t |
9 | | #include "gfxPlatform.h" // for gfxPlatform |
10 | | #include "mozilla/layers/CompositableForwarder.h" |
11 | | #include "mozilla/layers/ImageBridgeChild.h" |
12 | | #include "mozilla/layers/TextureClient.h" // for TextureClient, etc |
13 | | #include "mozilla/layers/TextureClientOGL.h" |
14 | | #include "mozilla/mozalloc.h" // for operator delete, etc |
15 | | #include "mozilla/layers/TextureClientRecycleAllocator.h" |
16 | | #ifdef XP_WIN |
17 | | #include "gfxWindowsPlatform.h" // for gfxWindowsPlatform |
18 | | #include "mozilla/layers/TextureD3D11.h" |
19 | | #endif |
20 | | #include "gfxUtils.h" |
21 | | #include "IPDLActor.h" |
22 | | |
23 | | namespace mozilla { |
24 | | namespace layers { |
25 | | |
26 | | using namespace mozilla::gfx; |
27 | | |
28 | | void |
29 | | CompositableClient::InitIPDL(const CompositableHandle& aHandle) |
30 | 0 | { |
31 | 0 | MOZ_ASSERT(aHandle); |
32 | 0 |
|
33 | 0 | mForwarder->AssertInForwarderThread(); |
34 | 0 |
|
35 | 0 | mHandle = aHandle; |
36 | 0 | mIsAsync = !NS_IsMainThread(); |
37 | 0 | } |
38 | | |
39 | | CompositableClient::CompositableClient(CompositableForwarder* aForwarder, |
40 | | TextureFlags aTextureFlags) |
41 | | : mForwarder(aForwarder) |
42 | | , mTextureFlags(aTextureFlags) |
43 | | , mIsAsync(false) |
44 | 0 | { |
45 | 0 | } |
46 | | |
47 | | CompositableClient::~CompositableClient() |
48 | 0 | { |
49 | 0 | Destroy(); |
50 | 0 | } |
51 | | |
52 | | LayersBackend |
53 | | CompositableClient::GetCompositorBackendType() const |
54 | 0 | { |
55 | 0 | return mForwarder->GetCompositorBackendType(); |
56 | 0 | } |
57 | | |
58 | | bool |
59 | | CompositableClient::Connect(ImageContainer* aImageContainer) |
60 | 0 | { |
61 | 0 | MOZ_ASSERT(!mHandle); |
62 | 0 | if (!GetForwarder() || mHandle) { |
63 | 0 | return false; |
64 | 0 | } |
65 | 0 | |
66 | 0 | GetForwarder()->AssertInForwarderThread(); |
67 | 0 | GetForwarder()->Connect(this, aImageContainer); |
68 | 0 | return true; |
69 | 0 | } |
70 | | |
71 | | bool |
72 | | CompositableClient::IsConnected() const |
73 | 0 | { |
74 | 0 | // CanSend() is only reliable in the same thread as the IPDL channel. |
75 | 0 | mForwarder->AssertInForwarderThread(); |
76 | 0 | return !!mHandle; |
77 | 0 | } |
78 | | |
79 | | void |
80 | | CompositableClient::Destroy() |
81 | 0 | { |
82 | 0 | if (mTextureClientRecycler) { |
83 | 0 | mTextureClientRecycler->Destroy(); |
84 | 0 | } |
85 | 0 |
|
86 | 0 | if (mHandle) { |
87 | 0 | mForwarder->ReleaseCompositable(mHandle); |
88 | 0 | mHandle = CompositableHandle(); |
89 | 0 | } |
90 | 0 | } |
91 | | |
92 | | CompositableHandle |
93 | | CompositableClient::GetAsyncHandle() const |
94 | 0 | { |
95 | 0 | if (mIsAsync) { |
96 | 0 | return mHandle; |
97 | 0 | } |
98 | 0 | return CompositableHandle(); |
99 | 0 | } |
100 | | |
101 | | already_AddRefed<TextureClient> |
102 | | CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, |
103 | | gfx::IntSize aSize, |
104 | | gfx::BackendType aMoz2DBackend, |
105 | | TextureFlags aTextureFlags) |
106 | 0 | { |
107 | 0 | return TextureClient::CreateForRawBufferAccess(GetForwarder(), |
108 | 0 | aFormat, aSize, aMoz2DBackend, |
109 | 0 | aTextureFlags | mTextureFlags); |
110 | 0 | } |
111 | | |
112 | | already_AddRefed<TextureClient> |
113 | | CompositableClient::CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat, |
114 | | gfx::IntSize aSize, |
115 | | BackendSelector aSelector, |
116 | | TextureFlags aTextureFlags, |
117 | | TextureAllocationFlags aAllocFlags) |
118 | 0 | { |
119 | 0 | return TextureClient::CreateForDrawing(GetForwarder(), |
120 | 0 | aFormat, aSize, aSelector, |
121 | 0 | aTextureFlags | mTextureFlags, |
122 | 0 | aAllocFlags); |
123 | 0 | } |
124 | | |
125 | | already_AddRefed<TextureClient> |
126 | | CompositableClient::CreateTextureClientFromSurface(gfx::SourceSurface* aSurface, |
127 | | BackendSelector aSelector, |
128 | | TextureFlags aTextureFlags, |
129 | | TextureAllocationFlags aAllocFlags) |
130 | 0 | { |
131 | 0 | return TextureClient::CreateFromSurface(GetForwarder(), |
132 | 0 | aSurface, |
133 | 0 | aSelector, |
134 | 0 | aTextureFlags | mTextureFlags, |
135 | 0 | aAllocFlags); |
136 | 0 | } |
137 | | |
138 | | bool |
139 | | CompositableClient::AddTextureClient(TextureClient* aClient) |
140 | 0 | { |
141 | 0 | if(!aClient) { |
142 | 0 | return false; |
143 | 0 | } |
144 | 0 | aClient->SetAddedToCompositableClient(); |
145 | 0 | return aClient->InitIPDLActor(mForwarder); |
146 | 0 | } |
147 | | |
148 | | void |
149 | | CompositableClient::ClearCachedResources() |
150 | 0 | { |
151 | 0 | if (mTextureClientRecycler) { |
152 | 0 | mTextureClientRecycler->ShrinkToMinimumSize(); |
153 | 0 | } |
154 | 0 | } |
155 | | |
156 | | void |
157 | | CompositableClient::HandleMemoryPressure() |
158 | 0 | { |
159 | 0 | if (mTextureClientRecycler) { |
160 | 0 | mTextureClientRecycler->ShrinkToMinimumSize(); |
161 | 0 | } |
162 | 0 | } |
163 | | |
164 | | void |
165 | | CompositableClient::RemoveTexture(TextureClient* aTexture) |
166 | 0 | { |
167 | 0 | mForwarder->RemoveTextureFromCompositable(this, aTexture); |
168 | 0 | } |
169 | | |
170 | | TextureClientRecycleAllocator* |
171 | | CompositableClient::GetTextureClientRecycler() |
172 | 0 | { |
173 | 0 | if (mTextureClientRecycler) { |
174 | 0 | return mTextureClientRecycler; |
175 | 0 | } |
176 | 0 | |
177 | 0 | if (!mForwarder) { |
178 | 0 | return nullptr; |
179 | 0 | } |
180 | 0 | |
181 | 0 | if(!mForwarder->GetTextureForwarder()->UsesImageBridge()) { |
182 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
183 | 0 | mTextureClientRecycler = new layers::TextureClientRecycleAllocator(mForwarder); |
184 | 0 | return mTextureClientRecycler; |
185 | 0 | } |
186 | 0 |
|
187 | 0 | // Handle a case that mForwarder is ImageBridge |
188 | 0 |
|
189 | 0 | if (InImageBridgeChildThread()) { |
190 | 0 | mTextureClientRecycler = new layers::TextureClientRecycleAllocator(mForwarder); |
191 | 0 | return mTextureClientRecycler; |
192 | 0 | } |
193 | 0 | |
194 | 0 | ReentrantMonitor barrier("CompositableClient::GetTextureClientRecycler"); |
195 | 0 | ReentrantMonitorAutoEnter mainThreadAutoMon(barrier); |
196 | 0 | bool done = false; |
197 | 0 |
|
198 | 0 | RefPtr<Runnable> runnable = NS_NewRunnableFunction( |
199 | 0 | "layers::CompositableClient::GetTextureClientRecycler", [&]() { |
200 | 0 | if (!mTextureClientRecycler) { |
201 | 0 | mTextureClientRecycler = new layers::TextureClientRecycleAllocator(mForwarder); |
202 | 0 | } |
203 | 0 | ReentrantMonitorAutoEnter childThreadAutoMon(barrier); |
204 | 0 | done = true; |
205 | 0 | barrier.NotifyAll(); |
206 | 0 | }); |
207 | 0 |
|
208 | 0 | ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(runnable.forget()); |
209 | 0 |
|
210 | 0 | // should stop the thread until done. |
211 | 0 | while (!done) { |
212 | 0 | barrier.Wait(); |
213 | 0 | } |
214 | 0 |
|
215 | 0 | return mTextureClientRecycler; |
216 | 0 | } |
217 | | |
218 | | void |
219 | | CompositableClient::DumpTextureClient(std::stringstream& aStream, |
220 | | TextureClient* aTexture, |
221 | | TextureDumpMode aCompress) |
222 | 0 | { |
223 | 0 | if (!aTexture) { |
224 | 0 | return; |
225 | 0 | } |
226 | 0 | RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface(); |
227 | 0 | if (!dSurf) { |
228 | 0 | return; |
229 | 0 | } |
230 | 0 | if (aCompress == TextureDumpMode::Compress) { |
231 | 0 | aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); |
232 | 0 | } else { |
233 | 0 | aStream << gfxUtils::GetAsDataURI(dSurf).get(); |
234 | 0 | } |
235 | 0 | } |
236 | | |
237 | | AutoRemoveTexture::~AutoRemoveTexture() |
238 | 0 | { |
239 | 0 | if (mCompositable && mTexture && mCompositable->IsConnected()) { |
240 | 0 | mCompositable->RemoveTexture(mTexture); |
241 | 0 | } |
242 | 0 | } |
243 | | |
244 | | } // namespace layers |
245 | | } // namespace mozilla |