• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
platformCALayer()57     virtual PlatformCALayer* platformCALayer() const { return primaryLayer(); }
58 
contentsScale()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 
hasContentsLayer()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 
allowTiledLayer()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
platformCALayerLayoutSublayersOfLayer(PlatformCALayer *)133     virtual void platformCALayerLayoutSublayersOfLayer(PlatformCALayer*) { }
platformCALayerRespondsToLayoutChanges()134     virtual bool platformCALayerRespondsToLayoutChanges() const { return false; }
135 
136     virtual void platformCALayerAnimationStarted(CFTimeInterval beginTime);
platformCALayerContentsOrientation()137     virtual CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return contentsOrientation(); }
platformCALayerPaintContents(GraphicsContext & context,const IntRect & clip)138     virtual void platformCALayerPaintContents(GraphicsContext& context, const IntRect& clip) { paintGraphicsLayerContents(context, clip); }
platformCALayerShowDebugBorders()139     virtual bool platformCALayerShowDebugBorders() const { return showDebugBorders(); }
platformCALayerShowRepaintCounter()140     virtual bool platformCALayerShowRepaintCounter() const { return showRepaintCounter(); }
platformCALayerIncrementRepaintCount()141     virtual int platformCALayerIncrementRepaintCount() { return incrementRepaintCount(); }
142 
platformCALayerContentsOpaque()143     virtual bool platformCALayerContentsOpaque() const { return contentsOpaque(); }
platformCALayerDrawsContent()144     virtual bool platformCALayerDrawsContent() const { return drawsContent(); }
platformCALayerLayerDidDisplay(PlatformLayer * layer)145     virtual void platformCALayerLayerDidDisplay(PlatformLayer* layer) { return layerDidDisplay(layer); }
146 
147     void updateOpacityOnLayer();
148 
primaryLayer()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.
isReplicatedRootClone(const CloneID & cloneID)155     static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; }
156 
157     typedef HashMap<CloneID, RefPtr<PlatformCALayer> > LayerMap;
primaryLayerClones()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 
animationIsRunning(const String & animationName)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*);
contentsLayer()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 };
ReplicaStateReplicaState202         ReplicaState(ReplicaBranchType firstBranch)
203             : m_replicaDepth(0)
204         {
205             push(firstBranch);
206         }
207 
208         // Called as we walk down the tree to build replicas.
pushReplicaState209         void push(ReplicaBranchType branchType)
210         {
211             m_replicaBranches.append(branchType);
212             if (branchType == ReplicaBranch)
213                 ++m_replicaDepth;
214         }
215 
setBranchTypeReplicaState216         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 
popReplicaState230         void pop()
231         {
232             if (m_replicaBranches.last() == ReplicaBranch)
233                 --m_replicaDepth;
234             m_replicaBranches.removeLast();
235         }
236 
depthReplicaState237         size_t depth() const { return m_replicaBranches.size(); }
replicaDepthReplicaState238         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 
hasCloneLayers()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 {
LayerPropertyAnimationLayerPropertyAnimation364         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)
actionAnimationProcessingAction385             : 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