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