1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/composite/AsyncCompositionManager.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,226 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; 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_ASYNCCOMPOSITIONMANAGER_H 1.10 +#define GFX_ASYNCCOMPOSITIONMANAGER_H 1.11 + 1.12 +#include "Units.h" // for LayerPoint, etc 1.13 +#include "mozilla/layers/LayerManagerComposite.h" // for LayerManagerComposite 1.14 +#include "gfx3DMatrix.h" // for gfx3DMatrix 1.15 +#include "mozilla/Attributes.h" // for MOZ_DELETE, MOZ_FINAL, etc 1.16 +#include "mozilla/RefPtr.h" // for RefCounted 1.17 +#include "mozilla/TimeStamp.h" // for TimeStamp 1.18 +#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation 1.19 +#include "mozilla/gfx/BasePoint.h" // for BasePoint 1.20 +#include "mozilla/layers/LayersMessages.h" // for TargetConfig 1.21 +#include "nsAutoPtr.h" // for nsRefPtr 1.22 +#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc 1.23 + 1.24 +namespace mozilla { 1.25 +namespace layers { 1.26 + 1.27 +class AsyncPanZoomController; 1.28 +class Layer; 1.29 +class LayerManagerComposite; 1.30 +class AutoResolveRefLayers; 1.31 + 1.32 +// Represents (affine) transforms that are calculated from a content view. 1.33 +struct ViewTransform { 1.34 + ViewTransform(LayerPoint aTranslation = LayerPoint(), 1.35 + ParentLayerToScreenScale aScale = ParentLayerToScreenScale()) 1.36 + : mTranslation(aTranslation) 1.37 + , mScale(aScale) 1.38 + {} 1.39 + 1.40 + operator gfx3DMatrix() const 1.41 + { 1.42 + return 1.43 + gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0) * 1.44 + gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1); 1.45 + } 1.46 + 1.47 + bool operator==(const ViewTransform& rhs) const { 1.48 + return mTranslation == rhs.mTranslation && mScale == rhs.mScale; 1.49 + } 1.50 + 1.51 + bool operator!=(const ViewTransform& rhs) const { 1.52 + return !(*this == rhs); 1.53 + } 1.54 + 1.55 + LayerPoint mTranslation; 1.56 + ParentLayerToScreenScale mScale; 1.57 +}; 1.58 + 1.59 +/** 1.60 + * Manage async composition effects. This class is only used with OMTC and only 1.61 + * lives on the compositor thread. It is a layer on top of the layer manager 1.62 + * (LayerManagerComposite) which deals with elements of composition which are 1.63 + * usually dealt with by dom or layout when main thread rendering, but which can 1.64 + * short circuit that stuff to directly affect layers as they are composited, 1.65 + * for example, off-main thread animation, async video, async pan/zoom. 1.66 + */ 1.67 +class AsyncCompositionManager MOZ_FINAL 1.68 +{ 1.69 + friend class AutoResolveRefLayers; 1.70 +public: 1.71 + NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager) 1.72 + 1.73 + AsyncCompositionManager(LayerManagerComposite* aManager) 1.74 + : mLayerManager(aManager) 1.75 + , mIsFirstPaint(false) 1.76 + , mLayersUpdated(false) 1.77 + , mReadyForCompose(true) 1.78 + { 1.79 + } 1.80 + ~AsyncCompositionManager() 1.81 + { 1.82 + } 1.83 + 1.84 + /** 1.85 + * This forces the is-first-paint flag to true. This is intended to 1.86 + * be called by the widget code when it loses its viewport information 1.87 + * (or for whatever reason wants to refresh the viewport information). 1.88 + * The information refresh happens because the compositor will call 1.89 + * SetFirstPaintViewport on the next frame of composition. 1.90 + */ 1.91 + void ForceIsFirstPaint() { mIsFirstPaint = true; } 1.92 + 1.93 + // Sample transforms for layer trees. Return true to request 1.94 + // another animation frame. 1.95 + bool TransformShadowTree(TimeStamp aCurrentFrame); 1.96 + 1.97 + // Calculates the correct rotation and applies the transform to 1.98 + // our layer manager 1.99 + void ComputeRotation(); 1.100 + 1.101 + // Call after updating our layer tree. 1.102 + void Updated(bool isFirstPaint, const TargetConfig& aTargetConfig) 1.103 + { 1.104 + mIsFirstPaint |= isFirstPaint; 1.105 + mLayersUpdated = true; 1.106 + mTargetConfig = aTargetConfig; 1.107 + } 1.108 + 1.109 + bool RequiresReorientation(mozilla::dom::ScreenOrientation aOrientation) 1.110 + { 1.111 + return mTargetConfig.orientation() != aOrientation; 1.112 + } 1.113 + 1.114 + // True if the underlying layer tree is ready to be composited. 1.115 + bool ReadyForCompose() { return mReadyForCompose; } 1.116 + 1.117 + // Returns true if the next composition will be the first for a 1.118 + // particular document. 1.119 + bool IsFirstPaint() { return mIsFirstPaint; } 1.120 + 1.121 +private: 1.122 + void TransformScrollableLayer(Layer* aLayer); 1.123 + // Return true if an AsyncPanZoomController content transform was 1.124 + // applied for |aLayer|. *aWantNextFrame is set to true if the 1.125 + // controller wants another animation frame. 1.126 + bool ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, Layer* aLayer, 1.127 + bool* aWantNextFrame); 1.128 + /** 1.129 + * Update the shadow transform for aLayer assuming that is a scrollbar, 1.130 + * so that it stays in sync with the content that is being scrolled by APZ. 1.131 + */ 1.132 + void ApplyAsyncTransformToScrollbar(TimeStamp aCurrentFrame, ContainerLayer* aLayer); 1.133 + 1.134 + void SetFirstPaintViewport(const LayerIntPoint& aOffset, 1.135 + const CSSToLayerScale& aZoom, 1.136 + const CSSRect& aCssPageRect); 1.137 + void SetPageRect(const CSSRect& aCssPageRect); 1.138 + void SyncViewportInfo(const LayerIntRect& aDisplayPort, 1.139 + const CSSToLayerScale& aDisplayResolution, 1.140 + bool aLayersUpdated, 1.141 + ScreenPoint& aScrollOffset, 1.142 + CSSToScreenScale& aScale, 1.143 + LayerMargin& aFixedLayerMargins, 1.144 + ScreenPoint& aOffset); 1.145 + void SyncFrameMetrics(const ScreenPoint& aScrollOffset, 1.146 + float aZoom, 1.147 + const CSSRect& aCssPageRect, 1.148 + bool aLayersUpdated, 1.149 + const CSSRect& aDisplayPort, 1.150 + const CSSToLayerScale& aDisplayResolution, 1.151 + bool aIsFirstPaint, 1.152 + LayerMargin& aFixedLayerMargins, 1.153 + ScreenPoint& aOffset); 1.154 + 1.155 + /** 1.156 + * Adds a translation to the transform of any fixed position (whose parent 1.157 + * layer is not fixed) or sticky position layer descendant of 1.158 + * aTransformedSubtreeRoot. The translation is chosen so that the layer's 1.159 + * anchor point relative to aTransformedSubtreeRoot's parent layer is the same 1.160 + * as it was when aTransformedSubtreeRoot's GetLocalTransform() was 1.161 + * aPreviousTransformForRoot. For sticky position layers, the translation is 1.162 + * further intersected with the layer's sticky scroll ranges. 1.163 + * This function will also adjust layers so that the given content document 1.164 + * fixed position margins will be respected during asynchronous panning and 1.165 + * zooming. 1.166 + */ 1.167 + void AlignFixedAndStickyLayers(Layer* aLayer, Layer* aTransformedSubtreeRoot, 1.168 + const gfx::Matrix4x4& aPreviousTransformForRoot, 1.169 + const LayerMargin& aFixedLayerMargins); 1.170 + 1.171 + /** 1.172 + * DRAWING PHASE ONLY 1.173 + * 1.174 + * For reach RefLayer in our layer tree, look up its referent and connect it 1.175 + * to the layer tree, if found. 1.176 + */ 1.177 + void ResolveRefLayers(); 1.178 + /** 1.179 + * Detaches all referents resolved by ResolveRefLayers. 1.180 + * Assumes that mLayerManager->GetRoot() and mTargetConfig have not changed 1.181 + * since ResolveRefLayers was called. 1.182 + */ 1.183 + void DetachRefLayers(); 1.184 + 1.185 + TargetConfig mTargetConfig; 1.186 + CSSRect mContentRect; 1.187 + 1.188 + nsRefPtr<LayerManagerComposite> mLayerManager; 1.189 + // When this flag is set, the next composition will be the first for a 1.190 + // particular document (i.e. the document displayed on the screen will change). 1.191 + // This happens when loading a new page or switching tabs. We notify the 1.192 + // front-end (e.g. Java on Android) about this so that it take the new page 1.193 + // size and zoom into account when providing us with the next view transform. 1.194 + bool mIsFirstPaint; 1.195 + 1.196 + // This flag is set during a layers update, so that the first composition 1.197 + // after a layers update has it set. It is cleared after that first composition. 1.198 + bool mLayersUpdated; 1.199 + 1.200 + bool mReadyForCompose; 1.201 +}; 1.202 + 1.203 +class MOZ_STACK_CLASS AutoResolveRefLayers { 1.204 +public: 1.205 + AutoResolveRefLayers(AsyncCompositionManager* aManager) : mManager(aManager) 1.206 + { 1.207 + if (mManager) { 1.208 + mManager->ResolveRefLayers(); 1.209 + } 1.210 + } 1.211 + 1.212 + ~AutoResolveRefLayers() 1.213 + { 1.214 + if (mManager) { 1.215 + mManager->DetachRefLayers(); 1.216 + } 1.217 + } 1.218 + 1.219 +private: 1.220 + AsyncCompositionManager* mManager; 1.221 + 1.222 + AutoResolveRefLayers(const AutoResolveRefLayers&) MOZ_DELETE; 1.223 + AutoResolveRefLayers& operator=(const AutoResolveRefLayers&) MOZ_DELETE; 1.224 +}; 1.225 + 1.226 +} // layers 1.227 +} // mozilla 1.228 + 1.229 +#endif