Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * vim: sw=2 ts=8 et : |
michael@0 | 3 | */ |
michael@0 | 4 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 7 | |
michael@0 | 8 | #include "LayerTransactionParent.h" |
michael@0 | 9 | #include <vector> // for vector |
michael@0 | 10 | #include "CompositableHost.h" // for CompositableParent, Get, etc |
michael@0 | 11 | #include "ImageLayers.h" // for ImageLayer |
michael@0 | 12 | #include "Layers.h" // for Layer, ContainerLayer, etc |
michael@0 | 13 | #include "ShadowLayerParent.h" // for ShadowLayerParent |
michael@0 | 14 | #include "gfx3DMatrix.h" // for gfx3DMatrix |
michael@0 | 15 | #include "gfxPoint3D.h" // for gfxPoint3D |
michael@0 | 16 | #include "CompositableTransactionParent.h" // for EditReplyVector |
michael@0 | 17 | #include "ShadowLayersManager.h" // for ShadowLayersManager |
michael@0 | 18 | #include "mozilla/gfx/BasePoint3D.h" // for BasePoint3D |
michael@0 | 19 | #include "mozilla/layers/CanvasLayerComposite.h" |
michael@0 | 20 | #include "mozilla/layers/ColorLayerComposite.h" |
michael@0 | 21 | #include "mozilla/layers/Compositor.h" // for Compositor |
michael@0 | 22 | #include "mozilla/layers/ContainerLayerComposite.h" |
michael@0 | 23 | #include "mozilla/layers/ImageLayerComposite.h" |
michael@0 | 24 | #include "mozilla/layers/LayerManagerComposite.h" |
michael@0 | 25 | #include "mozilla/layers/LayersMessages.h" // for EditReply, etc |
michael@0 | 26 | #include "mozilla/layers/LayersSurfaces.h" // for PGrallocBufferParent |
michael@0 | 27 | #include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG |
michael@0 | 28 | #include "mozilla/layers/PCompositableParent.h" |
michael@0 | 29 | #include "mozilla/layers/PLayerParent.h" // for PLayerParent |
michael@0 | 30 | #include "mozilla/layers/ThebesLayerComposite.h" |
michael@0 | 31 | #include "mozilla/mozalloc.h" // for operator delete, etc |
michael@0 | 32 | #include "nsCoord.h" // for NSAppUnitsToFloatPixels |
michael@0 | 33 | #include "nsDebug.h" // for NS_RUNTIMEABORT |
michael@0 | 34 | #include "nsDeviceContext.h" // for AppUnitsPerCSSPixel |
michael@0 | 35 | #include "nsISupportsImpl.h" // for Layer::Release, etc |
michael@0 | 36 | #include "nsLayoutUtils.h" // for nsLayoutUtils |
michael@0 | 37 | #include "nsMathUtils.h" // for NS_round |
michael@0 | 38 | #include "nsPoint.h" // for nsPoint |
michael@0 | 39 | #include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc |
michael@0 | 40 | #include "GeckoProfiler.h" |
michael@0 | 41 | #include "mozilla/layers/TextureHost.h" |
michael@0 | 42 | #include "mozilla/layers/AsyncCompositionManager.h" |
michael@0 | 43 | #include "mozilla/layers/AsyncPanZoomController.h" |
michael@0 | 44 | |
michael@0 | 45 | typedef std::vector<mozilla::layers::EditReply> EditReplyVector; |
michael@0 | 46 | |
michael@0 | 47 | using mozilla::layout::RenderFrameParent; |
michael@0 | 48 | |
michael@0 | 49 | namespace mozilla { |
michael@0 | 50 | namespace layers { |
michael@0 | 51 | |
michael@0 | 52 | class PGrallocBufferParent; |
michael@0 | 53 | |
michael@0 | 54 | //-------------------------------------------------- |
michael@0 | 55 | // Convenience accessors |
michael@0 | 56 | static ShadowLayerParent* |
michael@0 | 57 | cast(const PLayerParent* in) |
michael@0 | 58 | { |
michael@0 | 59 | return const_cast<ShadowLayerParent*>( |
michael@0 | 60 | static_cast<const ShadowLayerParent*>(in)); |
michael@0 | 61 | } |
michael@0 | 62 | |
michael@0 | 63 | template<class OpCreateT> |
michael@0 | 64 | static ShadowLayerParent* |
michael@0 | 65 | AsLayerComposite(const OpCreateT& op) |
michael@0 | 66 | { |
michael@0 | 67 | return cast(op.layerParent()); |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | static ShadowLayerParent* |
michael@0 | 71 | AsLayerComposite(const OpSetRoot& op) |
michael@0 | 72 | { |
michael@0 | 73 | return cast(op.rootParent()); |
michael@0 | 74 | } |
michael@0 | 75 | |
michael@0 | 76 | static ShadowLayerParent* |
michael@0 | 77 | ShadowContainer(const OpInsertAfter& op) |
michael@0 | 78 | { |
michael@0 | 79 | return cast(op.containerParent()); |
michael@0 | 80 | } |
michael@0 | 81 | static ShadowLayerParent* |
michael@0 | 82 | ShadowChild(const OpInsertAfter& op) |
michael@0 | 83 | { |
michael@0 | 84 | return cast(op.childLayerParent()); |
michael@0 | 85 | } |
michael@0 | 86 | static ShadowLayerParent* |
michael@0 | 87 | ShadowAfter(const OpInsertAfter& op) |
michael@0 | 88 | { |
michael@0 | 89 | return cast(op.afterParent()); |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | static ShadowLayerParent* |
michael@0 | 93 | ShadowContainer(const OpPrependChild& op) |
michael@0 | 94 | { |
michael@0 | 95 | return cast(op.containerParent()); |
michael@0 | 96 | } |
michael@0 | 97 | static ShadowLayerParent* |
michael@0 | 98 | ShadowChild(const OpPrependChild& op) |
michael@0 | 99 | { |
michael@0 | 100 | return cast(op.childLayerParent()); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | static ShadowLayerParent* |
michael@0 | 104 | ShadowContainer(const OpRemoveChild& op) |
michael@0 | 105 | { |
michael@0 | 106 | return cast(op.containerParent()); |
michael@0 | 107 | } |
michael@0 | 108 | static ShadowLayerParent* |
michael@0 | 109 | ShadowChild(const OpRemoveChild& op) |
michael@0 | 110 | { |
michael@0 | 111 | return cast(op.childLayerParent()); |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | static ShadowLayerParent* |
michael@0 | 115 | ShadowContainer(const OpRepositionChild& op) |
michael@0 | 116 | { |
michael@0 | 117 | return cast(op.containerParent()); |
michael@0 | 118 | } |
michael@0 | 119 | static ShadowLayerParent* |
michael@0 | 120 | ShadowChild(const OpRepositionChild& op) |
michael@0 | 121 | { |
michael@0 | 122 | return cast(op.childLayerParent()); |
michael@0 | 123 | } |
michael@0 | 124 | static ShadowLayerParent* |
michael@0 | 125 | ShadowAfter(const OpRepositionChild& op) |
michael@0 | 126 | { |
michael@0 | 127 | return cast(op.afterParent()); |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | static ShadowLayerParent* |
michael@0 | 131 | ShadowContainer(const OpRaiseToTopChild& op) |
michael@0 | 132 | { |
michael@0 | 133 | return cast(op.containerParent()); |
michael@0 | 134 | } |
michael@0 | 135 | static ShadowLayerParent* |
michael@0 | 136 | ShadowChild(const OpRaiseToTopChild& op) |
michael@0 | 137 | { |
michael@0 | 138 | return cast(op.childLayerParent()); |
michael@0 | 139 | } |
michael@0 | 140 | |
michael@0 | 141 | //-------------------------------------------------- |
michael@0 | 142 | // LayerTransactionParent |
michael@0 | 143 | LayerTransactionParent::LayerTransactionParent(LayerManagerComposite* aManager, |
michael@0 | 144 | ShadowLayersManager* aLayersManager, |
michael@0 | 145 | uint64_t aId) |
michael@0 | 146 | : mLayerManager(aManager) |
michael@0 | 147 | , mShadowLayersManager(aLayersManager) |
michael@0 | 148 | , mId(aId) |
michael@0 | 149 | , mDestroyed(false) |
michael@0 | 150 | , mIPCOpen(false) |
michael@0 | 151 | { |
michael@0 | 152 | MOZ_COUNT_CTOR(LayerTransactionParent); |
michael@0 | 153 | } |
michael@0 | 154 | |
michael@0 | 155 | LayerTransactionParent::~LayerTransactionParent() |
michael@0 | 156 | { |
michael@0 | 157 | MOZ_COUNT_DTOR(LayerTransactionParent); |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | void |
michael@0 | 161 | LayerTransactionParent::Destroy() |
michael@0 | 162 | { |
michael@0 | 163 | mDestroyed = true; |
michael@0 | 164 | for (size_t i = 0; i < ManagedPLayerParent().Length(); ++i) { |
michael@0 | 165 | ShadowLayerParent* slp = |
michael@0 | 166 | static_cast<ShadowLayerParent*>(ManagedPLayerParent()[i]); |
michael@0 | 167 | slp->Destroy(); |
michael@0 | 168 | } |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | LayersBackend |
michael@0 | 172 | LayerTransactionParent::GetCompositorBackendType() const |
michael@0 | 173 | { |
michael@0 | 174 | return mLayerManager->GetBackendType(); |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | /* virtual */ |
michael@0 | 178 | bool |
michael@0 | 179 | LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray<Edit>& cset, |
michael@0 | 180 | const TargetConfig& targetConfig, |
michael@0 | 181 | const bool& isFirstPaint, |
michael@0 | 182 | const bool& scheduleComposite) |
michael@0 | 183 | { |
michael@0 | 184 | return RecvUpdate(cset, targetConfig, isFirstPaint, scheduleComposite, nullptr); |
michael@0 | 185 | } |
michael@0 | 186 | |
michael@0 | 187 | bool |
michael@0 | 188 | LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset, |
michael@0 | 189 | const TargetConfig& targetConfig, |
michael@0 | 190 | const bool& isFirstPaint, |
michael@0 | 191 | const bool& scheduleComposite, |
michael@0 | 192 | InfallibleTArray<EditReply>* reply) |
michael@0 | 193 | { |
michael@0 | 194 | profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START); |
michael@0 | 195 | PROFILER_LABEL("LayerTransactionParent", "RecvUpdate"); |
michael@0 | 196 | #ifdef COMPOSITOR_PERFORMANCE_WARNING |
michael@0 | 197 | TimeStamp updateStart = TimeStamp::Now(); |
michael@0 | 198 | #endif |
michael@0 | 199 | |
michael@0 | 200 | MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length())); |
michael@0 | 201 | |
michael@0 | 202 | if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) { |
michael@0 | 203 | return true; |
michael@0 | 204 | } |
michael@0 | 205 | |
michael@0 | 206 | if (mLayerManager && mLayerManager->GetCompositor() && |
michael@0 | 207 | !targetConfig.naturalBounds().IsEmpty()) { |
michael@0 | 208 | mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation()); |
michael@0 | 209 | } |
michael@0 | 210 | |
michael@0 | 211 | // Clear fence handles used in previsou transaction. |
michael@0 | 212 | ClearPrevFenceHandles(); |
michael@0 | 213 | |
michael@0 | 214 | EditReplyVector replyv; |
michael@0 | 215 | |
michael@0 | 216 | { |
michael@0 | 217 | AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this)); |
michael@0 | 218 | layer_manager()->BeginTransaction(); |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | for (EditArray::index_type i = 0; i < cset.Length(); ++i) { |
michael@0 | 222 | const Edit& edit = cset[i]; |
michael@0 | 223 | |
michael@0 | 224 | switch (edit.type()) { |
michael@0 | 225 | // Create* ops |
michael@0 | 226 | case Edit::TOpCreateThebesLayer: { |
michael@0 | 227 | MOZ_LAYERS_LOG(("[ParentSide] CreateThebesLayer")); |
michael@0 | 228 | |
michael@0 | 229 | nsRefPtr<ThebesLayerComposite> layer = |
michael@0 | 230 | layer_manager()->CreateThebesLayerComposite(); |
michael@0 | 231 | AsLayerComposite(edit.get_OpCreateThebesLayer())->Bind(layer); |
michael@0 | 232 | break; |
michael@0 | 233 | } |
michael@0 | 234 | case Edit::TOpCreateContainerLayer: { |
michael@0 | 235 | MOZ_LAYERS_LOG(("[ParentSide] CreateContainerLayer")); |
michael@0 | 236 | |
michael@0 | 237 | nsRefPtr<ContainerLayer> layer = layer_manager()->CreateContainerLayerComposite(); |
michael@0 | 238 | AsLayerComposite(edit.get_OpCreateContainerLayer())->Bind(layer); |
michael@0 | 239 | break; |
michael@0 | 240 | } |
michael@0 | 241 | case Edit::TOpCreateImageLayer: { |
michael@0 | 242 | MOZ_LAYERS_LOG(("[ParentSide] CreateImageLayer")); |
michael@0 | 243 | |
michael@0 | 244 | nsRefPtr<ImageLayerComposite> layer = |
michael@0 | 245 | layer_manager()->CreateImageLayerComposite(); |
michael@0 | 246 | AsLayerComposite(edit.get_OpCreateImageLayer())->Bind(layer); |
michael@0 | 247 | break; |
michael@0 | 248 | } |
michael@0 | 249 | case Edit::TOpCreateColorLayer: { |
michael@0 | 250 | MOZ_LAYERS_LOG(("[ParentSide] CreateColorLayer")); |
michael@0 | 251 | |
michael@0 | 252 | nsRefPtr<ColorLayerComposite> layer = layer_manager()->CreateColorLayerComposite(); |
michael@0 | 253 | AsLayerComposite(edit.get_OpCreateColorLayer())->Bind(layer); |
michael@0 | 254 | break; |
michael@0 | 255 | } |
michael@0 | 256 | case Edit::TOpCreateCanvasLayer: { |
michael@0 | 257 | MOZ_LAYERS_LOG(("[ParentSide] CreateCanvasLayer")); |
michael@0 | 258 | |
michael@0 | 259 | nsRefPtr<CanvasLayerComposite> layer = |
michael@0 | 260 | layer_manager()->CreateCanvasLayerComposite(); |
michael@0 | 261 | AsLayerComposite(edit.get_OpCreateCanvasLayer())->Bind(layer); |
michael@0 | 262 | break; |
michael@0 | 263 | } |
michael@0 | 264 | case Edit::TOpCreateRefLayer: { |
michael@0 | 265 | MOZ_LAYERS_LOG(("[ParentSide] CreateRefLayer")); |
michael@0 | 266 | |
michael@0 | 267 | nsRefPtr<RefLayerComposite> layer = |
michael@0 | 268 | layer_manager()->CreateRefLayerComposite(); |
michael@0 | 269 | AsLayerComposite(edit.get_OpCreateRefLayer())->Bind(layer); |
michael@0 | 270 | break; |
michael@0 | 271 | } |
michael@0 | 272 | |
michael@0 | 273 | // Attributes |
michael@0 | 274 | case Edit::TOpSetLayerAttributes: { |
michael@0 | 275 | MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes")); |
michael@0 | 276 | |
michael@0 | 277 | const OpSetLayerAttributes& osla = edit.get_OpSetLayerAttributes(); |
michael@0 | 278 | ShadowLayerParent* layerParent = AsLayerComposite(osla); |
michael@0 | 279 | Layer* layer = layerParent->AsLayer(); |
michael@0 | 280 | if (!layer) { |
michael@0 | 281 | return false; |
michael@0 | 282 | } |
michael@0 | 283 | const LayerAttributes& attrs = osla.attrs(); |
michael@0 | 284 | |
michael@0 | 285 | const CommonLayerAttributes& common = attrs.common(); |
michael@0 | 286 | layer->SetVisibleRegion(common.visibleRegion()); |
michael@0 | 287 | layer->SetEventRegions(common.eventRegions()); |
michael@0 | 288 | layer->SetContentFlags(common.contentFlags()); |
michael@0 | 289 | layer->SetOpacity(common.opacity()); |
michael@0 | 290 | layer->SetClipRect(common.useClipRect() ? &common.clipRect() : nullptr); |
michael@0 | 291 | layer->SetBaseTransform(common.transform().value()); |
michael@0 | 292 | layer->SetPostScale(common.postXScale(), common.postYScale()); |
michael@0 | 293 | layer->SetIsFixedPosition(common.isFixedPosition()); |
michael@0 | 294 | layer->SetFixedPositionAnchor(common.fixedPositionAnchor()); |
michael@0 | 295 | layer->SetFixedPositionMargins(common.fixedPositionMargin()); |
michael@0 | 296 | if (common.isStickyPosition()) { |
michael@0 | 297 | layer->SetStickyPositionData(common.stickyScrollContainerId(), |
michael@0 | 298 | common.stickyScrollRangeOuter(), |
michael@0 | 299 | common.stickyScrollRangeInner()); |
michael@0 | 300 | } |
michael@0 | 301 | layer->SetScrollbarData(common.scrollbarTargetContainerId(), |
michael@0 | 302 | static_cast<Layer::ScrollDirection>(common.scrollbarDirection())); |
michael@0 | 303 | if (PLayerParent* maskLayer = common.maskLayerParent()) { |
michael@0 | 304 | layer->SetMaskLayer(cast(maskLayer)->AsLayer()); |
michael@0 | 305 | } else { |
michael@0 | 306 | layer->SetMaskLayer(nullptr); |
michael@0 | 307 | } |
michael@0 | 308 | layer->SetAnimations(common.animations()); |
michael@0 | 309 | layer->SetInvalidRegion(common.invalidRegion()); |
michael@0 | 310 | |
michael@0 | 311 | typedef SpecificLayerAttributes Specific; |
michael@0 | 312 | const SpecificLayerAttributes& specific = attrs.specific(); |
michael@0 | 313 | switch (specific.type()) { |
michael@0 | 314 | case Specific::Tnull_t: |
michael@0 | 315 | break; |
michael@0 | 316 | |
michael@0 | 317 | case Specific::TThebesLayerAttributes: { |
michael@0 | 318 | MOZ_LAYERS_LOG(("[ParentSide] thebes layer")); |
michael@0 | 319 | |
michael@0 | 320 | ThebesLayerComposite* thebesLayer = layerParent->AsThebesLayerComposite(); |
michael@0 | 321 | if (!thebesLayer) { |
michael@0 | 322 | return false; |
michael@0 | 323 | } |
michael@0 | 324 | const ThebesLayerAttributes& attrs = |
michael@0 | 325 | specific.get_ThebesLayerAttributes(); |
michael@0 | 326 | |
michael@0 | 327 | thebesLayer->SetValidRegion(attrs.validRegion()); |
michael@0 | 328 | |
michael@0 | 329 | break; |
michael@0 | 330 | } |
michael@0 | 331 | case Specific::TContainerLayerAttributes: { |
michael@0 | 332 | MOZ_LAYERS_LOG(("[ParentSide] container layer")); |
michael@0 | 333 | |
michael@0 | 334 | ContainerLayerComposite* containerLayer = layerParent->AsContainerLayerComposite(); |
michael@0 | 335 | if (!containerLayer) { |
michael@0 | 336 | return false; |
michael@0 | 337 | } |
michael@0 | 338 | const ContainerLayerAttributes& attrs = |
michael@0 | 339 | specific.get_ContainerLayerAttributes(); |
michael@0 | 340 | containerLayer->SetFrameMetrics(attrs.metrics()); |
michael@0 | 341 | containerLayer->SetScrollHandoffParentId(attrs.scrollParentId()); |
michael@0 | 342 | containerLayer->SetPreScale(attrs.preXScale(), attrs.preYScale()); |
michael@0 | 343 | containerLayer->SetInheritedScale(attrs.inheritedXScale(), attrs.inheritedYScale()); |
michael@0 | 344 | break; |
michael@0 | 345 | } |
michael@0 | 346 | case Specific::TColorLayerAttributes: { |
michael@0 | 347 | MOZ_LAYERS_LOG(("[ParentSide] color layer")); |
michael@0 | 348 | |
michael@0 | 349 | ColorLayerComposite* colorLayer = layerParent->AsColorLayerComposite(); |
michael@0 | 350 | if (!colorLayer) { |
michael@0 | 351 | return false; |
michael@0 | 352 | } |
michael@0 | 353 | colorLayer->SetColor(specific.get_ColorLayerAttributes().color().value()); |
michael@0 | 354 | colorLayer->SetBounds(specific.get_ColorLayerAttributes().bounds()); |
michael@0 | 355 | break; |
michael@0 | 356 | } |
michael@0 | 357 | case Specific::TCanvasLayerAttributes: { |
michael@0 | 358 | MOZ_LAYERS_LOG(("[ParentSide] canvas layer")); |
michael@0 | 359 | |
michael@0 | 360 | CanvasLayerComposite* canvasLayer = layerParent->AsCanvasLayerComposite(); |
michael@0 | 361 | if (!canvasLayer) { |
michael@0 | 362 | return false; |
michael@0 | 363 | } |
michael@0 | 364 | canvasLayer->SetFilter(specific.get_CanvasLayerAttributes().filter()); |
michael@0 | 365 | canvasLayer->SetBounds(specific.get_CanvasLayerAttributes().bounds()); |
michael@0 | 366 | break; |
michael@0 | 367 | } |
michael@0 | 368 | case Specific::TRefLayerAttributes: { |
michael@0 | 369 | MOZ_LAYERS_LOG(("[ParentSide] ref layer")); |
michael@0 | 370 | |
michael@0 | 371 | RefLayerComposite* refLayer = layerParent->AsRefLayerComposite(); |
michael@0 | 372 | if (!refLayer) { |
michael@0 | 373 | return false; |
michael@0 | 374 | } |
michael@0 | 375 | refLayer->SetReferentId(specific.get_RefLayerAttributes().id()); |
michael@0 | 376 | break; |
michael@0 | 377 | } |
michael@0 | 378 | case Specific::TImageLayerAttributes: { |
michael@0 | 379 | MOZ_LAYERS_LOG(("[ParentSide] image layer")); |
michael@0 | 380 | |
michael@0 | 381 | ImageLayerComposite* imageLayer = layerParent->AsImageLayerComposite(); |
michael@0 | 382 | if (!imageLayer) { |
michael@0 | 383 | return false; |
michael@0 | 384 | } |
michael@0 | 385 | const ImageLayerAttributes& attrs = specific.get_ImageLayerAttributes(); |
michael@0 | 386 | imageLayer->SetFilter(attrs.filter()); |
michael@0 | 387 | imageLayer->SetScaleToSize(attrs.scaleToSize(), attrs.scaleMode()); |
michael@0 | 388 | break; |
michael@0 | 389 | } |
michael@0 | 390 | default: |
michael@0 | 391 | NS_RUNTIMEABORT("not reached"); |
michael@0 | 392 | } |
michael@0 | 393 | break; |
michael@0 | 394 | } |
michael@0 | 395 | case Edit::TOpSetDiagnosticTypes: { |
michael@0 | 396 | mLayerManager->GetCompositor()->SetDiagnosticTypes( |
michael@0 | 397 | edit.get_OpSetDiagnosticTypes().diagnostics()); |
michael@0 | 398 | break; |
michael@0 | 399 | } |
michael@0 | 400 | // Tree ops |
michael@0 | 401 | case Edit::TOpSetRoot: { |
michael@0 | 402 | MOZ_LAYERS_LOG(("[ParentSide] SetRoot")); |
michael@0 | 403 | |
michael@0 | 404 | Layer* newRoot = AsLayerComposite(edit.get_OpSetRoot())->AsLayer(); |
michael@0 | 405 | if (!newRoot) { |
michael@0 | 406 | return false; |
michael@0 | 407 | } |
michael@0 | 408 | if (newRoot->GetParent()) { |
michael@0 | 409 | // newRoot is not a root! |
michael@0 | 410 | return false; |
michael@0 | 411 | } |
michael@0 | 412 | mRoot = newRoot; |
michael@0 | 413 | break; |
michael@0 | 414 | } |
michael@0 | 415 | case Edit::TOpInsertAfter: { |
michael@0 | 416 | MOZ_LAYERS_LOG(("[ParentSide] InsertAfter")); |
michael@0 | 417 | |
michael@0 | 418 | const OpInsertAfter& oia = edit.get_OpInsertAfter(); |
michael@0 | 419 | Layer* child = ShadowChild(oia)->AsLayer(); |
michael@0 | 420 | if (!child) { |
michael@0 | 421 | return false; |
michael@0 | 422 | } |
michael@0 | 423 | ContainerLayerComposite* container = ShadowContainer(oia)->AsContainerLayerComposite(); |
michael@0 | 424 | if (!container || |
michael@0 | 425 | !container->InsertAfter(child, ShadowAfter(oia)->AsLayer())) |
michael@0 | 426 | { |
michael@0 | 427 | return false; |
michael@0 | 428 | } |
michael@0 | 429 | break; |
michael@0 | 430 | } |
michael@0 | 431 | case Edit::TOpPrependChild: { |
michael@0 | 432 | MOZ_LAYERS_LOG(("[ParentSide] PrependChild")); |
michael@0 | 433 | |
michael@0 | 434 | const OpPrependChild& oac = edit.get_OpPrependChild(); |
michael@0 | 435 | Layer* child = ShadowChild(oac)->AsLayer(); |
michael@0 | 436 | if (!child) { |
michael@0 | 437 | return false; |
michael@0 | 438 | } |
michael@0 | 439 | ContainerLayerComposite* container = ShadowContainer(oac)->AsContainerLayerComposite(); |
michael@0 | 440 | if (!container || |
michael@0 | 441 | !container->InsertAfter(child, nullptr)) |
michael@0 | 442 | { |
michael@0 | 443 | return false; |
michael@0 | 444 | } |
michael@0 | 445 | break; |
michael@0 | 446 | } |
michael@0 | 447 | case Edit::TOpRemoveChild: { |
michael@0 | 448 | MOZ_LAYERS_LOG(("[ParentSide] RemoveChild")); |
michael@0 | 449 | |
michael@0 | 450 | const OpRemoveChild& orc = edit.get_OpRemoveChild(); |
michael@0 | 451 | Layer* childLayer = ShadowChild(orc)->AsLayer(); |
michael@0 | 452 | if (!childLayer) { |
michael@0 | 453 | return false; |
michael@0 | 454 | } |
michael@0 | 455 | ContainerLayerComposite* container = ShadowContainer(orc)->AsContainerLayerComposite(); |
michael@0 | 456 | if (!container || |
michael@0 | 457 | !container->RemoveChild(childLayer)) |
michael@0 | 458 | { |
michael@0 | 459 | return false; |
michael@0 | 460 | } |
michael@0 | 461 | break; |
michael@0 | 462 | } |
michael@0 | 463 | case Edit::TOpRepositionChild: { |
michael@0 | 464 | MOZ_LAYERS_LOG(("[ParentSide] RepositionChild")); |
michael@0 | 465 | |
michael@0 | 466 | const OpRepositionChild& orc = edit.get_OpRepositionChild(); |
michael@0 | 467 | Layer* child = ShadowChild(orc)->AsLayer(); |
michael@0 | 468 | if (!child) { |
michael@0 | 469 | return false; |
michael@0 | 470 | } |
michael@0 | 471 | ContainerLayerComposite* container = ShadowContainer(orc)->AsContainerLayerComposite(); |
michael@0 | 472 | if (!container || |
michael@0 | 473 | !container->RepositionChild(child, ShadowAfter(orc)->AsLayer())) |
michael@0 | 474 | { |
michael@0 | 475 | return false; |
michael@0 | 476 | } |
michael@0 | 477 | break; |
michael@0 | 478 | } |
michael@0 | 479 | case Edit::TOpRaiseToTopChild: { |
michael@0 | 480 | MOZ_LAYERS_LOG(("[ParentSide] RaiseToTopChild")); |
michael@0 | 481 | |
michael@0 | 482 | const OpRaiseToTopChild& rtc = edit.get_OpRaiseToTopChild(); |
michael@0 | 483 | Layer* child = ShadowChild(rtc)->AsLayer(); |
michael@0 | 484 | if (!child) { |
michael@0 | 485 | return false; |
michael@0 | 486 | } |
michael@0 | 487 | ContainerLayerComposite* container = ShadowContainer(rtc)->AsContainerLayerComposite(); |
michael@0 | 488 | if (!container || |
michael@0 | 489 | !container->RepositionChild(child, nullptr)) |
michael@0 | 490 | { |
michael@0 | 491 | return false; |
michael@0 | 492 | } |
michael@0 | 493 | break; |
michael@0 | 494 | } |
michael@0 | 495 | case Edit::TCompositableOperation: { |
michael@0 | 496 | if (!ReceiveCompositableUpdate(edit.get_CompositableOperation(), |
michael@0 | 497 | replyv)) { |
michael@0 | 498 | return false; |
michael@0 | 499 | } |
michael@0 | 500 | break; |
michael@0 | 501 | } |
michael@0 | 502 | case Edit::TOpAttachCompositable: { |
michael@0 | 503 | const OpAttachCompositable& op = edit.get_OpAttachCompositable(); |
michael@0 | 504 | CompositableHost* host = CompositableHost::FromIPDLActor(op.compositableParent()); |
michael@0 | 505 | if (!Attach(cast(op.layerParent()), host, false)) { |
michael@0 | 506 | return false; |
michael@0 | 507 | } |
michael@0 | 508 | host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID()); |
michael@0 | 509 | break; |
michael@0 | 510 | } |
michael@0 | 511 | case Edit::TOpAttachAsyncCompositable: { |
michael@0 | 512 | const OpAttachAsyncCompositable& op = edit.get_OpAttachAsyncCompositable(); |
michael@0 | 513 | PCompositableParent* compositableParent = CompositableMap::Get(op.containerID()); |
michael@0 | 514 | if (!compositableParent) { |
michael@0 | 515 | NS_ERROR("CompositableParent not found in the map"); |
michael@0 | 516 | return false; |
michael@0 | 517 | } |
michael@0 | 518 | CompositableHost* host = CompositableHost::FromIPDLActor(compositableParent); |
michael@0 | 519 | if (!Attach(cast(op.layerParent()), host, true)) { |
michael@0 | 520 | return false; |
michael@0 | 521 | } |
michael@0 | 522 | |
michael@0 | 523 | host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID()); |
michael@0 | 524 | break; |
michael@0 | 525 | } |
michael@0 | 526 | default: |
michael@0 | 527 | NS_RUNTIMEABORT("not reached"); |
michael@0 | 528 | } |
michael@0 | 529 | } |
michael@0 | 530 | |
michael@0 | 531 | { |
michael@0 | 532 | AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this)); |
michael@0 | 533 | layer_manager()->EndTransaction(nullptr, nullptr, LayerManager::END_NO_IMMEDIATE_REDRAW); |
michael@0 | 534 | } |
michael@0 | 535 | |
michael@0 | 536 | if (reply) { |
michael@0 | 537 | reply->SetCapacity(replyv.size()); |
michael@0 | 538 | if (replyv.size() > 0) { |
michael@0 | 539 | reply->AppendElements(&replyv.front(), replyv.size()); |
michael@0 | 540 | } |
michael@0 | 541 | } |
michael@0 | 542 | |
michael@0 | 543 | // Ensure that any pending operations involving back and front |
michael@0 | 544 | // buffers have completed, so that neither process stomps on the |
michael@0 | 545 | // other's buffer contents. |
michael@0 | 546 | LayerManagerComposite::PlatformSyncBeforeReplyUpdate(); |
michael@0 | 547 | |
michael@0 | 548 | mShadowLayersManager->ShadowLayersUpdated(this, targetConfig, isFirstPaint, scheduleComposite); |
michael@0 | 549 | |
michael@0 | 550 | #ifdef COMPOSITOR_PERFORMANCE_WARNING |
michael@0 | 551 | int compositeTime = (int)(mozilla::TimeStamp::Now() - updateStart).ToMilliseconds(); |
michael@0 | 552 | if (compositeTime > 15) { |
michael@0 | 553 | printf_stderr("Compositor: Layers update took %i ms (blocking gecko).\n", compositeTime); |
michael@0 | 554 | } |
michael@0 | 555 | #endif |
michael@0 | 556 | |
michael@0 | 557 | return true; |
michael@0 | 558 | } |
michael@0 | 559 | |
michael@0 | 560 | bool |
michael@0 | 561 | LayerTransactionParent::RecvSetTestSampleTime(const TimeStamp& aTime) |
michael@0 | 562 | { |
michael@0 | 563 | return mShadowLayersManager->SetTestSampleTime(this, aTime); |
michael@0 | 564 | } |
michael@0 | 565 | |
michael@0 | 566 | bool |
michael@0 | 567 | LayerTransactionParent::RecvLeaveTestMode() |
michael@0 | 568 | { |
michael@0 | 569 | mShadowLayersManager->LeaveTestMode(this); |
michael@0 | 570 | return true; |
michael@0 | 571 | } |
michael@0 | 572 | |
michael@0 | 573 | bool |
michael@0 | 574 | LayerTransactionParent::RecvGetOpacity(PLayerParent* aParent, |
michael@0 | 575 | float* aOpacity) |
michael@0 | 576 | { |
michael@0 | 577 | if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) { |
michael@0 | 578 | return false; |
michael@0 | 579 | } |
michael@0 | 580 | |
michael@0 | 581 | Layer* layer = cast(aParent)->AsLayer(); |
michael@0 | 582 | if (!layer) { |
michael@0 | 583 | return false; |
michael@0 | 584 | } |
michael@0 | 585 | |
michael@0 | 586 | *aOpacity = layer->GetLocalOpacity(); |
michael@0 | 587 | return true; |
michael@0 | 588 | } |
michael@0 | 589 | |
michael@0 | 590 | bool |
michael@0 | 591 | LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent, |
michael@0 | 592 | MaybeTransform* aTransform) |
michael@0 | 593 | { |
michael@0 | 594 | if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) { |
michael@0 | 595 | return false; |
michael@0 | 596 | } |
michael@0 | 597 | |
michael@0 | 598 | Layer* layer = cast(aParent)->AsLayer(); |
michael@0 | 599 | if (!layer) { |
michael@0 | 600 | return false; |
michael@0 | 601 | } |
michael@0 | 602 | |
michael@0 | 603 | // This method is specific to transforms applied by animation. |
michael@0 | 604 | // This is because this method uses the information stored with an animation |
michael@0 | 605 | // such as the origin of the reference frame corresponding to the layer, to |
michael@0 | 606 | // recover the untranslated transform from the shadow transform. For |
michael@0 | 607 | // transforms that are not set by animation we don't have this information |
michael@0 | 608 | // available. |
michael@0 | 609 | if (!layer->AsLayerComposite()->GetShadowTransformSetByAnimation()) { |
michael@0 | 610 | *aTransform = mozilla::void_t(); |
michael@0 | 611 | return true; |
michael@0 | 612 | } |
michael@0 | 613 | |
michael@0 | 614 | // The following code recovers the untranslated transform |
michael@0 | 615 | // from the shadow transform by undoing the translations in |
michael@0 | 616 | // AsyncCompositionManager::SampleValue. |
michael@0 | 617 | |
michael@0 | 618 | gfx3DMatrix transform; |
michael@0 | 619 | gfx::To3DMatrix(layer->AsLayerComposite()->GetShadowTransform(), transform); |
michael@0 | 620 | if (ContainerLayer* c = layer->AsContainerLayer()) { |
michael@0 | 621 | // Undo the scale transform applied by AsyncCompositionManager::SampleValue |
michael@0 | 622 | transform.ScalePost(1.0f/c->GetInheritedXScale(), |
michael@0 | 623 | 1.0f/c->GetInheritedYScale(), |
michael@0 | 624 | 1.0f); |
michael@0 | 625 | } |
michael@0 | 626 | float scale = 1; |
michael@0 | 627 | gfxPoint3D scaledOrigin; |
michael@0 | 628 | gfxPoint3D transformOrigin; |
michael@0 | 629 | for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) { |
michael@0 | 630 | if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) { |
michael@0 | 631 | const TransformData& data = layer->GetAnimations()[i].data().get_TransformData(); |
michael@0 | 632 | scale = data.appUnitsPerDevPixel(); |
michael@0 | 633 | scaledOrigin = |
michael@0 | 634 | gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)), |
michael@0 | 635 | NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)), |
michael@0 | 636 | 0.0f); |
michael@0 | 637 | double cssPerDev = |
michael@0 | 638 | double(nsDeviceContext::AppUnitsPerCSSPixel()) / double(scale); |
michael@0 | 639 | transformOrigin = data.transformOrigin() * cssPerDev; |
michael@0 | 640 | break; |
michael@0 | 641 | } |
michael@0 | 642 | } |
michael@0 | 643 | |
michael@0 | 644 | // Undo the translation to the origin of the reference frame applied by |
michael@0 | 645 | // AsyncCompositionManager::SampleValue |
michael@0 | 646 | transform.Translate(-scaledOrigin); |
michael@0 | 647 | |
michael@0 | 648 | // Undo the rebasing applied by |
michael@0 | 649 | // nsDisplayTransform::GetResultingTransformMatrixInternal |
michael@0 | 650 | transform = nsLayoutUtils::ChangeMatrixBasis(-scaledOrigin - transformOrigin, |
michael@0 | 651 | transform); |
michael@0 | 652 | |
michael@0 | 653 | // Convert to CSS pixels (this undoes the operations performed by |
michael@0 | 654 | // nsStyleTransformMatrix::ProcessTranslatePart which is called from |
michael@0 | 655 | // nsDisplayTransform::GetResultingTransformMatrix) |
michael@0 | 656 | double devPerCss = |
michael@0 | 657 | double(scale) / double(nsDeviceContext::AppUnitsPerCSSPixel()); |
michael@0 | 658 | transform._41 *= devPerCss; |
michael@0 | 659 | transform._42 *= devPerCss; |
michael@0 | 660 | transform._43 *= devPerCss; |
michael@0 | 661 | |
michael@0 | 662 | *aTransform = transform; |
michael@0 | 663 | return true; |
michael@0 | 664 | } |
michael@0 | 665 | |
michael@0 | 666 | bool |
michael@0 | 667 | LayerTransactionParent::RecvSetAsyncScrollOffset(PLayerParent* aLayer, |
michael@0 | 668 | const int32_t& aX, const int32_t& aY) |
michael@0 | 669 | { |
michael@0 | 670 | if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) { |
michael@0 | 671 | return false; |
michael@0 | 672 | } |
michael@0 | 673 | |
michael@0 | 674 | Layer* layer = cast(aLayer)->AsLayer(); |
michael@0 | 675 | if (!layer) { |
michael@0 | 676 | return false; |
michael@0 | 677 | } |
michael@0 | 678 | ContainerLayer* containerLayer = layer->AsContainerLayer(); |
michael@0 | 679 | if (!containerLayer) { |
michael@0 | 680 | return false; |
michael@0 | 681 | } |
michael@0 | 682 | AsyncPanZoomController* controller = containerLayer->GetAsyncPanZoomController(); |
michael@0 | 683 | if (!controller) { |
michael@0 | 684 | return false; |
michael@0 | 685 | } |
michael@0 | 686 | controller->SetTestAsyncScrollOffset(CSSPoint(aX, aY)); |
michael@0 | 687 | return true; |
michael@0 | 688 | } |
michael@0 | 689 | |
michael@0 | 690 | bool |
michael@0 | 691 | LayerTransactionParent::Attach(ShadowLayerParent* aLayerParent, |
michael@0 | 692 | CompositableHost* aCompositable, |
michael@0 | 693 | bool aIsAsync) |
michael@0 | 694 | { |
michael@0 | 695 | if (!aCompositable) { |
michael@0 | 696 | return false; |
michael@0 | 697 | } |
michael@0 | 698 | |
michael@0 | 699 | Layer* baselayer = aLayerParent->AsLayer(); |
michael@0 | 700 | if (!baselayer) { |
michael@0 | 701 | return false; |
michael@0 | 702 | } |
michael@0 | 703 | LayerComposite* layer = baselayer->AsLayerComposite(); |
michael@0 | 704 | if (!layer) { |
michael@0 | 705 | return false; |
michael@0 | 706 | } |
michael@0 | 707 | |
michael@0 | 708 | Compositor* compositor |
michael@0 | 709 | = static_cast<LayerManagerComposite*>(aLayerParent->AsLayer()->Manager())->GetCompositor(); |
michael@0 | 710 | |
michael@0 | 711 | if (!layer->SetCompositableHost(aCompositable)) { |
michael@0 | 712 | // not all layer types accept a compositable, see bug 967824 |
michael@0 | 713 | return false; |
michael@0 | 714 | } |
michael@0 | 715 | aCompositable->Attach(aLayerParent->AsLayer(), |
michael@0 | 716 | compositor, |
michael@0 | 717 | aIsAsync |
michael@0 | 718 | ? CompositableHost::ALLOW_REATTACH |
michael@0 | 719 | | CompositableHost::KEEP_ATTACHED |
michael@0 | 720 | : CompositableHost::NO_FLAGS); |
michael@0 | 721 | return true; |
michael@0 | 722 | } |
michael@0 | 723 | |
michael@0 | 724 | bool |
michael@0 | 725 | LayerTransactionParent::RecvClearCachedResources() |
michael@0 | 726 | { |
michael@0 | 727 | if (mRoot) { |
michael@0 | 728 | // NB: |mRoot| here is the *child* context's root. In this parent |
michael@0 | 729 | // context, it's just a subtree root. We need to scope the clear |
michael@0 | 730 | // of resources to exactly that subtree, so we specify it here. |
michael@0 | 731 | mLayerManager->ClearCachedResources(mRoot); |
michael@0 | 732 | } |
michael@0 | 733 | return true; |
michael@0 | 734 | } |
michael@0 | 735 | |
michael@0 | 736 | bool |
michael@0 | 737 | LayerTransactionParent::RecvForceComposite() |
michael@0 | 738 | { |
michael@0 | 739 | mShadowLayersManager->ForceComposite(this); |
michael@0 | 740 | return true; |
michael@0 | 741 | } |
michael@0 | 742 | |
michael@0 | 743 | |
michael@0 | 744 | PGrallocBufferParent* |
michael@0 | 745 | LayerTransactionParent::AllocPGrallocBufferParent(const IntSize& aSize, |
michael@0 | 746 | const uint32_t& aFormat, |
michael@0 | 747 | const uint32_t& aUsage, |
michael@0 | 748 | MaybeMagicGrallocBufferHandle* aOutHandle) |
michael@0 | 749 | { |
michael@0 | 750 | #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC |
michael@0 | 751 | return GrallocBufferActor::Create(aSize, aFormat, aUsage, aOutHandle); |
michael@0 | 752 | #else |
michael@0 | 753 | NS_RUNTIMEABORT("No gralloc buffers for you"); |
michael@0 | 754 | return nullptr; |
michael@0 | 755 | #endif |
michael@0 | 756 | } |
michael@0 | 757 | |
michael@0 | 758 | bool |
michael@0 | 759 | LayerTransactionParent::DeallocPGrallocBufferParent(PGrallocBufferParent* actor) |
michael@0 | 760 | { |
michael@0 | 761 | #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC |
michael@0 | 762 | delete actor; |
michael@0 | 763 | return true; |
michael@0 | 764 | #else |
michael@0 | 765 | NS_RUNTIMEABORT("Um, how did we get here?"); |
michael@0 | 766 | return false; |
michael@0 | 767 | #endif |
michael@0 | 768 | } |
michael@0 | 769 | |
michael@0 | 770 | PLayerParent* |
michael@0 | 771 | LayerTransactionParent::AllocPLayerParent() |
michael@0 | 772 | { |
michael@0 | 773 | return new ShadowLayerParent(); |
michael@0 | 774 | } |
michael@0 | 775 | |
michael@0 | 776 | bool |
michael@0 | 777 | LayerTransactionParent::DeallocPLayerParent(PLayerParent* actor) |
michael@0 | 778 | { |
michael@0 | 779 | delete actor; |
michael@0 | 780 | return true; |
michael@0 | 781 | } |
michael@0 | 782 | |
michael@0 | 783 | PCompositableParent* |
michael@0 | 784 | LayerTransactionParent::AllocPCompositableParent(const TextureInfo& aInfo) |
michael@0 | 785 | { |
michael@0 | 786 | return CompositableHost::CreateIPDLActor(this, aInfo, 0); |
michael@0 | 787 | } |
michael@0 | 788 | |
michael@0 | 789 | bool |
michael@0 | 790 | LayerTransactionParent::DeallocPCompositableParent(PCompositableParent* aActor) |
michael@0 | 791 | { |
michael@0 | 792 | return CompositableHost::DestroyIPDLActor(aActor); |
michael@0 | 793 | } |
michael@0 | 794 | |
michael@0 | 795 | PTextureParent* |
michael@0 | 796 | LayerTransactionParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData, |
michael@0 | 797 | const TextureFlags& aFlags) |
michael@0 | 798 | { |
michael@0 | 799 | return TextureHost::CreateIPDLActor(this, aSharedData, aFlags); |
michael@0 | 800 | } |
michael@0 | 801 | |
michael@0 | 802 | bool |
michael@0 | 803 | LayerTransactionParent::DeallocPTextureParent(PTextureParent* actor) |
michael@0 | 804 | { |
michael@0 | 805 | return TextureHost::DestroyIPDLActor(actor); |
michael@0 | 806 | } |
michael@0 | 807 | |
michael@0 | 808 | bool LayerTransactionParent::IsSameProcess() const |
michael@0 | 809 | { |
michael@0 | 810 | return OtherProcess() == ipc::kInvalidProcessHandle; |
michael@0 | 811 | } |
michael@0 | 812 | |
michael@0 | 813 | } // namespace layers |
michael@0 | 814 | } // namespace mozilla |