1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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/. */
10 #include "AutoOpenSurface.h"
11 #include "CompositorParent.h"
12 #include "gfxSharedImageSurface.h"
13 #include "ImageLayers.h"
14 #include "mozilla/layout/RenderFrameParent.h"
15 #include "mozilla/unused.h"
16 #include "RenderTrace.h"
17 #include "ShadowLayerParent.h"
18 #include "LayerTransactionParent.h"
19 #include "ShadowLayers.h"
20 #include "ShadowLayerUtils.h"
21 #include "TiledLayerBuffer.h"
22 #include "gfxPlatform.h"
23 #include "CompositableHost.h"
24 #include "mozilla/layers/ThebesLayerComposite.h"
25 #include "mozilla/layers/ImageLayerComposite.h"
26 #include "mozilla/layers/ColorLayerComposite.h"
27 #include "mozilla/layers/ContainerLayerComposite.h"
28 #include "mozilla/layers/CanvasLayerComposite.h"
29 #include "mozilla/layers/PLayerTransaction.h"
31 typedef std::vector
<mozilla::layers::EditReply
> EditReplyVector
;
33 using mozilla::layout::RenderFrameParent
;
38 //--------------------------------------------------
39 // Convenience accessors
40 static ShadowLayerParent
*
41 cast(const PLayerParent
* in
)
43 return const_cast<ShadowLayerParent
*>(
44 static_cast<const ShadowLayerParent
*>(in
));
47 static CompositableParent
*
48 cast(const PCompositableParent
* in
)
50 return const_cast<CompositableParent
*>(
51 static_cast<const CompositableParent
*>(in
));
54 template<class OpCreateT
>
55 static ShadowLayerParent
*
56 AsLayerComposite(const OpCreateT
& op
)
58 return cast(op
.layerParent());
61 static ShadowLayerParent
*
62 AsLayerComposite(const OpSetRoot
& op
)
64 return cast(op
.rootParent());
67 static ShadowLayerParent
*
68 ShadowContainer(const OpInsertAfter
& op
)
70 return cast(op
.containerParent());
72 static ShadowLayerParent
*
73 ShadowChild(const OpInsertAfter
& op
)
75 return cast(op
.childLayerParent());
77 static ShadowLayerParent
*
78 ShadowAfter(const OpInsertAfter
& op
)
80 return cast(op
.afterParent());
83 static ShadowLayerParent
*
84 ShadowContainer(const OpAppendChild
& op
)
86 return cast(op
.containerParent());
88 static ShadowLayerParent
*
89 ShadowChild(const OpAppendChild
& op
)
91 return cast(op
.childLayerParent());
94 static ShadowLayerParent
*
95 ShadowContainer(const OpRemoveChild
& op
)
97 return cast(op
.containerParent());
99 static ShadowLayerParent
*
100 ShadowChild(const OpRemoveChild
& op
)
102 return cast(op
.childLayerParent());
105 static ShadowLayerParent
*
106 ShadowContainer(const OpRepositionChild
& op
)
108 return cast(op
.containerParent());
110 static ShadowLayerParent
*
111 ShadowChild(const OpRepositionChild
& op
)
113 return cast(op
.childLayerParent());
115 static ShadowLayerParent
*
116 ShadowAfter(const OpRepositionChild
& op
)
118 return cast(op
.afterParent());
121 static ShadowLayerParent
*
122 ShadowContainer(const OpRaiseToTopChild
& op
)
124 return cast(op
.containerParent());
126 static ShadowLayerParent
*
127 ShadowChild(const OpRaiseToTopChild
& op
)
129 return cast(op
.childLayerParent());
132 //--------------------------------------------------
133 // LayerTransactionParent
134 LayerTransactionParent::LayerTransactionParent(LayerManagerComposite
* aManager
,
135 ShadowLayersManager
* aLayersManager
,
137 : mLayerManager(aManager
)
138 , mShadowLayersManager(aLayersManager
)
142 MOZ_COUNT_CTOR(LayerTransactionParent
);
145 LayerTransactionParent::~LayerTransactionParent()
147 MOZ_COUNT_DTOR(LayerTransactionParent
);
151 LayerTransactionParent::Destroy()
154 for (size_t i
= 0; i
< ManagedPLayerParent().Length(); ++i
) {
155 ShadowLayerParent
* slp
=
156 static_cast<ShadowLayerParent
*>(ManagedPLayerParent()[i
]);
163 LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray
<Edit
>& cset
,
164 const TargetConfig
& targetConfig
,
165 const bool& isFirstPaint
)
167 return RecvUpdate(cset
, targetConfig
, isFirstPaint
, nullptr);
171 LayerTransactionParent::RecvUpdate(const InfallibleTArray
<Edit
>& cset
,
172 const TargetConfig
& targetConfig
,
173 const bool& isFirstPaint
,
174 InfallibleTArray
<EditReply
>* reply
)
176 #ifdef COMPOSITOR_PERFORMANCE_WARNING
177 TimeStamp updateStart
= TimeStamp::Now();
180 MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset
.Length()));
182 if (mDestroyed
|| !layer_manager() || layer_manager()->IsDestroyed()) {
186 EditReplyVector replyv
;
188 layer_manager()->BeginTransactionWithTarget(nullptr);
190 for (EditArray::index_type i
= 0; i
< cset
.Length(); ++i
) {
191 const Edit
& edit
= cset
[i
];
193 switch (edit
.type()) {
195 case Edit::TOpCreateThebesLayer
: {
196 MOZ_LAYERS_LOG(("[ParentSide] CreateThebesLayer"));
198 nsRefPtr
<ThebesLayerComposite
> layer
=
199 layer_manager()->CreateThebesLayerComposite();
200 AsLayerComposite(edit
.get_OpCreateThebesLayer())->Bind(layer
);
203 case Edit::TOpCreateContainerLayer
: {
204 MOZ_LAYERS_LOG(("[ParentSide] CreateContainerLayer"));
206 nsRefPtr
<ContainerLayer
> layer
= layer_manager()->CreateContainerLayerComposite();
207 AsLayerComposite(edit
.get_OpCreateContainerLayer())->Bind(layer
);
210 case Edit::TOpCreateImageLayer
: {
211 MOZ_LAYERS_LOG(("[ParentSide] CreateImageLayer"));
213 nsRefPtr
<ImageLayerComposite
> layer
=
214 layer_manager()->CreateImageLayerComposite();
215 AsLayerComposite(edit
.get_OpCreateImageLayer())->Bind(layer
);
218 case Edit::TOpCreateColorLayer
: {
219 MOZ_LAYERS_LOG(("[ParentSide] CreateColorLayer"));
221 nsRefPtr
<ColorLayerComposite
> layer
= layer_manager()->CreateColorLayerComposite();
222 AsLayerComposite(edit
.get_OpCreateColorLayer())->Bind(layer
);
225 case Edit::TOpCreateCanvasLayer
: {
226 MOZ_LAYERS_LOG(("[ParentSide] CreateCanvasLayer"));
228 nsRefPtr
<CanvasLayerComposite
> layer
=
229 layer_manager()->CreateCanvasLayerComposite();
230 AsLayerComposite(edit
.get_OpCreateCanvasLayer())->Bind(layer
);
233 case Edit::TOpCreateRefLayer
: {
234 MOZ_LAYERS_LOG(("[ParentSide] CreateRefLayer"));
236 nsRefPtr
<RefLayerComposite
> layer
=
237 layer_manager()->CreateRefLayerComposite();
238 AsLayerComposite(edit
.get_OpCreateRefLayer())->Bind(layer
);
243 case Edit::TOpSetLayerAttributes
: {
244 MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes"));
246 const OpSetLayerAttributes
& osla
= edit
.get_OpSetLayerAttributes();
247 Layer
* layer
= AsLayerComposite(osla
)->AsLayer();
248 const LayerAttributes
& attrs
= osla
.attrs();
250 const CommonLayerAttributes
& common
= attrs
.common();
251 layer
->SetVisibleRegion(common
.visibleRegion());
252 layer
->SetContentFlags(common
.contentFlags());
253 layer
->SetOpacity(common
.opacity());
254 layer
->SetClipRect(common
.useClipRect() ? &common
.clipRect() : nullptr);
255 layer
->SetBaseTransform(common
.transform().value());
256 layer
->SetPostScale(common
.postXScale(), common
.postYScale());
257 layer
->SetIsFixedPosition(common
.isFixedPosition());
258 layer
->SetFixedPositionAnchor(common
.fixedPositionAnchor());
259 layer
->SetFixedPositionMargins(common
.fixedPositionMargin());
260 if (PLayerParent
* maskLayer
= common
.maskLayerParent()) {
261 layer
->SetMaskLayer(cast(maskLayer
)->AsLayer());
263 layer
->SetMaskLayer(nullptr);
265 layer
->SetAnimations(common
.animations());
267 typedef SpecificLayerAttributes Specific
;
268 const SpecificLayerAttributes
& specific
= attrs
.specific();
269 switch (specific
.type()) {
270 case Specific::Tnull_t
:
273 case Specific::TThebesLayerAttributes
: {
274 MOZ_LAYERS_LOG(("[ParentSide] thebes layer"));
276 ThebesLayerComposite
* thebesLayer
=
277 static_cast<ThebesLayerComposite
*>(layer
);
278 const ThebesLayerAttributes
& attrs
=
279 specific
.get_ThebesLayerAttributes();
281 thebesLayer
->SetValidRegion(attrs
.validRegion());
285 case Specific::TContainerLayerAttributes
: {
286 MOZ_LAYERS_LOG(("[ParentSide] container layer"));
288 ContainerLayer
* containerLayer
=
289 static_cast<ContainerLayer
*>(layer
);
290 const ContainerLayerAttributes
& attrs
=
291 specific
.get_ContainerLayerAttributes();
292 containerLayer
->SetFrameMetrics(attrs
.metrics());
293 containerLayer
->SetPreScale(attrs
.preXScale(), attrs
.preYScale());
294 containerLayer
->SetInheritedScale(attrs
.inheritedXScale(), attrs
.inheritedYScale());
297 case Specific::TColorLayerAttributes
:
298 MOZ_LAYERS_LOG(("[ParentSide] color layer"));
300 static_cast<ColorLayer
*>(layer
)->SetColor(
301 specific
.get_ColorLayerAttributes().color().value());
302 static_cast<ColorLayer
*>(layer
)->SetBounds(
303 specific
.get_ColorLayerAttributes().bounds());
306 case Specific::TCanvasLayerAttributes
:
307 MOZ_LAYERS_LOG(("[ParentSide] canvas layer"));
309 static_cast<CanvasLayer
*>(layer
)->SetFilter(
310 specific
.get_CanvasLayerAttributes().filter());
311 static_cast<CanvasLayerComposite
*>(layer
)->SetBounds(
312 specific
.get_CanvasLayerAttributes().bounds());
315 case Specific::TRefLayerAttributes
:
316 MOZ_LAYERS_LOG(("[ParentSide] ref layer"));
318 static_cast<RefLayer
*>(layer
)->SetReferentId(
319 specific
.get_RefLayerAttributes().id());
322 case Specific::TImageLayerAttributes
: {
323 MOZ_LAYERS_LOG(("[ParentSide] image layer"));
325 ImageLayer
* imageLayer
= static_cast<ImageLayer
*>(layer
);
326 const ImageLayerAttributes
& attrs
= specific
.get_ImageLayerAttributes();
327 imageLayer
->SetFilter(attrs
.filter());
328 imageLayer
->SetScaleToSize(attrs
.scaleToSize(), attrs
.scaleMode());
332 NS_RUNTIMEABORT("not reached");
336 case Edit::TOpSetColoredBorders
: {
337 if (edit
.get_OpSetColoredBorders().enabled()) {
338 mLayerManager
->GetCompositor()->EnableColoredBorders();
340 mLayerManager
->GetCompositor()->DisableColoredBorders();
345 case Edit::TOpSetRoot
: {
346 MOZ_LAYERS_LOG(("[ParentSide] SetRoot"));
348 mRoot
= AsLayerComposite(edit
.get_OpSetRoot())->AsLayer();
351 case Edit::TOpInsertAfter
: {
352 MOZ_LAYERS_LOG(("[ParentSide] InsertAfter"));
354 const OpInsertAfter
& oia
= edit
.get_OpInsertAfter();
355 ShadowContainer(oia
)->AsContainer()->InsertAfter(
356 ShadowChild(oia
)->AsLayer(), ShadowAfter(oia
)->AsLayer());
359 case Edit::TOpAppendChild
: {
360 MOZ_LAYERS_LOG(("[ParentSide] AppendChild"));
362 const OpAppendChild
& oac
= edit
.get_OpAppendChild();
363 ShadowContainer(oac
)->AsContainer()->InsertAfter(
364 ShadowChild(oac
)->AsLayer(), nullptr);
367 case Edit::TOpRemoveChild
: {
368 MOZ_LAYERS_LOG(("[ParentSide] RemoveChild"));
370 const OpRemoveChild
& orc
= edit
.get_OpRemoveChild();
371 Layer
* childLayer
= ShadowChild(orc
)->AsLayer();
372 ShadowContainer(orc
)->AsContainer()->RemoveChild(childLayer
);
375 case Edit::TOpRepositionChild
: {
376 MOZ_LAYERS_LOG(("[ParentSide] RepositionChild"));
378 const OpRepositionChild
& orc
= edit
.get_OpRepositionChild();
379 ShadowContainer(orc
)->AsContainer()->RepositionChild(
380 ShadowChild(orc
)->AsLayer(), ShadowAfter(orc
)->AsLayer());
383 case Edit::TOpRaiseToTopChild
: {
384 MOZ_LAYERS_LOG(("[ParentSide] RaiseToTopChild"));
386 const OpRaiseToTopChild
& rtc
= edit
.get_OpRaiseToTopChild();
387 ShadowContainer(rtc
)->AsContainer()->RepositionChild(
388 ShadowChild(rtc
)->AsLayer(), nullptr);
391 case Edit::TCompositableOperation
: {
392 ReceiveCompositableUpdate(edit
.get_CompositableOperation(),
396 case Edit::TOpAttachCompositable
: {
397 const OpAttachCompositable
& op
= edit
.get_OpAttachCompositable();
398 Attach(cast(op
.layerParent()), cast(op
.compositableParent()));
399 cast(op
.compositableParent())->SetCompositorID(
400 mLayerManager
->GetCompositor()->GetCompositorID());
403 case Edit::TOpAttachAsyncCompositable
: {
404 const OpAttachAsyncCompositable
& op
= edit
.get_OpAttachAsyncCompositable();
405 CompositableParent
* compositableParent
= CompositableMap::Get(op
.containerID());
406 MOZ_ASSERT(compositableParent
, "CompositableParent not found in the map");
407 Attach(cast(op
.layerParent()), compositableParent
);
408 compositableParent
->SetCompositorID(mLayerManager
->GetCompositor()->GetCompositorID());
412 NS_RUNTIMEABORT("not reached");
416 layer_manager()->EndTransaction(nullptr, nullptr, LayerManager::END_NO_IMMEDIATE_REDRAW
);
419 reply
->SetCapacity(replyv
.size());
420 if (replyv
.size() > 0) {
421 reply
->AppendElements(&replyv
.front(), replyv
.size());
425 // Ensure that any pending operations involving back and front
426 // buffers have completed, so that neither process stomps on the
427 // other's buffer contents.
428 LayerManagerComposite::PlatformSyncBeforeReplyUpdate();
430 mShadowLayersManager
->ShadowLayersUpdated(this, targetConfig
, isFirstPaint
);
432 #ifdef COMPOSITOR_PERFORMANCE_WARNING
433 int compositeTime
= (int)(mozilla::TimeStamp::Now() - updateStart
).ToMilliseconds();
434 if (compositeTime
> 15) {
435 printf_stderr("Compositor: Layers update took %i ms (blocking gecko).\n", compositeTime
);
443 LayerTransactionParent::RecvGetOpacity(PLayerParent
* aParent
,
446 if (mDestroyed
|| !layer_manager() || layer_manager()->IsDestroyed()) {
450 *aOpacity
= cast(aParent
)->AsLayer()->GetLocalOpacity();
455 LayerTransactionParent::RecvGetTransform(PLayerParent
* aParent
,
456 gfx3DMatrix
* aTransform
)
458 if (mDestroyed
|| !layer_manager() || layer_manager()->IsDestroyed()) {
462 // The following code recovers the untranslated transform
463 // from the shadow transform by undoing the translations in
464 // AsyncCompositionManager::SampleValue.
465 Layer
* layer
= cast(aParent
)->AsLayer();
466 *aTransform
= layer
->AsLayerComposite()->GetShadowTransform();
467 if (ContainerLayer
* c
= layer
->AsContainerLayer()) {
468 aTransform
->ScalePost(1.0f
/c
->GetInheritedXScale(),
469 1.0f
/c
->GetInheritedYScale(),
473 gfxPoint3D scaledOrigin
;
474 gfxPoint3D mozOrigin
;
475 for (uint32_t i
=0; i
< layer
->GetAnimations().Length(); i
++) {
476 if (layer
->GetAnimations()[i
].data().type() == AnimationData::TTransformData
) {
477 const TransformData
& data
= layer
->GetAnimations()[i
].data().get_TransformData();
478 scale
= data
.appUnitsPerDevPixel();
480 gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data
.origin().x
, scale
)),
481 NS_round(NSAppUnitsToFloatPixels(data
.origin().y
, scale
)),
483 mozOrigin
= data
.mozOrigin();
488 aTransform
->Translate(-scaledOrigin
);
489 *aTransform
= nsLayoutUtils::ChangeMatrixBasis(-scaledOrigin
- mozOrigin
, *aTransform
);
494 LayerTransactionParent::Attach(ShadowLayerParent
* aLayerParent
, CompositableParent
* aCompositable
)
496 LayerComposite
* layer
= aLayerParent
->AsLayer()->AsLayerComposite();
499 Compositor
* compositor
500 = static_cast<LayerManagerComposite
*>(aLayerParent
->AsLayer()->Manager())->GetCompositor();
502 CompositableHost
* compositable
= aCompositable
->GetCompositableHost();
503 MOZ_ASSERT(compositable
);
504 layer
->SetCompositableHost(compositable
);
505 compositable
->Attach(aLayerParent
->AsLayer(), compositor
);
509 LayerTransactionParent::RecvClearCachedResources()
512 // NB: |mRoot| here is the *child* context's root. In this parent
513 // context, it's just a subtree root. We need to scope the clear
514 // of resources to exactly that subtree, so we specify it here.
515 mLayerManager
->ClearCachedResources(mRoot
);
520 PGrallocBufferParent
*
521 LayerTransactionParent::AllocPGrallocBufferParent(const gfxIntSize
& aSize
,
522 const uint32_t& aFormat
,
523 const uint32_t& aUsage
,
524 MaybeMagicGrallocBufferHandle
* aOutHandle
)
526 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
527 return GrallocBufferActor::Create(aSize
, aFormat
, aUsage
, aOutHandle
);
529 NS_RUNTIMEABORT("No gralloc buffers for you");
535 LayerTransactionParent::DeallocPGrallocBufferParent(PGrallocBufferParent
* actor
)
537 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
541 NS_RUNTIMEABORT("Um, how did we get here?");
547 LayerTransactionParent::AllocPLayerParent()
549 return new ShadowLayerParent();
553 LayerTransactionParent::DeallocPLayerParent(PLayerParent
* actor
)
560 LayerTransactionParent::AllocPCompositableParent(const TextureInfo
& aInfo
)
562 return new CompositableParent(this, aInfo
);
566 LayerTransactionParent::DeallocPCompositableParent(PCompositableParent
* actor
)
572 } // namespace layers
573 } // namespace mozilla