Fix GraphicsLayerCA::recursiveVisibleRectChangeRequiresFlush() to do predictive visib...
[WebKit-https.git] / Source / WebCore / platform / graphics / ca / GraphicsLayerCA.h
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 // Enable this to add a light red wash over the visible portion of Tiled Layers, as computed
41 // by flushCompositingState().
42 // #define VISIBLE_TILE_WASH
43
44 namespace WebCore {
45
46 class PlatformCALayer;
47 class TransformState;
48
49 class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient {
50 public:
51     // The width and height of a single tile in a tiled layer. Should be large enough to
52     // avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough
53     // to keep the overall tile cost low.
54     static const int kTiledLayerTileSize = 512;
55
56     GraphicsLayerCA(GraphicsLayerClient*);
57     virtual ~GraphicsLayerCA();
58
59     virtual void setName(const String&);
60
61     virtual PlatformLayer* platformLayer() const;
62     virtual PlatformCALayer* platformCALayer() const { return primaryLayer(); }
63
64     virtual bool setChildren(const Vector<GraphicsLayer*>&);
65     virtual void addChild(GraphicsLayer*);
66     virtual void addChildAtIndex(GraphicsLayer*, int index);
67     virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling);
68     virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling);
69     virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
70
71     virtual void removeFromParent();
72
73     virtual void setMaskLayer(GraphicsLayer*);
74     virtual void setReplicatedLayer(GraphicsLayer*);
75
76     virtual void setPosition(const FloatPoint&);
77     virtual void setAnchorPoint(const FloatPoint3D&);
78     virtual void setSize(const FloatSize&);
79     virtual void setBoundsOrigin(const FloatPoint&);
80
81     virtual void setTransform(const TransformationMatrix&);
82
83     virtual void setChildrenTransform(const TransformationMatrix&);
84
85     virtual void setPreserves3D(bool);
86     virtual void setMasksToBounds(bool);
87     virtual void setDrawsContent(bool);
88     virtual void setContentsVisible(bool);
89     virtual void setAcceleratesDrawing(bool);
90
91     virtual void setBackgroundColor(const Color&);
92
93     virtual void setContentsOpaque(bool);
94     virtual void setBackfaceVisibility(bool);
95
96     // return true if we started an animation
97     virtual void setOpacity(float);
98
99 #if ENABLE(CSS_FILTERS)
100     virtual bool setFilters(const FilterOperations&);
101 #endif
102
103     virtual void setNeedsDisplay();
104     virtual void setNeedsDisplayInRect(const FloatRect&);
105     virtual void setContentsNeedsDisplay();
106     
107     virtual void setContentsRect(const IntRect&);
108     
109     virtual void suspendAnimations(double time);
110     virtual void resumeAnimations();
111
112     virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& animationName, double timeOffset);
113     virtual void pauseAnimation(const String& animationName, double timeOffset);
114     virtual void removeAnimation(const String& animationName);
115
116     virtual void setContentsToImage(Image*);
117     virtual void setContentsToMedia(PlatformLayer*);
118     virtual void setContentsToCanvas(PlatformLayer*);
119     virtual void setContentsToSolidColor(const Color&);
120
121     virtual bool hasContentsLayer() const { return m_contentsLayer; }
122     
123     virtual void setShowDebugBorder(bool) OVERRIDE;
124     virtual void setShowRepaintCounter(bool) OVERRIDE;
125
126     virtual void setDebugBackgroundColor(const Color&);
127     virtual void setDebugBorder(const Color&, float borderWidth);
128
129     virtual void layerDidDisplay(PlatformLayer*);
130
131     virtual void setMaintainsPixelAlignment(bool);
132     virtual void deviceOrPageScaleFactorChanged();
133
134     struct CommitState {
135         bool ancestorHasTransformAnimation;
136         CommitState()
137             : ancestorHasTransformAnimation(false)
138         { }
139     };
140     void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
141
142     virtual void flushCompositingState(const FloatRect&);
143     virtual void flushCompositingStateForThisLayerOnly();
144
145     virtual bool visibleRectChangeRequiresFlush(const FloatRect& visibleRect) const OVERRIDE;
146
147     virtual TiledBacking* tiledBacking() const OVERRIDE;
148
149     bool allowTiledLayer() const { return m_allowTiledLayer; }
150     virtual void setAllowTiledLayer(bool b);
151
152 protected:
153     virtual void setOpacityInternal(float);
154
155 private:
156     virtual void willBeDestroyed();
157
158     // PlatformCALayerClient overrides
159     virtual void platformCALayerLayoutSublayersOfLayer(PlatformCALayer*) { }
160     virtual bool platformCALayerRespondsToLayoutChanges() const { return false; }
161
162     virtual void platformCALayerAnimationStarted(CFTimeInterval beginTime);
163     virtual CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return contentsOrientation(); }
164     virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& clip);
165     virtual bool platformCALayerShowDebugBorders() const { return isShowingDebugBorder(); }
166     virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const;
167     virtual int platformCALayerIncrementRepaintCount() { return incrementRepaintCount(); }
168
169     virtual bool platformCALayerContentsOpaque() const { return contentsOpaque(); }
170     virtual bool platformCALayerDrawsContent() const { return drawsContent(); }
171     virtual void platformCALayerLayerDidDisplay(PlatformLayer* layer) { return layerDidDisplay(layer); }
172     virtual void platformCALayerDidCreateTiles(const Vector<FloatRect>& dirtyRects) OVERRIDE;
173     virtual float platformCALayerDeviceScaleFactor() OVERRIDE;
174
175     virtual double backingStoreMemoryEstimate() const;
176
177     void updateOpacityOnLayer();
178     
179 #if ENABLE(CSS_FILTERS)
180     void updateFilters();
181 #endif
182
183     PlatformCALayer* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); }
184     PlatformCALayer* hostLayerForSublayers() const;
185     PlatformCALayer* layerForSuperlayer() const;
186     PlatformCALayer* animatedLayer(AnimatedPropertyID) const;
187
188     typedef String CloneID; // Identifier for a given clone, based on original/replica branching down the tree.
189     static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; }
190
191     typedef HashMap<CloneID, RefPtr<PlatformCALayer> > LayerMap;
192     LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); }
193     LayerMap* animatedLayerClones(AnimatedPropertyID) const;
194
195     bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
196     bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize);
197 #if ENABLE(CSS_FILTERS)
198     bool createFilterAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
199 #endif
200
201     // Return autoreleased animation (use RetainPtr?)
202     PassRefPtr<PlatformCAAnimation> createBasicAnimation(const Animation*, const String& keyPath, bool additive);
203     PassRefPtr<PlatformCAAnimation> createKeyframeAnimation(const Animation*, const String&, bool additive);
204     void setupAnimation(PlatformCAAnimation*, const Animation*, bool additive);
205     
206     const TimingFunction* timingFunctionForAnimationValue(const AnimationValue*, const Animation*);
207     
208     bool setAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*);
209     bool setAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*);
210
211     bool setTransformAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
212     bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
213     
214 #if ENABLE(CSS_FILTERS)
215     bool setFilterAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, int internalFilterPropertyIndex);
216     bool setFilterAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType);
217 #endif
218
219     bool isRunningTransformAnimation() const;
220
221     bool animationIsRunning(const String& animationName) const
222     {
223         return m_runningAnimations.find(animationName) != m_runningAnimations.end();
224     }
225
226     void commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect);
227     void commitLayerChangesAfterSublayers();
228
229     FloatPoint computePositionRelativeToBase(float& pageScale) const;
230
231     FloatSize constrainedSize() const;
232
233     bool requiresTiledLayer(float pageScaleFactor) const;
234     void swapFromOrToTiledLayer(bool useTiledLayer);
235
236     CompositingCoordinatesOrientation defaultContentsOrientation() const;
237     
238     void setupContentsLayer(PlatformCALayer*);
239     PlatformCALayer* contentsLayer() const { return m_contentsLayer.get(); }
240
241     virtual void setReplicatedByLayer(GraphicsLayer*);
242
243     virtual void getDebugBorderInfo(Color&, float& width) const;
244     virtual void dumpAdditionalProperties(TextStream&, int indent, LayerTreeAsTextBehavior) const;
245
246     void computePixelAlignment(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase,
247         FloatPoint& position, FloatSize&, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const;
248     enum ComputeVisibleRectFlag { RespectAnimatingTransforms = 1 << 0 };
249     typedef unsigned ComputeVisibleRectFlags;
250     FloatRect computeVisibleRect(TransformState&, ComputeVisibleRectFlags = RespectAnimatingTransforms) const;
251     const FloatRect& visibleRect() const { return m_visibleRect; }
252     
253     static FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatRect& newVisibleRect, const FloatSize& oldSize, const FloatSize& newSize);
254
255     bool recursiveVisibleRectChangeRequiresFlush(const TransformState&) const;
256
257     virtual bool canThrottleLayerFlush() const;
258
259     // Used to track the path down the tree for replica layers.
260     struct ReplicaState {
261         static const size_t maxReplicaDepth = 16;
262         enum ReplicaBranchType { ChildBranch = 0, ReplicaBranch = 1 };
263         ReplicaState(ReplicaBranchType firstBranch)
264             : m_replicaDepth(0)
265         {
266             push(firstBranch);
267         }
268         
269         // Called as we walk down the tree to build replicas.
270         void push(ReplicaBranchType branchType)
271         {
272             m_replicaBranches.append(branchType);
273             if (branchType == ReplicaBranch)
274                 ++m_replicaDepth;
275         }
276         
277         void setBranchType(ReplicaBranchType branchType)
278         {
279             ASSERT(!m_replicaBranches.isEmpty());
280
281             if (m_replicaBranches.last() != branchType) {
282                 if (branchType == ReplicaBranch)
283                     ++m_replicaDepth;
284                 else
285                     --m_replicaDepth;
286             }
287
288             m_replicaBranches.last() = branchType;
289         }
290
291         void pop()
292         {
293             if (m_replicaBranches.last() == ReplicaBranch)
294                 --m_replicaDepth;
295             m_replicaBranches.removeLast();
296         }
297         
298         size_t depth() const { return m_replicaBranches.size(); }
299         size_t replicaDepth() const { return m_replicaDepth; }
300
301         CloneID cloneID() const;        
302
303     private:
304         Vector<ReplicaBranchType> m_replicaBranches;
305         size_t m_replicaDepth;
306     };
307     PassRefPtr<PlatformCALayer>replicatedLayerRoot(ReplicaState&);
308
309     enum CloneLevel { RootCloneLevel, IntermediateCloneLevel };
310     PassRefPtr<PlatformCALayer> fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState&, CloneLevel);
311     
312     PassRefPtr<PlatformCALayer> cloneLayer(PlatformCALayer *, CloneLevel);
313     PassRefPtr<PlatformCALayer> findOrMakeClone(CloneID, PlatformCALayer *, LayerMap*, CloneLevel);
314
315     void ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel);
316
317     bool hasCloneLayers() const { return m_layerClones; }
318     void removeCloneLayers();
319     FloatPoint positionForCloneRootLayer() const;
320     
321     void propagateLayerChangeToReplicas();
322     
323     // All these "update" methods will be called inside a BEGIN_BLOCK_OBJC_EXCEPTIONS/END_BLOCK_OBJC_EXCEPTIONS block.
324     void updateLayerNames();
325     void updateSublayerList();
326     void updateGeometry(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase);
327     void updateTransform();
328     void updateChildrenTransform();
329     void updateMasksToBounds();
330     void updateContentsVisibility();
331     void updateContentsOpaque();
332     void updateBackfaceVisibility();
333     void updateStructuralLayer();
334     void updateLayerDrawsContent();
335     void updateBackgroundColor();
336
337     void updateContentsImage();
338     void updateContentsMediaLayer();
339     void updateContentsCanvasLayer();
340     void updateContentsColorLayer();
341     void updateContentsRect();
342     void updateMaskLayer();
343     void updateReplicatedLayers();
344
345     void updateAnimations();
346     void updateContentsNeedsDisplay();
347     void updateAcceleratesDrawing();
348     void updateDebugBorder();
349     void updateVisibleRect(const FloatRect& oldVisibleRect);
350     void updateContentsScale(float pageScaleFactor);
351     
352     enum StructuralLayerPurpose {
353         NoStructuralLayer = 0,
354         StructuralLayerForPreserves3D,
355         StructuralLayerForReplicaFlattening
356     };
357     void ensureStructuralLayer(StructuralLayerPurpose);
358     StructuralLayerPurpose structuralLayerPurpose() const;
359
360     void setAnimationOnLayer(PlatformCAAnimation*, AnimatedPropertyID, const String& animationName, int index, int subIndex, double timeOffset);
361     bool removeCAAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index, int subINdex);
362     void pauseCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, int subIndex, double timeOffset);
363
364     enum MoveOrCopy { Move, Copy };
365     static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer);
366     void moveOrCopyAnimations(MoveOrCopy, PlatformCALayer * fromLayer, PlatformCALayer * toLayer);
367     
368     bool appendToUncommittedAnimations(const KeyframeValueList&, const TransformOperations*, const Animation*, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation);
369 #if ENABLE(CSS_FILTERS)
370     bool appendToUncommittedAnimations(const KeyframeValueList&, const FilterOperation*, const Animation*, const String& animationName, int animationIndex, double timeOffset);
371 #endif
372     
373     enum LayerChange {
374         NoChange = 0,
375         NameChanged = 1 << 1,
376         ChildrenChanged = 1 << 2, // also used for content layer, and preserves-3d, and size if tiling changes?
377         GeometryChanged = 1 << 3,
378         TransformChanged = 1 << 4,
379         ChildrenTransformChanged = 1 << 5,
380         Preserves3DChanged = 1 << 6,
381         MasksToBoundsChanged = 1 << 7,
382         DrawsContentChanged = 1 << 8,
383         BackgroundColorChanged = 1 << 9,
384         ContentsOpaqueChanged = 1 << 10,
385         BackfaceVisibilityChanged = 1 << 11,
386         OpacityChanged = 1 << 12,
387         AnimationChanged = 1 << 13,
388         DirtyRectsChanged = 1 << 14,
389         ContentsImageChanged = 1 << 15,
390         ContentsMediaLayerChanged = 1 << 16,
391         ContentsCanvasLayerChanged = 1 << 17,
392         ContentsColorLayerChanged = 1 << 18,
393         ContentsRectChanged = 1 << 19,
394         MaskLayerChanged = 1 << 20,
395         ReplicatedLayerChanged = 1 << 21,
396         ContentsNeedsDisplay = 1 << 22,
397         AcceleratesDrawingChanged = 1 << 23,
398         ContentsScaleChanged = 1 << 24,
399         ContentsVisibilityChanged = 1 << 25,
400         VisibleRectChanged = 1 << 26,
401         FiltersChanged = 1 << 27,
402         TilesAdded = 1 < 28,
403         DebugIndicatorsChanged = 1 << 29
404     };
405     typedef unsigned LayerChangeFlags;
406     void noteLayerPropertyChanged(LayerChangeFlags flags);
407     void noteSublayersChanged();
408     void noteChangesForScaleSensitiveProperties();
409
410     void repaintLayerDirtyRects();
411
412     RefPtr<PlatformCALayer> m_layer; // The main layer
413     RefPtr<PlatformCALayer> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer.
414     RefPtr<PlatformCALayer> m_contentsLayer; // A layer used for inner content, like image and video
415
416     // References to clones of our layers, for replicated layers.
417     OwnPtr<LayerMap> m_layerClones;
418     OwnPtr<LayerMap> m_structuralLayerClones;
419     OwnPtr<LayerMap> m_contentsLayerClones;
420
421 #ifdef VISIBLE_TILE_WASH
422     RefPtr<PlatformCALayer> m_visibleTileWashLayer;
423 #endif
424     FloatRect m_visibleRect;
425     FloatSize m_sizeAtLastVisibleRectUpdate;
426     
427     enum ContentsLayerPurpose {
428         NoContentsLayer = 0,
429         ContentsLayerForImage,
430         ContentsLayerForMedia,
431         ContentsLayerForCanvas,
432         ContentsLayerForBackgroundColor
433     };
434     
435     ContentsLayerPurpose m_contentsLayerPurpose;
436     bool m_allowTiledLayer : 1;
437     bool m_isPageTiledBackingLayer : 1;
438     
439     Color m_contentsSolidColor;
440
441     RetainPtr<CGImageRef> m_uncorrectedContentsImage;
442     RetainPtr<CGImageRef> m_pendingContentsImage;
443     
444     // This represents the animation of a single property. There may be multiple transform animations for
445     // a single transition or keyframe animation, so index is used to distinguish these.
446     struct LayerPropertyAnimation {
447         LayerPropertyAnimation(PassRefPtr<PlatformCAAnimation> caAnimation, const String& animationName, AnimatedPropertyID property, int index, int subIndex, double timeOffset)
448         : m_animation(caAnimation)
449         , m_name(animationName)
450         , m_property(property)
451         , m_index(index)
452         , m_subIndex(subIndex)
453         , m_timeOffset(timeOffset)
454         { }
455
456         RefPtr<PlatformCAAnimation> m_animation;
457         String m_name;
458         AnimatedPropertyID m_property;
459         int m_index;
460         int m_subIndex;
461         double m_timeOffset;
462     };
463     
464     // Uncommitted transitions and animations.
465     Vector<LayerPropertyAnimation> m_uncomittedAnimations;
466     
467     enum Action { Remove, Pause };
468     struct AnimationProcessingAction {
469         AnimationProcessingAction(Action action = Remove, double timeOffset = 0)
470             : action(action)
471             , timeOffset(timeOffset)
472         {
473         }
474         Action action;
475         double timeOffset; // only used for pause
476     };
477     typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
478     AnimationsToProcessMap m_animationsToProcess;
479
480     // Map of animation names to their associated lists of property animations, so we can remove/pause them.
481     typedef HashMap<String, Vector<LayerPropertyAnimation> > AnimationsMap;
482     AnimationsMap m_runningAnimations;
483
484     Vector<FloatRect> m_dirtyRects;
485     FloatSize m_pixelAlignmentOffset;
486     
487     LayerChangeFlags m_uncommittedChanges;
488 };
489
490 } // namespace WebCore
491
492
493 #endif // USE(ACCELERATED_COMPOSITING)
494
495 #endif // GraphicsLayerCA_h