Bug 858914 - New texture classes + OGL backend (preffed off). r=bas, nrc
[gecko.git] / gfx / layers / ipc / LayerTransactionParent.cpp
blobd25f75e2ccef11ec6b2b9a807f89649bac7da59b
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/. */
8 #include <vector>
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;
35 namespace mozilla {
36 namespace layers {
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,
136 uint64_t aId)
137 : mLayerManager(aManager)
138 , mShadowLayersManager(aLayersManager)
139 , mId(aId)
140 , mDestroyed(false)
142 MOZ_COUNT_CTOR(LayerTransactionParent);
145 LayerTransactionParent::~LayerTransactionParent()
147 MOZ_COUNT_DTOR(LayerTransactionParent);
150 void
151 LayerTransactionParent::Destroy()
153 mDestroyed = true;
154 for (size_t i = 0; i < ManagedPLayerParent().Length(); ++i) {
155 ShadowLayerParent* slp =
156 static_cast<ShadowLayerParent*>(ManagedPLayerParent()[i]);
157 slp->Destroy();
161 /* virtual */
162 bool
163 LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray<Edit>& cset,
164 const TargetConfig& targetConfig,
165 const bool& isFirstPaint)
167 return RecvUpdate(cset, targetConfig, isFirstPaint, nullptr);
170 bool
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();
178 #endif
180 MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length()));
182 if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
183 return true;
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()) {
194 // Create* ops
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);
201 break;
203 case Edit::TOpCreateContainerLayer: {
204 MOZ_LAYERS_LOG(("[ParentSide] CreateContainerLayer"));
206 nsRefPtr<ContainerLayer> layer = layer_manager()->CreateContainerLayerComposite();
207 AsLayerComposite(edit.get_OpCreateContainerLayer())->Bind(layer);
208 break;
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);
216 break;
218 case Edit::TOpCreateColorLayer: {
219 MOZ_LAYERS_LOG(("[ParentSide] CreateColorLayer"));
221 nsRefPtr<ColorLayerComposite> layer = layer_manager()->CreateColorLayerComposite();
222 AsLayerComposite(edit.get_OpCreateColorLayer())->Bind(layer);
223 break;
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);
231 break;
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);
239 break;
242 // Attributes
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());
262 } else {
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:
271 break;
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());
283 break;
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());
295 break;
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());
304 break;
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());
313 break;
315 case Specific::TRefLayerAttributes:
316 MOZ_LAYERS_LOG(("[ParentSide] ref layer"));
318 static_cast<RefLayer*>(layer)->SetReferentId(
319 specific.get_RefLayerAttributes().id());
320 break;
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());
329 break;
331 default:
332 NS_RUNTIMEABORT("not reached");
334 break;
336 case Edit::TOpSetColoredBorders: {
337 if (edit.get_OpSetColoredBorders().enabled()) {
338 mLayerManager->GetCompositor()->EnableColoredBorders();
339 } else {
340 mLayerManager->GetCompositor()->DisableColoredBorders();
342 break;
344 // Tree ops
345 case Edit::TOpSetRoot: {
346 MOZ_LAYERS_LOG(("[ParentSide] SetRoot"));
348 mRoot = AsLayerComposite(edit.get_OpSetRoot())->AsLayer();
349 break;
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());
357 break;
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);
365 break;
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);
373 break;
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());
381 break;
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);
389 break;
391 case Edit::TCompositableOperation: {
392 ReceiveCompositableUpdate(edit.get_CompositableOperation(),
393 replyv);
394 break;
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());
401 break;
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());
409 break;
411 default:
412 NS_RUNTIMEABORT("not reached");
416 layer_manager()->EndTransaction(nullptr, nullptr, LayerManager::END_NO_IMMEDIATE_REDRAW);
418 if (reply) {
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);
437 #endif
439 return true;
442 bool
443 LayerTransactionParent::RecvGetOpacity(PLayerParent* aParent,
444 float* aOpacity)
446 if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
447 return false;
450 *aOpacity = cast(aParent)->AsLayer()->GetLocalOpacity();
451 return true;
454 bool
455 LayerTransactionParent::RecvGetTransform(PLayerParent* aParent,
456 gfx3DMatrix* aTransform)
458 if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
459 return false;
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(),
470 1.0f);
472 float scale = 1;
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();
479 scaledOrigin =
480 gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)),
481 NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)),
482 0.0f);
483 mozOrigin = data.mozOrigin();
484 break;
488 aTransform->Translate(-scaledOrigin);
489 *aTransform = nsLayoutUtils::ChangeMatrixBasis(-scaledOrigin - mozOrigin, *aTransform);
490 return true;
493 void
494 LayerTransactionParent::Attach(ShadowLayerParent* aLayerParent, CompositableParent* aCompositable)
496 LayerComposite* layer = aLayerParent->AsLayer()->AsLayerComposite();
497 MOZ_ASSERT(layer);
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);
508 bool
509 LayerTransactionParent::RecvClearCachedResources()
511 if (mRoot) {
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);
517 return true;
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);
528 #else
529 NS_RUNTIMEABORT("No gralloc buffers for you");
530 return nullptr;
531 #endif
534 bool
535 LayerTransactionParent::DeallocPGrallocBufferParent(PGrallocBufferParent* actor)
537 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
538 delete actor;
539 return true;
540 #else
541 NS_RUNTIMEABORT("Um, how did we get here?");
542 return false;
543 #endif
546 PLayerParent*
547 LayerTransactionParent::AllocPLayerParent()
549 return new ShadowLayerParent();
552 bool
553 LayerTransactionParent::DeallocPLayerParent(PLayerParent* actor)
555 delete actor;
556 return true;
559 PCompositableParent*
560 LayerTransactionParent::AllocPCompositableParent(const TextureInfo& aInfo)
562 return new CompositableParent(this, aInfo);
565 bool
566 LayerTransactionParent::DeallocPCompositableParent(PCompositableParent* actor)
568 delete actor;
569 return true;
572 } // namespace layers
573 } // namespace mozilla