1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/Layers.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2113 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef GFX_LAYERS_H 1.10 +#define GFX_LAYERS_H 1.11 + 1.12 +#include <stdint.h> // for uint32_t, uint64_t, uint8_t 1.13 +#include <stdio.h> // for FILE 1.14 +#include <sys/types.h> // for int32_t, int64_t 1.15 +#include "FrameMetrics.h" // for FrameMetrics 1.16 +#include "Units.h" // for LayerMargin, LayerPoint 1.17 +#include "gfxContext.h" // for GraphicsOperator 1.18 +#include "gfxTypes.h" 1.19 +#include "gfxColor.h" // for gfxRGBA 1.20 +#include "gfxMatrix.h" // for gfxMatrix 1.21 +#include "GraphicsFilter.h" // for GraphicsFilter 1.22 +#include "gfxPoint.h" // for gfxPoint 1.23 +#include "gfxRect.h" // for gfxRect 1.24 +#include "gfx2DGlue.h" 1.25 +#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc 1.26 +#include "mozilla/DebugOnly.h" // for DebugOnly 1.27 +#include "mozilla/EventForwards.h" // for nsPaintEvent 1.28 +#include "mozilla/RefPtr.h" // for TemporaryRef 1.29 +#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration 1.30 +#include "mozilla/gfx/BaseMargin.h" // for BaseMargin 1.31 +#include "mozilla/gfx/BasePoint.h" // for BasePoint 1.32 +#include "mozilla/gfx/Point.h" // for IntSize 1.33 +#include "mozilla/gfx/Types.h" // for SurfaceFormat 1.34 +#include "mozilla/gfx/UserData.h" // for UserData, etc 1.35 +#include "mozilla/layers/LayersTypes.h" 1.36 +#include "mozilla/mozalloc.h" // for operator delete, etc 1.37 +#include "nsAutoPtr.h" // for nsAutoPtr, nsRefPtr, etc 1.38 +#include "nsCOMPtr.h" // for already_AddRefed 1.39 +#include "nsCSSProperty.h" // for nsCSSProperty 1.40 +#include "nsDebug.h" // for NS_ASSERTION 1.41 +#include "nsISupportsImpl.h" // for Layer::Release, etc 1.42 +#include "nsRect.h" // for nsIntRect 1.43 +#include "nsRegion.h" // for nsIntRegion 1.44 +#include "nsSize.h" // for nsIntSize 1.45 +#include "nsString.h" // for nsCString 1.46 +#include "nsStyleAnimation.h" // for nsStyleAnimation::Value, etc 1.47 +#include "nsTArray.h" // for nsTArray 1.48 +#include "nsTArrayForwardDeclare.h" // for InfallibleTArray 1.49 +#include "nscore.h" // for nsACString, nsAString 1.50 +#include "prlog.h" // for PRLogModuleInfo 1.51 +#include "gfx2DGlue.h" 1.52 + 1.53 +class gfxContext; 1.54 + 1.55 +extern uint8_t gLayerManagerLayerBuilder; 1.56 + 1.57 +namespace mozilla { 1.58 + 1.59 +class FrameLayerBuilder; 1.60 +class WebGLContext; 1.61 + 1.62 +namespace gl { 1.63 +class GLContext; 1.64 +} 1.65 + 1.66 +namespace gfx { 1.67 +class DrawTarget; 1.68 +class SurfaceStream; 1.69 +} 1.70 + 1.71 +namespace css { 1.72 +class ComputedTimingFunction; 1.73 +} 1.74 + 1.75 +namespace layers { 1.76 + 1.77 +class Animation; 1.78 +class AnimationData; 1.79 +class AsyncPanZoomController; 1.80 +class CommonLayerAttributes; 1.81 +class Layer; 1.82 +class ThebesLayer; 1.83 +class ContainerLayer; 1.84 +class ImageLayer; 1.85 +class ColorLayer; 1.86 +class ImageContainer; 1.87 +class CanvasLayer; 1.88 +class ReadbackLayer; 1.89 +class ReadbackProcessor; 1.90 +class RefLayer; 1.91 +class LayerComposite; 1.92 +class ShadowableLayer; 1.93 +class ShadowLayerForwarder; 1.94 +class LayerManagerComposite; 1.95 +class SpecificLayerAttributes; 1.96 +class SurfaceDescriptor; 1.97 +class Compositor; 1.98 +struct TextureFactoryIdentifier; 1.99 +struct EffectMask; 1.100 + 1.101 +#define MOZ_LAYER_DECL_NAME(n, e) \ 1.102 + virtual const char* Name() const { return n; } \ 1.103 + virtual LayerType GetType() const { return e; } 1.104 + 1.105 +/** 1.106 + * Base class for userdata objects attached to layers and layer managers. 1.107 + */ 1.108 +class LayerUserData { 1.109 +public: 1.110 + virtual ~LayerUserData() {} 1.111 +}; 1.112 + 1.113 +/* 1.114 + * Motivation: For truly smooth animation and video playback, we need to 1.115 + * be able to compose frames and render them on a dedicated thread (i.e. 1.116 + * off the main thread where DOM manipulation, script execution and layout 1.117 + * induce difficult-to-bound latency). This requires Gecko to construct 1.118 + * some kind of persistent scene structure (graph or tree) that can be 1.119 + * safely transmitted across threads. We have other scenarios (e.g. mobile 1.120 + * browsing) where retaining some rendered data between paints is desired 1.121 + * for performance, so again we need a retained scene structure. 1.122 + * 1.123 + * Our retained scene structure is a layer tree. Each layer represents 1.124 + * content which can be composited onto a destination surface; the root 1.125 + * layer is usually composited into a window, and non-root layers are 1.126 + * composited into their parent layers. Layers have attributes (e.g. 1.127 + * opacity and clipping) that influence their compositing. 1.128 + * 1.129 + * We want to support a variety of layer implementations, including 1.130 + * a simple "immediate mode" implementation that doesn't retain any 1.131 + * rendered data between paints (i.e. uses cairo in just the way that 1.132 + * Gecko used it before layers were introduced). But we also don't want 1.133 + * to have bifurcated "layers"/"non-layers" rendering paths in Gecko. 1.134 + * Therefore the layers API is carefully designed to permit maximally 1.135 + * efficient implementation in an "immediate mode" style. See the 1.136 + * BasicLayerManager for such an implementation. 1.137 + */ 1.138 + 1.139 +static void LayerManagerUserDataDestroy(void *data) 1.140 +{ 1.141 + delete static_cast<LayerUserData*>(data); 1.142 +} 1.143 + 1.144 +/** 1.145 + * A LayerManager controls a tree of layers. All layers in the tree 1.146 + * must use the same LayerManager. 1.147 + * 1.148 + * All modifications to a layer tree must happen inside a transaction. 1.149 + * Only the state of the layer tree at the end of a transaction is 1.150 + * rendered. Transactions cannot be nested 1.151 + * 1.152 + * Each transaction has two phases: 1.153 + * 1) Construction: layers are created, inserted, removed and have 1.154 + * properties set on them in this phase. 1.155 + * BeginTransaction and BeginTransactionWithTarget start a transaction in 1.156 + * the Construction phase. When the client has finished constructing the layer 1.157 + * tree, it should call EndConstruction() to enter the drawing phase. 1.158 + * 2) Drawing: ThebesLayers are rendered into in this phase, in tree 1.159 + * order. When the client has finished drawing into the ThebesLayers, it should 1.160 + * call EndTransaction to complete the transaction. 1.161 + * 1.162 + * All layer API calls happen on the main thread. 1.163 + * 1.164 + * Layers are refcounted. The layer manager holds a reference to the 1.165 + * root layer, and each container layer holds a reference to its children. 1.166 + */ 1.167 +class LayerManager { 1.168 + NS_INLINE_DECL_REFCOUNTING(LayerManager) 1.169 + 1.170 +protected: 1.171 + typedef mozilla::gfx::DrawTarget DrawTarget; 1.172 + typedef mozilla::gfx::IntSize IntSize; 1.173 + typedef mozilla::gfx::SurfaceFormat SurfaceFormat; 1.174 + 1.175 +public: 1.176 + LayerManager() 1.177 + : mDestroyed(false) 1.178 + , mSnapEffectiveTransforms(true) 1.179 + , mId(0) 1.180 + , mInTransaction(false) 1.181 + { 1.182 + InitLog(); 1.183 + } 1.184 + 1.185 + /** 1.186 + * Release layers and resources held by this layer manager, and mark 1.187 + * it as destroyed. Should do any cleanup necessary in preparation 1.188 + * for its widget going away. After this call, only user data calls 1.189 + * are valid on the layer manager. 1.190 + */ 1.191 + virtual void Destroy() 1.192 + { 1.193 + mDestroyed = true; 1.194 + mUserData.Destroy(); 1.195 + mRoot = nullptr; 1.196 + } 1.197 + bool IsDestroyed() { return mDestroyed; } 1.198 + 1.199 + virtual ShadowLayerForwarder* AsShadowForwarder() 1.200 + { return nullptr; } 1.201 + 1.202 + virtual LayerManagerComposite* AsLayerManagerComposite() 1.203 + { return nullptr; } 1.204 + 1.205 + /** 1.206 + * Returns true if this LayerManager is owned by an nsIWidget, 1.207 + * and is used for drawing into the widget. 1.208 + */ 1.209 + virtual bool IsWidgetLayerManager() { return true; } 1.210 + 1.211 + /** 1.212 + * Start a new transaction. Nested transactions are not allowed so 1.213 + * there must be no transaction currently in progress. 1.214 + * This transaction will update the state of the window from which 1.215 + * this LayerManager was obtained. 1.216 + */ 1.217 + virtual void BeginTransaction() = 0; 1.218 + /** 1.219 + * Start a new transaction. Nested transactions are not allowed so 1.220 + * there must be no transaction currently in progress. 1.221 + * This transaction will render the contents of the layer tree to 1.222 + * the given target context. The rendering will be complete when 1.223 + * EndTransaction returns. 1.224 + */ 1.225 + virtual void BeginTransactionWithTarget(gfxContext* aTarget) = 0; 1.226 + 1.227 + enum EndTransactionFlags { 1.228 + END_DEFAULT = 0, 1.229 + END_NO_IMMEDIATE_REDRAW = 1 << 0, // Do not perform the drawing phase 1.230 + END_NO_COMPOSITE = 1 << 1, // Do not composite after drawing thebes layer contents. 1.231 + END_NO_REMOTE_COMPOSITE = 1 << 2 // Do not schedule a composition with a remote Compositor, if one exists. 1.232 + }; 1.233 + 1.234 + FrameLayerBuilder* GetLayerBuilder() { 1.235 + return reinterpret_cast<FrameLayerBuilder*>(GetUserData(&gLayerManagerLayerBuilder)); 1.236 + } 1.237 + 1.238 + /** 1.239 + * Attempts to end an "empty transaction". There must have been no 1.240 + * changes to the layer tree since the BeginTransaction(). 1.241 + * It's possible for this to fail; ThebesLayers may need to be updated 1.242 + * due to VRAM data being lost, for example. In such cases this method 1.243 + * returns false, and the caller must proceed with a normal layer tree 1.244 + * update and EndTransaction. 1.245 + */ 1.246 + virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) = 0; 1.247 + 1.248 + /** 1.249 + * Function called to draw the contents of each ThebesLayer. 1.250 + * aRegionToDraw contains the region that needs to be drawn. 1.251 + * This would normally be a subregion of the visible region. 1.252 + * The callee must draw all of aRegionToDraw. Drawing outside 1.253 + * aRegionToDraw will be clipped out or ignored. 1.254 + * The callee must draw all of aRegionToDraw. 1.255 + * This region is relative to 0,0 in the ThebesLayer. 1.256 + * 1.257 + * aRegionToInvalidate contains a region whose contents have been 1.258 + * changed by the layer manager and which must therefore be invalidated. 1.259 + * For example, this could be non-empty if a retained layer internally 1.260 + * switches from RGBA to RGB or back ... we might want to repaint it to 1.261 + * consistently use subpixel-AA or not. 1.262 + * This region is relative to 0,0 in the ThebesLayer. 1.263 + * aRegionToInvalidate may contain areas that are outside 1.264 + * aRegionToDraw; the callee must ensure that these areas are repainted 1.265 + * in the current layer manager transaction or in a later layer 1.266 + * manager transaction. 1.267 + * 1.268 + * aContext must not be used after the call has returned. 1.269 + * We guarantee that buffered contents in the visible 1.270 + * region are valid once drawing is complete. 1.271 + * 1.272 + * The origin of aContext is 0,0 in the ThebesLayer. 1.273 + */ 1.274 + typedef void (* DrawThebesLayerCallback)(ThebesLayer* aLayer, 1.275 + gfxContext* aContext, 1.276 + const nsIntRegion& aRegionToDraw, 1.277 + DrawRegionClip aClip, 1.278 + const nsIntRegion& aRegionToInvalidate, 1.279 + void* aCallbackData); 1.280 + 1.281 + /** 1.282 + * Finish the construction phase of the transaction, perform the 1.283 + * drawing phase, and end the transaction. 1.284 + * During the drawing phase, all ThebesLayers in the tree are 1.285 + * drawn in tree order, exactly once each, except for those layers 1.286 + * where it is known that the visible region is empty. 1.287 + */ 1.288 + virtual void EndTransaction(DrawThebesLayerCallback aCallback, 1.289 + void* aCallbackData, 1.290 + EndTransactionFlags aFlags = END_DEFAULT) = 0; 1.291 + 1.292 + /** 1.293 + * Schedule a composition with the remote Compositor, if one exists 1.294 + * for this LayerManager. Useful in conjunction with the END_NO_REMOTE_COMPOSITE 1.295 + * flag to EndTransaction. 1.296 + */ 1.297 + virtual void Composite() {} 1.298 + 1.299 + virtual bool HasShadowManagerInternal() const { return false; } 1.300 + bool HasShadowManager() const { return HasShadowManagerInternal(); } 1.301 + 1.302 + bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; } 1.303 + 1.304 + /** 1.305 + * Returns true if this LayerManager can properly support layers with 1.306 + * SurfaceMode::SURFACE_COMPONENT_ALPHA. This can include disabling component 1.307 + * alpha if required. 1.308 + */ 1.309 + virtual bool AreComponentAlphaLayersEnabled() { return true; } 1.310 + 1.311 + /** 1.312 + * CONSTRUCTION PHASE ONLY 1.313 + * Set the root layer. The root layer is initially null. If there is 1.314 + * no root layer, EndTransaction won't draw anything. 1.315 + */ 1.316 + virtual void SetRoot(Layer* aLayer) = 0; 1.317 + /** 1.318 + * Can be called anytime 1.319 + */ 1.320 + Layer* GetRoot() { return mRoot; } 1.321 + 1.322 + /** 1.323 + * Does a breadth-first search from the root layer to find the first 1.324 + * scrollable layer. 1.325 + * Can be called any time. 1.326 + */ 1.327 + Layer* GetPrimaryScrollableLayer(); 1.328 + 1.329 + /** 1.330 + * Returns a list of all descendant layers for which 1.331 + * GetFrameMetrics().IsScrollable() is true. 1.332 + */ 1.333 + void GetScrollableLayers(nsTArray<Layer*>& aArray); 1.334 + 1.335 + /** 1.336 + * CONSTRUCTION PHASE ONLY 1.337 + * Called when a managee has mutated. 1.338 + * Subclasses overriding this method must first call their 1.339 + * superclass's impl 1.340 + */ 1.341 +#ifdef DEBUG 1.342 + // In debug builds, we check some properties of |aLayer|. 1.343 + virtual void Mutated(Layer* aLayer); 1.344 +#else 1.345 + virtual void Mutated(Layer* aLayer) { } 1.346 +#endif 1.347 + 1.348 + /** 1.349 + * Hints that can be used during Thebes layer creation to influence the type 1.350 + * or properties of the layer created. 1.351 + * 1.352 + * NONE: No hint. 1.353 + * SCROLLABLE: This layer may represent scrollable content. 1.354 + */ 1.355 + enum ThebesLayerCreationHint { 1.356 + NONE, SCROLLABLE 1.357 + }; 1.358 + 1.359 + /** 1.360 + * CONSTRUCTION PHASE ONLY 1.361 + * Create a ThebesLayer for this manager's layer tree. 1.362 + */ 1.363 + virtual already_AddRefed<ThebesLayer> CreateThebesLayer() = 0; 1.364 + /** 1.365 + * CONSTRUCTION PHASE ONLY 1.366 + * Create a ThebesLayer for this manager's layer tree, with a creation hint 1.367 + * parameter to help optimise the type of layer created. 1.368 + */ 1.369 + virtual already_AddRefed<ThebesLayer> CreateThebesLayerWithHint(ThebesLayerCreationHint) { 1.370 + return CreateThebesLayer(); 1.371 + } 1.372 + /** 1.373 + * CONSTRUCTION PHASE ONLY 1.374 + * Create a ContainerLayer for this manager's layer tree. 1.375 + */ 1.376 + virtual already_AddRefed<ContainerLayer> CreateContainerLayer() = 0; 1.377 + /** 1.378 + * CONSTRUCTION PHASE ONLY 1.379 + * Create an ImageLayer for this manager's layer tree. 1.380 + */ 1.381 + virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0; 1.382 + /** 1.383 + * CONSTRUCTION PHASE ONLY 1.384 + * Create a ColorLayer for this manager's layer tree. 1.385 + */ 1.386 + virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0; 1.387 + /** 1.388 + * CONSTRUCTION PHASE ONLY 1.389 + * Create a CanvasLayer for this manager's layer tree. 1.390 + */ 1.391 + virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() = 0; 1.392 + /** 1.393 + * CONSTRUCTION PHASE ONLY 1.394 + * Create a ReadbackLayer for this manager's layer tree. 1.395 + */ 1.396 + virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() { return nullptr; } 1.397 + /** 1.398 + * CONSTRUCTION PHASE ONLY 1.399 + * Create a RefLayer for this manager's layer tree. 1.400 + */ 1.401 + virtual already_AddRefed<RefLayer> CreateRefLayer() { return nullptr; } 1.402 + 1.403 + 1.404 + /** 1.405 + * Can be called anytime, from any thread. 1.406 + * 1.407 + * Creates an Image container which forwards its images to the compositor within 1.408 + * layer transactions on the main thread. 1.409 + */ 1.410 + static already_AddRefed<ImageContainer> CreateImageContainer(); 1.411 + 1.412 + /** 1.413 + * Can be called anytime, from any thread. 1.414 + * 1.415 + * Tries to create an Image container which forwards its images to the compositor 1.416 + * asynchronously using the ImageBridge IPDL protocol. If the protocol is not 1.417 + * available, the returned ImageContainer will forward images within layer 1.418 + * transactions, just like if it was created with CreateImageContainer(). 1.419 + */ 1.420 + static already_AddRefed<ImageContainer> CreateAsynchronousImageContainer(); 1.421 + 1.422 + /** 1.423 + * Type of layer manager his is. This is to be used sparsely in order to 1.424 + * avoid a lot of Layers backend specific code. It should be used only when 1.425 + * Layers backend specific functionality is necessary. 1.426 + */ 1.427 + virtual LayersBackend GetBackendType() = 0; 1.428 + 1.429 + /** 1.430 + * Type of layers backend that will be used to composite this layer tree. 1.431 + * When compositing is done remotely, then this returns the layers type 1.432 + * of the compositor. 1.433 + */ 1.434 + virtual LayersBackend GetCompositorBackendType() { return GetBackendType(); } 1.435 + 1.436 + /** 1.437 + * Creates a DrawTarget which is optimized for inter-operating with this 1.438 + * layer manager. 1.439 + */ 1.440 + virtual TemporaryRef<DrawTarget> 1.441 + CreateOptimalDrawTarget(const IntSize &aSize, 1.442 + SurfaceFormat imageFormat); 1.443 + 1.444 + /** 1.445 + * Creates a DrawTarget for alpha masks which is optimized for inter- 1.446 + * operating with this layer manager. In contrast to CreateOptimalDrawTarget, 1.447 + * this surface is optimised for drawing alpha only and we assume that 1.448 + * drawing the mask is fairly simple. 1.449 + */ 1.450 + virtual TemporaryRef<DrawTarget> 1.451 + CreateOptimalMaskDrawTarget(const IntSize &aSize); 1.452 + 1.453 + /** 1.454 + * Creates a DrawTarget for use with canvas which is optimized for 1.455 + * inter-operating with this layermanager. 1.456 + */ 1.457 + virtual TemporaryRef<mozilla::gfx::DrawTarget> 1.458 + CreateDrawTarget(const mozilla::gfx::IntSize &aSize, 1.459 + mozilla::gfx::SurfaceFormat aFormat); 1.460 + 1.461 + virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) { return true; } 1.462 + 1.463 + /** 1.464 + * returns the maximum texture size on this layer backend, or INT32_MAX 1.465 + * if there is no maximum 1.466 + */ 1.467 + virtual int32_t GetMaxTextureSize() const = 0; 1.468 + 1.469 + /** 1.470 + * Return the name of the layer manager's backend. 1.471 + */ 1.472 + virtual void GetBackendName(nsAString& aName) = 0; 1.473 + 1.474 + /** 1.475 + * This setter can be used anytime. The user data for all keys is 1.476 + * initially null. Ownership pases to the layer manager. 1.477 + */ 1.478 + void SetUserData(void* aKey, LayerUserData* aData) 1.479 + { 1.480 + mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy); 1.481 + } 1.482 + /** 1.483 + * This can be used anytime. Ownership passes to the caller! 1.484 + */ 1.485 + nsAutoPtr<LayerUserData> RemoveUserData(void* aKey) 1.486 + { 1.487 + nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey)))); 1.488 + return d; 1.489 + } 1.490 + /** 1.491 + * This getter can be used anytime. 1.492 + */ 1.493 + bool HasUserData(void* aKey) 1.494 + { 1.495 + return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey)); 1.496 + } 1.497 + /** 1.498 + * This getter can be used anytime. Ownership is retained by the layer 1.499 + * manager. 1.500 + */ 1.501 + LayerUserData* GetUserData(void* aKey) const 1.502 + { 1.503 + return static_cast<LayerUserData*>(mUserData.Get(static_cast<gfx::UserDataKey*>(aKey))); 1.504 + } 1.505 + 1.506 + /** 1.507 + * Must be called outside of a layers transaction. 1.508 + * 1.509 + * For the subtree rooted at |aSubtree|, this attempts to free up 1.510 + * any free-able resources like retained buffers, but may do nothing 1.511 + * at all. After this call, the layer tree is left in an undefined 1.512 + * state; the layers in |aSubtree|'s subtree may no longer have 1.513 + * buffers with valid content and may no longer be able to draw 1.514 + * their visible and valid regions. 1.515 + * 1.516 + * In general, a painting or forwarding transaction on |this| must 1.517 + * complete on the tree before it returns to a valid state. 1.518 + * 1.519 + * Resource freeing begins from |aSubtree| or |mRoot| if |aSubtree| 1.520 + * is null. |aSubtree|'s manager must be this. 1.521 + */ 1.522 + virtual void ClearCachedResources(Layer* aSubtree = nullptr) {} 1.523 + 1.524 + /** 1.525 + * Flag the next paint as the first for a document. 1.526 + */ 1.527 + virtual void SetIsFirstPaint() {} 1.528 + 1.529 + /** 1.530 + * Make sure that the previous transaction has been entirely 1.531 + * completed. 1.532 + * 1.533 + * Note: This may sychronously wait on a remote compositor 1.534 + * to complete rendering. 1.535 + */ 1.536 + virtual void FlushRendering() { } 1.537 + 1.538 + /** 1.539 + * Checks if we need to invalidate the OS widget to trigger 1.540 + * painting when updating this layer manager. 1.541 + */ 1.542 + virtual bool NeedsWidgetInvalidation() { return true; } 1.543 + 1.544 + virtual const char* Name() const { return "???"; } 1.545 + 1.546 + /** 1.547 + * Dump information about this layer manager and its managed tree to 1.548 + * aFile, which defaults to stderr. 1.549 + */ 1.550 + void Dump(FILE* aFile=nullptr, const char* aPrefix="", bool aDumpHtml=false); 1.551 + /** 1.552 + * Dump information about just this layer manager itself to aFile, 1.553 + * which defaults to stderr. 1.554 + */ 1.555 + void DumpSelf(FILE* aFile=nullptr, const char* aPrefix=""); 1.556 + 1.557 + /** 1.558 + * Log information about this layer manager and its managed tree to 1.559 + * the NSPR log (if enabled for "Layers"). 1.560 + */ 1.561 + void Log(const char* aPrefix=""); 1.562 + /** 1.563 + * Log information about just this layer manager itself to the NSPR 1.564 + * log (if enabled for "Layers"). 1.565 + */ 1.566 + void LogSelf(const char* aPrefix=""); 1.567 + 1.568 + /** 1.569 + * Record (and return) frame-intervals and paint-times for frames which were presented 1.570 + * between calling StartFrameTimeRecording and StopFrameTimeRecording. 1.571 + * 1.572 + * - Uses a cyclic buffer and serves concurrent consumers, so if Stop is called too late 1.573 + * (elements were overwritten since Start), result is considered invalid and hence empty. 1.574 + * - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were less frequent). 1.575 + * Can be changed (up to 1 hour) via pref: toolkit.framesRecording.bufferSize. 1.576 + * - Note: the first frame-interval may be longer than expected because last frame 1.577 + * might have been presented some time before calling StartFrameTimeRecording. 1.578 + */ 1.579 + 1.580 + /** 1.581 + * Returns a handle which represents current recording start position. 1.582 + */ 1.583 + virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize); 1.584 + 1.585 + /** 1.586 + * Clears, then populates aFrameIntervals with the recorded frame timing 1.587 + * data. The array will be empty if data was overwritten since 1.588 + * aStartIndex was obtained. 1.589 + */ 1.590 + virtual void StopFrameTimeRecording(uint32_t aStartIndex, 1.591 + nsTArray<float>& aFrameIntervals); 1.592 + 1.593 + void RecordFrame(); 1.594 + void PostPresent(); 1.595 + 1.596 + void BeginTabSwitch(); 1.597 + 1.598 + static bool IsLogEnabled(); 1.599 + static PRLogModuleInfo* GetLog() { return sLog; } 1.600 + 1.601 + bool IsCompositingCheap(LayersBackend aBackend) 1.602 + { 1.603 + // LayersBackend::LAYERS_NONE is an error state, but in that case we should try to 1.604 + // avoid loading the compositor! 1.605 + return LayersBackend::LAYERS_BASIC != aBackend && LayersBackend::LAYERS_NONE != aBackend; 1.606 + } 1.607 + 1.608 + virtual bool IsCompositingCheap() { return true; } 1.609 + 1.610 + bool IsInTransaction() const { return mInTransaction; } 1.611 + 1.612 + virtual void SetRegionToClear(const nsIntRegion& aRegion) 1.613 + { 1.614 + mRegionToClear = aRegion; 1.615 + } 1.616 + 1.617 +protected: 1.618 + nsRefPtr<Layer> mRoot; 1.619 + gfx::UserData mUserData; 1.620 + bool mDestroyed; 1.621 + bool mSnapEffectiveTransforms; 1.622 + 1.623 + nsIntRegion mRegionToClear; 1.624 + 1.625 + // Protected destructor, to discourage deletion outside of Release(): 1.626 + virtual ~LayerManager() {} 1.627 + 1.628 + // Print interesting information about this into aTo. Internally 1.629 + // used to implement Dump*() and Log*(). 1.630 + virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); 1.631 + 1.632 + static void InitLog(); 1.633 + static PRLogModuleInfo* sLog; 1.634 + uint64_t mId; 1.635 + bool mInTransaction; 1.636 +private: 1.637 + struct FramesTimingRecording 1.638 + { 1.639 + // Stores state and data for frame intervals and paint times recording. 1.640 + // see LayerManager::StartFrameTimeRecording() at Layers.cpp for more details. 1.641 + FramesTimingRecording() 1.642 + : mIsPaused(true) 1.643 + , mNextIndex(0) 1.644 + {} 1.645 + bool mIsPaused; 1.646 + uint32_t mNextIndex; 1.647 + TimeStamp mLastFrameTime; 1.648 + nsTArray<float> mIntervals; 1.649 + uint32_t mLatestStartIndex; 1.650 + uint32_t mCurrentRunStartIndex; 1.651 + }; 1.652 + FramesTimingRecording mRecording; 1.653 + 1.654 + TimeStamp mTabSwitchStart; 1.655 +}; 1.656 + 1.657 +typedef InfallibleTArray<Animation> AnimationArray; 1.658 + 1.659 +struct AnimData { 1.660 + InfallibleTArray<nsStyleAnimation::Value> mStartValues; 1.661 + InfallibleTArray<nsStyleAnimation::Value> mEndValues; 1.662 + InfallibleTArray<nsAutoPtr<mozilla::css::ComputedTimingFunction> > mFunctions; 1.663 +}; 1.664 + 1.665 +/** 1.666 + * A Layer represents anything that can be rendered onto a destination 1.667 + * surface. 1.668 + */ 1.669 +class Layer { 1.670 + NS_INLINE_DECL_REFCOUNTING(Layer) 1.671 + 1.672 +public: 1.673 + // Keep these in alphabetical order 1.674 + enum LayerType { 1.675 + TYPE_CANVAS, 1.676 + TYPE_COLOR, 1.677 + TYPE_CONTAINER, 1.678 + TYPE_IMAGE, 1.679 + TYPE_READBACK, 1.680 + TYPE_REF, 1.681 + TYPE_SHADOW, 1.682 + TYPE_THEBES 1.683 + }; 1.684 + 1.685 + /** 1.686 + * Returns the LayerManager this Layer belongs to. Note that the layer 1.687 + * manager might be in a destroyed state, at which point it's only 1.688 + * valid to set/get user data from it. 1.689 + */ 1.690 + LayerManager* Manager() { return mManager; } 1.691 + 1.692 + enum { 1.693 + /** 1.694 + * If this is set, the caller is promising that by the end of this 1.695 + * transaction the entire visible region (as specified by 1.696 + * SetVisibleRegion) will be filled with opaque content. 1.697 + */ 1.698 + CONTENT_OPAQUE = 0x01, 1.699 + /** 1.700 + * If this is set, the caller is notifying that the contents of this layer 1.701 + * require per-component alpha for optimal fidelity. However, there is no 1.702 + * guarantee that component alpha will be supported for this layer at 1.703 + * paint time. 1.704 + * This should never be set at the same time as CONTENT_OPAQUE. 1.705 + */ 1.706 + CONTENT_COMPONENT_ALPHA = 0x02, 1.707 + 1.708 + /** 1.709 + * If this is set then this layer is part of a preserve-3d group, and should 1.710 + * be sorted with sibling layers that are also part of the same group. 1.711 + */ 1.712 + CONTENT_PRESERVE_3D = 0x04, 1.713 + /** 1.714 + * This indicates that the transform may be changed on during an empty 1.715 + * transaction where there is no possibility of redrawing the content, so the 1.716 + * implementation should be ready for that. 1.717 + */ 1.718 + CONTENT_MAY_CHANGE_TRANSFORM = 0x08, 1.719 + 1.720 + /** 1.721 + * Disable subpixel AA for this layer. This is used if the display isn't suited 1.722 + * for subpixel AA like hidpi or rotated content. 1.723 + */ 1.724 + CONTENT_DISABLE_SUBPIXEL_AA = 0x10 1.725 + }; 1.726 + /** 1.727 + * CONSTRUCTION PHASE ONLY 1.728 + * This lets layout make some promises about what will be drawn into the 1.729 + * visible region of the ThebesLayer. This enables internal quality 1.730 + * and performance optimizations. 1.731 + */ 1.732 + void SetContentFlags(uint32_t aFlags) 1.733 + { 1.734 + NS_ASSERTION((aFlags & (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA)) != 1.735 + (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA), 1.736 + "Can't be opaque and require component alpha"); 1.737 + if (mContentFlags != aFlags) { 1.738 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ContentFlags", this)); 1.739 + mContentFlags = aFlags; 1.740 + Mutated(); 1.741 + } 1.742 + } 1.743 + /** 1.744 + * CONSTRUCTION PHASE ONLY 1.745 + * Tell this layer which region will be visible. The visible region 1.746 + * is a region which contains all the contents of the layer that can 1.747 + * actually affect the rendering of the window. It can exclude areas 1.748 + * that are covered by opaque contents of other layers, and it can 1.749 + * exclude areas where this layer simply contains no content at all. 1.750 + * (This can be an overapproximation to the "true" visible region.) 1.751 + * 1.752 + * There is no general guarantee that drawing outside the bounds of the 1.753 + * visible region will be ignored. So if a layer draws outside the bounds 1.754 + * of its visible region, it needs to ensure that what it draws is valid. 1.755 + */ 1.756 + virtual void SetVisibleRegion(const nsIntRegion& aRegion) 1.757 + { 1.758 + if (!mVisibleRegion.IsEqual(aRegion)) { 1.759 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) VisibleRegion was %s is %s", this, 1.760 + mVisibleRegion.ToString().get(), aRegion.ToString().get())); 1.761 + mVisibleRegion = aRegion; 1.762 + Mutated(); 1.763 + } 1.764 + } 1.765 + 1.766 + /* 1.767 + * Compositor event handling 1.768 + * ========================= 1.769 + * When a touch-start event (or similar) is sent to the AsyncPanZoomController, 1.770 + * it needs to decide whether the event should be sent to the main thread. 1.771 + * Each layer has a list of event handling regions. When the compositor needs 1.772 + * to determine how to handle a touch event, it scans the layer tree from top 1.773 + * to bottom in z-order (traversing children before their parents). Points 1.774 + * outside the clip region for a layer cause that layer (and its subtree) 1.775 + * to be ignored. If a layer has a mask layer, and that mask layer's alpha 1.776 + * value is zero at the event point, then the layer and its subtree should 1.777 + * be ignored. 1.778 + * For each layer, if the point is outside its hit region, we ignore the layer 1.779 + * and move onto the next. If the point is inside its hit region but 1.780 + * outside the dispatch-to-content region, we can initiate a gesture without 1.781 + * consulting the content thread. Otherwise we must dispatch the event to 1.782 + * content. 1.783 + */ 1.784 + /** 1.785 + * CONSTRUCTION PHASE ONLY 1.786 + * Set the event handling region. 1.787 + */ 1.788 + void SetEventRegions(const EventRegions& aRegions) 1.789 + { 1.790 + if (mEventRegions != aRegions) { 1.791 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) eventregions were %s, now %s", this, 1.792 + mEventRegions.ToString().get(), aRegions.ToString().get())); 1.793 + mEventRegions = aRegions; 1.794 + Mutated(); 1.795 + } 1.796 + } 1.797 + 1.798 + /** 1.799 + * CONSTRUCTION PHASE ONLY 1.800 + * Set the opacity which will be applied to this layer as it 1.801 + * is composited to the destination. 1.802 + */ 1.803 + void SetOpacity(float aOpacity) 1.804 + { 1.805 + if (mOpacity != aOpacity) { 1.806 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Opacity", this)); 1.807 + mOpacity = aOpacity; 1.808 + Mutated(); 1.809 + } 1.810 + } 1.811 + 1.812 + void SetMixBlendMode(gfx::CompositionOp aMixBlendMode) 1.813 + { 1.814 + if (mMixBlendMode != aMixBlendMode) { 1.815 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MixBlendMode", this)); 1.816 + mMixBlendMode = aMixBlendMode; 1.817 + Mutated(); 1.818 + } 1.819 + } 1.820 + 1.821 + void DeprecatedSetMixBlendMode(gfxContext::GraphicsOperator aMixBlendMode) 1.822 + { 1.823 + SetMixBlendMode(gfx::CompositionOpForOp(aMixBlendMode)); 1.824 + } 1.825 + 1.826 + void SetForceIsolatedGroup(bool aForceIsolatedGroup) 1.827 + { 1.828 + if(mForceIsolatedGroup != aForceIsolatedGroup) { 1.829 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ForceIsolatedGroup", this)); 1.830 + mForceIsolatedGroup = aForceIsolatedGroup; 1.831 + Mutated(); 1.832 + } 1.833 + } 1.834 + 1.835 + bool GetForceIsolatedGroup() const 1.836 + { 1.837 + return mForceIsolatedGroup; 1.838 + } 1.839 + 1.840 + /** 1.841 + * CONSTRUCTION PHASE ONLY 1.842 + * Set a clip rect which will be applied to this layer as it is 1.843 + * composited to the destination. The coordinates are relative to 1.844 + * the parent layer (i.e. the contents of this layer 1.845 + * are transformed before this clip rect is applied). 1.846 + * For the root layer, the coordinates are relative to the widget, 1.847 + * in device pixels. 1.848 + * If aRect is null no clipping will be performed. 1.849 + */ 1.850 + void SetClipRect(const nsIntRect* aRect) 1.851 + { 1.852 + if (mUseClipRect) { 1.853 + if (!aRect) { 1.854 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is <none>", this, 1.855 + mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height)); 1.856 + mUseClipRect = false; 1.857 + Mutated(); 1.858 + } else { 1.859 + if (!aRect->IsEqualEdges(mClipRect)) { 1.860 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is %d,%d,%d,%d", this, 1.861 + mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height, 1.862 + aRect->x, aRect->y, aRect->width, aRect->height)); 1.863 + mClipRect = *aRect; 1.864 + Mutated(); 1.865 + } 1.866 + } 1.867 + } else { 1.868 + if (aRect) { 1.869 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was <none> is %d,%d,%d,%d", this, 1.870 + aRect->x, aRect->y, aRect->width, aRect->height)); 1.871 + mUseClipRect = true; 1.872 + mClipRect = *aRect; 1.873 + Mutated(); 1.874 + } 1.875 + } 1.876 + } 1.877 + 1.878 + /** 1.879 + * CONSTRUCTION PHASE ONLY 1.880 + * Set a layer to mask this layer. 1.881 + * 1.882 + * The mask layer should be applied using its effective transform (after it 1.883 + * is calculated by ComputeEffectiveTransformForMaskLayer), this should use 1.884 + * this layer's parent's transform and the mask layer's transform, but not 1.885 + * this layer's. That is, the mask layer is specified relative to this layer's 1.886 + * position in it's parent layer's coord space. 1.887 + * Currently, only 2D translations are supported for the mask layer transform. 1.888 + * 1.889 + * Ownership of aMaskLayer passes to this. 1.890 + * Typical use would be an ImageLayer with an alpha image used for masking. 1.891 + * See also ContainerState::BuildMaskLayer in FrameLayerBuilder.cpp. 1.892 + */ 1.893 + void SetMaskLayer(Layer* aMaskLayer) 1.894 + { 1.895 +#ifdef DEBUG 1.896 + if (aMaskLayer) { 1.897 + bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D(); 1.898 + NS_ASSERTION(maskIs2D, "Mask layer has invalid transform."); 1.899 + } 1.900 +#endif 1.901 + 1.902 + if (mMaskLayer != aMaskLayer) { 1.903 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MaskLayer", this)); 1.904 + mMaskLayer = aMaskLayer; 1.905 + Mutated(); 1.906 + } 1.907 + } 1.908 + 1.909 + /** 1.910 + * CONSTRUCTION PHASE ONLY 1.911 + * Tell this layer what its transform should be. The transformation 1.912 + * is applied when compositing the layer into its parent container. 1.913 + */ 1.914 + void SetBaseTransform(const gfx::Matrix4x4& aMatrix) 1.915 + { 1.916 + NS_ASSERTION(!aMatrix.IsSingular(), 1.917 + "Shouldn't be trying to draw with a singular matrix!"); 1.918 + mPendingTransform = nullptr; 1.919 + if (mTransform == aMatrix) { 1.920 + return; 1.921 + } 1.922 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) BaseTransform", this)); 1.923 + mTransform = aMatrix; 1.924 + Mutated(); 1.925 + } 1.926 + 1.927 + /** 1.928 + * Can be called at any time. 1.929 + * 1.930 + * Like SetBaseTransform(), but can be called before the next 1.931 + * transform (i.e. outside an open transaction). Semantically, this 1.932 + * method enqueues a new transform value to be set immediately after 1.933 + * the next transaction is opened. 1.934 + */ 1.935 + void SetBaseTransformForNextTransaction(const gfx::Matrix4x4& aMatrix) 1.936 + { 1.937 + mPendingTransform = new gfx::Matrix4x4(aMatrix); 1.938 + } 1.939 + 1.940 + void SetPostScale(float aXScale, float aYScale) 1.941 + { 1.942 + if (mPostXScale == aXScale && mPostYScale == aYScale) { 1.943 + return; 1.944 + } 1.945 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PostScale", this)); 1.946 + mPostXScale = aXScale; 1.947 + mPostYScale = aYScale; 1.948 + Mutated(); 1.949 + } 1.950 + 1.951 + /** 1.952 + * CONSTRUCTION PHASE ONLY 1.953 + * A layer is "fixed position" when it draws content from a content 1.954 + * (not chrome) document, the topmost content document has a root scrollframe 1.955 + * with a displayport, but the layer does not move when that displayport scrolls. 1.956 + */ 1.957 + void SetIsFixedPosition(bool aFixedPosition) 1.958 + { 1.959 + if (mIsFixedPosition != aFixedPosition) { 1.960 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) IsFixedPosition", this)); 1.961 + mIsFixedPosition = aFixedPosition; 1.962 + Mutated(); 1.963 + } 1.964 + } 1.965 + 1.966 + // Call AddAnimation to add a new animation to this layer from layout code. 1.967 + // Caller must fill in all the properties of the returned animation. 1.968 + Animation* AddAnimation(); 1.969 + // ClearAnimations clears animations on this layer. 1.970 + void ClearAnimations(); 1.971 + // This is only called when the layer tree is updated. Do not call this from 1.972 + // layout code. To add an animation to this layer, use AddAnimation. 1.973 + void SetAnimations(const AnimationArray& aAnimations); 1.974 + 1.975 + // These are a parallel to AddAnimation and clearAnimations, except 1.976 + // they add pending animations that apply only when the next 1.977 + // transaction is begun. (See also 1.978 + // SetBaseTransformForNextTransaction.) 1.979 + Animation* AddAnimationForNextTransaction(); 1.980 + void ClearAnimationsForNextTransaction(); 1.981 + 1.982 + /** 1.983 + * CONSTRUCTION PHASE ONLY 1.984 + * If a layer is "fixed position", this determines which point on the layer 1.985 + * is considered the "anchor" point, that is, the point which remains in the 1.986 + * same position when compositing the layer tree with a transformation 1.987 + * (such as when asynchronously scrolling and zooming). 1.988 + */ 1.989 + void SetFixedPositionAnchor(const LayerPoint& aAnchor) 1.990 + { 1.991 + if (mAnchor != aAnchor) { 1.992 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionAnchor", this)); 1.993 + mAnchor = aAnchor; 1.994 + Mutated(); 1.995 + } 1.996 + } 1.997 + 1.998 + /** 1.999 + * CONSTRUCTION PHASE ONLY 1.1000 + * If a layer represents a fixed position element or elements that are on 1.1001 + * a document that has had fixed position element margins set on it, these 1.1002 + * will be mirrored here. This allows for asynchronous animation of the 1.1003 + * margins by reconciling the difference between this value and a value that 1.1004 + * is updated more frequently. 1.1005 + * If the left or top margins are negative, it means that the elements this 1.1006 + * layer represents are auto-positioned, and so fixed position margins should 1.1007 + * not have an effect on the corresponding axis. 1.1008 + */ 1.1009 + void SetFixedPositionMargins(const LayerMargin& aMargins) 1.1010 + { 1.1011 + if (mMargins != aMargins) { 1.1012 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionMargins", this)); 1.1013 + mMargins = aMargins; 1.1014 + Mutated(); 1.1015 + } 1.1016 + } 1.1017 + 1.1018 + /** 1.1019 + * CONSTRUCTION PHASE ONLY 1.1020 + * If a layer is "sticky position", |aScrollId| holds the scroll identifier 1.1021 + * of the scrollable content that contains it. The difference between the two 1.1022 + * rectangles |aOuter| and |aInner| is treated as two intervals in each 1.1023 + * dimension, with the current scroll position at the origin. For each 1.1024 + * dimension, while that component of the scroll position lies within either 1.1025 + * interval, the layer should not move relative to its scrolling container. 1.1026 + */ 1.1027 + void SetStickyPositionData(FrameMetrics::ViewID aScrollId, LayerRect aOuter, 1.1028 + LayerRect aInner) 1.1029 + { 1.1030 + if (!mStickyPositionData || 1.1031 + !mStickyPositionData->mOuter.IsEqualEdges(aOuter) || 1.1032 + !mStickyPositionData->mInner.IsEqualEdges(aInner)) { 1.1033 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) StickyPositionData", this)); 1.1034 + if (!mStickyPositionData) { 1.1035 + mStickyPositionData = new StickyPositionData; 1.1036 + } 1.1037 + mStickyPositionData->mScrollId = aScrollId; 1.1038 + mStickyPositionData->mOuter = aOuter; 1.1039 + mStickyPositionData->mInner = aInner; 1.1040 + Mutated(); 1.1041 + } 1.1042 + } 1.1043 + 1.1044 + enum ScrollDirection { 1.1045 + NONE, 1.1046 + VERTICAL, 1.1047 + HORIZONTAL 1.1048 + }; 1.1049 + 1.1050 + /** 1.1051 + * CONSTRUCTION PHASE ONLY 1.1052 + * If a layer is a scrollbar layer, |aScrollId| holds the scroll identifier 1.1053 + * of the scrollable content that the scrollbar is for. 1.1054 + */ 1.1055 + void SetScrollbarData(FrameMetrics::ViewID aScrollId, ScrollDirection aDir) 1.1056 + { 1.1057 + if (mScrollbarTargetId != aScrollId || 1.1058 + mScrollbarDirection != aDir) { 1.1059 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this)); 1.1060 + mScrollbarTargetId = aScrollId; 1.1061 + mScrollbarDirection = aDir; 1.1062 + Mutated(); 1.1063 + } 1.1064 + } 1.1065 + 1.1066 + // These getters can be used anytime. 1.1067 + float GetOpacity() { return mOpacity; } 1.1068 + gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; } 1.1069 + const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; } 1.1070 + uint32_t GetContentFlags() { return mContentFlags; } 1.1071 + const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; } 1.1072 + const EventRegions& GetEventRegions() const { return mEventRegions; } 1.1073 + ContainerLayer* GetParent() { return mParent; } 1.1074 + Layer* GetNextSibling() { return mNextSibling; } 1.1075 + const Layer* GetNextSibling() const { return mNextSibling; } 1.1076 + Layer* GetPrevSibling() { return mPrevSibling; } 1.1077 + const Layer* GetPrevSibling() const { return mPrevSibling; } 1.1078 + virtual Layer* GetFirstChild() const { return nullptr; } 1.1079 + virtual Layer* GetLastChild() const { return nullptr; } 1.1080 + const gfx::Matrix4x4 GetTransform() const; 1.1081 + const gfx::Matrix4x4& GetBaseTransform() const { return mTransform; } 1.1082 + float GetPostXScale() const { return mPostXScale; } 1.1083 + float GetPostYScale() const { return mPostYScale; } 1.1084 + bool GetIsFixedPosition() { return mIsFixedPosition; } 1.1085 + bool GetIsStickyPosition() { return mStickyPositionData; } 1.1086 + LayerPoint GetFixedPositionAnchor() { return mAnchor; } 1.1087 + const LayerMargin& GetFixedPositionMargins() { return mMargins; } 1.1088 + FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; } 1.1089 + const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; } 1.1090 + const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; } 1.1091 + FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; } 1.1092 + ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; } 1.1093 + Layer* GetMaskLayer() const { return mMaskLayer; } 1.1094 + 1.1095 + // Note that all lengths in animation data are either in CSS pixels or app 1.1096 + // units and must be converted to device pixels by the compositor. 1.1097 + AnimationArray& GetAnimations() { return mAnimations; } 1.1098 + InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; } 1.1099 + 1.1100 + uint64_t GetAnimationGeneration() { return mAnimationGeneration; } 1.1101 + void SetAnimationGeneration(uint64_t aCount) { mAnimationGeneration = aCount; } 1.1102 + 1.1103 + /** 1.1104 + * Returns the local transform for this layer: either mTransform or, 1.1105 + * for shadow layers, GetShadowTransform() 1.1106 + */ 1.1107 + const gfx::Matrix4x4 GetLocalTransform(); 1.1108 + 1.1109 + /** 1.1110 + * Returns the local opacity for this layer: either mOpacity or, 1.1111 + * for shadow layers, GetShadowOpacity() 1.1112 + */ 1.1113 + const float GetLocalOpacity(); 1.1114 + 1.1115 + /** 1.1116 + * DRAWING PHASE ONLY 1.1117 + * 1.1118 + * Apply pending changes to layers before drawing them, if those 1.1119 + * pending changes haven't been overridden by later changes. 1.1120 + */ 1.1121 + void ApplyPendingUpdatesToSubtree(); 1.1122 + 1.1123 + /** 1.1124 + * DRAWING PHASE ONLY 1.1125 + * 1.1126 + * Write layer-subtype-specific attributes into aAttrs. Used to 1.1127 + * synchronize layer attributes to their shadows'. 1.1128 + */ 1.1129 + virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) { } 1.1130 + 1.1131 + // Returns true if it's OK to save the contents of aLayer in an 1.1132 + // opaque surface (a surface without an alpha channel). 1.1133 + // If we can use a surface without an alpha channel, we should, because 1.1134 + // it will often make painting of antialiased text faster and higher 1.1135 + // quality. 1.1136 + bool CanUseOpaqueSurface(); 1.1137 + 1.1138 + SurfaceMode GetSurfaceMode() 1.1139 + { 1.1140 + if (CanUseOpaqueSurface()) 1.1141 + return SurfaceMode::SURFACE_OPAQUE; 1.1142 + if (mContentFlags & CONTENT_COMPONENT_ALPHA) 1.1143 + return SurfaceMode::SURFACE_COMPONENT_ALPHA; 1.1144 + return SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA; 1.1145 + } 1.1146 + 1.1147 + /** 1.1148 + * This setter can be used anytime. The user data for all keys is 1.1149 + * initially null. Ownership pases to the layer manager. 1.1150 + */ 1.1151 + void SetUserData(void* aKey, LayerUserData* aData) 1.1152 + { 1.1153 + mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy); 1.1154 + } 1.1155 + /** 1.1156 + * This can be used anytime. Ownership passes to the caller! 1.1157 + */ 1.1158 + nsAutoPtr<LayerUserData> RemoveUserData(void* aKey) 1.1159 + { 1.1160 + nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey)))); 1.1161 + return d; 1.1162 + } 1.1163 + /** 1.1164 + * This getter can be used anytime. 1.1165 + */ 1.1166 + bool HasUserData(void* aKey) 1.1167 + { 1.1168 + return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey)); 1.1169 + } 1.1170 + /** 1.1171 + * This getter can be used anytime. Ownership is retained by the layer 1.1172 + * manager. 1.1173 + */ 1.1174 + LayerUserData* GetUserData(void* aKey) const 1.1175 + { 1.1176 + return static_cast<LayerUserData*>(mUserData.Get(static_cast<gfx::UserDataKey*>(aKey))); 1.1177 + } 1.1178 + 1.1179 + /** 1.1180 + * |Disconnect()| is used by layers hooked up over IPC. It may be 1.1181 + * called at any time, and may not be called at all. Using an 1.1182 + * IPC-enabled layer after Destroy() (drawing etc.) results in a 1.1183 + * safe no-op; no crashy or uaf etc. 1.1184 + * 1.1185 + * XXX: this interface is essentially LayerManager::Destroy, but at 1.1186 + * Layer granularity. It might be beneficial to unify them. 1.1187 + */ 1.1188 + virtual void Disconnect() {} 1.1189 + 1.1190 + /** 1.1191 + * Dynamic downcast to a Thebes layer. Returns null if this is not 1.1192 + * a ThebesLayer. 1.1193 + */ 1.1194 + virtual ThebesLayer* AsThebesLayer() { return nullptr; } 1.1195 + 1.1196 + /** 1.1197 + * Dynamic cast to a ContainerLayer. Returns null if this is not 1.1198 + * a ContainerLayer. 1.1199 + */ 1.1200 + virtual ContainerLayer* AsContainerLayer() { return nullptr; } 1.1201 + virtual const ContainerLayer* AsContainerLayer() const { return nullptr; } 1.1202 + 1.1203 + /** 1.1204 + * Dynamic cast to a RefLayer. Returns null if this is not a 1.1205 + * RefLayer. 1.1206 + */ 1.1207 + virtual RefLayer* AsRefLayer() { return nullptr; } 1.1208 + 1.1209 + /** 1.1210 + * Dynamic cast to a Color. Returns null if this is not a 1.1211 + * ColorLayer. 1.1212 + */ 1.1213 + virtual ColorLayer* AsColorLayer() { return nullptr; } 1.1214 + 1.1215 + /** 1.1216 + * Dynamic cast to a LayerComposite. Return null if this is not a 1.1217 + * LayerComposite. Can be used anytime. 1.1218 + */ 1.1219 + virtual LayerComposite* AsLayerComposite() { return nullptr; } 1.1220 + 1.1221 + /** 1.1222 + * Dynamic cast to a ShadowableLayer. Return null if this is not a 1.1223 + * ShadowableLayer. Can be used anytime. 1.1224 + */ 1.1225 + virtual ShadowableLayer* AsShadowableLayer() { return nullptr; } 1.1226 + 1.1227 + // These getters can be used anytime. They return the effective 1.1228 + // values that should be used when drawing this layer to screen, 1.1229 + // accounting for this layer possibly being a shadow. 1.1230 + const nsIntRect* GetEffectiveClipRect(); 1.1231 + const nsIntRegion& GetEffectiveVisibleRegion(); 1.1232 + 1.1233 + /** 1.1234 + * Returns the product of the opacities of this layer and all ancestors up 1.1235 + * to and excluding the nearest ancestor that has UseIntermediateSurface() set. 1.1236 + */ 1.1237 + float GetEffectiveOpacity(); 1.1238 + 1.1239 + /** 1.1240 + * Returns the blendmode of this layer. 1.1241 + */ 1.1242 + gfx::CompositionOp GetEffectiveMixBlendMode(); 1.1243 + gfxContext::GraphicsOperator DeprecatedGetEffectiveMixBlendMode(); 1.1244 + 1.1245 + /** 1.1246 + * This returns the effective transform computed by 1.1247 + * ComputeEffectiveTransforms. Typically this is a transform that transforms 1.1248 + * this layer all the way to some intermediate surface or destination 1.1249 + * surface. For non-BasicLayers this will be a transform to the nearest 1.1250 + * ancestor with UseIntermediateSurface() (or to the root, if there is no 1.1251 + * such ancestor), but for BasicLayers it's different. 1.1252 + */ 1.1253 + const gfx::Matrix4x4& GetEffectiveTransform() const { return mEffectiveTransform; } 1.1254 + 1.1255 + /** 1.1256 + * @param aTransformToSurface the composition of the transforms 1.1257 + * from the parent layer (if any) to the destination pixel grid. 1.1258 + * 1.1259 + * Computes mEffectiveTransform for this layer and all its descendants. 1.1260 + * mEffectiveTransform transforms this layer up to the destination 1.1261 + * pixel grid (whatever aTransformToSurface is relative to). 1.1262 + * 1.1263 + * We promise that when this is called on a layer, all ancestor layers 1.1264 + * have already had ComputeEffectiveTransforms called. 1.1265 + */ 1.1266 + virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) = 0; 1.1267 + 1.1268 + /** 1.1269 + * computes the effective transform for a mask layer, if this layer has one 1.1270 + */ 1.1271 + void ComputeEffectiveTransformForMaskLayer(const gfx::Matrix4x4& aTransformToSurface); 1.1272 + 1.1273 + /** 1.1274 + * Calculate the scissor rect required when rendering this layer. 1.1275 + * Returns a rectangle relative to the intermediate surface belonging to the 1.1276 + * nearest ancestor that has an intermediate surface, or relative to the root 1.1277 + * viewport if no ancestor has an intermediate surface, corresponding to the 1.1278 + * clip rect for this layer intersected with aCurrentScissorRect. 1.1279 + * If no ancestor has an intermediate surface, the clip rect is transformed 1.1280 + * by aWorldTransform before being combined with aCurrentScissorRect, if 1.1281 + * aWorldTransform is non-null. 1.1282 + */ 1.1283 + nsIntRect CalculateScissorRect(const nsIntRect& aCurrentScissorRect, 1.1284 + const gfx::Matrix* aWorldTransform); 1.1285 + 1.1286 + virtual const char* Name() const =0; 1.1287 + virtual LayerType GetType() const =0; 1.1288 + 1.1289 + /** 1.1290 + * Only the implementation should call this. This is per-implementation 1.1291 + * private data. Normally, all layers with a given layer manager 1.1292 + * use the same type of ImplData. 1.1293 + */ 1.1294 + void* ImplData() { return mImplData; } 1.1295 + 1.1296 + /** 1.1297 + * Only the implementation should use these methods. 1.1298 + */ 1.1299 + void SetParent(ContainerLayer* aParent) { mParent = aParent; } 1.1300 + void SetNextSibling(Layer* aSibling) { mNextSibling = aSibling; } 1.1301 + void SetPrevSibling(Layer* aSibling) { mPrevSibling = aSibling; } 1.1302 + 1.1303 + /** 1.1304 + * Dump information about this layer manager and its managed tree to 1.1305 + * aFile, which defaults to stderr. 1.1306 + */ 1.1307 + void Dump(FILE* aFile=nullptr, const char* aPrefix="", bool aDumpHtml=false); 1.1308 + /** 1.1309 + * Dump information about just this layer manager itself to aFile, 1.1310 + * which defaults to stderr. 1.1311 + */ 1.1312 + void DumpSelf(FILE* aFile=nullptr, const char* aPrefix=""); 1.1313 + 1.1314 + /** 1.1315 + * Log information about this layer manager and its managed tree to 1.1316 + * the NSPR log (if enabled for "Layers"). 1.1317 + */ 1.1318 + void Log(const char* aPrefix=""); 1.1319 + /** 1.1320 + * Log information about just this layer manager itself to the NSPR 1.1321 + * log (if enabled for "Layers"). 1.1322 + */ 1.1323 + void LogSelf(const char* aPrefix=""); 1.1324 + 1.1325 + // Print interesting information about this into aTo. Internally 1.1326 + // used to implement Dump*() and Log*(). If subclasses have 1.1327 + // additional interesting properties, they should override this with 1.1328 + // an implementation that first calls the base implementation then 1.1329 + // appends additional info to aTo. 1.1330 + virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); 1.1331 + 1.1332 + static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); } 1.1333 + 1.1334 + /** 1.1335 + * Returns the current area of the layer (in layer-space coordinates) 1.1336 + * marked as needed to be recomposited. 1.1337 + */ 1.1338 + const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; } 1.1339 + const void SetInvalidRegion(const nsIntRegion& aRect) { mInvalidRegion = aRect; } 1.1340 + 1.1341 + /** 1.1342 + * Mark the entirety of the layer's visible region as being invalid. 1.1343 + */ 1.1344 + void SetInvalidRectToVisibleRegion() { mInvalidRegion = GetVisibleRegion(); } 1.1345 + 1.1346 + /** 1.1347 + * Adds to the current invalid rect. 1.1348 + */ 1.1349 + void AddInvalidRect(const nsIntRect& aRect) { mInvalidRegion.Or(mInvalidRegion, aRect); } 1.1350 + 1.1351 + /** 1.1352 + * Clear the invalid rect, marking the layer as being identical to what is currently 1.1353 + * composited. 1.1354 + */ 1.1355 + void ClearInvalidRect() { mInvalidRegion.SetEmpty(); } 1.1356 + 1.1357 + void ApplyPendingUpdatesForThisTransaction(); 1.1358 + 1.1359 +#ifdef DEBUG 1.1360 + void SetDebugColorIndex(uint32_t aIndex) { mDebugColorIndex = aIndex; } 1.1361 + uint32_t GetDebugColorIndex() { return mDebugColorIndex; } 1.1362 +#endif 1.1363 + 1.1364 + virtual LayerRenderState GetRenderState() { return LayerRenderState(); } 1.1365 + 1.1366 + 1.1367 + void Mutated() 1.1368 + { 1.1369 + mManager->Mutated(this); 1.1370 + } 1.1371 + 1.1372 +protected: 1.1373 + Layer(LayerManager* aManager, void* aImplData); 1.1374 + 1.1375 + // Protected destructor, to discourage deletion outside of Release(): 1.1376 + virtual ~Layer(); 1.1377 + 1.1378 + /** 1.1379 + * We can snap layer transforms for two reasons: 1.1380 + * 1) To avoid unnecessary resampling when a transform is a translation 1.1381 + * by a non-integer number of pixels. 1.1382 + * Snapping the translation to an integer number of pixels avoids 1.1383 + * blurring the layer and can be faster to composite. 1.1384 + * 2) When a layer is used to render a rectangular object, we need to 1.1385 + * emulate the rendering of rectangular inactive content and snap the 1.1386 + * edges of the rectangle to pixel boundaries. This is both to ensure 1.1387 + * layer rendering is consistent with inactive content rendering, and to 1.1388 + * avoid seams. 1.1389 + * This function implements type 1 snapping. If aTransform is a 2D 1.1390 + * translation, and this layer's layer manager has enabled snapping 1.1391 + * (which is the default), return aTransform with the translation snapped 1.1392 + * to nearest pixels. Otherwise just return aTransform. Call this when the 1.1393 + * layer does not correspond to a single rectangular content object. 1.1394 + * This function does not try to snap if aTransform has a scale, because in 1.1395 + * that case resampling is inevitable and there's no point in trying to 1.1396 + * avoid it. In fact snapping can cause problems because pixel edges in the 1.1397 + * layer's content can be rendered unpredictably (jiggling) as the scale 1.1398 + * interacts with the snapping of the translation, especially with animated 1.1399 + * transforms. 1.1400 + * @param aResidualTransform a transform to apply before the result transform 1.1401 + * in order to get the results to completely match aTransform. 1.1402 + */ 1.1403 + gfx::Matrix4x4 SnapTransformTranslation(const gfx::Matrix4x4& aTransform, 1.1404 + gfx::Matrix* aResidualTransform); 1.1405 + /** 1.1406 + * See comment for SnapTransformTranslation. 1.1407 + * This function implements type 2 snapping. If aTransform is a translation 1.1408 + * and/or scale, transform aSnapRect by aTransform, snap to pixel boundaries, 1.1409 + * and return the transform that maps aSnapRect to that rect. Otherwise 1.1410 + * just return aTransform. 1.1411 + * @param aSnapRect a rectangle whose edges should be snapped to pixel 1.1412 + * boundaries in the destination surface. 1.1413 + * @param aResidualTransform a transform to apply before the result transform 1.1414 + * in order to get the results to completely match aTransform. 1.1415 + */ 1.1416 + gfx::Matrix4x4 SnapTransform(const gfx::Matrix4x4& aTransform, 1.1417 + const gfxRect& aSnapRect, 1.1418 + gfx::Matrix* aResidualTransform); 1.1419 + 1.1420 + /** 1.1421 + * Returns true if this layer's effective transform is not just 1.1422 + * a translation by integers, or if this layer or some ancestor layer 1.1423 + * is marked as having a transform that may change without a full layer 1.1424 + * transaction. 1.1425 + */ 1.1426 + bool MayResample(); 1.1427 + 1.1428 + LayerManager* mManager; 1.1429 + ContainerLayer* mParent; 1.1430 + Layer* mNextSibling; 1.1431 + Layer* mPrevSibling; 1.1432 + void* mImplData; 1.1433 + nsRefPtr<Layer> mMaskLayer; 1.1434 + gfx::UserData mUserData; 1.1435 + nsIntRegion mVisibleRegion; 1.1436 + EventRegions mEventRegions; 1.1437 + gfx::Matrix4x4 mTransform; 1.1438 + // A mutation of |mTransform| that we've queued to be applied at the 1.1439 + // end of the next transaction (if nothing else overrides it in the 1.1440 + // meantime). 1.1441 + nsAutoPtr<gfx::Matrix4x4> mPendingTransform; 1.1442 + float mPostXScale; 1.1443 + float mPostYScale; 1.1444 + gfx::Matrix4x4 mEffectiveTransform; 1.1445 + AnimationArray mAnimations; 1.1446 + // See mPendingTransform above. 1.1447 + nsAutoPtr<AnimationArray> mPendingAnimations; 1.1448 + InfallibleTArray<AnimData> mAnimationData; 1.1449 + float mOpacity; 1.1450 + gfx::CompositionOp mMixBlendMode; 1.1451 + bool mForceIsolatedGroup; 1.1452 + nsIntRect mClipRect; 1.1453 + nsIntRect mTileSourceRect; 1.1454 + nsIntRegion mInvalidRegion; 1.1455 + uint32_t mContentFlags; 1.1456 + bool mUseClipRect; 1.1457 + bool mUseTileSourceRect; 1.1458 + bool mIsFixedPosition; 1.1459 + LayerPoint mAnchor; 1.1460 + LayerMargin mMargins; 1.1461 + struct StickyPositionData { 1.1462 + FrameMetrics::ViewID mScrollId; 1.1463 + LayerRect mOuter; 1.1464 + LayerRect mInner; 1.1465 + }; 1.1466 + nsAutoPtr<StickyPositionData> mStickyPositionData; 1.1467 + FrameMetrics::ViewID mScrollbarTargetId; 1.1468 + ScrollDirection mScrollbarDirection; 1.1469 + DebugOnly<uint32_t> mDebugColorIndex; 1.1470 + // If this layer is used for OMTA, then this counter is used to ensure we 1.1471 + // stay in sync with the animation manager 1.1472 + uint64_t mAnimationGeneration; 1.1473 +}; 1.1474 + 1.1475 +/** 1.1476 + * A Layer which we can draw into using Thebes. It is a conceptually 1.1477 + * infinite surface, but each ThebesLayer has an associated "valid region" 1.1478 + * of contents that it is currently storing, which is finite. ThebesLayer 1.1479 + * implementations can store content between paints. 1.1480 + * 1.1481 + * ThebesLayers are rendered into during the drawing phase of a transaction. 1.1482 + * 1.1483 + * Currently the contents of a ThebesLayer are in the device output color 1.1484 + * space. 1.1485 + */ 1.1486 +class ThebesLayer : public Layer { 1.1487 +public: 1.1488 + /** 1.1489 + * CONSTRUCTION PHASE ONLY 1.1490 + * Tell this layer that the content in some region has changed and 1.1491 + * will need to be repainted. This area is removed from the valid 1.1492 + * region. 1.1493 + */ 1.1494 + virtual void InvalidateRegion(const nsIntRegion& aRegion) = 0; 1.1495 + /** 1.1496 + * CONSTRUCTION PHASE ONLY 1.1497 + * Set whether ComputeEffectiveTransforms should compute the 1.1498 + * "residual translation" --- the translation that should be applied *before* 1.1499 + * mEffectiveTransform to get the ideal transform for this ThebesLayer. 1.1500 + * When this is true, ComputeEffectiveTransforms will compute the residual 1.1501 + * and ensure that the layer is invalidated whenever the residual changes. 1.1502 + * When it's false, a change in the residual will not trigger invalidation 1.1503 + * and GetResidualTranslation will return 0,0. 1.1504 + * So when the residual is to be ignored, set this to false for better 1.1505 + * performance. 1.1506 + */ 1.1507 + void SetAllowResidualTranslation(bool aAllow) { mAllowResidualTranslation = aAllow; } 1.1508 + 1.1509 + /** 1.1510 + * Can be used anytime 1.1511 + */ 1.1512 + const nsIntRegion& GetValidRegion() const { return mValidRegion; } 1.1513 + 1.1514 + virtual ThebesLayer* AsThebesLayer() { return this; } 1.1515 + 1.1516 + MOZ_LAYER_DECL_NAME("ThebesLayer", TYPE_THEBES) 1.1517 + 1.1518 + virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) 1.1519 + { 1.1520 + gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; 1.1521 + gfx::Matrix residual; 1.1522 + mEffectiveTransform = SnapTransformTranslation(idealTransform, 1.1523 + mAllowResidualTranslation ? &residual : nullptr); 1.1524 + // The residual can only be a translation because SnapTransformTranslation 1.1525 + // only changes the transform if it's a translation 1.1526 + NS_ASSERTION(residual.IsTranslation(), 1.1527 + "Residual transform can only be a translation"); 1.1528 + if (!gfx::ThebesPoint(residual.GetTranslation()).WithinEpsilonOf(mResidualTranslation, 1e-3f)) { 1.1529 + mResidualTranslation = gfx::ThebesPoint(residual.GetTranslation()); 1.1530 + NS_ASSERTION(-0.5 <= mResidualTranslation.x && mResidualTranslation.x < 0.5 && 1.1531 + -0.5 <= mResidualTranslation.y && mResidualTranslation.y < 0.5, 1.1532 + "Residual translation out of range"); 1.1533 + mValidRegion.SetEmpty(); 1.1534 + } 1.1535 + ComputeEffectiveTransformForMaskLayer(aTransformToSurface); 1.1536 + } 1.1537 + 1.1538 + bool UsedForReadback() { return mUsedForReadback; } 1.1539 + void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; } 1.1540 + /** 1.1541 + * Returns the residual translation. Apply this translation when drawing 1.1542 + * into the ThebesLayer so that when mEffectiveTransform is applied afterwards 1.1543 + * by layer compositing, the results exactly match the "ideal transform" 1.1544 + * (the product of the transform of this layer and its ancestors). 1.1545 + * Returns 0,0 unless SetAllowResidualTranslation(true) has been called. 1.1546 + * The residual translation components are always in the range [-0.5, 0.5). 1.1547 + */ 1.1548 + gfxPoint GetResidualTranslation() const { return mResidualTranslation; } 1.1549 + 1.1550 +protected: 1.1551 + ThebesLayer(LayerManager* aManager, void* aImplData) 1.1552 + : Layer(aManager, aImplData) 1.1553 + , mValidRegion() 1.1554 + , mUsedForReadback(false) 1.1555 + , mAllowResidualTranslation(false) 1.1556 + { 1.1557 + mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT 1.1558 + } 1.1559 + 1.1560 + virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); 1.1561 + 1.1562 + /** 1.1563 + * ComputeEffectiveTransforms snaps the ideal transform to get mEffectiveTransform. 1.1564 + * mResidualTranslation is the translation that should be applied *before* 1.1565 + * mEffectiveTransform to get the ideal transform. 1.1566 + */ 1.1567 + gfxPoint mResidualTranslation; 1.1568 + nsIntRegion mValidRegion; 1.1569 + /** 1.1570 + * Set when this ThebesLayer is participating in readback, i.e. some 1.1571 + * ReadbackLayer (may) be getting its background from this layer. 1.1572 + */ 1.1573 + bool mUsedForReadback; 1.1574 + /** 1.1575 + * True when 1.1576 + */ 1.1577 + bool mAllowResidualTranslation; 1.1578 +}; 1.1579 + 1.1580 +/** 1.1581 + * A Layer which other layers render into. It holds references to its 1.1582 + * children. 1.1583 + */ 1.1584 +class ContainerLayer : public Layer { 1.1585 +public: 1.1586 + 1.1587 + ~ContainerLayer(); 1.1588 + 1.1589 + /** 1.1590 + * CONSTRUCTION PHASE ONLY 1.1591 + * Insert aChild into the child list of this container. aChild must 1.1592 + * not be currently in any child list or the root for the layer manager. 1.1593 + * If aAfter is non-null, it must be a child of this container and 1.1594 + * we insert after that layer. If it's null we insert at the start. 1.1595 + */ 1.1596 + virtual bool InsertAfter(Layer* aChild, Layer* aAfter); 1.1597 + /** 1.1598 + * CONSTRUCTION PHASE ONLY 1.1599 + * Remove aChild from the child list of this container. aChild must 1.1600 + * be a child of this container. 1.1601 + */ 1.1602 + virtual bool RemoveChild(Layer* aChild); 1.1603 + /** 1.1604 + * CONSTRUCTION PHASE ONLY 1.1605 + * Reposition aChild from the child list of this container. aChild must 1.1606 + * be a child of this container. 1.1607 + * If aAfter is non-null, it must be a child of this container and we 1.1608 + * reposition after that layer. If it's null, we reposition at the start. 1.1609 + */ 1.1610 + virtual bool RepositionChild(Layer* aChild, Layer* aAfter); 1.1611 + 1.1612 + /** 1.1613 + * CONSTRUCTION PHASE ONLY 1.1614 + * Set the (sub)document metrics used to render the Layer subtree 1.1615 + * rooted at this. 1.1616 + */ 1.1617 + void SetFrameMetrics(const FrameMetrics& aFrameMetrics) 1.1618 + { 1.1619 + if (mFrameMetrics != aFrameMetrics) { 1.1620 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FrameMetrics", this)); 1.1621 + mFrameMetrics = aFrameMetrics; 1.1622 + Mutated(); 1.1623 + } 1.1624 + } 1.1625 + 1.1626 + // These functions allow attaching an AsyncPanZoomController to this layer, 1.1627 + // and can be used anytime. 1.1628 + // A container layer has an APZC only-if GetFrameMetrics().IsScrollable() 1.1629 + void SetAsyncPanZoomController(AsyncPanZoomController *controller); 1.1630 + AsyncPanZoomController* GetAsyncPanZoomController() const; 1.1631 + 1.1632 + /** 1.1633 + * CONSTRUCTION PHASE ONLY 1.1634 + * Set the ViewID of the ContainerLayer to which overscroll should be handed 1.1635 + * off. A value of NULL_SCROLL_ID means that the default handoff-parent-finding 1.1636 + * behaviour should be used (i.e. walk up the layer tree to find the next 1.1637 + * scrollable ancestor layer). 1.1638 + */ 1.1639 + void SetScrollHandoffParentId(FrameMetrics::ViewID aScrollParentId) 1.1640 + { 1.1641 + if (mScrollHandoffParentId != aScrollParentId) { 1.1642 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollHandoffParentId", this)); 1.1643 + mScrollHandoffParentId = aScrollParentId; 1.1644 + Mutated(); 1.1645 + } 1.1646 + } 1.1647 + 1.1648 + void SetPreScale(float aXScale, float aYScale) 1.1649 + { 1.1650 + if (mPreXScale == aXScale && mPreYScale == aYScale) { 1.1651 + return; 1.1652 + } 1.1653 + 1.1654 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PreScale", this)); 1.1655 + mPreXScale = aXScale; 1.1656 + mPreYScale = aYScale; 1.1657 + Mutated(); 1.1658 + } 1.1659 + 1.1660 + void SetInheritedScale(float aXScale, float aYScale) 1.1661 + { 1.1662 + if (mInheritedXScale == aXScale && mInheritedYScale == aYScale) { 1.1663 + return; 1.1664 + } 1.1665 + 1.1666 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) InheritedScale", this)); 1.1667 + mInheritedXScale = aXScale; 1.1668 + mInheritedYScale = aYScale; 1.1669 + Mutated(); 1.1670 + } 1.1671 + 1.1672 + virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs); 1.1673 + 1.1674 + void SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray); 1.1675 + 1.1676 + // These getters can be used anytime. 1.1677 + 1.1678 + virtual ContainerLayer* AsContainerLayer() { return this; } 1.1679 + virtual const ContainerLayer* AsContainerLayer() const { return this; } 1.1680 + 1.1681 + virtual Layer* GetFirstChild() const { return mFirstChild; } 1.1682 + virtual Layer* GetLastChild() const { return mLastChild; } 1.1683 + const FrameMetrics& GetFrameMetrics() const { return mFrameMetrics; } 1.1684 + FrameMetrics::ViewID GetScrollHandoffParentId() const { return mScrollHandoffParentId; } 1.1685 + float GetPreXScale() const { return mPreXScale; } 1.1686 + float GetPreYScale() const { return mPreYScale; } 1.1687 + float GetInheritedXScale() const { return mInheritedXScale; } 1.1688 + float GetInheritedYScale() const { return mInheritedYScale; } 1.1689 + 1.1690 + MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER) 1.1691 + 1.1692 + /** 1.1693 + * ContainerLayer backends need to override ComputeEffectiveTransforms 1.1694 + * since the decision about whether to use a temporary surface for the 1.1695 + * container is backend-specific. ComputeEffectiveTransforms must also set 1.1696 + * mUseIntermediateSurface. 1.1697 + */ 1.1698 + virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) = 0; 1.1699 + 1.1700 + /** 1.1701 + * Call this only after ComputeEffectiveTransforms has been invoked 1.1702 + * on this layer. 1.1703 + * Returns true if this will use an intermediate surface. This is largely 1.1704 + * backend-dependent, but it affects the operation of GetEffectiveOpacity(). 1.1705 + */ 1.1706 + bool UseIntermediateSurface() { return mUseIntermediateSurface; } 1.1707 + 1.1708 + /** 1.1709 + * Returns the rectangle covered by the intermediate surface, 1.1710 + * in this layer's coordinate system 1.1711 + */ 1.1712 + nsIntRect GetIntermediateSurfaceRect() 1.1713 + { 1.1714 + NS_ASSERTION(mUseIntermediateSurface, "Must have intermediate surface"); 1.1715 + return mVisibleRegion.GetBounds(); 1.1716 + } 1.1717 + 1.1718 + /** 1.1719 + * Returns true if this container has more than one non-empty child 1.1720 + */ 1.1721 + bool HasMultipleChildren(); 1.1722 + 1.1723 + /** 1.1724 + * Returns true if this container supports children with component alpha. 1.1725 + * Should only be called while painting a child of this layer. 1.1726 + */ 1.1727 + bool SupportsComponentAlphaChildren() { return mSupportsComponentAlphaChildren; } 1.1728 + 1.1729 + /** 1.1730 + * Returns true if aLayer or any layer in its parent chain has the opaque 1.1731 + * content flag set. 1.1732 + */ 1.1733 + static bool HasOpaqueAncestorLayer(Layer* aLayer); 1.1734 + 1.1735 +protected: 1.1736 + friend class ReadbackProcessor; 1.1737 + 1.1738 + void DidInsertChild(Layer* aLayer); 1.1739 + void DidRemoveChild(Layer* aLayer); 1.1740 + 1.1741 + ContainerLayer(LayerManager* aManager, void* aImplData); 1.1742 + 1.1743 + /** 1.1744 + * A default implementation of ComputeEffectiveTransforms for use by OpenGL 1.1745 + * and D3D. 1.1746 + */ 1.1747 + void DefaultComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface); 1.1748 + 1.1749 + /** 1.1750 + * Loops over the children calling ComputeEffectiveTransforms on them. 1.1751 + */ 1.1752 + void ComputeEffectiveTransformsForChildren(const gfx::Matrix4x4& aTransformToSurface); 1.1753 + 1.1754 + virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); 1.1755 + 1.1756 + Layer* mFirstChild; 1.1757 + Layer* mLastChild; 1.1758 + FrameMetrics mFrameMetrics; 1.1759 + nsRefPtr<AsyncPanZoomController> mAPZC; 1.1760 + FrameMetrics::ViewID mScrollHandoffParentId; 1.1761 + float mPreXScale; 1.1762 + float mPreYScale; 1.1763 + // The resolution scale inherited from the parent layer. This will already 1.1764 + // be part of mTransform. 1.1765 + float mInheritedXScale; 1.1766 + float mInheritedYScale; 1.1767 + bool mUseIntermediateSurface; 1.1768 + bool mSupportsComponentAlphaChildren; 1.1769 + bool mMayHaveReadbackChild; 1.1770 +}; 1.1771 + 1.1772 +/** 1.1773 + * A Layer which just renders a solid color in its visible region. It actually 1.1774 + * can fill any area that contains the visible region, so if you need to 1.1775 + * restrict the area filled, set a clip region on this layer. 1.1776 + */ 1.1777 +class ColorLayer : public Layer { 1.1778 +public: 1.1779 + virtual ColorLayer* AsColorLayer() { return this; } 1.1780 + 1.1781 + /** 1.1782 + * CONSTRUCTION PHASE ONLY 1.1783 + * Set the color of the layer. 1.1784 + */ 1.1785 + virtual void SetColor(const gfxRGBA& aColor) 1.1786 + { 1.1787 + if (mColor != aColor) { 1.1788 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Color", this)); 1.1789 + mColor = aColor; 1.1790 + Mutated(); 1.1791 + } 1.1792 + } 1.1793 + 1.1794 + void SetBounds(const nsIntRect& aBounds) 1.1795 + { 1.1796 + if (!mBounds.IsEqualEdges(aBounds)) { 1.1797 + mBounds = aBounds; 1.1798 + Mutated(); 1.1799 + } 1.1800 + } 1.1801 + 1.1802 + const nsIntRect& GetBounds() 1.1803 + { 1.1804 + return mBounds; 1.1805 + } 1.1806 + 1.1807 + // This getter can be used anytime. 1.1808 + virtual const gfxRGBA& GetColor() { return mColor; } 1.1809 + 1.1810 + MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR) 1.1811 + 1.1812 + virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) 1.1813 + { 1.1814 + gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; 1.1815 + mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr); 1.1816 + ComputeEffectiveTransformForMaskLayer(aTransformToSurface); 1.1817 + } 1.1818 + 1.1819 +protected: 1.1820 + ColorLayer(LayerManager* aManager, void* aImplData) 1.1821 + : Layer(aManager, aImplData), 1.1822 + mColor(0.0, 0.0, 0.0, 0.0) 1.1823 + {} 1.1824 + 1.1825 + virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); 1.1826 + 1.1827 + nsIntRect mBounds; 1.1828 + gfxRGBA mColor; 1.1829 +}; 1.1830 + 1.1831 +/** 1.1832 + * A Layer for HTML Canvas elements. It's backed by either a 1.1833 + * gfxASurface or a GLContext (for WebGL layers), and has some control 1.1834 + * for intelligent updating from the source if necessary (for example, 1.1835 + * if hardware compositing is not available, for reading from the GL 1.1836 + * buffer into an image surface that we can layer composite.) 1.1837 + * 1.1838 + * After Initialize is called, the underlying canvas Surface/GLContext 1.1839 + * must not be modified during a layer transaction. 1.1840 + */ 1.1841 +class CanvasLayer : public Layer { 1.1842 +public: 1.1843 + struct Data { 1.1844 + Data() 1.1845 + : mDrawTarget(nullptr) 1.1846 + , mGLContext(nullptr) 1.1847 + , mStream(nullptr) 1.1848 + , mTexID(0) 1.1849 + , mSize(0,0) 1.1850 + , mIsGLAlphaPremult(false) 1.1851 + { } 1.1852 + 1.1853 + // One of these two must be specified for Canvas2D, but never both 1.1854 + mozilla::gfx::DrawTarget *mDrawTarget; // a DrawTarget for the canvas contents 1.1855 + mozilla::gl::GLContext* mGLContext; // or this, for GL. 1.1856 + 1.1857 + // Canvas/SkiaGL uses this 1.1858 + mozilla::gfx::SurfaceStream* mStream; 1.1859 + 1.1860 + // ID of the texture backing the canvas layer (defaults to 0) 1.1861 + uint32_t mTexID; 1.1862 + 1.1863 + // The size of the canvas content 1.1864 + nsIntSize mSize; 1.1865 + 1.1866 + // Whether mGLContext contains data that is alpha-premultiplied. 1.1867 + bool mIsGLAlphaPremult; 1.1868 + }; 1.1869 + 1.1870 + /** 1.1871 + * CONSTRUCTION PHASE ONLY 1.1872 + * Initialize this CanvasLayer with the given data. The data must 1.1873 + * have either mSurface or mGLContext initialized (but not both), as 1.1874 + * well as mSize. 1.1875 + * 1.1876 + * This must only be called once. 1.1877 + */ 1.1878 + virtual void Initialize(const Data& aData) = 0; 1.1879 + 1.1880 + /** 1.1881 + * Check the data is owned by this layer is still valid for rendering 1.1882 + */ 1.1883 + virtual bool IsDataValid(const Data& aData) { return true; } 1.1884 + 1.1885 + /** 1.1886 + * Notify this CanvasLayer that the canvas surface contents have 1.1887 + * changed (or will change) before the next transaction. 1.1888 + */ 1.1889 + void Updated() { mDirty = true; SetInvalidRectToVisibleRegion(); } 1.1890 + 1.1891 + /** 1.1892 + * Notify this CanvasLayer that the canvas surface contents have 1.1893 + * been painted since the last change. 1.1894 + */ 1.1895 + void Painted() { mDirty = false; } 1.1896 + 1.1897 + /** 1.1898 + * Returns true if the canvas surface contents have changed since the 1.1899 + * last paint. 1.1900 + */ 1.1901 + bool IsDirty() 1.1902 + { 1.1903 + // We can only tell if we are dirty if we're part of the 1.1904 + // widget's retained layer tree. 1.1905 + if (!mManager || !mManager->IsWidgetLayerManager()) { 1.1906 + return true; 1.1907 + } 1.1908 + return mDirty; 1.1909 + } 1.1910 + 1.1911 + /** 1.1912 + * Register a callback to be called at the start of each transaction. 1.1913 + */ 1.1914 + typedef void PreTransactionCallback(void* closureData); 1.1915 + void SetPreTransactionCallback(PreTransactionCallback* callback, void* closureData) 1.1916 + { 1.1917 + mPreTransCallback = callback; 1.1918 + mPreTransCallbackData = closureData; 1.1919 + } 1.1920 + 1.1921 +protected: 1.1922 + void FirePreTransactionCallback() 1.1923 + { 1.1924 + if (mPreTransCallback) { 1.1925 + mPreTransCallback(mPreTransCallbackData); 1.1926 + } 1.1927 + } 1.1928 + 1.1929 +public: 1.1930 + /** 1.1931 + * Register a callback to be called at the end of each transaction. 1.1932 + */ 1.1933 + typedef void (* DidTransactionCallback)(void* aClosureData); 1.1934 + void SetDidTransactionCallback(DidTransactionCallback aCallback, void* aClosureData) 1.1935 + { 1.1936 + mPostTransCallback = aCallback; 1.1937 + mPostTransCallbackData = aClosureData; 1.1938 + } 1.1939 + 1.1940 + /** 1.1941 + * CONSTRUCTION PHASE ONLY 1.1942 + * Set the filter used to resample this image (if necessary). 1.1943 + */ 1.1944 + void SetFilter(GraphicsFilter aFilter) 1.1945 + { 1.1946 + if (mFilter != aFilter) { 1.1947 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this)); 1.1948 + mFilter = aFilter; 1.1949 + Mutated(); 1.1950 + } 1.1951 + } 1.1952 + GraphicsFilter GetFilter() const { return mFilter; } 1.1953 + 1.1954 + MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS) 1.1955 + 1.1956 + virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) 1.1957 + { 1.1958 + // Snap our local transform first, and snap the inherited transform as well. 1.1959 + // This makes our snapping equivalent to what would happen if our content 1.1960 + // was drawn into a ThebesLayer (gfxContext would snap using the local 1.1961 + // transform, then we'd snap again when compositing the ThebesLayer). 1.1962 + mEffectiveTransform = 1.1963 + SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height), 1.1964 + nullptr)* 1.1965 + SnapTransformTranslation(aTransformToSurface, nullptr); 1.1966 + ComputeEffectiveTransformForMaskLayer(aTransformToSurface); 1.1967 + } 1.1968 + 1.1969 +protected: 1.1970 + CanvasLayer(LayerManager* aManager, void* aImplData) 1.1971 + : Layer(aManager, aImplData) 1.1972 + , mPreTransCallback(nullptr) 1.1973 + , mPreTransCallbackData(nullptr) 1.1974 + , mPostTransCallback(nullptr) 1.1975 + , mPostTransCallbackData(nullptr) 1.1976 + , mFilter(GraphicsFilter::FILTER_GOOD) 1.1977 + , mDirty(false) 1.1978 + {} 1.1979 + 1.1980 + virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); 1.1981 + 1.1982 + void FireDidTransactionCallback() 1.1983 + { 1.1984 + if (mPostTransCallback) { 1.1985 + mPostTransCallback(mPostTransCallbackData); 1.1986 + } 1.1987 + } 1.1988 + 1.1989 + /** 1.1990 + * 0, 0, canvaswidth, canvasheight 1.1991 + */ 1.1992 + nsIntRect mBounds; 1.1993 + PreTransactionCallback* mPreTransCallback; 1.1994 + void* mPreTransCallbackData; 1.1995 + DidTransactionCallback mPostTransCallback; 1.1996 + void* mPostTransCallbackData; 1.1997 + GraphicsFilter mFilter; 1.1998 + 1.1999 +private: 1.2000 + /** 1.2001 + * Set to true in Updated(), cleared during a transaction. 1.2002 + */ 1.2003 + bool mDirty; 1.2004 +}; 1.2005 + 1.2006 +/** 1.2007 + * ContainerLayer that refers to a "foreign" layer tree, through an 1.2008 + * ID. Usage of RefLayer looks like 1.2009 + * 1.2010 + * Construction phase: 1.2011 + * allocate ID for layer subtree 1.2012 + * create RefLayer, SetReferentId(ID) 1.2013 + * 1.2014 + * Composition: 1.2015 + * look up subtree for GetReferentId() 1.2016 + * ConnectReferentLayer(subtree) 1.2017 + * compose 1.2018 + * ClearReferentLayer() 1.2019 + * 1.2020 + * Clients will usually want to Connect/Clear() on each transaction to 1.2021 + * avoid difficulties managing memory across multiple layer subtrees. 1.2022 + */ 1.2023 +class RefLayer : public ContainerLayer { 1.2024 + friend class LayerManager; 1.2025 + 1.2026 +private: 1.2027 + virtual bool InsertAfter(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE 1.2028 + { MOZ_CRASH(); return false; } 1.2029 + 1.2030 + virtual bool RemoveChild(Layer* aChild) 1.2031 + { MOZ_CRASH(); return false; } 1.2032 + 1.2033 + virtual bool RepositionChild(Layer* aChild, Layer* aAfter) 1.2034 + { MOZ_CRASH(); return false; } 1.2035 + 1.2036 + using ContainerLayer::SetFrameMetrics; 1.2037 + 1.2038 +public: 1.2039 + /** 1.2040 + * CONSTRUCTION PHASE ONLY 1.2041 + * Set the ID of the layer's referent. 1.2042 + */ 1.2043 + void SetReferentId(uint64_t aId) 1.2044 + { 1.2045 + MOZ_ASSERT(aId != 0); 1.2046 + if (mId != aId) { 1.2047 + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ReferentId", this)); 1.2048 + mId = aId; 1.2049 + Mutated(); 1.2050 + } 1.2051 + } 1.2052 + /** 1.2053 + * CONSTRUCTION PHASE ONLY 1.2054 + * Connect this ref layer to its referent, temporarily. 1.2055 + * ClearReferentLayer() must be called after composition. 1.2056 + */ 1.2057 + void ConnectReferentLayer(Layer* aLayer) 1.2058 + { 1.2059 + MOZ_ASSERT(!mFirstChild && !mLastChild); 1.2060 + MOZ_ASSERT(!aLayer->GetParent()); 1.2061 + MOZ_ASSERT(aLayer->Manager() == Manager()); 1.2062 + 1.2063 + mFirstChild = mLastChild = aLayer; 1.2064 + aLayer->SetParent(this); 1.2065 + } 1.2066 + 1.2067 + /** 1.2068 + * DRAWING PHASE ONLY 1.2069 + * |aLayer| is the same as the argument to ConnectReferentLayer(). 1.2070 + */ 1.2071 + void DetachReferentLayer(Layer* aLayer) 1.2072 + { 1.2073 + MOZ_ASSERT(aLayer == mFirstChild && mFirstChild == mLastChild); 1.2074 + MOZ_ASSERT(aLayer->GetParent() == this); 1.2075 + 1.2076 + mFirstChild = mLastChild = nullptr; 1.2077 + aLayer->SetParent(nullptr); 1.2078 + } 1.2079 + 1.2080 + // These getters can be used anytime. 1.2081 + virtual RefLayer* AsRefLayer() { return this; } 1.2082 + 1.2083 + virtual int64_t GetReferentId() { return mId; } 1.2084 + 1.2085 + /** 1.2086 + * DRAWING PHASE ONLY 1.2087 + */ 1.2088 + virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs); 1.2089 + 1.2090 + MOZ_LAYER_DECL_NAME("RefLayer", TYPE_REF) 1.2091 + 1.2092 +protected: 1.2093 + RefLayer(LayerManager* aManager, void* aImplData) 1.2094 + : ContainerLayer(aManager, aImplData) , mId(0) 1.2095 + {} 1.2096 + 1.2097 + virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); 1.2098 + 1.2099 + Layer* mTempReferent; 1.2100 + // 0 is a special value that means "no ID". 1.2101 + uint64_t mId; 1.2102 +}; 1.2103 + 1.2104 +void SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget); 1.2105 +void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget); 1.2106 + 1.2107 +#ifdef MOZ_DUMP_PAINTING 1.2108 +void WriteSnapshotToDumpFile(Layer* aLayer, gfx::DataSourceSurface* aSurf); 1.2109 +void WriteSnapshotToDumpFile(LayerManager* aManager, gfx::DataSourceSurface* aSurf); 1.2110 +void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget); 1.2111 +#endif 1.2112 + 1.2113 +} 1.2114 +} 1.2115 + 1.2116 +#endif /* GFX_LAYERS_H */