/src/mozilla-central/gfx/layers/mlgpu/LayerManagerMLGPU.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 "LayerManagerMLGPU.h" |
8 | | #include "LayerTreeInvalidation.h" |
9 | | #include "PaintedLayerMLGPU.h" |
10 | | #include "ImageLayerMLGPU.h" |
11 | | #include "CanvasLayerMLGPU.h" |
12 | | #include "GeckoProfiler.h" // for profiler_* |
13 | | #include "gfxEnv.h" // for gfxEnv |
14 | | #include "MLGDevice.h" |
15 | | #include "RenderPassMLGPU.h" |
16 | | #include "RenderViewMLGPU.h" |
17 | | #include "ShaderDefinitionsMLGPU.h" |
18 | | #include "SharedBufferMLGPU.h" |
19 | | #include "UnitTransforms.h" |
20 | | #include "TextureSourceProviderMLGPU.h" |
21 | | #include "TreeTraversal.h" |
22 | | #include "FrameBuilder.h" |
23 | | #include "LayersLogging.h" |
24 | | #include "UtilityMLGPU.h" |
25 | | #include "mozilla/layers/Diagnostics.h" |
26 | | #include "mozilla/layers/TextRenderer.h" |
27 | | |
28 | | #ifdef XP_WIN |
29 | | #include "mozilla/widget/WinCompositorWidget.h" |
30 | | #include "mozilla/gfx/DeviceManagerDx.h" |
31 | | #endif |
32 | | |
33 | | using namespace std; |
34 | | |
35 | | namespace mozilla { |
36 | | namespace layers { |
37 | | |
38 | | using namespace gfx; |
39 | | |
40 | | static const int kDebugOverlayX = 2; |
41 | | static const int kDebugOverlayY = 5; |
42 | | static const int kDebugOverlayMaxWidth = 600; |
43 | | static const int kDebugOverlayMaxHeight = 96; |
44 | | |
45 | | LayerManagerMLGPU::LayerManagerMLGPU(widget::CompositorWidget* aWidget) |
46 | | : mWidget(aWidget), |
47 | | mDrawDiagnostics(false), |
48 | | mUsingInvalidation(false), |
49 | | mCurrentFrame(nullptr), |
50 | | mDebugFrameNumber(0) |
51 | 0 | { |
52 | 0 | if (!aWidget) { |
53 | 0 | return; |
54 | 0 | } |
55 | 0 | |
56 | | #ifdef WIN32 |
57 | | mDevice = DeviceManagerDx::Get()->GetMLGDevice(); |
58 | | #endif |
59 | 0 | if (!mDevice || !mDevice->IsValid()) { |
60 | 0 | gfxWarning() << "Could not acquire an MLGDevice!"; |
61 | 0 | return; |
62 | 0 | } |
63 | 0 |
|
64 | 0 | mSwapChain = mDevice->CreateSwapChainForWidget(aWidget); |
65 | 0 | if (!mSwapChain) { |
66 | 0 | gfxWarning() << "Could not acquire an MLGSwapChain!"; |
67 | 0 | return; |
68 | 0 | } |
69 | 0 |
|
70 | 0 | mDiagnostics = MakeUnique<Diagnostics>(); |
71 | 0 | mTextRenderer = new TextRenderer(); |
72 | 0 | } |
73 | | |
74 | | LayerManagerMLGPU::~LayerManagerMLGPU() |
75 | 0 | { |
76 | 0 | if (mTextureSourceProvider) { |
77 | 0 | mTextureSourceProvider->Destroy(); |
78 | 0 | } |
79 | 0 | } |
80 | | |
81 | | bool |
82 | | LayerManagerMLGPU::Initialize() |
83 | 0 | { |
84 | 0 | if (!mDevice || !mSwapChain) { |
85 | 0 | return false; |
86 | 0 | } |
87 | 0 | |
88 | 0 | mTextureSourceProvider = new TextureSourceProviderMLGPU(this, mDevice); |
89 | 0 | return true; |
90 | 0 | } |
91 | | |
92 | | void |
93 | | LayerManagerMLGPU::Destroy() |
94 | 0 | { |
95 | 0 | if (IsDestroyed()) { |
96 | 0 | return; |
97 | 0 | } |
98 | 0 | |
99 | 0 | LayerManager::Destroy(); |
100 | 0 |
|
101 | 0 | if (mDevice && mDevice->IsValid()) { |
102 | 0 | mDevice->Flush(); |
103 | 0 | } |
104 | 0 | if (mSwapChain) { |
105 | 0 | mSwapChain->Destroy(); |
106 | 0 | mSwapChain = nullptr; |
107 | 0 | } |
108 | 0 | if (mTextureSourceProvider) { |
109 | 0 | mTextureSourceProvider->Destroy(); |
110 | 0 | mTextureSourceProvider = nullptr; |
111 | 0 | } |
112 | 0 | mWidget = nullptr; |
113 | 0 | mDevice = nullptr; |
114 | 0 | } |
115 | | |
116 | | void |
117 | | LayerManagerMLGPU::ForcePresent() |
118 | 0 | { |
119 | 0 | if (!mDevice->IsValid()) { |
120 | 0 | return; |
121 | 0 | } |
122 | 0 | |
123 | 0 | IntSize windowSize = mWidget->GetClientSize().ToUnknownSize(); |
124 | 0 | if (mSwapChain->GetSize() != windowSize) { |
125 | 0 | return; |
126 | 0 | } |
127 | 0 | |
128 | 0 | mSwapChain->ForcePresent(); |
129 | 0 | } |
130 | | |
131 | | already_AddRefed<ContainerLayer> |
132 | | LayerManagerMLGPU::CreateContainerLayer() |
133 | 0 | { |
134 | 0 | return MakeAndAddRef<ContainerLayerMLGPU>(this); |
135 | 0 | } |
136 | | |
137 | | already_AddRefed<ColorLayer> |
138 | | LayerManagerMLGPU::CreateColorLayer() |
139 | 0 | { |
140 | 0 | return MakeAndAddRef<ColorLayerMLGPU>(this); |
141 | 0 | } |
142 | | |
143 | | already_AddRefed<RefLayer> |
144 | | LayerManagerMLGPU::CreateRefLayer() |
145 | 0 | { |
146 | 0 | return MakeAndAddRef<RefLayerMLGPU>(this); |
147 | 0 | } |
148 | | |
149 | | already_AddRefed<PaintedLayer> |
150 | | LayerManagerMLGPU::CreatePaintedLayer() |
151 | 0 | { |
152 | 0 | return MakeAndAddRef<PaintedLayerMLGPU>(this); |
153 | 0 | } |
154 | | |
155 | | already_AddRefed<ImageLayer> |
156 | | LayerManagerMLGPU::CreateImageLayer() |
157 | 0 | { |
158 | 0 | return MakeAndAddRef<ImageLayerMLGPU>(this); |
159 | 0 | } |
160 | | |
161 | | already_AddRefed<CanvasLayer> |
162 | | LayerManagerMLGPU::CreateCanvasLayer() |
163 | 0 | { |
164 | 0 | return MakeAndAddRef<CanvasLayerMLGPU>(this); |
165 | 0 | } |
166 | | |
167 | | TextureFactoryIdentifier |
168 | | LayerManagerMLGPU::GetTextureFactoryIdentifier() |
169 | 0 | { |
170 | 0 | TextureFactoryIdentifier ident; |
171 | 0 | if (mDevice) { |
172 | 0 | ident = mDevice->GetTextureFactoryIdentifier(); |
173 | 0 | } |
174 | 0 | ident.mUsingAdvancedLayers = true; |
175 | 0 | return ident; |
176 | 0 | } |
177 | | |
178 | | LayersBackend |
179 | | LayerManagerMLGPU::GetBackendType() |
180 | 0 | { |
181 | 0 | return mDevice ? mDevice->GetLayersBackend() : LayersBackend::LAYERS_NONE; |
182 | 0 | } |
183 | | |
184 | | void |
185 | | LayerManagerMLGPU::SetRoot(Layer* aLayer) |
186 | 0 | { |
187 | 0 | mRoot = aLayer; |
188 | 0 | } |
189 | | |
190 | | bool |
191 | | LayerManagerMLGPU::BeginTransaction() |
192 | 0 | { |
193 | 0 | MOZ_ASSERT(!mTarget); |
194 | 0 | return true; |
195 | 0 | } |
196 | | |
197 | | void |
198 | | LayerManagerMLGPU::BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, |
199 | | const gfx::IntRect& aRect) |
200 | 0 | { |
201 | 0 | MOZ_ASSERT(!mTarget); |
202 | 0 |
|
203 | 0 | mTarget = aTarget; |
204 | 0 | mTargetRect = aRect; |
205 | 0 | return; |
206 | 0 | } |
207 | | |
208 | | // Helper class for making sure textures are unlocked. |
209 | | class MOZ_STACK_CLASS AutoUnlockAllTextures |
210 | | { |
211 | | public: |
212 | | explicit AutoUnlockAllTextures(MLGDevice* aDevice) |
213 | | : mDevice(aDevice) |
214 | 0 | {} |
215 | 0 | ~AutoUnlockAllTextures() { |
216 | 0 | mDevice->UnlockAllTextures(); |
217 | 0 | } |
218 | | |
219 | | private: |
220 | | RefPtr<MLGDevice> mDevice; |
221 | | }; |
222 | | |
223 | | void |
224 | | LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFlags aFlags) |
225 | 0 | { |
226 | 0 | AUTO_PROFILER_LABEL("LayerManager::EndTransaction", GRAPHICS); |
227 | 0 |
|
228 | 0 | SetCompositionTime(aTimeStamp); |
229 | 0 |
|
230 | 0 | TextureSourceProvider::AutoReadUnlockTextures unlock(mTextureSourceProvider); |
231 | 0 |
|
232 | 0 | if (!mRoot || (aFlags & END_NO_IMMEDIATE_REDRAW) || !mWidget) { |
233 | 0 | return; |
234 | 0 | } |
235 | 0 | |
236 | 0 | mCompositionStartTime = TimeStamp::Now(); |
237 | 0 |
|
238 | 0 | IntSize windowSize = mWidget->GetClientSize().ToUnknownSize(); |
239 | 0 | if (windowSize.IsEmpty()) { |
240 | 0 | return; |
241 | 0 | } |
242 | 0 | |
243 | 0 | // Resize the window if needed. |
244 | 0 | if (mSwapChain->GetSize() != windowSize) { |
245 | 0 | // Note: all references to the backbuffer must be cleared. |
246 | 0 | mDevice->SetRenderTarget(nullptr); |
247 | 0 | if (!mSwapChain->ResizeBuffers(windowSize)) { |
248 | 0 | gfxCriticalNote << "Could not resize the swapchain (" << |
249 | 0 | hexa(windowSize.width) << "," << hexa(windowSize.height) << ")"; |
250 | 0 | return; |
251 | 0 | } |
252 | 0 | } |
253 | 0 |
|
254 | 0 | // Don't draw the diagnostic overlay if we want to snapshot the output. |
255 | 0 | mDrawDiagnostics = gfxPrefs::LayersDrawFPS() && !mTarget; |
256 | 0 | mUsingInvalidation = gfxPrefs::AdvancedLayersUseInvalidation(); |
257 | 0 | mDebugFrameNumber++; |
258 | 0 |
|
259 | 0 | AL_LOG("--- Compositing frame %d ---\n", mDebugFrameNumber); |
260 | 0 |
|
261 | 0 | // Compute transforms - and the changed area, if enabled. |
262 | 0 | mRoot->ComputeEffectiveTransforms(Matrix4x4()); |
263 | 0 | ComputeInvalidRegion(); |
264 | 0 |
|
265 | 0 | // Build and execute draw commands, and present. |
266 | 0 | if (PreRender()) { |
267 | 0 | Composite(); |
268 | 0 | PostRender(); |
269 | 0 | } |
270 | 0 |
|
271 | 0 | mTextureSourceProvider->FlushPendingNotifyNotUsed(); |
272 | 0 |
|
273 | 0 | // Finish composition. |
274 | 0 | mLastCompositionEndTime = TimeStamp::Now(); |
275 | 0 | } |
276 | | |
277 | | void |
278 | | LayerManagerMLGPU::Composite() |
279 | 0 | { |
280 | 0 | if (gfxEnv::SkipComposition()) { |
281 | 0 | return; |
282 | 0 | } |
283 | 0 | |
284 | 0 | AUTO_PROFILER_LABEL("LayerManagerMLGPU::Composite", GRAPHICS); |
285 | 0 |
|
286 | 0 | // Don't composite if we're minimized/hidden, or if there is nothing to draw. |
287 | 0 | if (mWidget->IsHidden()) { |
288 | 0 | return; |
289 | 0 | } |
290 | 0 | |
291 | 0 | // Make sure the diagnostic area gets invalidated. We do this now, rather than |
292 | 0 | // earlier, so we don't accidentally cause extra composites. |
293 | 0 | Maybe<IntRect> diagnosticRect; |
294 | 0 | if (mDrawDiagnostics) { |
295 | 0 | diagnosticRect = Some(IntRect( |
296 | 0 | kDebugOverlayX, kDebugOverlayY, |
297 | 0 | kDebugOverlayMaxWidth, kDebugOverlayMaxHeight)); |
298 | 0 | } |
299 | 0 |
|
300 | 0 | AL_LOG("Computed invalid region: %s\n", Stringify(mInvalidRegion).c_str()); |
301 | 0 |
|
302 | 0 | // Now that we have the final invalid region, give it to the swap chain which |
303 | 0 | // will tell us if we still need to render. |
304 | 0 | if (!mSwapChain->ApplyNewInvalidRegion(std::move(mInvalidRegion), diagnosticRect)) { |
305 | 0 | return; |
306 | 0 | } |
307 | 0 | |
308 | 0 | AutoUnlockAllTextures autoUnlock(mDevice); |
309 | 0 |
|
310 | 0 | mDevice->BeginFrame(); |
311 | 0 |
|
312 | 0 | RenderLayers(); |
313 | 0 |
|
314 | 0 | if (mDrawDiagnostics) { |
315 | 0 | DrawDebugOverlay(); |
316 | 0 | } |
317 | 0 |
|
318 | 0 | if (mTarget) { |
319 | 0 | mSwapChain->CopyBackbuffer(mTarget, mTargetRect); |
320 | 0 | mTarget = nullptr; |
321 | 0 | mTargetRect = IntRect(); |
322 | 0 | } |
323 | 0 | mSwapChain->Present(); |
324 | 0 |
|
325 | 0 | // We call this here to mimic the behavior in LayerManagerComposite, as to |
326 | 0 | // not change what Talos measures. That is, we do not record an empty frame |
327 | 0 | // as a frame, since we short-circuit at the top of this function. |
328 | 0 | RecordFrame(); |
329 | 0 |
|
330 | 0 | mDevice->EndFrame(); |
331 | 0 |
|
332 | 0 | // Free the old cloned property tree, then clone a new one. Note that we do |
333 | 0 | // this after compositing, since layer preparation actually mutates the layer |
334 | 0 | // tree (for example, ImageHost::mLastFrameID). We want the property tree to |
335 | 0 | // pick up these changes. Similarly, we are careful to not mutate the tree |
336 | 0 | // in any way that we *don't* want LayerProperties to catch, lest we cause |
337 | 0 | // extra invalidation. |
338 | 0 | // |
339 | 0 | // Note that the old Compositor performs occlusion culling directly on the |
340 | 0 | // shadow visible region, and does this *before* cloning layer tree |
341 | 0 | // properties. Advanced Layers keeps the occlusion region separate and |
342 | 0 | // performs invalidation against the clean layer tree. |
343 | 0 | mClonedLayerTreeProperties = nullptr; |
344 | 0 | mClonedLayerTreeProperties = LayerProperties::CloneFrom(mRoot); |
345 | 0 | } |
346 | | |
347 | | void |
348 | | LayerManagerMLGPU::RenderLayers() |
349 | 0 | { |
350 | 0 | AUTO_PROFILER_LABEL("LayerManagerMLGPU::RenderLayers", GRAPHICS); |
351 | 0 |
|
352 | 0 | // Traverse the layer tree and assign each layer to a render target. |
353 | 0 | FrameBuilder builder(this, mSwapChain); |
354 | 0 | mCurrentFrame = &builder; |
355 | 0 |
|
356 | 0 | if (!builder.Build()) { |
357 | 0 | return; |
358 | 0 | } |
359 | 0 | |
360 | 0 | if (mDrawDiagnostics) { |
361 | 0 | mDiagnostics->RecordPrepareTime((TimeStamp::Now() - mCompositionStartTime).ToMilliseconds()); |
362 | 0 | } |
363 | 0 |
|
364 | 0 | // Make sure we acquire/release the sync object. |
365 | 0 | if (!mDevice->Synchronize()) { |
366 | 0 | // Catastrophic failure - probably a device reset. |
367 | 0 | return; |
368 | 0 | } |
369 | 0 | |
370 | 0 | TimeStamp start = TimeStamp::Now(); |
371 | 0 |
|
372 | 0 | // Upload shared buffers. |
373 | 0 | mDevice->FinishSharedBufferUse(); |
374 | 0 |
|
375 | 0 | // Prepare the pipeline. |
376 | 0 | if (mDrawDiagnostics) { |
377 | 0 | IntSize size = mSwapChain->GetBackBufferInvalidRegion().GetBounds().Size(); |
378 | 0 | uint32_t numPixels = size.width * size.height; |
379 | 0 | mDevice->StartDiagnostics(numPixels); |
380 | 0 | } |
381 | 0 |
|
382 | 0 | // Execute all render passes. |
383 | 0 | builder.Render(); |
384 | 0 | mCurrentFrame = nullptr; |
385 | 0 |
|
386 | 0 | if (mDrawDiagnostics) { |
387 | 0 | mDiagnostics->RecordCompositeTime((TimeStamp::Now() - start).ToMilliseconds()); |
388 | 0 | mDevice->EndDiagnostics(); |
389 | 0 | } |
390 | 0 | } |
391 | | |
392 | | void |
393 | | LayerManagerMLGPU::DrawDebugOverlay() |
394 | 0 | { |
395 | 0 | IntSize windowSize = mSwapChain->GetSize(); |
396 | 0 |
|
397 | 0 | GPUStats stats; |
398 | 0 | mDevice->GetDiagnostics(&stats); |
399 | 0 | stats.mScreenPixels = windowSize.width * windowSize.height; |
400 | 0 |
|
401 | 0 | std::string text = mDiagnostics->GetFrameOverlayString(stats); |
402 | 0 | RefPtr<TextureSource> texture = mTextRenderer->RenderText( |
403 | 0 | mTextureSourceProvider, |
404 | 0 | text, |
405 | 0 | 30, |
406 | 0 | 600, |
407 | 0 | TextRenderer::FontType::FixedWidth); |
408 | 0 | if (!texture) { |
409 | 0 | return; |
410 | 0 | } |
411 | 0 | |
412 | 0 | if (mUsingInvalidation && |
413 | 0 | (texture->GetSize().width > kDebugOverlayMaxWidth || |
414 | 0 | texture->GetSize().height > kDebugOverlayMaxHeight)) |
415 | 0 | { |
416 | 0 | gfxCriticalNote << "Diagnostic overlay exceeds invalidation area: %s" << Stringify(texture->GetSize()).c_str(); |
417 | 0 | } |
418 | 0 |
|
419 | 0 | struct DebugRect { |
420 | 0 | Rect bounds; |
421 | 0 | Rect texCoords; |
422 | 0 | }; |
423 | 0 |
|
424 | 0 | if (!mDiagnosticVertices) { |
425 | 0 | DebugRect rect; |
426 | 0 | rect.bounds = Rect(Point(kDebugOverlayX, kDebugOverlayY), Size(texture->GetSize())); |
427 | 0 | rect.texCoords = Rect(0.0, 0.0, 1.0, 1.0); |
428 | 0 |
|
429 | 0 | VertexStagingBuffer instances; |
430 | 0 | if (!instances.AppendItem(rect)) { |
431 | 0 | return; |
432 | 0 | } |
433 | 0 | |
434 | 0 | mDiagnosticVertices = mDevice->CreateBuffer( |
435 | 0 | MLGBufferType::Vertex, |
436 | 0 | instances.NumItems() * instances.SizeOfItem(), |
437 | 0 | MLGUsage::Immutable, |
438 | 0 | instances.GetBufferStart()); |
439 | 0 | if (!mDiagnosticVertices) { |
440 | 0 | return; |
441 | 0 | } |
442 | 0 | } |
443 | 0 | |
444 | 0 | // Note: we rely on the world transform being correctly left bound by the |
445 | 0 | // outermost render view. |
446 | 0 | mDevice->SetScissorRect(Nothing()); |
447 | 0 | mDevice->SetDepthTestMode(MLGDepthTestMode::Disabled); |
448 | 0 | mDevice->SetTopology(MLGPrimitiveTopology::UnitQuad); |
449 | 0 | mDevice->SetVertexShader(VertexShaderID::DiagnosticText); |
450 | 0 | mDevice->SetVertexBuffer(1, mDiagnosticVertices, sizeof(DebugRect)); |
451 | 0 | mDevice->SetPixelShader(PixelShaderID::DiagnosticText); |
452 | 0 | mDevice->SetBlendState(MLGBlendState::Over); |
453 | 0 | mDevice->SetPSTexture(0, texture); |
454 | 0 | mDevice->SetSamplerMode(0, SamplerMode::Point); |
455 | 0 | mDevice->DrawInstanced(4, 1, 0, 0); |
456 | 0 | } |
457 | | |
458 | | void |
459 | | LayerManagerMLGPU::ComputeInvalidRegion() |
460 | 0 | { |
461 | 0 | // If invalidation is disabled, throw away cloned properties and redraw the |
462 | 0 | // whole target area. |
463 | 0 | if (!mUsingInvalidation) { |
464 | 0 | mInvalidRegion = mTarget ? mTargetRect : mRenderBounds; |
465 | 0 | mNextFrameInvalidRegion.SetEmpty(); |
466 | 0 | return; |
467 | 0 | } |
468 | 0 |
|
469 | 0 | nsIntRegion changed; |
470 | 0 | if (mClonedLayerTreeProperties) { |
471 | 0 | if (!mClonedLayerTreeProperties->ComputeDifferences(mRoot, changed, nullptr)) { |
472 | 0 | changed = mRenderBounds; |
473 | 0 | } |
474 | 0 | } else { |
475 | 0 | changed = mRenderBounds; |
476 | 0 | } |
477 | 0 |
|
478 | 0 | // We compute the change region, but if we're painting to a target, we save |
479 | 0 | // it for the next frame instead. |
480 | 0 | if (mTarget) { |
481 | 0 | mInvalidRegion = mTargetRect; |
482 | 0 | mNextFrameInvalidRegion.OrWith(changed); |
483 | 0 | } else { |
484 | 0 | mInvalidRegion = std::move(mNextFrameInvalidRegion); |
485 | 0 | mInvalidRegion.OrWith(changed); |
486 | 0 | } |
487 | 0 | } |
488 | | |
489 | | void |
490 | | LayerManagerMLGPU::AddInvalidRegion(const nsIntRegion& aRegion) |
491 | 0 | { |
492 | 0 | mNextFrameInvalidRegion.OrWith(aRegion); |
493 | 0 | } |
494 | | |
495 | | TextureSourceProvider* |
496 | | LayerManagerMLGPU::GetTextureSourceProvider() const |
497 | 0 | { |
498 | 0 | return mTextureSourceProvider; |
499 | 0 | } |
500 | | |
501 | | bool |
502 | | LayerManagerMLGPU::IsCompositingToScreen() const |
503 | 0 | { |
504 | 0 | return !mTarget; |
505 | 0 | } |
506 | | |
507 | | bool |
508 | | LayerManagerMLGPU::AreComponentAlphaLayersEnabled() |
509 | 0 | { |
510 | 0 | return LayerManager::AreComponentAlphaLayersEnabled(); |
511 | 0 | } |
512 | | |
513 | | bool |
514 | | LayerManagerMLGPU::BlendingRequiresIntermediateSurface() |
515 | 0 | { |
516 | 0 | return true; |
517 | 0 | } |
518 | | |
519 | | void |
520 | | LayerManagerMLGPU::EndTransaction(DrawPaintedLayerCallback aCallback, |
521 | | void* aCallbackData, |
522 | | EndTransactionFlags aFlags) |
523 | 0 | { |
524 | 0 | MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)"); |
525 | 0 | } |
526 | | |
527 | | void |
528 | | LayerManagerMLGPU::ClearCachedResources(Layer* aSubtree) |
529 | 0 | { |
530 | 0 | Layer* root = aSubtree ? aSubtree : mRoot.get(); |
531 | 0 | if (!root) { |
532 | 0 | return; |
533 | 0 | } |
534 | 0 | |
535 | 0 | ForEachNode<ForwardIterator>(root, [](Layer* aLayer) { |
536 | 0 | LayerMLGPU* layer = aLayer->AsHostLayer()->AsLayerMLGPU(); |
537 | 0 | if (!layer) { |
538 | 0 | return; |
539 | 0 | } |
540 | 0 | layer->ClearCachedResources(); |
541 | 0 | }); |
542 | 0 | } |
543 | | |
544 | | void |
545 | | LayerManagerMLGPU::NotifyShadowTreeTransaction() |
546 | 0 | { |
547 | 0 | if (gfxPrefs::LayersDrawFPS()) { |
548 | 0 | mDiagnostics->AddTxnFrame(); |
549 | 0 | } |
550 | 0 | } |
551 | | |
552 | | void |
553 | | LayerManagerMLGPU::UpdateRenderBounds(const gfx::IntRect& aRect) |
554 | 0 | { |
555 | 0 | mRenderBounds = aRect; |
556 | 0 | } |
557 | | |
558 | | bool |
559 | | LayerManagerMLGPU::PreRender() |
560 | 0 | { |
561 | 0 | AUTO_PROFILER_LABEL("LayerManagerMLGPU::PreRender", GRAPHICS); |
562 | 0 |
|
563 | 0 | widget::WidgetRenderingContext context; |
564 | 0 | if (!mWidget->PreRender(&context)) { |
565 | 0 | return false; |
566 | 0 | } |
567 | 0 | mWidgetContext = Some(context); |
568 | 0 | return true; |
569 | 0 | } |
570 | | |
571 | | void |
572 | | LayerManagerMLGPU::PostRender() |
573 | 0 | { |
574 | 0 | mWidget->PostRender(mWidgetContext.ptr()); |
575 | 0 | mWidgetContext = Nothing(); |
576 | 0 | } |
577 | | |
578 | | } // namespace layers |
579 | | } // namespace mozilla |