|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * vim: sw=2 ts=8 et : |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #include "ShadowLayers.h" |
|
9 #include <set> // for _Rb_tree_const_iterator, etc |
|
10 #include <vector> // for vector |
|
11 #include "GeckoProfiler.h" // for PROFILER_LABEL |
|
12 #include "ISurfaceAllocator.h" // for IsSurfaceDescriptorValid |
|
13 #include "Layers.h" // for Layer |
|
14 #include "RenderTrace.h" // for RenderTraceScope |
|
15 #include "ShadowLayerChild.h" // for ShadowLayerChild |
|
16 #include "gfx2DGlue.h" // for Moz2D transition helpers |
|
17 #include "gfxPlatform.h" // for gfxImageFormat, gfxPlatform |
|
18 #include "gfxSharedImageSurface.h" // for gfxSharedImageSurface |
|
19 #include "ipc/IPCMessageUtils.h" // for gfxContentType, null_t |
|
20 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
|
21 #include "mozilla/gfx/Point.h" // for IntSize |
|
22 #include "mozilla/layers/CompositableClient.h" // for CompositableClient, etc |
|
23 #include "mozilla/layers/LayersMessages.h" // for Edit, etc |
|
24 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc |
|
25 #include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG |
|
26 #include "mozilla/layers/LayerTransactionChild.h" |
|
27 #include "ShadowLayerUtils.h" |
|
28 #include "mozilla/layers/TextureClient.h" // for TextureClient |
|
29 #include "mozilla/mozalloc.h" // for operator new, etc |
|
30 #include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc |
|
31 #include "nsDebug.h" // for NS_ABORT_IF_FALSE, etc |
|
32 #include "nsRect.h" // for nsIntRect |
|
33 #include "nsSize.h" // for nsIntSize |
|
34 #include "nsTArray.h" // for nsAutoTArray, nsTArray, etc |
|
35 #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc |
|
36 |
|
37 struct nsIntPoint; |
|
38 |
|
39 using namespace mozilla::ipc; |
|
40 using namespace mozilla::gl; |
|
41 using namespace mozilla::dom; |
|
42 |
|
43 namespace mozilla { |
|
44 namespace ipc { |
|
45 class Shmem; |
|
46 } |
|
47 |
|
48 namespace layers { |
|
49 |
|
50 class ClientTiledLayerBuffer; |
|
51 |
|
52 typedef nsTArray<SurfaceDescriptor> BufferArray; |
|
53 typedef std::vector<Edit> EditVector; |
|
54 typedef std::set<ShadowableLayer*> ShadowableLayerSet; |
|
55 |
|
56 class Transaction |
|
57 { |
|
58 public: |
|
59 Transaction() |
|
60 : mTargetRotation(ROTATION_0) |
|
61 , mSwapRequired(false) |
|
62 , mOpen(false) |
|
63 , mRotationChanged(false) |
|
64 {} |
|
65 |
|
66 void Begin(const nsIntRect& aTargetBounds, ScreenRotation aRotation, |
|
67 const nsIntRect& aClientBounds, ScreenOrientation aOrientation) |
|
68 { |
|
69 mOpen = true; |
|
70 mTargetBounds = aTargetBounds; |
|
71 if (aRotation != mTargetRotation) { |
|
72 // the first time this is called, mRotationChanged will be false if |
|
73 // aRotation is 0, but we should be OK because for the first transaction |
|
74 // we should only compose if it is non-empty. See the caller(s) of |
|
75 // RotationChanged. |
|
76 mRotationChanged = true; |
|
77 } |
|
78 mTargetRotation = aRotation; |
|
79 mClientBounds = aClientBounds; |
|
80 mTargetOrientation = aOrientation; |
|
81 } |
|
82 void MarkSyncTransaction() |
|
83 { |
|
84 mSwapRequired = true; |
|
85 } |
|
86 void AddEdit(const Edit& aEdit) |
|
87 { |
|
88 NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
|
89 mCset.push_back(aEdit); |
|
90 } |
|
91 void AddEdit(const CompositableOperation& aEdit) |
|
92 { |
|
93 AddEdit(Edit(aEdit)); |
|
94 } |
|
95 void AddPaint(const Edit& aPaint) |
|
96 { |
|
97 AddNoSwapPaint(aPaint); |
|
98 mSwapRequired = true; |
|
99 } |
|
100 void AddPaint(const CompositableOperation& aPaint) |
|
101 { |
|
102 AddNoSwapPaint(Edit(aPaint)); |
|
103 mSwapRequired = true; |
|
104 } |
|
105 |
|
106 void AddNoSwapPaint(const Edit& aPaint) |
|
107 { |
|
108 NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
|
109 mPaints.push_back(aPaint); |
|
110 } |
|
111 void AddNoSwapPaint(const CompositableOperation& aPaint) |
|
112 { |
|
113 NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
|
114 mPaints.push_back(Edit(aPaint)); |
|
115 } |
|
116 void AddMutant(ShadowableLayer* aLayer) |
|
117 { |
|
118 NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?"); |
|
119 mMutants.insert(aLayer); |
|
120 } |
|
121 void End() |
|
122 { |
|
123 mCset.clear(); |
|
124 mPaints.clear(); |
|
125 mMutants.clear(); |
|
126 mOpen = false; |
|
127 mSwapRequired = false; |
|
128 mRotationChanged = false; |
|
129 } |
|
130 |
|
131 bool Empty() const { |
|
132 return mCset.empty() && mPaints.empty() && mMutants.empty(); |
|
133 } |
|
134 bool RotationChanged() const { |
|
135 return mRotationChanged; |
|
136 } |
|
137 bool Finished() const { return !mOpen && Empty(); } |
|
138 |
|
139 EditVector mCset; |
|
140 EditVector mPaints; |
|
141 ShadowableLayerSet mMutants; |
|
142 nsIntRect mTargetBounds; |
|
143 ScreenRotation mTargetRotation; |
|
144 nsIntRect mClientBounds; |
|
145 ScreenOrientation mTargetOrientation; |
|
146 bool mSwapRequired; |
|
147 |
|
148 private: |
|
149 bool mOpen; |
|
150 bool mRotationChanged; |
|
151 |
|
152 // disabled |
|
153 Transaction(const Transaction&); |
|
154 Transaction& operator=(const Transaction&); |
|
155 }; |
|
156 struct AutoTxnEnd { |
|
157 AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {} |
|
158 ~AutoTxnEnd() { mTxn->End(); } |
|
159 Transaction* mTxn; |
|
160 }; |
|
161 |
|
162 void |
|
163 CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier) |
|
164 { |
|
165 mTextureFactoryIdentifier = aIdentifier; |
|
166 } |
|
167 |
|
168 ShadowLayerForwarder::ShadowLayerForwarder() |
|
169 : mDiagnosticTypes(DIAGNOSTIC_NONE) |
|
170 , mIsFirstPaint(false) |
|
171 , mWindowOverlayChanged(false) |
|
172 { |
|
173 mTxn = new Transaction(); |
|
174 } |
|
175 |
|
176 ShadowLayerForwarder::~ShadowLayerForwarder() |
|
177 { |
|
178 NS_ABORT_IF_FALSE(mTxn->Finished(), "unfinished transaction?"); |
|
179 delete mTxn; |
|
180 } |
|
181 |
|
182 void |
|
183 ShadowLayerForwarder::BeginTransaction(const nsIntRect& aTargetBounds, |
|
184 ScreenRotation aRotation, |
|
185 const nsIntRect& aClientBounds, |
|
186 ScreenOrientation aOrientation) |
|
187 { |
|
188 NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); |
|
189 NS_ABORT_IF_FALSE(mTxn->Finished(), "uncommitted txn?"); |
|
190 mTxn->Begin(aTargetBounds, aRotation, aClientBounds, aOrientation); |
|
191 } |
|
192 |
|
193 static PLayerChild* |
|
194 Shadow(ShadowableLayer* aLayer) |
|
195 { |
|
196 return aLayer->GetShadow(); |
|
197 } |
|
198 |
|
199 template<typename OpCreateT> |
|
200 static void |
|
201 CreatedLayer(Transaction* aTxn, ShadowableLayer* aLayer) |
|
202 { |
|
203 aTxn->AddEdit(OpCreateT(nullptr, Shadow(aLayer))); |
|
204 } |
|
205 |
|
206 void |
|
207 ShadowLayerForwarder::CreatedThebesLayer(ShadowableLayer* aThebes) |
|
208 { |
|
209 CreatedLayer<OpCreateThebesLayer>(mTxn, aThebes); |
|
210 } |
|
211 void |
|
212 ShadowLayerForwarder::CreatedContainerLayer(ShadowableLayer* aContainer) |
|
213 { |
|
214 CreatedLayer<OpCreateContainerLayer>(mTxn, aContainer); |
|
215 } |
|
216 void |
|
217 ShadowLayerForwarder::CreatedImageLayer(ShadowableLayer* aImage) |
|
218 { |
|
219 CreatedLayer<OpCreateImageLayer>(mTxn, aImage); |
|
220 } |
|
221 void |
|
222 ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer* aColor) |
|
223 { |
|
224 CreatedLayer<OpCreateColorLayer>(mTxn, aColor); |
|
225 } |
|
226 void |
|
227 ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer* aCanvas) |
|
228 { |
|
229 CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas); |
|
230 } |
|
231 void |
|
232 ShadowLayerForwarder::CreatedRefLayer(ShadowableLayer* aRef) |
|
233 { |
|
234 CreatedLayer<OpCreateRefLayer>(mTxn, aRef); |
|
235 } |
|
236 |
|
237 void |
|
238 ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant) |
|
239 { |
|
240 mTxn->AddMutant(aMutant); |
|
241 } |
|
242 |
|
243 void |
|
244 ShadowLayerForwarder::SetRoot(ShadowableLayer* aRoot) |
|
245 { |
|
246 mTxn->AddEdit(OpSetRoot(nullptr, Shadow(aRoot))); |
|
247 } |
|
248 void |
|
249 ShadowLayerForwarder::InsertAfter(ShadowableLayer* aContainer, |
|
250 ShadowableLayer* aChild, |
|
251 ShadowableLayer* aAfter) |
|
252 { |
|
253 if (aAfter) |
|
254 mTxn->AddEdit(OpInsertAfter(nullptr, Shadow(aContainer), |
|
255 nullptr, Shadow(aChild), |
|
256 nullptr, Shadow(aAfter))); |
|
257 else |
|
258 mTxn->AddEdit(OpPrependChild(nullptr, Shadow(aContainer), |
|
259 nullptr, Shadow(aChild))); |
|
260 } |
|
261 void |
|
262 ShadowLayerForwarder::RemoveChild(ShadowableLayer* aContainer, |
|
263 ShadowableLayer* aChild) |
|
264 { |
|
265 MOZ_LAYERS_LOG(("[LayersForwarder] OpRemoveChild container=%p child=%p\n", |
|
266 aContainer->AsLayer(), aChild->AsLayer())); |
|
267 |
|
268 mTxn->AddEdit(OpRemoveChild(nullptr, Shadow(aContainer), |
|
269 nullptr, Shadow(aChild))); |
|
270 } |
|
271 void |
|
272 ShadowLayerForwarder::RepositionChild(ShadowableLayer* aContainer, |
|
273 ShadowableLayer* aChild, |
|
274 ShadowableLayer* aAfter) |
|
275 { |
|
276 if (aAfter) { |
|
277 MOZ_LAYERS_LOG(("[LayersForwarder] OpRepositionChild container=%p child=%p after=%p", |
|
278 aContainer->AsLayer(), aChild->AsLayer(), aAfter->AsLayer())); |
|
279 mTxn->AddEdit(OpRepositionChild(nullptr, Shadow(aContainer), |
|
280 nullptr, Shadow(aChild), |
|
281 nullptr, Shadow(aAfter))); |
|
282 } else { |
|
283 MOZ_LAYERS_LOG(("[LayersForwarder] OpRaiseToTopChild container=%p child=%p", |
|
284 aContainer->AsLayer(), aChild->AsLayer())); |
|
285 mTxn->AddEdit(OpRaiseToTopChild(nullptr, Shadow(aContainer), |
|
286 nullptr, Shadow(aChild))); |
|
287 } |
|
288 } |
|
289 |
|
290 |
|
291 #ifdef DEBUG |
|
292 void |
|
293 ShadowLayerForwarder::CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const |
|
294 { |
|
295 if (!aDescriptor) { |
|
296 return; |
|
297 } |
|
298 |
|
299 if (aDescriptor->type() == SurfaceDescriptor::TSurfaceDescriptorShmem) { |
|
300 const SurfaceDescriptorShmem& shmem = aDescriptor->get_SurfaceDescriptorShmem(); |
|
301 shmem.data().AssertInvariants(); |
|
302 MOZ_ASSERT(mShadowManager && |
|
303 mShadowManager->IsTrackingSharedMemory(shmem.data().mSegment)); |
|
304 } |
|
305 } |
|
306 #endif |
|
307 |
|
308 void |
|
309 ShadowLayerForwarder::UseTiledLayerBuffer(CompositableClient* aCompositable, |
|
310 const SurfaceDescriptorTiles& aTileLayerDescriptor) |
|
311 { |
|
312 MOZ_ASSERT(aCompositable); |
|
313 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
314 mTxn->AddNoSwapPaint(OpUseTiledLayerBuffer(nullptr, aCompositable->GetIPDLActor(), |
|
315 aTileLayerDescriptor)); |
|
316 } |
|
317 |
|
318 void |
|
319 ShadowLayerForwarder::UpdateTextureRegion(CompositableClient* aCompositable, |
|
320 const ThebesBufferData& aThebesBufferData, |
|
321 const nsIntRegion& aUpdatedRegion) |
|
322 { |
|
323 MOZ_ASSERT(aCompositable); |
|
324 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
325 mTxn->AddPaint(OpPaintTextureRegion(nullptr, aCompositable->GetIPDLActor(), |
|
326 aThebesBufferData, |
|
327 aUpdatedRegion)); |
|
328 } |
|
329 |
|
330 void |
|
331 ShadowLayerForwarder::UpdateTextureIncremental(CompositableClient* aCompositable, |
|
332 TextureIdentifier aTextureId, |
|
333 SurfaceDescriptor& aDescriptor, |
|
334 const nsIntRegion& aUpdatedRegion, |
|
335 const nsIntRect& aBufferRect, |
|
336 const nsIntPoint& aBufferRotation) |
|
337 { |
|
338 CheckSurfaceDescriptor(&aDescriptor); |
|
339 MOZ_ASSERT(aCompositable); |
|
340 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
341 mTxn->AddNoSwapPaint(OpPaintTextureIncremental(nullptr, aCompositable->GetIPDLActor(), |
|
342 aTextureId, |
|
343 aDescriptor, |
|
344 aUpdatedRegion, |
|
345 aBufferRect, |
|
346 aBufferRotation)); |
|
347 } |
|
348 |
|
349 |
|
350 void |
|
351 ShadowLayerForwarder::UpdatePictureRect(CompositableClient* aCompositable, |
|
352 const nsIntRect& aRect) |
|
353 { |
|
354 MOZ_ASSERT(aCompositable); |
|
355 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
356 mTxn->AddNoSwapPaint(OpUpdatePictureRect(nullptr, aCompositable->GetIPDLActor(), aRect)); |
|
357 } |
|
358 |
|
359 void |
|
360 ShadowLayerForwarder::UpdatedTexture(CompositableClient* aCompositable, |
|
361 TextureClient* aTexture, |
|
362 nsIntRegion* aRegion) |
|
363 { |
|
364 MOZ_ASSERT(aCompositable); |
|
365 MOZ_ASSERT(aTexture); |
|
366 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
367 MOZ_ASSERT(aTexture->GetIPDLActor()); |
|
368 MaybeRegion region = aRegion ? MaybeRegion(*aRegion) |
|
369 : MaybeRegion(null_t()); |
|
370 if (aTexture->GetFlags() & TEXTURE_IMMEDIATE_UPLOAD) { |
|
371 mTxn->AddPaint(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(), |
|
372 nullptr, aTexture->GetIPDLActor(), |
|
373 region)); |
|
374 } else { |
|
375 mTxn->AddNoSwapPaint(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(), |
|
376 nullptr, aTexture->GetIPDLActor(), |
|
377 region)); |
|
378 } |
|
379 } |
|
380 |
|
381 void |
|
382 ShadowLayerForwarder::UseTexture(CompositableClient* aCompositable, |
|
383 TextureClient* aTexture) |
|
384 { |
|
385 MOZ_ASSERT(aCompositable); |
|
386 MOZ_ASSERT(aTexture); |
|
387 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
388 MOZ_ASSERT(aTexture->GetIPDLActor()); |
|
389 mTxn->AddEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(), |
|
390 nullptr, aTexture->GetIPDLActor())); |
|
391 } |
|
392 |
|
393 void |
|
394 ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositable, |
|
395 TextureClient* aTextureOnBlack, |
|
396 TextureClient* aTextureOnWhite) |
|
397 { |
|
398 MOZ_ASSERT(aCompositable); |
|
399 MOZ_ASSERT(aTextureOnWhite); |
|
400 MOZ_ASSERT(aTextureOnBlack); |
|
401 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
402 MOZ_ASSERT(aTextureOnBlack->GetIPDLActor()); |
|
403 MOZ_ASSERT(aTextureOnWhite->GetIPDLActor()); |
|
404 MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize()); |
|
405 mTxn->AddEdit(OpUseComponentAlphaTextures(nullptr, aCompositable->GetIPDLActor(), |
|
406 nullptr, aTextureOnBlack->GetIPDLActor(), |
|
407 nullptr, aTextureOnWhite->GetIPDLActor())); |
|
408 } |
|
409 |
|
410 void |
|
411 ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aCompositable, |
|
412 TextureClient* aTexture) |
|
413 { |
|
414 MOZ_ASSERT(aCompositable); |
|
415 MOZ_ASSERT(aTexture); |
|
416 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
417 MOZ_ASSERT(aTexture->GetIPDLActor()); |
|
418 mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), |
|
419 nullptr, aTexture->GetIPDLActor())); |
|
420 if (aTexture->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) { |
|
421 mTxn->MarkSyncTransaction(); |
|
422 } |
|
423 // Hold texture until transaction complete. |
|
424 HoldUntilTransaction(aTexture); |
|
425 } |
|
426 |
|
427 void |
|
428 ShadowLayerForwarder::RemoveTexture(TextureClient* aTexture) |
|
429 { |
|
430 MOZ_ASSERT(aTexture); |
|
431 aTexture->ForceRemove(); |
|
432 } |
|
433 |
|
434 bool |
|
435 ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies, |
|
436 const nsIntRegion& aRegionToClear, |
|
437 bool aScheduleComposite, |
|
438 bool* aSent) |
|
439 { |
|
440 *aSent = false; |
|
441 |
|
442 PROFILER_LABEL("ShadowLayerForwarder", "EndTranscation"); |
|
443 RenderTraceScope rendertrace("Foward Transaction", "000091"); |
|
444 NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); |
|
445 NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?"); |
|
446 |
|
447 DiagnosticTypes diagnostics = gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes(); |
|
448 if (mDiagnosticTypes != diagnostics) { |
|
449 mDiagnosticTypes = diagnostics; |
|
450 mTxn->AddEdit(OpSetDiagnosticTypes(diagnostics)); |
|
451 } |
|
452 |
|
453 AutoTxnEnd _(mTxn); |
|
454 |
|
455 if (mTxn->Empty() && !mTxn->RotationChanged() && !mWindowOverlayChanged) { |
|
456 MOZ_LAYERS_LOG(("[LayersForwarder] 0-length cset (?) and no rotation event, skipping Update()")); |
|
457 return true; |
|
458 } |
|
459 |
|
460 MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers...")); |
|
461 |
|
462 MOZ_LAYERS_LOG(("[LayersForwarder] building transaction...")); |
|
463 |
|
464 // We purposely add attribute-change ops to the final changeset |
|
465 // before we add paint ops. This allows layers to record the |
|
466 // attribute changes before new pixels arrive, which can be useful |
|
467 // for setting up back/front buffers. |
|
468 RenderTraceScope rendertrace2("Foward Transaction", "000092"); |
|
469 for (ShadowableLayerSet::const_iterator it = mTxn->mMutants.begin(); |
|
470 it != mTxn->mMutants.end(); ++it) { |
|
471 ShadowableLayer* shadow = *it; |
|
472 Layer* mutant = shadow->AsLayer(); |
|
473 NS_ABORT_IF_FALSE(!!mutant, "unshadowable layer?"); |
|
474 |
|
475 LayerAttributes attrs; |
|
476 CommonLayerAttributes& common = attrs.common(); |
|
477 common.visibleRegion() = mutant->GetVisibleRegion(); |
|
478 common.eventRegions() = mutant->GetEventRegions(); |
|
479 common.postXScale() = mutant->GetPostXScale(); |
|
480 common.postYScale() = mutant->GetPostYScale(); |
|
481 common.transform() = mutant->GetBaseTransform(); |
|
482 common.contentFlags() = mutant->GetContentFlags(); |
|
483 common.opacity() = mutant->GetOpacity(); |
|
484 common.useClipRect() = !!mutant->GetClipRect(); |
|
485 common.clipRect() = (common.useClipRect() ? |
|
486 *mutant->GetClipRect() : nsIntRect()); |
|
487 common.isFixedPosition() = mutant->GetIsFixedPosition(); |
|
488 common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor(); |
|
489 common.fixedPositionMargin() = mutant->GetFixedPositionMargins(); |
|
490 common.isStickyPosition() = mutant->GetIsStickyPosition(); |
|
491 if (mutant->GetIsStickyPosition()) { |
|
492 common.stickyScrollContainerId() = mutant->GetStickyScrollContainerId(); |
|
493 common.stickyScrollRangeOuter() = mutant->GetStickyScrollRangeOuter(); |
|
494 common.stickyScrollRangeInner() = mutant->GetStickyScrollRangeInner(); |
|
495 } |
|
496 common.scrollbarTargetContainerId() = mutant->GetScrollbarTargetContainerId(); |
|
497 common.scrollbarDirection() = mutant->GetScrollbarDirection(); |
|
498 if (Layer* maskLayer = mutant->GetMaskLayer()) { |
|
499 common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer()); |
|
500 } else { |
|
501 common.maskLayerChild() = nullptr; |
|
502 } |
|
503 common.maskLayerParent() = nullptr; |
|
504 common.animations() = mutant->GetAnimations(); |
|
505 common.invalidRegion() = mutant->GetInvalidRegion(); |
|
506 attrs.specific() = null_t(); |
|
507 mutant->FillSpecificAttributes(attrs.specific()); |
|
508 |
|
509 MOZ_LAYERS_LOG(("[LayersForwarder] OpSetLayerAttributes(%p)\n", mutant)); |
|
510 |
|
511 mTxn->AddEdit(OpSetLayerAttributes(nullptr, Shadow(shadow), attrs)); |
|
512 } |
|
513 |
|
514 AutoInfallibleTArray<Edit, 10> cset; |
|
515 size_t nCsets = mTxn->mCset.size() + mTxn->mPaints.size(); |
|
516 NS_ABORT_IF_FALSE(nCsets > 0 || mWindowOverlayChanged, "should have bailed by now"); |
|
517 |
|
518 cset.SetCapacity(nCsets); |
|
519 if (!mTxn->mCset.empty()) { |
|
520 cset.AppendElements(&mTxn->mCset.front(), mTxn->mCset.size()); |
|
521 } |
|
522 // Paints after non-paint ops, including attribute changes. See |
|
523 // above. |
|
524 if (!mTxn->mPaints.empty()) { |
|
525 cset.AppendElements(&mTxn->mPaints.front(), mTxn->mPaints.size()); |
|
526 } |
|
527 |
|
528 mWindowOverlayChanged = false; |
|
529 |
|
530 TargetConfig targetConfig(mTxn->mTargetBounds, |
|
531 mTxn->mTargetRotation, |
|
532 mTxn->mClientBounds, |
|
533 mTxn->mTargetOrientation, |
|
534 aRegionToClear); |
|
535 |
|
536 MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send...")); |
|
537 PlatformSyncBeforeUpdate(); |
|
538 |
|
539 profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_END); |
|
540 if (mTxn->mSwapRequired) { |
|
541 MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); |
|
542 RenderTraceScope rendertrace3("Forward Transaction", "000093"); |
|
543 if (!HasShadowManager() || |
|
544 !mShadowManager->IPCOpen() || |
|
545 !mShadowManager->SendUpdate(cset, targetConfig, mIsFirstPaint, |
|
546 aScheduleComposite, aReplies)) { |
|
547 MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); |
|
548 return false; |
|
549 } |
|
550 } else { |
|
551 // If we don't require a swap we can call SendUpdateNoSwap which |
|
552 // assumes that aReplies is empty (DEBUG assertion) |
|
553 MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction...")); |
|
554 RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093"); |
|
555 if (!HasShadowManager() || |
|
556 !mShadowManager->IPCOpen() || |
|
557 !mShadowManager->SendUpdateNoSwap(cset, targetConfig, mIsFirstPaint, aScheduleComposite)) { |
|
558 MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); |
|
559 return false; |
|
560 } |
|
561 } |
|
562 |
|
563 *aSent = true; |
|
564 mIsFirstPaint = false; |
|
565 MOZ_LAYERS_LOG(("[LayersForwarder] ... done")); |
|
566 return true; |
|
567 } |
|
568 |
|
569 bool |
|
570 ShadowLayerForwarder::AllocShmem(size_t aSize, |
|
571 ipc::SharedMemory::SharedMemoryType aType, |
|
572 ipc::Shmem* aShmem) |
|
573 { |
|
574 NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager"); |
|
575 if (!mShadowManager->IPCOpen()) { |
|
576 return false; |
|
577 } |
|
578 return mShadowManager->AllocShmem(aSize, aType, aShmem); |
|
579 } |
|
580 bool |
|
581 ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize, |
|
582 ipc::SharedMemory::SharedMemoryType aType, |
|
583 ipc::Shmem* aShmem) |
|
584 { |
|
585 NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager"); |
|
586 if (!mShadowManager->IPCOpen()) { |
|
587 return false; |
|
588 } |
|
589 return mShadowManager->AllocUnsafeShmem(aSize, aType, aShmem); |
|
590 } |
|
591 void |
|
592 ShadowLayerForwarder::DeallocShmem(ipc::Shmem& aShmem) |
|
593 { |
|
594 NS_ABORT_IF_FALSE(HasShadowManager(), "no shadow manager"); |
|
595 if (!mShadowManager->IPCOpen()) { |
|
596 return; |
|
597 } |
|
598 mShadowManager->DeallocShmem(aShmem); |
|
599 } |
|
600 |
|
601 bool |
|
602 ShadowLayerForwarder::IPCOpen() const |
|
603 { |
|
604 return mShadowManager->IPCOpen(); |
|
605 } |
|
606 |
|
607 bool |
|
608 ShadowLayerForwarder::IsSameProcess() const |
|
609 { |
|
610 if (!mShadowManager->IPCOpen()) { |
|
611 return false; |
|
612 } |
|
613 return mShadowManager->OtherProcess() == kInvalidProcessHandle; |
|
614 } |
|
615 |
|
616 /** |
|
617 * We bail out when we have no shadow manager. That can happen when the |
|
618 * layer manager is created by the preallocated process. |
|
619 * See bug 914843 for details. |
|
620 */ |
|
621 PLayerChild* |
|
622 ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer) |
|
623 { |
|
624 NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); |
|
625 if (!mShadowManager->IPCOpen()) { |
|
626 return nullptr; |
|
627 } |
|
628 return mShadowManager->SendPLayerConstructor(new ShadowLayerChild(aLayer)); |
|
629 } |
|
630 |
|
631 #if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS) |
|
632 |
|
633 /*static*/ void |
|
634 ShadowLayerForwarder::PlatformSyncBeforeUpdate() |
|
635 { |
|
636 } |
|
637 |
|
638 #endif // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS) |
|
639 |
|
640 void |
|
641 ShadowLayerForwarder::Connect(CompositableClient* aCompositable) |
|
642 { |
|
643 #ifdef GFX_COMPOSITOR_LOGGING |
|
644 printf("ShadowLayerForwarder::Connect(Compositable)\n"); |
|
645 #endif |
|
646 MOZ_ASSERT(aCompositable); |
|
647 MOZ_ASSERT(mShadowManager); |
|
648 if (!mShadowManager->IPCOpen()) { |
|
649 return; |
|
650 } |
|
651 PCompositableChild* actor = |
|
652 mShadowManager->SendPCompositableConstructor(aCompositable->GetTextureInfo()); |
|
653 MOZ_ASSERT(actor); |
|
654 aCompositable->InitIPDLActor(actor); |
|
655 } |
|
656 |
|
657 void |
|
658 ShadowLayerForwarder::CreatedIncrementalBuffer(CompositableClient* aCompositable, |
|
659 const TextureInfo& aTextureInfo, |
|
660 const nsIntRect& aBufferRect) |
|
661 { |
|
662 MOZ_ASSERT(aCompositable); |
|
663 mTxn->AddNoSwapPaint(OpCreatedIncrementalTexture(nullptr, aCompositable->GetIPDLActor(), |
|
664 aTextureInfo, aBufferRect)); |
|
665 } |
|
666 |
|
667 void ShadowLayerForwarder::Attach(CompositableClient* aCompositable, |
|
668 ShadowableLayer* aLayer) |
|
669 { |
|
670 MOZ_ASSERT(aLayer); |
|
671 MOZ_ASSERT(aCompositable); |
|
672 MOZ_ASSERT(aCompositable->GetIPDLActor()); |
|
673 mTxn->AddEdit(OpAttachCompositable(nullptr, Shadow(aLayer), |
|
674 nullptr, aCompositable->GetIPDLActor())); |
|
675 } |
|
676 |
|
677 void ShadowLayerForwarder::AttachAsyncCompositable(uint64_t aCompositableID, |
|
678 ShadowableLayer* aLayer) |
|
679 { |
|
680 MOZ_ASSERT(aLayer); |
|
681 MOZ_ASSERT(aCompositableID != 0); // zero is always an invalid compositable id. |
|
682 mTxn->AddEdit(OpAttachAsyncCompositable(nullptr, Shadow(aLayer), |
|
683 aCompositableID)); |
|
684 } |
|
685 |
|
686 PTextureChild* |
|
687 ShadowLayerForwarder::CreateTexture(const SurfaceDescriptor& aSharedData, |
|
688 TextureFlags aFlags) |
|
689 { |
|
690 if (!mShadowManager->IPCOpen()) { |
|
691 return nullptr; |
|
692 } |
|
693 return mShadowManager->SendPTextureConstructor(aSharedData, aFlags); |
|
694 } |
|
695 |
|
696 |
|
697 void ShadowLayerForwarder::SetShadowManager(PLayerTransactionChild* aShadowManager) |
|
698 { |
|
699 mShadowManager = static_cast<LayerTransactionChild*>(aShadowManager); |
|
700 } |
|
701 |
|
702 |
|
703 } // namespace layers |
|
704 } // namespace mozilla |