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