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