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 namespace WebCore { 41 42 class PlatformCALayer; 43 44 class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient { 45 public: 46 // The width and height of a single tile in a tiled layer. Should be large enough to 47 // avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough 48 // to keep the overall tile cost low. 49 static const int kTiledLayerTileSize = 512; 50 51 GraphicsLayerCA(GraphicsLayerClient*); 52 virtual ~GraphicsLayerCA(); 53 54 virtual void setName(const String&); 55 56 virtual PlatformLayer* platformLayer() const; 57 virtual PlatformCALayer* platformCALayer() const { return primaryLayer(); } 58 59 virtual float contentsScale() const { return m_contentsScale; } 60 virtual void setContentsScale(float); 61 62 virtual bool setChildren(const Vector<GraphicsLayer*>&); 63 virtual void addChild(GraphicsLayer*); 64 virtual void addChildAtIndex(GraphicsLayer*, int index); 65 virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling); 66 virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling); 67 virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild); 68 69 virtual void removeFromParent(); 70 71 virtual void setMaskLayer(GraphicsLayer*); 72 virtual void setReplicatedLayer(GraphicsLayer*); 73 74 virtual void setPosition(const FloatPoint&); 75 virtual void setAnchorPoint(const FloatPoint3D&); 76 virtual void setSize(const FloatSize&); 77 78 virtual void setTransform(const TransformationMatrix&); 79 80 virtual void setChildrenTransform(const TransformationMatrix&); 81 82 virtual void setPreserves3D(bool); 83 virtual void setMasksToBounds(bool); 84 virtual void setDrawsContent(bool); 85 virtual void setAcceleratesDrawing(bool); 86 87 virtual void setBackgroundColor(const Color&); 88 virtual void clearBackgroundColor(); 89 90 virtual void setContentsOpaque(bool); 91 virtual void setBackfaceVisibility(bool); 92 93 // return true if we started an animation 94 virtual void setOpacity(float); 95 96 virtual void setNeedsDisplay(); 97 virtual void setNeedsDisplayInRect(const FloatRect&); 98 virtual void setContentsNeedsDisplay(); 99 100 virtual void setContentsRect(const IntRect&); 101 102 virtual void suspendAnimations(double time); 103 virtual void resumeAnimations(); 104 105 virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& animationName, double timeOffset); 106 virtual void pauseAnimation(const String& animationName, double timeOffset); 107 virtual void removeAnimation(const String& animationName); 108 109 virtual void setContentsToImage(Image*); 110 virtual void setContentsToMedia(PlatformLayer*); 111 virtual void setContentsToCanvas(PlatformLayer*); 112 113 virtual bool hasContentsLayer() const { return m_contentsLayer; } 114 115 virtual void setDebugBackgroundColor(const Color&); 116 virtual void setDebugBorder(const Color&, float borderWidth); 117 118 virtual void layerDidDisplay(PlatformLayer*); 119 120 void recursiveCommitChanges(); 121 122 virtual void syncCompositingState(); 123 virtual void syncCompositingStateForThisLayerOnly(); 124 125 bool allowTiledLayer() const { return m_allowTiledLayer; } 126 virtual void setAllowTiledLayer(bool b); 127 128 protected: 129 virtual void setOpacityInternal(float); 130 131 private: 132 // PlatformCALayerClient overrides 133 virtual void platformCALayerLayoutSublayersOfLayer(PlatformCALayer*) { } 134 virtual bool platformCALayerRespondsToLayoutChanges() const { return false; } 135 136 virtual void platformCALayerAnimationStarted(CFTimeInterval beginTime); 137 virtual CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return contentsOrientation(); } 138 virtual void platformCALayerPaintContents(GraphicsContext& context, const IntRect& clip) { paintGraphicsLayerContents(context, clip); } 139 virtual bool platformCALayerShowDebugBorders() const { return showDebugBorders(); } 140 virtual bool platformCALayerShowRepaintCounter() const { return showRepaintCounter(); } 141 virtual int platformCALayerIncrementRepaintCount() { return incrementRepaintCount(); } 142 143 virtual bool platformCALayerContentsOpaque() const { return contentsOpaque(); } 144 virtual bool platformCALayerDrawsContent() const { return drawsContent(); } 145 virtual void platformCALayerLayerDidDisplay(PlatformLayer* layer) { return layerDidDisplay(layer); } 146 147 void updateOpacityOnLayer(); 148 149 PlatformCALayer* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); } 150 PlatformCALayer* hostLayerForSublayers() const; 151 PlatformCALayer* layerForSuperlayer() const; 152 PlatformCALayer* animatedLayer(AnimatedPropertyID) const; 153 154 typedef String CloneID; // Identifier for a given clone, based on original/replica branching down the tree. 155 static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; } 156 157 typedef HashMap<CloneID, RefPtr<PlatformCALayer> > LayerMap; 158 LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); } 159 LayerMap* animatedLayerClones(AnimatedPropertyID) const; 160 161 bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset); 162 bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize); 163 164 // Return autoreleased animation (use RetainPtr?) 165 PassRefPtr<PlatformCAAnimation> createBasicAnimation(const Animation*, AnimatedPropertyID, bool additive); 166 PassRefPtr<PlatformCAAnimation> createKeyframeAnimation(const Animation*, AnimatedPropertyID, bool additive); 167 void setupAnimation(PlatformCAAnimation*, const Animation*, bool additive); 168 169 const TimingFunction* timingFunctionForAnimationValue(const AnimationValue*, const Animation*); 170 171 bool setAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*); 172 bool setAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*); 173 174 bool setTransformAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize); 175 bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize); 176 177 bool animationIsRunning(const String& animationName) const 178 { 179 return m_runningAnimations.find(animationName) != m_runningAnimations.end(); 180 } 181 182 void commitLayerChangesBeforeSublayers(); 183 void commitLayerChangesAfterSublayers(); 184 185 FloatSize constrainedSize() const; 186 187 bool requiresTiledLayer(const FloatSize&) const; 188 void swapFromOrToTiledLayer(bool useTiledLayer); 189 190 CompositingCoordinatesOrientation defaultContentsOrientation() const; 191 void updateContentsTransform(); 192 193 void setupContentsLayer(PlatformCALayer*); 194 PlatformCALayer* contentsLayer() const { return m_contentsLayer.get(); } 195 196 virtual void setReplicatedByLayer(GraphicsLayer*); 197 198 // Used to track the path down the tree for replica layers. 199 struct ReplicaState { 200 static const size_t maxReplicaDepth = 16; 201 enum ReplicaBranchType { ChildBranch = 0, ReplicaBranch = 1 }; 202 ReplicaState(ReplicaBranchType firstBranch) 203 : m_replicaDepth(0) 204 { 205 push(firstBranch); 206 } 207 208 // Called as we walk down the tree to build replicas. 209 void push(ReplicaBranchType branchType) 210 { 211 m_replicaBranches.append(branchType); 212 if (branchType == ReplicaBranch) 213 ++m_replicaDepth; 214 } 215 216 void setBranchType(ReplicaBranchType branchType) 217 { 218 ASSERT(!m_replicaBranches.isEmpty()); 219 220 if (m_replicaBranches.last() != branchType) { 221 if (branchType == ReplicaBranch) 222 ++m_replicaDepth; 223 else 224 --m_replicaDepth; 225 } 226 227 m_replicaBranches.last() = branchType; 228 } 229 230 void pop() 231 { 232 if (m_replicaBranches.last() == ReplicaBranch) 233 --m_replicaDepth; 234 m_replicaBranches.removeLast(); 235 } 236 237 size_t depth() const { return m_replicaBranches.size(); } 238 size_t replicaDepth() const { return m_replicaDepth; } 239 240 CloneID cloneID() const; 241 242 private: 243 Vector<ReplicaBranchType> m_replicaBranches; 244 size_t m_replicaDepth; 245 }; 246 PassRefPtr<PlatformCALayer>replicatedLayerRoot(ReplicaState&); 247 248 enum CloneLevel { RootCloneLevel, IntermediateCloneLevel }; 249 PassRefPtr<PlatformCALayer> fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState&, CloneLevel); 250 251 PassRefPtr<PlatformCALayer> cloneLayer(PlatformCALayer *, CloneLevel); 252 PassRefPtr<PlatformCALayer> findOrMakeClone(CloneID, PlatformCALayer *, LayerMap*, CloneLevel); 253 254 void ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel); 255 256 bool hasCloneLayers() const { return m_layerClones; } 257 void removeCloneLayers(); 258 FloatPoint positionForCloneRootLayer() const; 259 260 void propagateLayerChangeToReplicas(); 261 262 // All these "update" methods will be called inside a BEGIN_BLOCK_OBJC_EXCEPTIONS/END_BLOCK_OBJC_EXCEPTIONS block. 263 void updateLayerNames(); 264 void updateSublayerList(); 265 void updateLayerPosition(); 266 void updateLayerSize(); 267 void updateAnchorPoint(); 268 void updateTransform(); 269 void updateChildrenTransform(); 270 void updateMasksToBounds(); 271 void updateContentsOpaque(); 272 void updateBackfaceVisibility(); 273 void updateStructuralLayer(); 274 void updateLayerDrawsContent(); 275 void updateLayerBackgroundColor(); 276 277 void updateContentsImage(); 278 void updateContentsMediaLayer(); 279 void updateContentsCanvasLayer(); 280 void updateContentsRect(); 281 void updateMaskLayer(); 282 void updateReplicatedLayers(); 283 284 void updateLayerAnimations(); 285 void updateContentsNeedsDisplay(); 286 void updateAcceleratesDrawing(); 287 void updateContentsScale(); 288 289 enum StructuralLayerPurpose { 290 NoStructuralLayer = 0, 291 StructuralLayerForPreserves3D, 292 StructuralLayerForReplicaFlattening 293 }; 294 void ensureStructuralLayer(StructuralLayerPurpose); 295 StructuralLayerPurpose structuralLayerPurpose() const; 296 297 void setAnimationOnLayer(PlatformCAAnimation*, AnimatedPropertyID, const String& animationName, int index, double timeOffset); 298 bool removeCAAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index); 299 void pauseCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, double timeOffset); 300 301 enum MoveOrCopy { Move, Copy }; 302 static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer); 303 void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID, PlatformCALayer * fromLayer, PlatformCALayer * toLayer); 304 305 enum LayerChange { 306 NoChange = 0, 307 NameChanged = 1 << 1, 308 ChildrenChanged = 1 << 2, // also used for content layer, and preserves-3d, and size if tiling changes? 309 PositionChanged = 1 << 3, 310 AnchorPointChanged = 1 << 4, 311 SizeChanged = 1 << 5, 312 TransformChanged = 1 << 6, 313 ChildrenTransformChanged = 1 << 7, 314 Preserves3DChanged = 1 << 8, 315 MasksToBoundsChanged = 1 << 9, 316 DrawsContentChanged = 1 << 10, // need this? 317 BackgroundColorChanged = 1 << 11, 318 ContentsOpaqueChanged = 1 << 12, 319 BackfaceVisibilityChanged = 1 << 13, 320 OpacityChanged = 1 << 14, 321 AnimationChanged = 1 << 15, 322 DirtyRectsChanged = 1 << 16, 323 ContentsImageChanged = 1 << 17, 324 ContentsMediaLayerChanged = 1 << 18, 325 ContentsCanvasLayerChanged = 1 << 19, 326 ContentsRectChanged = 1 << 20, 327 MaskLayerChanged = 1 << 21, 328 ReplicatedLayerChanged = 1 << 22, 329 ContentsNeedsDisplay = 1 << 23, 330 AcceleratesDrawingChanged = 1 << 24, 331 ContentsScaleChanged = 1 << 25 332 }; 333 typedef unsigned LayerChangeFlags; 334 void noteLayerPropertyChanged(LayerChangeFlags flags); 335 void noteSublayersChanged(); 336 337 void repaintLayerDirtyRects(); 338 339 RefPtr<PlatformCALayer> m_layer; // The main layer 340 RefPtr<PlatformCALayer> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer. 341 RefPtr<PlatformCALayer> m_contentsLayer; // A layer used for inner content, like image and video 342 343 // References to clones of our layers, for replicated layers. 344 OwnPtr<LayerMap> m_layerClones; 345 OwnPtr<LayerMap> m_structuralLayerClones; 346 OwnPtr<LayerMap> m_contentsLayerClones; 347 348 enum ContentsLayerPurpose { 349 NoContentsLayer = 0, 350 ContentsLayerForImage, 351 ContentsLayerForMedia, 352 ContentsLayerForCanvas 353 }; 354 355 ContentsLayerPurpose m_contentsLayerPurpose; 356 bool m_contentsLayerHasBackgroundColor : 1; 357 358 RetainPtr<CGImageRef> m_uncorrectedContentsImage; 359 RetainPtr<CGImageRef> m_pendingContentsImage; 360 361 // This represents the animation of a single property. There may be multiple transform animations for 362 // a single transition or keyframe animation, so index is used to distinguish these. 363 struct LayerPropertyAnimation { 364 LayerPropertyAnimation(PassRefPtr<PlatformCAAnimation> caAnimation, const String& animationName, AnimatedPropertyID property, int index, double timeOffset) 365 : m_animation(caAnimation) 366 , m_name(animationName) 367 , m_property(property) 368 , m_index(index) 369 , m_timeOffset(timeOffset) 370 { } 371 372 RefPtr<PlatformCAAnimation> m_animation; 373 String m_name; 374 AnimatedPropertyID m_property; 375 int m_index; 376 double m_timeOffset; 377 }; 378 379 // Uncommitted transitions and animations. 380 Vector<LayerPropertyAnimation> m_uncomittedAnimations; 381 382 enum Action { Remove, Pause }; 383 struct AnimationProcessingAction { 384 AnimationProcessingAction(Action action = Remove, double timeOffset = 0) 385 : action(action) 386 , timeOffset(timeOffset) 387 { 388 } 389 Action action; 390 double timeOffset; // only used for pause 391 }; 392 typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap; 393 AnimationsToProcessMap m_animationsToProcess; 394 395 // Map of animation names to their associated lists of property animations, so we can remove/pause them. 396 typedef HashMap<String, Vector<LayerPropertyAnimation> > AnimationsMap; 397 AnimationsMap m_runningAnimations; 398 399 Vector<FloatRect> m_dirtyRects; 400 401 LayerChangeFlags m_uncommittedChanges; 402 403 float clampedContentsScaleForScale(float) const; 404 float m_contentsScale; 405 406 bool m_allowTiledLayer; 407 }; 408 409 } // namespace WebCore 410 411 412 #endif // USE(ACCELERATED_COMPOSITING) 413 414 #endif // GraphicsLayerCA_h 415