1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef GraphicsLayerCA_h 27#define GraphicsLayerCA_h 28 29#if USE(ACCELERATED_COMPOSITING) 30 31#include "GraphicsLayer.h" 32#include "Image.h" 33#include "PlatformCAAnimation.h" 34#include "PlatformCALayerClient.h" 35#include <wtf/HashMap.h> 36#include <wtf/HashSet.h> 37#include <wtf/RetainPtr.h> 38#include <wtf/text/StringHash.h> 39 40// Enable this to add a light red wash over the visible portion of Tiled Layers, as computed 41// by flushCompositingState(). 42// #define VISIBLE_TILE_WASH 43 44namespace WebCore { 45 46class PlatformCALayer; 47class TransformState; 48 49class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient { 50public: 51 // The width and height of a single tile in a tiled layer. Should be large enough to 52 // avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough 53 // to keep the overall tile cost low. 54 static const int kTiledLayerTileSize = 512; 55 56 GraphicsLayerCA(GraphicsLayerClient*); 57 virtual ~GraphicsLayerCA(); 58 59 virtual void setName(const String&); 60 61 virtual PlatformLayer* platformLayer() const; 62 virtual PlatformCALayer* platformCALayer() const { return primaryLayer(); } 63 64 virtual bool setChildren(const Vector<GraphicsLayer*>&); 65 virtual void addChild(GraphicsLayer*); 66 virtual void addChildAtIndex(GraphicsLayer*, int index); 67 virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling); 68 virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling); 69 virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild); 70 71 virtual void removeFromParent(); 72 73 virtual void setMaskLayer(GraphicsLayer*); 74 virtual void setReplicatedLayer(GraphicsLayer*); 75 76 virtual void setPosition(const FloatPoint&); 77 virtual void setAnchorPoint(const FloatPoint3D&); 78 virtual void setSize(const FloatSize&); 79 virtual void setBoundsOrigin(const FloatPoint&); 80 81 virtual void setTransform(const TransformationMatrix&); 82 83 virtual void setChildrenTransform(const TransformationMatrix&); 84 85 virtual void setPreserves3D(bool); 86 virtual void setMasksToBounds(bool); 87 virtual void setDrawsContent(bool); 88 virtual void setContentsVisible(bool); 89 virtual void setAcceleratesDrawing(bool); 90 91 virtual void setBackgroundColor(const Color&); 92 93 virtual void setContentsOpaque(bool); 94 virtual void setBackfaceVisibility(bool); 95 96 // return true if we started an animation 97 virtual void setOpacity(float); 98 99#if ENABLE(CSS_FILTERS) 100 virtual bool setFilters(const FilterOperations&); 101#endif 102 103 virtual void setNeedsDisplay(); 104 virtual void setNeedsDisplayInRect(const FloatRect&); 105 virtual void setContentsNeedsDisplay(); 106 107 virtual void setContentsRect(const IntRect&); 108 109 virtual void suspendAnimations(double time); 110 virtual void resumeAnimations(); 111 112 virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& animationName, double timeOffset); 113 virtual void pauseAnimation(const String& animationName, double timeOffset); 114 virtual void removeAnimation(const String& animationName); 115 116 virtual void setContentsToImage(Image*); 117 virtual void setContentsToMedia(PlatformLayer*); 118 virtual void setContentsToCanvas(PlatformLayer*); 119 virtual void setContentsToSolidColor(const Color&); 120 121 virtual bool hasContentsLayer() const { return m_contentsLayer; } 122 123 virtual void setShowDebugBorder(bool) OVERRIDE; 124 virtual void setShowRepaintCounter(bool) OVERRIDE; 125 126 virtual void setDebugBackgroundColor(const Color&); 127 virtual void setDebugBorder(const Color&, float borderWidth); 128 129 virtual void layerDidDisplay(PlatformLayer*); 130 131 virtual void setMaintainsPixelAlignment(bool); 132 virtual void deviceOrPageScaleFactorChanged(); 133 134 struct CommitState { 135 bool ancestorHasTransformAnimation; 136 int treeDepth; 137 CommitState() 138 : ancestorHasTransformAnimation(false) 139 , treeDepth(0) 140 { } 141 }; 142 void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false); 143 144 virtual void flushCompositingState(const FloatRect&); 145 virtual void flushCompositingStateForThisLayerOnly(); 146 147 virtual bool visibleRectChangeRequiresFlush(const FloatRect& visibleRect) const OVERRIDE; 148 149 virtual TiledBacking* tiledBacking() const OVERRIDE; 150 151 bool allowTiledLayer() const { return m_allowTiledLayer; } 152 virtual void setAllowTiledLayer(bool b); 153 154protected: 155 virtual void setOpacityInternal(float); 156 157private: 158 virtual void willBeDestroyed(); 159 160 // PlatformCALayerClient overrides 161 virtual void platformCALayerLayoutSublayersOfLayer(PlatformCALayer*) { } 162 virtual bool platformCALayerRespondsToLayoutChanges() const { return false; } 163 164 virtual void platformCALayerAnimationStarted(CFTimeInterval beginTime); 165 virtual CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return contentsOrientation(); } 166 virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& clip); 167 virtual bool platformCALayerShowDebugBorders() const { return isShowingDebugBorder(); } 168 virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const; 169 virtual int platformCALayerIncrementRepaintCount() { return incrementRepaintCount(); } 170 171 virtual bool platformCALayerContentsOpaque() const { return contentsOpaque(); } 172 virtual bool platformCALayerDrawsContent() const { return drawsContent(); } 173 virtual void platformCALayerLayerDidDisplay(PlatformLayer* layer) { return layerDidDisplay(layer); } 174 virtual void platformCALayerDidCreateTiles(const Vector<FloatRect>& dirtyRects) OVERRIDE; 175 virtual float platformCALayerDeviceScaleFactor() OVERRIDE; 176 177 virtual double backingStoreMemoryEstimate() const; 178 179 virtual bool shouldRepaintOnSizeChange() const OVERRIDE; 180 181 void updateOpacityOnLayer(); 182 183#if ENABLE(CSS_FILTERS) 184 void updateFilters(); 185#endif 186 187 PlatformCALayer* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); } 188 PlatformCALayer* hostLayerForSublayers() const; 189 PlatformCALayer* layerForSuperlayer() const; 190 PlatformCALayer* animatedLayer(AnimatedPropertyID) const; 191 192 typedef String CloneID; // Identifier for a given clone, based on original/replica branching down the tree. 193 static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; } 194 195 typedef HashMap<CloneID, RefPtr<PlatformCALayer> > LayerMap; 196 LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); } 197 LayerMap* animatedLayerClones(AnimatedPropertyID) const; 198 199 bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset); 200 bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize); 201#if ENABLE(CSS_FILTERS) 202 bool createFilterAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset); 203#endif 204 205 // Return autoreleased animation (use RetainPtr?) 206 PassRefPtr<PlatformCAAnimation> createBasicAnimation(const Animation*, const String& keyPath, bool additive); 207 PassRefPtr<PlatformCAAnimation> createKeyframeAnimation(const Animation*, const String&, bool additive); 208 void setupAnimation(PlatformCAAnimation*, const Animation*, bool additive); 209 210 const TimingFunction* timingFunctionForAnimationValue(const AnimationValue&, const Animation&); 211 212 bool setAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*); 213 bool setAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*); 214 215 bool setTransformAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize); 216 bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize); 217 218#if ENABLE(CSS_FILTERS) 219 bool setFilterAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, int internalFilterPropertyIndex); 220 bool setFilterAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType); 221#endif 222 223 bool isRunningTransformAnimation() const; 224 225 bool animationIsRunning(const String& animationName) const 226 { 227 return m_runningAnimations.find(animationName) != m_runningAnimations.end(); 228 } 229 230 void commitLayerChangesBeforeSublayers(CommitState&, float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect); 231 void commitLayerChangesAfterSublayers(CommitState&); 232 233 FloatPoint computePositionRelativeToBase(float& pageScale) const; 234 235 bool requiresTiledLayer(float pageScaleFactor) const; 236 void swapFromOrToTiledLayer(bool useTiledLayer); 237 238 CompositingCoordinatesOrientation defaultContentsOrientation() const; 239 240 void setupContentsLayer(PlatformCALayer*); 241 PlatformCALayer* contentsLayer() const { return m_contentsLayer.get(); } 242 243 virtual void setReplicatedByLayer(GraphicsLayer*); 244 245 virtual void getDebugBorderInfo(Color&, float& width) const; 246 virtual void dumpAdditionalProperties(TextStream&, int indent, LayerTreeAsTextBehavior) const; 247 248 void computePixelAlignment(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase, 249 FloatPoint& position, FloatSize&, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const; 250 enum ComputeVisibleRectFlag { RespectAnimatingTransforms = 1 << 0 }; 251 typedef unsigned ComputeVisibleRectFlags; 252 FloatRect computeVisibleRect(TransformState&, ComputeVisibleRectFlags = RespectAnimatingTransforms) const; 253 const FloatRect& visibleRect() const { return m_visibleRect; } 254 255 static FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatRect& newVisibleRect, const FloatSize& oldSize, const FloatSize& newSize); 256 257 bool recursiveVisibleRectChangeRequiresFlush(const TransformState&) const; 258 259 virtual bool canThrottleLayerFlush() const; 260 261 // Used to track the path down the tree for replica layers. 262 struct ReplicaState { 263 static const size_t maxReplicaDepth = 16; 264 enum ReplicaBranchType { ChildBranch = 0, ReplicaBranch = 1 }; 265 ReplicaState(ReplicaBranchType firstBranch) 266 : m_replicaDepth(0) 267 { 268 push(firstBranch); 269 } 270 271 // Called as we walk down the tree to build replicas. 272 void push(ReplicaBranchType branchType) 273 { 274 m_replicaBranches.append(branchType); 275 if (branchType == ReplicaBranch) 276 ++m_replicaDepth; 277 } 278 279 void setBranchType(ReplicaBranchType branchType) 280 { 281 ASSERT(!m_replicaBranches.isEmpty()); 282 283 if (m_replicaBranches.last() != branchType) { 284 if (branchType == ReplicaBranch) 285 ++m_replicaDepth; 286 else 287 --m_replicaDepth; 288 } 289 290 m_replicaBranches.last() = branchType; 291 } 292 293 void pop() 294 { 295 if (m_replicaBranches.last() == ReplicaBranch) 296 --m_replicaDepth; 297 m_replicaBranches.removeLast(); 298 } 299 300 size_t depth() const { return m_replicaBranches.size(); } 301 size_t replicaDepth() const { return m_replicaDepth; } 302 303 CloneID cloneID() const; 304 305 private: 306 Vector<ReplicaBranchType> m_replicaBranches; 307 size_t m_replicaDepth; 308 }; 309 PassRefPtr<PlatformCALayer>replicatedLayerRoot(ReplicaState&); 310 311 enum CloneLevel { RootCloneLevel, IntermediateCloneLevel }; 312 PassRefPtr<PlatformCALayer> fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState&, CloneLevel); 313 314 PassRefPtr<PlatformCALayer> cloneLayer(PlatformCALayer *, CloneLevel); 315 PassRefPtr<PlatformCALayer> findOrMakeClone(CloneID, PlatformCALayer *, LayerMap*, CloneLevel); 316 317 void ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel); 318 319 bool hasCloneLayers() const { return m_layerClones; } 320 void removeCloneLayers(); 321 FloatPoint positionForCloneRootLayer() const; 322 323 void propagateLayerChangeToReplicas(); 324 325 // All these "update" methods will be called inside a BEGIN_BLOCK_OBJC_EXCEPTIONS/END_BLOCK_OBJC_EXCEPTIONS block. 326 void updateLayerNames(); 327 void updateSublayerList(bool maxLayerDepthReached = false); 328 void updateGeometry(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase); 329 void updateTransform(); 330 void updateChildrenTransform(); 331 void updateMasksToBounds(); 332 void updateContentsVisibility(); 333 void updateContentsOpaque(float pageScaleFactor); 334 void updateBackfaceVisibility(); 335 void updateStructuralLayer(); 336 void updateLayerDrawsContent(); 337 void updateBackgroundColor(); 338 339 void updateContentsImage(); 340 void updateContentsMediaLayer(); 341 void updateContentsCanvasLayer(); 342 void updateContentsColorLayer(); 343 void updateContentsRect(); 344 void updateMaskLayer(); 345 void updateReplicatedLayers(); 346 347 void updateAnimations(); 348 void updateContentsNeedsDisplay(); 349 void updateAcceleratesDrawing(); 350 void updateDebugBorder(); 351 void updateVisibleRect(const FloatRect& oldVisibleRect); 352 void updateContentsScale(float pageScaleFactor); 353 354 enum StructuralLayerPurpose { 355 NoStructuralLayer = 0, 356 StructuralLayerForPreserves3D, 357 StructuralLayerForReplicaFlattening 358 }; 359 void ensureStructuralLayer(StructuralLayerPurpose); 360 StructuralLayerPurpose structuralLayerPurpose() const; 361 362 void setAnimationOnLayer(PlatformCAAnimation*, AnimatedPropertyID, const String& animationName, int index, int subIndex, double timeOffset); 363 bool removeCAAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index, int subINdex); 364 void pauseCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, int subIndex, double timeOffset); 365 366 enum MoveOrCopy { Move, Copy }; 367 static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer); 368 void moveOrCopyAnimations(MoveOrCopy, PlatformCALayer * fromLayer, PlatformCALayer * toLayer); 369 370 bool appendToUncommittedAnimations(const KeyframeValueList&, const TransformOperations*, const Animation*, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation); 371#if ENABLE(CSS_FILTERS) 372 bool appendToUncommittedAnimations(const KeyframeValueList&, const FilterOperation*, const Animation*, const String& animationName, int animationIndex, double timeOffset); 373#endif 374 375 enum LayerChange { 376 NoChange = 0, 377 NameChanged = 1 << 1, 378 ChildrenChanged = 1 << 2, // also used for content layer, and preserves-3d, and size if tiling changes? 379 GeometryChanged = 1 << 3, 380 TransformChanged = 1 << 4, 381 ChildrenTransformChanged = 1 << 5, 382 Preserves3DChanged = 1 << 6, 383 MasksToBoundsChanged = 1 << 7, 384 DrawsContentChanged = 1 << 8, 385 BackgroundColorChanged = 1 << 9, 386 ContentsOpaqueChanged = 1 << 10, 387 BackfaceVisibilityChanged = 1 << 11, 388 OpacityChanged = 1 << 12, 389 AnimationChanged = 1 << 13, 390 DirtyRectsChanged = 1 << 14, 391 ContentsImageChanged = 1 << 15, 392 ContentsMediaLayerChanged = 1 << 16, 393 ContentsCanvasLayerChanged = 1 << 17, 394 ContentsColorLayerChanged = 1 << 18, 395 ContentsRectChanged = 1 << 19, 396 MaskLayerChanged = 1 << 20, 397 ReplicatedLayerChanged = 1 << 21, 398 ContentsNeedsDisplay = 1 << 22, 399 AcceleratesDrawingChanged = 1 << 23, 400 ContentsScaleChanged = 1 << 24, 401 ContentsVisibilityChanged = 1 << 25, 402 VisibleRectChanged = 1 << 26, 403 FiltersChanged = 1 << 27, 404 TilesAdded = 1 < 28, 405 DebugIndicatorsChanged = 1 << 29 406 }; 407 typedef unsigned LayerChangeFlags; 408 void noteLayerPropertyChanged(LayerChangeFlags flags); 409 void noteSublayersChanged(); 410 void noteChangesForScaleSensitiveProperties(); 411 412 void repaintLayerDirtyRects(); 413 414 RefPtr<PlatformCALayer> m_layer; // The main layer 415 RefPtr<PlatformCALayer> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer. 416 RefPtr<PlatformCALayer> m_contentsLayer; // A layer used for inner content, like image and video 417 418 // References to clones of our layers, for replicated layers. 419 OwnPtr<LayerMap> m_layerClones; 420 OwnPtr<LayerMap> m_structuralLayerClones; 421 OwnPtr<LayerMap> m_contentsLayerClones; 422 423#ifdef VISIBLE_TILE_WASH 424 RefPtr<PlatformCALayer> m_visibleTileWashLayer; 425#endif 426 FloatRect m_visibleRect; 427 FloatSize m_sizeAtLastVisibleRectUpdate; 428 429 enum ContentsLayerPurpose { 430 NoContentsLayer = 0, 431 ContentsLayerForImage, 432 ContentsLayerForMedia, 433 ContentsLayerForCanvas, 434 ContentsLayerForBackgroundColor 435 }; 436 437 ContentsLayerPurpose m_contentsLayerPurpose; 438 bool m_allowTiledLayer : 1; 439 bool m_isPageTiledBackingLayer : 1; 440 441 Color m_contentsSolidColor; 442 443 RetainPtr<CGImageRef> m_uncorrectedContentsImage; 444 RetainPtr<CGImageRef> m_pendingContentsImage; 445 446 // This represents the animation of a single property. There may be multiple transform animations for 447 // a single transition or keyframe animation, so index is used to distinguish these. 448 struct LayerPropertyAnimation { 449 LayerPropertyAnimation(PassRefPtr<PlatformCAAnimation> caAnimation, const String& animationName, AnimatedPropertyID property, int index, int subIndex, double timeOffset) 450 : m_animation(caAnimation) 451 , m_name(animationName) 452 , m_property(property) 453 , m_index(index) 454 , m_subIndex(subIndex) 455 , m_timeOffset(timeOffset) 456 { } 457 458 RefPtr<PlatformCAAnimation> m_animation; 459 String m_name; 460 AnimatedPropertyID m_property; 461 int m_index; 462 int m_subIndex; 463 double m_timeOffset; 464 }; 465 466 // Uncommitted transitions and animations. 467 Vector<LayerPropertyAnimation> m_uncomittedAnimations; 468 469 enum Action { Remove, Pause }; 470 struct AnimationProcessingAction { 471 AnimationProcessingAction(Action action = Remove, double timeOffset = 0) 472 : action(action) 473 , timeOffset(timeOffset) 474 { 475 } 476 Action action; 477 double timeOffset; // only used for pause 478 }; 479 typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap; 480 AnimationsToProcessMap m_animationsToProcess; 481 482 // Map of animation names to their associated lists of property animations, so we can remove/pause them. 483 typedef HashMap<String, Vector<LayerPropertyAnimation> > AnimationsMap; 484 AnimationsMap m_runningAnimations; 485 486 Vector<FloatRect> m_dirtyRects; 487 FloatSize m_pixelAlignmentOffset; 488 489 LayerChangeFlags m_uncommittedChanges; 490}; 491 492} // namespace WebCore 493 494 495#endif // USE(ACCELERATED_COMPOSITING) 496 497#endif // GraphicsLayerCA_h 498