Home | History | Annotate | Download | only in mac
      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