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 GraphicsLayer_h
27#define GraphicsLayer_h
28
29#include "core/platform/animation/CSSAnimationData.h"
30#include "core/platform/graphics/Color.h"
31#include "core/platform/graphics/FloatPoint.h"
32#include "core/platform/graphics/FloatPoint3D.h"
33#include "core/platform/graphics/FloatSize.h"
34#include "core/platform/graphics/GraphicsLayerClient.h"
35#include "core/platform/graphics/IntRect.h"
36#include "core/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h"
37#include "core/platform/graphics/filters/FilterOperations.h"
38#include "core/platform/graphics/transforms/TransformOperations.h"
39#include "core/platform/graphics/transforms/TransformationMatrix.h"
40
41#include "wtf/HashMap.h"
42#include "wtf/OwnPtr.h"
43#include "wtf/PassOwnPtr.h"
44
45#include "public/platform/WebAnimationDelegate.h"
46#include "public/platform/WebCompositingReasons.h"
47#include "public/platform/WebContentLayer.h"
48#include "public/platform/WebImageLayer.h"
49#include "public/platform/WebLayerScrollClient.h"
50#include "public/platform/WebSolidColorLayer.h"
51
52namespace WebKit {
53class GraphicsLayerFactoryChromium;
54class WebLayer;
55}
56
57namespace WebCore {
58
59class FloatRect;
60class GraphicsContext;
61class GraphicsLayerFactory;
62class Image;
63class ScrollableArea;
64class TextStream;
65class TimingFunction;
66
67// Base class for animation values (also used for transitions). Here to
68// represent values for properties being animated via the GraphicsLayer,
69// without pulling in style-related data from outside of the platform directory.
70// FIXME: Should be moved to its own header file.
71class AnimationValue {
72    WTF_MAKE_FAST_ALLOCATED;
73public:
74    explicit AnimationValue(float keyTime, PassRefPtr<TimingFunction> timingFunction = 0)
75        : m_keyTime(keyTime)
76        , m_timingFunction(timingFunction)
77    {
78    }
79
80    virtual ~AnimationValue() { }
81
82    float keyTime() const { return m_keyTime; }
83    const TimingFunction* timingFunction() const { return m_timingFunction.get(); }
84    virtual PassOwnPtr<AnimationValue> clone() const = 0;
85
86private:
87    float m_keyTime;
88    RefPtr<TimingFunction> m_timingFunction;
89};
90
91// Used to store one float value of an animation.
92// FIXME: Should be moved to its own header file.
93class FloatAnimationValue : public AnimationValue {
94public:
95    FloatAnimationValue(float keyTime, float value, PassRefPtr<TimingFunction> timingFunction = 0)
96        : AnimationValue(keyTime, timingFunction)
97        , m_value(value)
98    {
99    }
100    virtual PassOwnPtr<AnimationValue> clone() const OVERRIDE { return adoptPtr(new FloatAnimationValue(*this)); }
101
102    float value() const { return m_value; }
103
104private:
105    float m_value;
106};
107
108// Used to store one transform value in a keyframe list.
109// FIXME: Should be moved to its own header file.
110class TransformAnimationValue : public AnimationValue {
111public:
112    explicit TransformAnimationValue(float keyTime, const TransformOperations* value = 0, PassRefPtr<TimingFunction> timingFunction = 0)
113        : AnimationValue(keyTime, timingFunction)
114    {
115        if (value)
116            m_value = *value;
117    }
118    virtual PassOwnPtr<AnimationValue> clone() const OVERRIDE { return adoptPtr(new TransformAnimationValue(*this)); }
119
120    const TransformOperations* value() const { return &m_value; }
121
122private:
123    TransformOperations m_value;
124};
125
126// Used to store one filter value in a keyframe list.
127// FIXME: Should be moved to its own header file.
128class FilterAnimationValue : public AnimationValue {
129public:
130    explicit FilterAnimationValue(float keyTime, const FilterOperations* value = 0, PassRefPtr<TimingFunction> timingFunction = 0)
131        : AnimationValue(keyTime, timingFunction)
132    {
133        if (value)
134            m_value = *value;
135    }
136    virtual PassOwnPtr<AnimationValue> clone() const OVERRIDE { return adoptPtr(new FilterAnimationValue(*this)); }
137
138    const FilterOperations* value() const { return &m_value; }
139
140private:
141    FilterOperations m_value;
142};
143
144// Used to store a series of values in a keyframe list.
145// Values will all be of the same type, which can be inferred from the property.
146// FIXME: Should be moved to its own header file.
147class KeyframeValueList {
148public:
149    explicit KeyframeValueList(AnimatedPropertyID property)
150        : m_property(property)
151    {
152    }
153
154    KeyframeValueList(const KeyframeValueList& other)
155        : m_property(other.property())
156    {
157        for (size_t i = 0; i < other.m_values.size(); ++i)
158            m_values.append(other.m_values[i]->clone());
159    }
160
161    KeyframeValueList& operator=(const KeyframeValueList& other)
162    {
163        KeyframeValueList copy(other);
164        swap(copy);
165        return *this;
166    }
167
168    void swap(KeyframeValueList& other)
169    {
170        std::swap(m_property, other.m_property);
171        m_values.swap(other.m_values);
172    }
173
174    AnimatedPropertyID property() const { return m_property; }
175
176    size_t size() const { return m_values.size(); }
177    const AnimationValue* at(size_t i) const { return m_values.at(i).get(); }
178
179    // Insert, sorted by keyTime.
180    void insert(PassOwnPtr<const AnimationValue>);
181
182protected:
183    Vector<OwnPtr<const AnimationValue> > m_values;
184    AnimatedPropertyID m_property;
185};
186
187// FIXME: find a better home for this declaration.
188class LinkHighlightClient {
189public:
190    virtual void invalidate() = 0;
191    virtual void clearCurrentGraphicsLayer() = 0;
192    virtual WebKit::WebLayer* layer() = 0;
193
194protected:
195    virtual ~LinkHighlightClient() { }
196};
197
198// GraphicsLayer is an abstraction for a rendering surface with backing store,
199// which may have associated transformation and animations.
200
201class GraphicsLayer : public GraphicsContextPainter, public WebKit::WebAnimationDelegate, public WebKit::WebLayerScrollClient {
202    WTF_MAKE_NONCOPYABLE(GraphicsLayer); WTF_MAKE_FAST_ALLOCATED;
203public:
204    enum ContentsLayerPurpose {
205        NoContentsLayer = 0,
206        ContentsLayerForImage,
207        ContentsLayerForVideo,
208        ContentsLayerForCanvas,
209    };
210
211    static PassOwnPtr<GraphicsLayer> create(GraphicsLayerFactory*, GraphicsLayerClient*);
212
213    virtual ~GraphicsLayer();
214
215    GraphicsLayerClient* client() const { return m_client; }
216
217    // Layer name. Only used to identify layers in debug output
218    const String& name() const { return m_name; }
219    void setName(const String&);
220
221    void setCompositingReasons(WebKit::WebCompositingReasons);
222
223    GraphicsLayer* parent() const { return m_parent; };
224    void setParent(GraphicsLayer*); // Internal use only.
225
226    // Returns true if the layer has the given layer as an ancestor (excluding self).
227    bool hasAncestor(GraphicsLayer*) const;
228
229    const Vector<GraphicsLayer*>& children() const { return m_children; }
230    // Returns true if the child list changed.
231    bool setChildren(const Vector<GraphicsLayer*>&);
232
233    // Add child layers. If the child is already parented, it will be removed from its old parent.
234    void addChild(GraphicsLayer*);
235    void addChildAtIndex(GraphicsLayer*, int index);
236    void addChildAbove(GraphicsLayer*, GraphicsLayer* sibling);
237    void addChildBelow(GraphicsLayer*, GraphicsLayer* sibling);
238    bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
239
240    void removeAllChildren();
241    void removeFromParent();
242
243    GraphicsLayer* maskLayer() const { return m_maskLayer; }
244    void setMaskLayer(GraphicsLayer*);
245
246    // The given layer will replicate this layer and its children; the replica renders behind this layer.
247    void setReplicatedByLayer(GraphicsLayer*);
248    // Whether this layer is being replicated by another layer.
249    bool isReplicated() const { return m_replicaLayer; }
250    // The layer that replicates this layer (if any).
251    GraphicsLayer* replicaLayer() const { return m_replicaLayer; }
252
253    const FloatPoint& replicatedLayerPosition() const { return m_replicatedLayerPosition; }
254    void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; }
255
256    enum ShouldSetNeedsDisplay {
257        DontSetNeedsDisplay,
258        SetNeedsDisplay
259    };
260
261    // Offset is origin of the renderer minus origin of the graphics layer (so either zero or negative).
262    IntSize offsetFromRenderer() const { return m_offsetFromRenderer; }
263    void setOffsetFromRenderer(const IntSize&, ShouldSetNeedsDisplay = SetNeedsDisplay);
264
265    // The position of the layer (the location of its top-left corner in its parent)
266    const FloatPoint& position() const { return m_position; }
267    void setPosition(const FloatPoint&);
268
269    // Anchor point: (0, 0) is top left, (1, 1) is bottom right. The anchor point
270    // affects the origin of the transforms.
271    const FloatPoint3D& anchorPoint() const { return m_anchorPoint; }
272    void setAnchorPoint(const FloatPoint3D&);
273
274    // The size of the layer.
275    const FloatSize& size() const { return m_size; }
276    void setSize(const FloatSize&);
277
278    // The boundOrigin affects the offset at which content is rendered, and sublayers are positioned.
279    const FloatPoint& boundsOrigin() const { return m_boundsOrigin; }
280    void setBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; }
281
282    const TransformationMatrix& transform() const { return m_transform; }
283    void setTransform(const TransformationMatrix&);
284
285    const TransformationMatrix& childrenTransform() const { return m_childrenTransform; }
286    void setChildrenTransform(const TransformationMatrix&);
287
288    bool preserves3D() const { return m_preserves3D; }
289    void setPreserves3D(bool);
290
291    bool masksToBounds() const { return m_masksToBounds; }
292    void setMasksToBounds(bool);
293
294    bool drawsContent() const { return m_drawsContent; }
295    void setDrawsContent(bool);
296
297    bool contentsAreVisible() const { return m_contentsVisible; }
298    void setContentsVisible(bool);
299
300    // For special cases, e.g. drawing missing tiles on Android.
301    // The compositor should never paint this color in normal cases because the RenderLayer
302    // will paint background by itself.
303    const Color& backgroundColor() const { return m_backgroundColor; }
304    void setBackgroundColor(const Color&);
305
306    // opaque means that we know the layer contents have no alpha
307    bool contentsOpaque() const { return m_contentsOpaque; }
308    void setContentsOpaque(bool);
309
310    bool backfaceVisibility() const { return m_backfaceVisibility; }
311    void setBackfaceVisibility(bool visible);
312
313    float opacity() const { return m_opacity; }
314    void setOpacity(float);
315
316    const FilterOperations& filters() const { return m_filters; }
317
318    // Returns true if filter can be rendered by the compositor
319    bool setFilters(const FilterOperations&);
320    void setBackgroundFilters(const FilterOperations&);
321
322    // Some GraphicsLayers paint only the foreground or the background content
323    GraphicsLayerPaintingPhase paintingPhase() const { return m_paintingPhase; }
324    void setPaintingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; }
325
326    void setNeedsDisplay();
327    // mark the given rect (in layer coords) as needing dispay. Never goes deep.
328    void setNeedsDisplayInRect(const FloatRect&);
329
330    void setContentsNeedsDisplay();
331
332    // Set that the position/size of the contents (image or video).
333    IntRect contentsRect() const { return m_contentsRect; }
334    void setContentsRect(const IntRect&);
335
336    // Transitions are identified by a special animation name that cannot clash with a keyframe identifier.
337    static String animationNameForTransition(AnimatedPropertyID);
338
339    // Return true if the animation is handled by the compositing system. If this returns
340    // false, the animation will be run by AnimationController.
341    // These methods handle both transitions and keyframe animations.
342    bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const CSSAnimationData*, const String& /*animationName*/, double /*timeOffset*/);
343    void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/);
344    void removeAnimation(const String& /*animationName*/);
345
346    void suspendAnimations(double time);
347    void resumeAnimations();
348
349    // Layer contents
350    void setContentsToImage(Image*);
351    bool shouldDirectlyCompositeImage(Image*) const { return true; }
352    void setContentsToMedia(WebKit::WebLayer*); // video or plug-in
353    // Pass an invalid color to remove the contents layer.
354    void setContentsToSolidColor(const Color&) { }
355    void setContentsToCanvas(WebKit::WebLayer*);
356    // FIXME: webkit.org/b/109658
357    // Should unify setContentsToMedia and setContentsToCanvas
358    void setContentsToPlatformLayer(WebKit::WebLayer* layer) { setContentsToMedia(layer); }
359    bool hasContentsLayer() const { return m_contentsLayer; }
360
361    // Callback from the underlying graphics system to draw layer contents.
362    void paintGraphicsLayerContents(GraphicsContext&, const IntRect& clip);
363    // Callback from the underlying graphics system when the layer has been displayed
364    void layerDidDisplay(WebKit::WebLayer*) { }
365
366    // For hosting this GraphicsLayer in a native layer hierarchy.
367    WebKit::WebLayer* platformLayer() const;
368
369    enum CompositingCoordinatesOrientation { CompositingCoordinatesTopDown, CompositingCoordinatesBottomUp };
370
371    // Flippedness of the contents of this layer. Does not affect sublayer geometry.
372    void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; }
373    CompositingCoordinatesOrientation contentsOrientation() const { return m_contentsOrientation; }
374
375    void dumpLayer(TextStream&, int indent = 0, LayerTreeFlags = LayerTreeNormal) const;
376
377    void setShowRepaintCounter(bool show) { m_showRepaintCounter = show; }
378    bool isShowingRepaintCounter() const { return m_showRepaintCounter; }
379
380    // FIXME: this is really a paint count.
381    int repaintCount() const { return m_repaintCount; }
382    int incrementRepaintCount() { return ++m_repaintCount; }
383
384    // z-position is the z-equivalent of position(). It's only used for debugging purposes.
385    float zPosition() const { return m_zPosition; }
386    void setZPosition(float);
387
388    void distributeOpacity(float);
389    float accumulatedOpacity() const;
390
391    // If the exposed rect of this layer changes, returns true if this or descendant layers need a flush,
392    // for example to allocate new tiles.
393    bool visibleRectChangeRequiresFlush(const FloatRect& /* clipRect */) const { return false; }
394
395    // Return a string with a human readable form of the layer tree, If debug is true
396    // pointers for the layers and timing data will be included in the returned string.
397    String layerTreeAsText(LayerTreeFlags = LayerTreeNormal) const;
398
399    // Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers.
400    double backingStoreMemoryEstimate() const;
401
402    void resetTrackedRepaints();
403    void addRepaintRect(const FloatRect&);
404
405    static bool supportsBackgroundColorContent()
406    {
407        return false;
408    }
409
410    void setLinkHighlight(LinkHighlightClient*);
411    // Exposed for tests
412    LinkHighlightClient* linkHighlight() { return m_linkHighlight; }
413
414    void setScrollableArea(ScrollableArea*, bool isMainFrame);
415    ScrollableArea* scrollableArea() const { return m_scrollableArea; }
416
417    WebKit::WebContentLayer* contentLayer() const { return m_layer.get(); }
418
419    // Exposed for tests. FIXME - name is too similar to contentLayer(), very error prone.
420    WebKit::WebLayer* contentsLayer() const { return m_contentsLayer; }
421
422    static void registerContentsLayer(WebKit::WebLayer*);
423    static void unregisterContentsLayer(WebKit::WebLayer*);
424
425    // GraphicsContextPainter implementation.
426    virtual void paint(GraphicsContext&, const IntRect& clip) OVERRIDE;
427
428    // WebAnimationDelegate implementation.
429    virtual void notifyAnimationStarted(double startTime) OVERRIDE;
430    virtual void notifyAnimationFinished(double finishTime) OVERRIDE;
431
432    // WebLayerScrollClient implementation.
433    virtual void didScroll() OVERRIDE;
434
435protected:
436    // Adds a child without calling updateChildList(), so that adding children
437    // can be batched before updating.
438    void addChildInternal(GraphicsLayer*);
439
440    // This method is used by platform GraphicsLayer classes to clear the filters
441    // when compositing is not done in hardware. It is not virtual, so the caller
442    // needs to notifiy the change to the platform layer as needed.
443    void clearFilters() { m_filters.clear(); }
444
445    // Given a KeyframeValueList containing filterOperations, return true if the operations are valid.
446    static int validateFilterOperations(const KeyframeValueList&);
447
448    // Given a list of TransformAnimationValues, see if all the operations for each keyframe match. If so
449    // return the index of the KeyframeValueList entry that has that list of operations (it may not be
450    // the first entry because some keyframes might have an empty transform and those match any list).
451    // If the lists don't match return -1. On return, if hasBigRotation is true, functions contain
452    // rotations of >= 180 degrees
453    static int validateTransformOperations(const KeyframeValueList&, bool& hasBigRotation);
454
455    // The layer being replicated.
456    GraphicsLayer* replicatedLayer() const { return m_replicatedLayer; }
457    void setReplicatedLayer(GraphicsLayer* layer) { m_replicatedLayer = layer; }
458
459    // Any factory classes that want to create a GraphicsLayer need to be friends.
460    friend class WebKit::GraphicsLayerFactoryChromium;
461    explicit GraphicsLayer(GraphicsLayerClient*);
462
463    static void writeIndent(TextStream&, int indent);
464
465    void dumpProperties(TextStream&, int indent, LayerTreeFlags) const;
466    void dumpAdditionalProperties(TextStream&, int /*indent*/, LayerTreeFlags) const { }
467
468    // Helper functions used by settors to keep layer's the state consistent.
469    void updateNames();
470    void updateChildList();
471    void updateLayerIsDrawable();
472    void updateContentsRect();
473
474    void setContentsTo(ContentsLayerPurpose, WebKit::WebLayer*);
475    void setupContentsLayer(WebKit::WebLayer*);
476    void clearContentsLayerIfUnregistered();
477    WebKit::WebLayer* contentsLayerIfRegistered();
478
479    GraphicsLayerClient* m_client;
480    String m_name;
481
482    // Offset from the owning renderer
483    IntSize m_offsetFromRenderer;
484
485    // Position is relative to the parent GraphicsLayer
486    FloatPoint m_position;
487    FloatPoint3D m_anchorPoint;
488    FloatSize m_size;
489    FloatPoint m_boundsOrigin;
490
491    TransformationMatrix m_transform;
492    TransformationMatrix m_childrenTransform;
493
494    Color m_backgroundColor;
495    float m_opacity;
496    float m_zPosition;
497
498    FilterOperations m_filters;
499
500    bool m_contentsOpaque : 1;
501    bool m_preserves3D: 1;
502    bool m_backfaceVisibility : 1;
503    bool m_masksToBounds : 1;
504    bool m_drawsContent : 1;
505    bool m_contentsVisible : 1;
506    bool m_showRepaintCounter : 1;
507
508    GraphicsLayerPaintingPhase m_paintingPhase;
509    CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents
510
511    Vector<GraphicsLayer*> m_children;
512    GraphicsLayer* m_parent;
513
514    GraphicsLayer* m_maskLayer; // Reference to mask layer. We don't own this.
515
516    GraphicsLayer* m_replicaLayer; // A layer that replicates this layer. We only allow one, for now.
517                                   // The replica is not parented; this is the primary reference to it.
518    GraphicsLayer* m_replicatedLayer; // For a replica layer, a reference to the original layer.
519    FloatPoint m_replicatedLayerPosition; // For a replica layer, the position of the replica.
520
521    IntRect m_contentsRect;
522
523    int m_repaintCount;
524
525    String m_nameBase;
526
527    Color m_contentsSolidColor;
528
529    OwnPtr<WebKit::WebContentLayer> m_layer;
530    OwnPtr<WebKit::WebImageLayer> m_imageLayer;
531    OwnPtr<WebKit::WebSolidColorLayer> m_contentsSolidColorLayer;
532    WebKit::WebLayer* m_contentsLayer;
533    // We don't have ownership of m_contentsLayer, but we do want to know if a given layer is the
534    // same as our current layer in setContentsTo(). Since m_contentsLayer may be deleted at this point,
535    // we stash an ID away when we know m_contentsLayer is alive and use that for comparisons from that point
536    // on.
537    int m_contentsLayerId;
538
539    LinkHighlightClient* m_linkHighlight;
540
541    OwnPtr<OpaqueRectTrackingContentLayerDelegate> m_opaqueRectTrackingContentLayerDelegate;
542
543    ContentsLayerPurpose m_contentsLayerPurpose;
544    bool m_inSetChildren;
545
546    typedef HashMap<String, int> AnimationIdMap;
547    AnimationIdMap m_animationIdMap;
548
549    ScrollableArea* m_scrollableArea;
550};
551
552
553} // namespace WebCore
554
555#ifndef NDEBUG
556// Outside the WebCore namespace for ease of invocation from gdb.
557void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer);
558#endif
559
560#endif // GraphicsLayer_h
561