1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2011, 2012 Collabora Ltd.
4 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef GraphicsLayerClutter_h
29#define GraphicsLayerClutter_h
30
31#if USE(ACCELERATED_COMPOSITING)
32
33#include "GraphicsLayer.h"
34#include "GraphicsLayerClient.h"
35#include "Image.h"
36#include "ImageSource.h"
37#include "PlatformClutterAnimation.h"
38#include "PlatformClutterLayerClient.h"
39#include <wtf/HashMap.h>
40#include <wtf/HashSet.h>
41#include <wtf/text/StringHash.h>
42
43#include <clutter/clutter.h>
44#include <wtf/gobject/GRefPtr.h>
45
46typedef struct _GraphicsLayerActor GraphicsLayerActor;
47
48namespace WebCore {
49
50class TransformState;
51
52typedef Vector<GRefPtr<GraphicsLayerActor> > GraphicsLayerActorList;
53
54class GraphicsLayerClutter : public GraphicsLayer, public PlatformClutterLayerClient {
55public:
56    enum LayerType { LayerTypeLayer, LayerTypeWebLayer, LayerTypeVideoLayer, LayerTypeTransformLayer, LayerTypeRootLayer, LayerTypeCustom };
57
58    GraphicsLayerClutter(GraphicsLayerClient*);
59    virtual ~GraphicsLayerClutter();
60
61    virtual ClutterActor* platformLayer() const;
62    virtual void addChild(GraphicsLayer*);
63    virtual void addChildAtIndex(GraphicsLayer*, int index);
64    virtual void addChildAbove(GraphicsLayer*, GraphicsLayer* sibling);
65    virtual void addChildBelow(GraphicsLayer*, GraphicsLayer* sibling);
66
67    virtual void removeFromParent();
68
69    virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
70    virtual bool setChildren(const Vector<GraphicsLayer*>&);
71    virtual void setParent(GraphicsLayer*);
72
73    virtual void setDrawsContent(bool);
74    virtual void setAnchorPoint(const FloatPoint3D&);
75    virtual void setOpacity(float);
76    virtual void setPosition(const FloatPoint&);
77    virtual void setSize(const FloatSize&);
78
79    virtual void setTransform(const TransformationMatrix&);
80    virtual void setName(const String&);
81    virtual void setNeedsDisplay();
82    virtual void setNeedsDisplayInRect(const FloatRect&);
83    virtual void setContentsNeedsDisplay();
84
85    virtual void setContentsToImage(Image*);
86    virtual void setContentsRect(const IntRect&);
87
88    virtual bool hasContentsLayer() const { return m_contentsLayer; }
89
90    virtual void setPreserves3D(bool);
91    virtual void setMasksToBounds(bool);
92
93    virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& animationName, double timeOffset);
94    virtual void removeAnimation(const String& animationName);
95
96    virtual void flushCompositingState(const FloatRect&);
97    virtual void flushCompositingStateForThisLayerOnly();
98
99    struct CommitState {
100        bool ancestorHasTransformAnimation;
101        CommitState()
102            : ancestorHasTransformAnimation(false)
103        { }
104    };
105    void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
106
107private:
108    FloatPoint computePositionRelativeToBase(float& pageScale) const;
109
110    bool animationIsRunning(const String& animationName) const
111    {
112        return m_runningAnimations.find(animationName) != m_runningAnimations.end();
113    }
114
115    void commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase);
116    void commitLayerChangesAfterSublayers();
117
118    void updateOpacityOnLayer();
119    void setupContentsLayer(GraphicsLayerActor*);
120    GraphicsLayerActor* contentsLayer() const { return m_contentsLayer.get(); }
121
122    virtual void platformClutterLayerAnimationStarted(double beginTime);
123    virtual void platformClutterLayerPaintContents(GraphicsContext&, const IntRect& clip);
124
125    GraphicsLayerActor* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); }
126    GraphicsLayerActor* layerForSuperlayer() const;
127    GraphicsLayerActor* animatedLayer(AnimatedPropertyID) const;
128
129    PassRefPtr<PlatformClutterAnimation> createBasicAnimation(const Animation*, const String& keyPath, bool additive);
130    PassRefPtr<PlatformClutterAnimation> createKeyframeAnimation(const Animation*, const String&, bool additive);
131    void setupAnimation(PlatformClutterAnimation*, const Animation*, bool additive);
132
133    const TimingFunction* timingFunctionForAnimationValue(const AnimationValue&, const Animation&);
134
135    bool setAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformClutterAnimation*);
136    bool setAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformClutterAnimation*);
137
138    void setAnimationOnLayer(PlatformClutterAnimation*, AnimatedPropertyID, const String& animationName, int index, double timeOffset);
139    bool removeClutterAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index);
140    void pauseClutterAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, double timeOffset);
141
142    bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
143    bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize);
144
145    bool setTransformAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformClutterAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
146    bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformClutterAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
147
148    enum MoveOrCopy { Move, Copy };
149    static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, GraphicsLayerActor* fromLayer, GraphicsLayerActor* toLayer);
150    void moveOrCopyAnimations(MoveOrCopy, GraphicsLayerActor* fromLayer, GraphicsLayerActor* toLayer);
151
152    bool appendToUncommittedAnimations(const KeyframeValueList&, const TransformOperations*, const Animation*, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation);
153
154    enum LayerChange {
155        NoChange = 0,
156        NameChanged = 1 << 1,
157        ChildrenChanged = 1 << 2, // also used for content layer, and preserves-3d, and size if tiling changes?
158        GeometryChanged = 1 << 3,
159        TransformChanged = 1 << 4,
160        ChildrenTransformChanged = 1 << 5,
161        Preserves3DChanged = 1 << 6,
162        MasksToBoundsChanged = 1 << 7,
163        DrawsContentChanged = 1 << 8, // need this?
164        BackgroundColorChanged = 1 << 9,
165        ContentsOpaqueChanged = 1 << 10,
166        BackfaceVisibilityChanged = 1 << 11,
167        OpacityChanged = 1 << 12,
168        AnimationChanged = 1 << 13,
169        DirtyRectsChanged = 1 << 14,
170        ContentsImageChanged = 1 << 15,
171        ContentsMediaLayerChanged = 1 << 16,
172        ContentsCanvasLayerChanged = 1 << 17,
173        ContentsColorLayerChanged = 1 << 18,
174        ContentsRectChanged = 1 << 19,
175        MaskLayerChanged = 1 << 20,
176        ReplicatedLayerChanged = 1 << 21,
177        ContentsNeedsDisplay = 1 << 22,
178        AcceleratesDrawingChanged = 1 << 23,
179        ContentsScaleChanged = 1 << 24,
180        ContentsVisibilityChanged = 1 << 25,
181        VisibleRectChanged = 1 << 26,
182        FiltersChanged = 1 << 27,
183        DebugIndicatorsChanged = 1 << 28
184    };
185
186    typedef unsigned LayerChangeFlags;
187    void noteLayerPropertyChanged(LayerChangeFlags);
188    void noteSublayersChanged();
189
190    void updateBackfaceVisibility();
191    void updateStructuralLayer();
192    void updateLayerNames();
193    void updateSublayerList();
194    void updateGeometry(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase);
195    void updateTransform();
196    void updateMasksToBounds();
197    void updateLayerDrawsContent(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase);
198    void updateContentsImage();
199    void updateContentsRect();
200    void updateContentsNeedsDisplay();
201    void updateAnimations();
202
203    enum StructuralLayerPurpose {
204        NoStructuralLayer = 0,
205        StructuralLayerForPreserves3D,
206        StructuralLayerForReplicaFlattening
207    };
208    void ensureStructuralLayer(StructuralLayerPurpose);
209    StructuralLayerPurpose structuralLayerPurpose() const;
210
211    void repaintLayerDirtyRects();
212
213    GRefPtr<GraphicsLayerActor> m_layer;
214    GRefPtr<GraphicsLayerActor> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer.
215    GRefPtr<GraphicsLayerActor> m_contentsLayer; // A layer used for inner content, like image and video
216    enum ContentsLayerPurpose {
217        NoContentsLayer = 0,
218        ContentsLayerForImage,
219        ContentsLayerForMedia,
220        ContentsLayerForCanvas,
221        ContentsLayerForBackgroundColor
222    };
223
224    ContentsLayerPurpose m_contentsLayerPurpose;
225    RefPtr<cairo_surface_t> m_pendingContentsImage;
226
227    Vector<FloatRect> m_dirtyRects;
228    LayerChangeFlags m_uncommittedChanges;
229
230    // This represents the animation of a single property. There may be multiple transform animations for
231    // a single transition or keyframe animation, so index is used to distinguish these.
232    struct LayerPropertyAnimation {
233        LayerPropertyAnimation(PassRefPtr<PlatformClutterAnimation> caAnimation, const String& animationName, AnimatedPropertyID property, int index, double timeOffset)
234        : m_animation(caAnimation)
235        , m_name(animationName)
236        , m_property(property)
237        , m_index(index)
238        , m_timeOffset(timeOffset)
239        { }
240
241        RefPtr<PlatformClutterAnimation> m_animation;
242        String m_name;
243        AnimatedPropertyID m_property;
244        int m_index;
245        double m_timeOffset;
246    };
247
248    // Uncommitted transitions and animations.
249    Vector<LayerPropertyAnimation> m_uncomittedAnimations;
250
251    enum Action { Remove, Pause };
252    struct AnimationProcessingAction {
253        AnimationProcessingAction(Action action = Remove, double timeOffset = 0)
254            : action(action)
255            , timeOffset(timeOffset)
256        {
257        }
258        Action action;
259        double timeOffset; // only used for pause
260    };
261    typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
262    AnimationsToProcessMap m_animationsToProcess;
263
264    // Map of animation names to their associated lists of property animations, so we can remove/pause them.
265    typedef HashMap<String, Vector<LayerPropertyAnimation> > AnimationsMap;
266    AnimationsMap m_runningAnimations;
267};
268
269} // namespace WebCore
270
271#endif // USE(ACCELERATED_COMPOSITING)
272
273#endif // GraphicsLayerClutter_h
274