| Index: Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
|
| diff --git a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp b/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
|
| deleted file mode 100644
|
| index 31b17df2c373dc4860cd9b750f486afc9dba0576..0000000000000000000000000000000000000000
|
| --- a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
|
| +++ /dev/null
|
| @@ -1,1242 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2010 Apple Inc. All rights reserved.
|
| - * Copyright (C) 2011, 2012, 2013 Collabora Ltd.
|
| - * Copyright (C) 2012 Intel Corporation. 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.
|
| - */
|
| -
|
| -#include "config.h"
|
| -
|
| -#if USE(ACCELERATED_COMPOSITING)
|
| -#include "GraphicsLayerClutter.h"
|
| -
|
| -#include "Animation.h"
|
| -#include "FloatConversion.h"
|
| -#include "FloatRect.h"
|
| -#include "GraphicsLayerActor.h"
|
| -#include "GraphicsLayerFactory.h"
|
| -#include "NotImplemented.h"
|
| -#include "RefPtrCairo.h"
|
| -#include "RotateTransformOperation.h"
|
| -#include "ScaleTransformOperation.h"
|
| -#include "TransformState.h"
|
| -#include "TransformationMatrix.h"
|
| -#include "TranslateTransformOperation.h"
|
| -#include <limits.h>
|
| -#include <wtf/text/CString.h>
|
| -#include <wtf/text/WTFString.h>
|
| -
|
| -using namespace std;
|
| -
|
| -namespace WebCore {
|
| -
|
| -// If we send a duration of 0 to ClutterTimeline, then it will fail to set the duration.
|
| -// So send a very small value instead.
|
| -static const float cAnimationAlmostZeroDuration = 1e-3f;
|
| -
|
| -static bool isTransformTypeTransformationMatrix(TransformOperation::OperationType transformType)
|
| -{
|
| - switch (transformType) {
|
| - case TransformOperation::SKEW_X:
|
| - case TransformOperation::SKEW_Y:
|
| - case TransformOperation::SKEW:
|
| - case TransformOperation::MATRIX:
|
| - case TransformOperation::ROTATE_3D:
|
| - case TransformOperation::MATRIX_3D:
|
| - case TransformOperation::PERSPECTIVE:
|
| - case TransformOperation::IDENTITY:
|
| - case TransformOperation::NONE:
|
| - return true;
|
| - default:
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -static bool isTransformTypeFloatPoint3D(TransformOperation::OperationType transformType)
|
| -{
|
| - switch (transformType) {
|
| - case TransformOperation::SCALE:
|
| - case TransformOperation::SCALE_3D:
|
| - case TransformOperation::TRANSLATE:
|
| - case TransformOperation::TRANSLATE_3D:
|
| - return true;
|
| - default:
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -static bool isTransformTypeNumber(TransformOperation::OperationType transformType)
|
| -{
|
| - return !isTransformTypeTransformationMatrix(transformType) && !isTransformTypeFloatPoint3D(transformType);
|
| -}
|
| -
|
| -static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, float& value)
|
| -{
|
| - switch (transformType) {
|
| - case TransformOperation::ROTATE:
|
| - case TransformOperation::ROTATE_X:
|
| - case TransformOperation::ROTATE_Y:
|
| - value = transformOp ? narrowPrecisionToFloat(deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle())) : 0;
|
| - break;
|
| - case TransformOperation::SCALE_X:
|
| - value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1;
|
| - break;
|
| - case TransformOperation::SCALE_Y:
|
| - value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1;
|
| - break;
|
| - case TransformOperation::SCALE_Z:
|
| - value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1;
|
| - break;
|
| - case TransformOperation::TRANSLATE_X:
|
| - value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0;
|
| - break;
|
| - case TransformOperation::TRANSLATE_Y:
|
| - value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0;
|
| - break;
|
| - case TransformOperation::TRANSLATE_Z:
|
| - value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0;
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| -}
|
| -
|
| -static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, FloatPoint3D& value)
|
| -{
|
| - switch (transformType) {
|
| - case TransformOperation::SCALE:
|
| - case TransformOperation::SCALE_3D:
|
| - value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1);
|
| - value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1);
|
| - value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1);
|
| - break;
|
| - case TransformOperation::TRANSLATE:
|
| - case TransformOperation::TRANSLATE_3D:
|
| - value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0);
|
| - value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0);
|
| - value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0);
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| -}
|
| -
|
| -static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, TransformationMatrix& value)
|
| -{
|
| - switch (transformType) {
|
| - case TransformOperation::SKEW_X:
|
| - case TransformOperation::SKEW_Y:
|
| - case TransformOperation::SKEW:
|
| - case TransformOperation::MATRIX:
|
| - case TransformOperation::ROTATE_3D:
|
| - case TransformOperation::MATRIX_3D:
|
| - case TransformOperation::PERSPECTIVE:
|
| - case TransformOperation::IDENTITY:
|
| - case TransformOperation::NONE:
|
| - if (transformOp)
|
| - transformOp->apply(value, size);
|
| - else
|
| - value.makeIdentity();
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| -}
|
| -
|
| -static PlatformClutterAnimation::ValueFunctionType getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
|
| -{
|
| - // Use literal strings to avoid link-time dependency on those symbols.
|
| - switch (transformType) {
|
| - case TransformOperation::ROTATE_X:
|
| - return PlatformClutterAnimation::RotateX;
|
| - case TransformOperation::ROTATE_Y:
|
| - return PlatformClutterAnimation::RotateY;
|
| - case TransformOperation::ROTATE:
|
| - return PlatformClutterAnimation::RotateZ;
|
| - case TransformOperation::SCALE_X:
|
| - return PlatformClutterAnimation::ScaleX;
|
| - case TransformOperation::SCALE_Y:
|
| - return PlatformClutterAnimation::ScaleY;
|
| - case TransformOperation::SCALE_Z:
|
| - return PlatformClutterAnimation::ScaleZ;
|
| - case TransformOperation::TRANSLATE_X:
|
| - return PlatformClutterAnimation::TranslateX;
|
| - case TransformOperation::TRANSLATE_Y:
|
| - return PlatformClutterAnimation::TranslateY;
|
| - case TransformOperation::TRANSLATE_Z:
|
| - return PlatformClutterAnimation::TranslateZ;
|
| - case TransformOperation::SCALE:
|
| - case TransformOperation::SCALE_3D:
|
| - return PlatformClutterAnimation::Scale;
|
| - case TransformOperation::TRANSLATE:
|
| - case TransformOperation::TRANSLATE_3D:
|
| - return PlatformClutterAnimation::Translate;
|
| - case TransformOperation::MATRIX_3D:
|
| - return PlatformClutterAnimation::Matrix;
|
| - default:
|
| - return PlatformClutterAnimation::NoValueFunction;
|
| - }
|
| -}
|
| -
|
| -static String propertyIdToString(AnimatedPropertyID property)
|
| -{
|
| - switch (property) {
|
| - case AnimatedPropertyWebkitTransform:
|
| - return "transform";
|
| - case AnimatedPropertyOpacity:
|
| - return "opacity";
|
| - case AnimatedPropertyBackgroundColor:
|
| - return "backgroundColor";
|
| - case AnimatedPropertyWebkitFilter:
|
| - ASSERT_NOT_REACHED();
|
| - case AnimatedPropertyInvalid:
|
| - ASSERT_NOT_REACHED();
|
| - }
|
| - ASSERT_NOT_REACHED();
|
| - return "";
|
| -}
|
| -
|
| -static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index)
|
| -{
|
| - return animationName + '_' + String::number(property) + '_' + String::number(index);
|
| -}
|
| -
|
| -static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
|
| -{
|
| - if (anim->timingFunction()->isStepsTimingFunction())
|
| - return true;
|
| -
|
| - for (unsigned i = 0; i < valueList.size(); ++i) {
|
| - const TimingFunction* timingFunction = valueList.at(i)->timingFunction();
|
| - if (timingFunction && timingFunction->isStepsTimingFunction())
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -// This is the hook for WebCore compositor to know that the webKit clutter port implements
|
| -// compositing with GraphicsLayerClutter.
|
| -PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
|
| -{
|
| - if (!factory)
|
| - return adoptPtr(new GraphicsLayerClutter(client));
|
| -
|
| - return factory->createGraphicsLayer(client);
|
| -}
|
| -
|
| -PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
|
| -{
|
| - return adoptPtr(new GraphicsLayerClutter(client));
|
| -}
|
| -
|
| -GraphicsLayerClutter::GraphicsLayerClutter(GraphicsLayerClient* client)
|
| - : GraphicsLayer(client)
|
| - , m_uncommittedChanges(0)
|
| -{
|
| - // ClutterRectangle will be used to show the debug border.
|
| - m_layer = graphicsLayerActorNewWithClient(LayerTypeWebLayer, this);
|
| -}
|
| -
|
| -static gboolean idleDestroy(gpointer data)
|
| -{
|
| - GRefPtr<ClutterActor> actor = adoptGRef(CLUTTER_ACTOR(data));
|
| - ClutterActor* parent = clutter_actor_get_parent(actor.get());
|
| -
|
| - // We should remove child actors manually because the container of Clutter
|
| - // seems to have a bug to remove its child actors when it is removed.
|
| - if (GRAPHICS_LAYER_IS_ACTOR(GRAPHICS_LAYER_ACTOR(actor.get())))
|
| - graphicsLayerActorRemoveAll(GRAPHICS_LAYER_ACTOR(actor.get()));
|
| -
|
| - if (parent)
|
| - clutter_actor_remove_child(parent, actor.get());
|
| -
|
| - // FIXME: we should assert that the actor's ref count is 1 here, but some
|
| - // of them are getting here with 2!
|
| - // ASSERT((G_OBJECT(actor.get()))->ref_count == 1);
|
| -
|
| - return FALSE;
|
| -}
|
| -
|
| -GraphicsLayerClutter::~GraphicsLayerClutter()
|
| -{
|
| - if (graphicsLayerActorGetLayerType(m_layer.get()) == GraphicsLayerClutter::LayerTypeRootLayer)
|
| - return;
|
| -
|
| - // Even though we call notifyFlushRequired to remove existing animations in removeAnimation(),
|
| - // removeClutterAnimationFromLayer has been never reached since the root layer is destroyed.
|
| - // It means that we haven't lost a change to remove actual animations from clutterActor.
|
| - // So, we call explictly updateAnimations once here to remove uncommitted animations.
|
| - if (m_uncommittedChanges & AnimationChanged)
|
| - updateAnimations();
|
| -
|
| - willBeDestroyed();
|
| -
|
| - // We destroy the actors on an idle so that the main loop can run enough to
|
| - // repaint the background that will replace the actor.
|
| - if (m_layer) {
|
| - graphicsLayerActorSetClient(m_layer.get(), 0);
|
| - g_idle_add(idleDestroy, m_layer.leakRef());
|
| - }
|
| -
|
| - if (m_structuralLayer) {
|
| - graphicsLayerActorSetClient(m_structuralLayer.get(), 0);
|
| - g_idle_add(idleDestroy, m_structuralLayer.leakRef());
|
| - }
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setName(const String& name)
|
| -{
|
| - String longName = String::format("Actor(%p) GraphicsLayer(%p) ", m_layer.get(), this) + name;
|
| - GraphicsLayer::setName(longName);
|
| - noteLayerPropertyChanged(NameChanged);
|
| -}
|
| -
|
| -ClutterActor* GraphicsLayerClutter::platformLayer() const
|
| -{
|
| - return CLUTTER_ACTOR(primaryLayer());
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setNeedsDisplay()
|
| -{
|
| - FloatRect hugeRect(FloatPoint(), m_size);
|
| - setNeedsDisplayInRect(hugeRect);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setNeedsDisplayInRect(const FloatRect& r)
|
| -{
|
| - if (!drawsContent())
|
| - return;
|
| -
|
| - FloatRect rect(r);
|
| - FloatRect layerBounds(FloatPoint(), m_size);
|
| - rect.intersect(layerBounds);
|
| - if (rect.isEmpty())
|
| - return;
|
| -
|
| - const size_t maxDirtyRects = 32;
|
| -
|
| - for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
|
| - if (m_dirtyRects[i].contains(rect))
|
| - return;
|
| - }
|
| -
|
| - if (m_dirtyRects.size() < maxDirtyRects)
|
| - m_dirtyRects.append(rect);
|
| - else
|
| - m_dirtyRects[0].unite(rect);
|
| -
|
| - noteLayerPropertyChanged(DirtyRectsChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setAnchorPoint(const FloatPoint3D& point)
|
| -{
|
| - if (point == m_anchorPoint)
|
| - return;
|
| -
|
| - GraphicsLayer::setAnchorPoint(point);
|
| - noteLayerPropertyChanged(GeometryChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setOpacity(float opacity)
|
| -{
|
| - float clampedOpacity = max(0.0f, min(opacity, 1.0f));
|
| - if (clampedOpacity == m_opacity)
|
| - return;
|
| -
|
| - GraphicsLayer::setOpacity(clampedOpacity);
|
| - noteLayerPropertyChanged(OpacityChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setPosition(const FloatPoint& point)
|
| -{
|
| - if (point == m_position)
|
| - return;
|
| -
|
| - GraphicsLayer::setPosition(point);
|
| - noteLayerPropertyChanged(GeometryChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setSize(const FloatSize& size)
|
| -{
|
| - if (size == m_size)
|
| - return;
|
| -
|
| - GraphicsLayer::setSize(size);
|
| - noteLayerPropertyChanged(GeometryChanged);
|
| -}
|
| -void GraphicsLayerClutter::setTransform(const TransformationMatrix& t)
|
| -{
|
| - if (t == m_transform)
|
| - return;
|
| -
|
| - GraphicsLayer::setTransform(t);
|
| - noteLayerPropertyChanged(TransformChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::moveOrCopyAnimations(MoveOrCopy operation, GraphicsLayerActor* fromLayer, GraphicsLayerActor* toLayer)
|
| -{
|
| - notImplemented();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setPreserves3D(bool preserves3D)
|
| -{
|
| - if (preserves3D == m_preserves3D)
|
| - return;
|
| -
|
| - GraphicsLayer::setPreserves3D(preserves3D);
|
| - noteLayerPropertyChanged(Preserves3DChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setDrawsContent(bool drawsContent)
|
| -{
|
| - if (drawsContent == m_drawsContent)
|
| - return;
|
| -
|
| - GraphicsLayer::setDrawsContent(drawsContent);
|
| - noteLayerPropertyChanged(DrawsContentChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setParent(GraphicsLayer* childLayer)
|
| -{
|
| - notImplemented();
|
| -
|
| - GraphicsLayer::setParent(childLayer);
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::setChildren(const Vector<GraphicsLayer*>& children)
|
| -{
|
| - bool childrenChanged = GraphicsLayer::setChildren(children);
|
| - if (childrenChanged)
|
| - noteSublayersChanged();
|
| -
|
| - return childrenChanged;
|
| -}
|
| -
|
| -void GraphicsLayerClutter::addChild(GraphicsLayer* childLayer)
|
| -{
|
| - GraphicsLayer::addChild(childLayer);
|
| - noteSublayersChanged();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::addChildAtIndex(GraphicsLayer* childLayer, int index)
|
| -{
|
| - GraphicsLayer::addChildAtIndex(childLayer, index);
|
| - noteSublayersChanged();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
|
| -{
|
| - GraphicsLayer::addChildBelow(childLayer, sibling);
|
| - noteSublayersChanged();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
|
| -{
|
| - GraphicsLayer::addChildAbove(childLayer, sibling);
|
| - noteSublayersChanged();
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
|
| -{
|
| - if (GraphicsLayer::replaceChild(oldChild, newChild)) {
|
| - noteSublayersChanged();
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -void GraphicsLayerClutter::removeFromParent()
|
| -{
|
| - if (m_parent)
|
| - static_cast<GraphicsLayerClutter*>(m_parent)->noteSublayersChanged();
|
| - GraphicsLayer::removeFromParent();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::platformClutterLayerPaintContents(GraphicsContext& context, const IntRect& clip)
|
| -{
|
| - paintGraphicsLayerContents(context, clip);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::platformClutterLayerAnimationStarted(double startTime)
|
| -{
|
| - if (m_client)
|
| - m_client->notifyAnimationStarted(this, startTime);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::repaintLayerDirtyRects()
|
| -{
|
| - if (!m_dirtyRects.size())
|
| - return;
|
| -
|
| - for (size_t i = 0; i < m_dirtyRects.size(); ++i)
|
| - graphicsLayerActorInvalidateRectangle(m_layer.get(), m_dirtyRects[i]);
|
| -
|
| - m_dirtyRects.clear();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::updateOpacityOnLayer()
|
| -{
|
| - clutter_actor_set_opacity(CLUTTER_ACTOR(primaryLayer()), static_cast<guint8>(roundf(m_opacity * 255)));
|
| -}
|
| -
|
| -void GraphicsLayerClutter::updateAnimations()
|
| -{
|
| - if (m_animationsToProcess.size()) {
|
| - AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
|
| - for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
|
| - const String& currAnimationName = it->key;
|
| - AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
|
| - if (animationIt == m_runningAnimations.end())
|
| - continue;
|
| -
|
| - const AnimationProcessingAction& processingInfo = it->value;
|
| - const Vector<LayerPropertyAnimation>& animations = animationIt->value;
|
| - for (size_t i = 0; i < animations.size(); ++i) {
|
| - const LayerPropertyAnimation& currAnimation = animations[i];
|
| - switch (processingInfo.action) {
|
| - case Remove:
|
| - removeClutterAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index);
|
| - break;
|
| - case Pause:
|
| - pauseClutterAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, processingInfo.timeOffset);
|
| - break;
|
| - }
|
| - }
|
| -
|
| - if (processingInfo.action == Remove)
|
| - m_runningAnimations.remove(currAnimationName);
|
| - }
|
| -
|
| - m_animationsToProcess.clear();
|
| - }
|
| -
|
| - size_t numAnimations;
|
| - if ((numAnimations = m_uncomittedAnimations.size())) {
|
| - for (size_t i = 0; i < numAnimations; ++i) {
|
| - const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
|
| - setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
|
| -
|
| - AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
|
| - if (it == m_runningAnimations.end()) {
|
| - Vector<LayerPropertyAnimation> animations;
|
| - animations.append(pendingAnimation);
|
| - m_runningAnimations.add(pendingAnimation.m_name, animations);
|
| - } else {
|
| - Vector<LayerPropertyAnimation>& animations = it->value;
|
| - animations.append(pendingAnimation);
|
| - }
|
| - }
|
| -
|
| - m_uncomittedAnimations.clear();
|
| - }
|
| -}
|
| -
|
| -FloatPoint GraphicsLayerClutter::computePositionRelativeToBase(float& pageScale) const
|
| -{
|
| - pageScale = 1;
|
| -
|
| - FloatPoint offset;
|
| - for (const GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
|
| - if (currLayer->appliesPageScale()) {
|
| - if (currLayer->client())
|
| - pageScale = currLayer->pageScaleFactor();
|
| - return offset;
|
| - }
|
| -
|
| - offset += currLayer->position();
|
| - }
|
| -
|
| - return FloatPoint();
|
| -}
|
| -
|
| -// called from void RenderLayerCompositor::flushPendingLayerChanges
|
| -void GraphicsLayerClutter::flushCompositingState(const FloatRect& clipRect)
|
| -{
|
| - TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
|
| - recursiveCommitChanges(CommitState(), state);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::recursiveCommitChanges(const CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
|
| -{
|
| - if (appliesPageScale()) {
|
| - pageScaleFactor = this->pageScaleFactor();
|
| - affectedByPageScale = true;
|
| - }
|
| -
|
| - // Accumulate an offset from the ancestral pixel-aligned layer.
|
| - FloatPoint baseRelativePosition = positionRelativeToBase;
|
| - if (affectedByPageScale)
|
| - baseRelativePosition += m_position;
|
| -
|
| - commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition);
|
| -
|
| - const Vector<GraphicsLayer*>& childLayers = children();
|
| - size_t numChildren = childLayers.size();
|
| -
|
| - for (size_t i = 0; i < numChildren; ++i) {
|
| - GraphicsLayerClutter* currentChild = static_cast<GraphicsLayerClutter*>(childLayers[i]);
|
| - currentChild->recursiveCommitChanges(commitState, state, pageScaleFactor, baseRelativePosition, affectedByPageScale);
|
| - }
|
| -
|
| - commitLayerChangesAfterSublayers();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::flushCompositingStateForThisLayerOnly()
|
| -{
|
| - float pageScaleFactor;
|
| - FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
|
| - commitLayerChangesBeforeSublayers(pageScaleFactor, offset);
|
| - commitLayerChangesAfterSublayers();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::commitLayerChangesAfterSublayers()
|
| -{
|
| - if (!m_uncommittedChanges)
|
| - return;
|
| -
|
| - if (m_uncommittedChanges & ChildrenChanged)
|
| - updateSublayerList();
|
| -
|
| - m_uncommittedChanges = NoChange;
|
| -}
|
| -void GraphicsLayerClutter::noteSublayersChanged()
|
| -{
|
| - noteLayerPropertyChanged(ChildrenChanged);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::noteLayerPropertyChanged(LayerChangeFlags flags)
|
| -{
|
| - if (!m_uncommittedChanges && m_client)
|
| - m_client->notifyFlushRequired(this); // call RenderLayerBacking::notifyFlushRequired
|
| -
|
| - m_uncommittedChanges |= flags;
|
| -}
|
| -
|
| -void GraphicsLayerClutter::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
|
| -{
|
| - if (!m_uncommittedChanges)
|
| - return;
|
| -
|
| - // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
|
| - if (m_uncommittedChanges & Preserves3DChanged)
|
| - updateStructuralLayer();
|
| -
|
| - if (m_uncommittedChanges & GeometryChanged)
|
| - updateGeometry(pageScaleFactor, positionRelativeToBase);
|
| -
|
| - if (m_uncommittedChanges & DrawsContentChanged)
|
| - updateLayerDrawsContent(pageScaleFactor, positionRelativeToBase);
|
| -
|
| - if (m_uncommittedChanges & NameChanged)
|
| - updateLayerNames();
|
| -
|
| - if (m_uncommittedChanges & TransformChanged)
|
| - updateTransform();
|
| -
|
| - if (m_uncommittedChanges & OpacityChanged)
|
| - updateOpacityOnLayer();
|
| -
|
| - if (m_uncommittedChanges & AnimationChanged)
|
| - updateAnimations();
|
| -
|
| - if (m_uncommittedChanges & DirtyRectsChanged)
|
| - repaintLayerDirtyRects();
|
| -
|
| - if (m_uncommittedChanges & ChildrenChanged) {
|
| - updateSublayerList();
|
| - // Sublayers may set this flag again, so clear it to avoid always updating sublayers in commitLayerChangesAfterSublayers().
|
| - m_uncommittedChanges &= ~ChildrenChanged;
|
| - }
|
| -}
|
| -
|
| -void GraphicsLayerClutter::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
|
| -{
|
| - // FIXME: Need to support page scaling.
|
| - if (m_structuralLayer) {
|
| - clutter_actor_set_position(CLUTTER_ACTOR(m_structuralLayer.get()), m_position.x(), m_position.y());
|
| - clutter_actor_set_size(CLUTTER_ACTOR(m_structuralLayer.get()), m_size.width(), m_size.height());
|
| - graphicsLayerActorSetAnchorPoint(m_structuralLayer.get(), m_anchorPoint.x(), m_anchorPoint.y(), m_anchorPoint.z());
|
| - }
|
| -
|
| - clutter_actor_set_position(CLUTTER_ACTOR(m_layer.get()), m_position.x(), m_position.y());
|
| - clutter_actor_set_size(CLUTTER_ACTOR(m_layer.get()), m_size.width(), m_size.height());
|
| - graphicsLayerActorSetAnchorPoint(m_layer.get(), m_anchorPoint.x(), m_anchorPoint.y(), m_anchorPoint.z());
|
| -}
|
| -
|
| -// Each GraphicsLayer has the corresponding layer in the platform port.
|
| -// So whenever the list of child layer changes, the list of GraphicsLayerActor should be updated accordingly.
|
| -void GraphicsLayerClutter::updateSublayerList()
|
| -{
|
| - GraphicsLayerActorList structuralLayerChildren;
|
| - GraphicsLayerActorList primaryLayerChildren;
|
| -
|
| - GraphicsLayerActorList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
|
| -
|
| - if (m_structuralLayer)
|
| - structuralLayerChildren.append(m_layer);
|
| -
|
| - const Vector<GraphicsLayer*>& childLayers = children();
|
| - size_t numChildren = childLayers.size();
|
| - for (size_t i = 0; i < numChildren; ++i) {
|
| - GraphicsLayerClutter* currentChild = static_cast<GraphicsLayerClutter*>(childLayers[i]);
|
| - GraphicsLayerActor* childLayer = currentChild->layerForSuperlayer();
|
| - ASSERT(GRAPHICS_LAYER_IS_ACTOR(childLayer));
|
| - childListForSublayers.append(childLayer);
|
| -
|
| - // The child layer only preserves 3D if either itself or its parent has preserves3D set.
|
| - graphicsLayerActorSetFlatten(childLayer, !(preserves3D() || currentChild->preserves3D()));
|
| - }
|
| -
|
| - if (m_structuralLayer)
|
| - graphicsLayerActorSetSublayers(m_structuralLayer.get(), structuralLayerChildren);
|
| -
|
| - graphicsLayerActorSetSublayers(m_layer.get(), primaryLayerChildren);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::updateLayerNames()
|
| -{
|
| - clutter_actor_set_name(CLUTTER_ACTOR(m_layer.get()), name().utf8().data());
|
| -}
|
| -
|
| -void GraphicsLayerClutter::updateTransform()
|
| -{
|
| - CoglMatrix matrix = m_transform;
|
| - clutter_actor_set_transform(CLUTTER_ACTOR(primaryLayer()), &matrix);
|
| -}
|
| -
|
| -void GraphicsLayerClutter::updateStructuralLayer()
|
| -{
|
| - ensureStructuralLayer(structuralLayerPurpose());
|
| -}
|
| -
|
| -void GraphicsLayerClutter::ensureStructuralLayer(StructuralLayerPurpose purpose)
|
| -{
|
| - const LayerChangeFlags structuralLayerChangeFlags = NameChanged
|
| - | GeometryChanged
|
| - | TransformChanged
|
| - | ChildrenTransformChanged
|
| - | ChildrenChanged
|
| - | BackfaceVisibilityChanged
|
| - | OpacityChanged;
|
| -
|
| - if (purpose == NoStructuralLayer) {
|
| - if (m_structuralLayer) {
|
| - // Replace the transformLayer in the parent with this layer.
|
| - graphicsLayerActorRemoveFromSuperLayer(m_layer.get());
|
| -
|
| - // If m_layer doesn't have a parent, it means it's the root layer and
|
| - // is likely hosted by something that is not expecting to be changed
|
| - ClutterActor* parentActor = clutter_actor_get_parent(CLUTTER_ACTOR(m_structuralLayer.get()));
|
| - ASSERT(parentActor);
|
| - graphicsLayerActorReplaceSublayer(GRAPHICS_LAYER_ACTOR(parentActor), CLUTTER_ACTOR(m_structuralLayer.get()), CLUTTER_ACTOR(m_layer.get()));
|
| -
|
| - moveOrCopyAnimations(Move, m_structuralLayer.get(), m_layer.get());
|
| -
|
| - // Release the structural layer.
|
| - m_structuralLayer = 0;
|
| -
|
| - m_uncommittedChanges |= structuralLayerChangeFlags;
|
| - }
|
| - return;
|
| - }
|
| -
|
| - bool structuralLayerChanged = false;
|
| - if (purpose == StructuralLayerForPreserves3D) {
|
| - if (m_structuralLayer && (graphicsLayerActorGetLayerType(m_structuralLayer.get()) != GraphicsLayerClutter::LayerTypeTransformLayer))
|
| - m_structuralLayer = 0;
|
| -
|
| - if (!m_structuralLayer) {
|
| - m_structuralLayer = graphicsLayerActorNewWithClient(GraphicsLayerClutter::LayerTypeTransformLayer, this);
|
| - structuralLayerChanged = true;
|
| - }
|
| - } else {
|
| - if (m_structuralLayer && (graphicsLayerActorGetLayerType(m_structuralLayer.get()) != GraphicsLayerClutter::LayerTypeLayer))
|
| - m_structuralLayer = 0;
|
| -
|
| - if (!m_structuralLayer) {
|
| - m_structuralLayer = graphicsLayerActorNewWithClient(GraphicsLayerClutter::LayerTypeLayer, this);
|
| - structuralLayerChanged = true;
|
| - }
|
| - }
|
| -
|
| - if (!structuralLayerChanged)
|
| - return;
|
| -
|
| - m_uncommittedChanges |= structuralLayerChangeFlags;
|
| -
|
| - // We've changed the layer that our parent added to its sublayer list, so tell it to update
|
| - // sublayers again in its commitLayerChangesAfterSublayers().
|
| - static_cast<GraphicsLayerClutter*>(parent())->noteSublayersChanged();
|
| -
|
| - // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
|
| - FloatPoint point(0, 0);
|
| - FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
|
| - clutter_actor_set_position(CLUTTER_ACTOR(m_layer.get()), point.x(), point.y());
|
| - graphicsLayerActorSetAnchorPoint(m_layer.get(), anchorPoint.x(), anchorPoint.y(), anchorPoint.z());
|
| -
|
| - CoglMatrix matrix = TransformationMatrix();
|
| - clutter_actor_set_transform(CLUTTER_ACTOR(m_layer.get()), &matrix);
|
| -
|
| - clutter_actor_set_opacity(CLUTTER_ACTOR(m_layer.get()), 255);
|
| -
|
| - moveOrCopyAnimations(Move, m_layer.get(), m_structuralLayer.get());
|
| -}
|
| -
|
| -GraphicsLayerClutter::StructuralLayerPurpose GraphicsLayerClutter::structuralLayerPurpose() const
|
| -{
|
| - if (preserves3D())
|
| - return StructuralLayerForPreserves3D;
|
| -
|
| - return NoStructuralLayer;
|
| -}
|
| -
|
| -void GraphicsLayerClutter::updateLayerDrawsContent(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
|
| -{
|
| - if (m_drawsContent) {
|
| - graphicsLayerActorSetDrawsContent(m_layer.get(), TRUE);
|
| - setNeedsDisplay();
|
| - } else {
|
| - graphicsLayerActorSetDrawsContent(m_layer.get(), FALSE);
|
| - graphicsLayerActorSetSurface(m_layer.get(), 0);
|
| - }
|
| -
|
| - updateDebugIndicators();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setupAnimation(PlatformClutterAnimation* propertyAnim, const Animation* anim, bool additive)
|
| -{
|
| - double duration = anim->duration();
|
| - if (duration <= 0)
|
| - duration = cAnimationAlmostZeroDuration;
|
| -
|
| - float repeatCount = anim->iterationCount();
|
| - if (repeatCount == Animation::IterationCountInfinite)
|
| - repeatCount = numeric_limits<float>::max();
|
| - else if (anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse)
|
| - repeatCount /= 2;
|
| -
|
| - PlatformClutterAnimation::FillModeType fillMode = PlatformClutterAnimation::NoFillMode;
|
| - switch (anim->fillMode()) {
|
| - case AnimationFillModeNone:
|
| - fillMode = PlatformClutterAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
|
| - break;
|
| - case AnimationFillModeBackwards:
|
| - fillMode = PlatformClutterAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
|
| - break;
|
| - case AnimationFillModeForwards:
|
| - fillMode = PlatformClutterAnimation::Forwards;
|
| - break;
|
| - case AnimationFillModeBoth:
|
| - fillMode = PlatformClutterAnimation::Both;
|
| - break;
|
| - }
|
| -
|
| - propertyAnim->setDuration(duration);
|
| - propertyAnim->setRepeatCount(repeatCount);
|
| - propertyAnim->setAutoreverses(anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse);
|
| - propertyAnim->setRemovedOnCompletion(false);
|
| - propertyAnim->setAdditive(additive);
|
| - propertyAnim->setFillMode(fillMode);
|
| -}
|
| -
|
| -const TimingFunction* GraphicsLayerClutter::timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
|
| -{
|
| - if (animValue->timingFunction())
|
| - return animValue->timingFunction();
|
| - if (anim->isTimingFunctionSet())
|
| - return anim->timingFunction().get();
|
| -
|
| - return CubicBezierTimingFunction::defaultTimingFunction();
|
| -}
|
| -
|
| -PassRefPtr<PlatformClutterAnimation> GraphicsLayerClutter::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive)
|
| -{
|
| - RefPtr<PlatformClutterAnimation> basicAnim = PlatformClutterAnimation::create(PlatformClutterAnimation::Basic, keyPath);
|
| - setupAnimation(basicAnim.get(), anim, additive);
|
| - return basicAnim;
|
| -}
|
| -
|
| -PassRefPtr<PlatformClutterAnimation>GraphicsLayerClutter::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
|
| -{
|
| - RefPtr<PlatformClutterAnimation> keyframeAnim = PlatformClutterAnimation::create(PlatformClutterAnimation::Keyframe, keyPath);
|
| - setupAnimation(keyframeAnim.get(), anim, additive);
|
| - return keyframeAnim;
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
|
| -{
|
| - Vector<float> keyTimes;
|
| - Vector<float> floatValues;
|
| - Vector<FloatPoint3D> floatPoint3DValues;
|
| - Vector<TransformationMatrix> transformationMatrixValues;
|
| - Vector<const TimingFunction*> timingFunctions;
|
| -
|
| - bool forwards = animation->directionIsForwards();
|
| -
|
| - for (unsigned i = 0; i < valueList.size(); ++i) {
|
| - unsigned index = forwards ? i : (valueList.size() - i - 1);
|
| - const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(index));
|
| - keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
|
| -
|
| - if (isMatrixAnimation) {
|
| - TransformationMatrix transform;
|
| - curValue->value()->apply(boxSize, transform);
|
| -
|
| - // FIXME: In CoreAnimation case, if any matrix is singular, CA won't animate it correctly.
|
| - // But I'm not sure clutter also does. Check it later, and then decide
|
| - // whether removing following lines or not.
|
| - if (!transform.isInvertible())
|
| - return false;
|
| -
|
| - transformationMatrixValues.append(transform);
|
| - } else {
|
| - const TransformOperation* transformOp = curValue->value()->at(functionIndex);
|
| - if (isTransformTypeNumber(transformOpType)) {
|
| - float value;
|
| - getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
|
| - floatValues.append(value);
|
| - } else if (isTransformTypeFloatPoint3D(transformOpType)) {
|
| - FloatPoint3D value;
|
| - getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
|
| - floatPoint3DValues.append(value);
|
| - } else {
|
| - TransformationMatrix value;
|
| - getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
|
| - transformationMatrixValues.append(value);
|
| - }
|
| - }
|
| -
|
| - if (i < (valueList.size() - 1))
|
| - timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
|
| - }
|
| -
|
| - keyframeAnim->setKeyTimes(keyTimes);
|
| -
|
| - if (isTransformTypeNumber(transformOpType))
|
| - keyframeAnim->setValues(floatValues);
|
| - else if (isTransformTypeFloatPoint3D(transformOpType))
|
| - keyframeAnim->setValues(floatPoint3DValues);
|
| - else
|
| - keyframeAnim->setValues(transformationMatrixValues);
|
| -
|
| - keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
|
| -
|
| - PlatformClutterAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
|
| - if (valueFunction != PlatformClutterAnimation::NoValueFunction)
|
| - keyframeAnim->setValueFunction(valueFunction);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
|
| -{
|
| - ASSERT(valueList.size() == 2);
|
| -
|
| - bool forwards = animation->directionIsForwards();
|
| -
|
| - unsigned fromIndex = !forwards;
|
| - unsigned toIndex = forwards;
|
| -
|
| - const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(fromIndex));
|
| - const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(toIndex));
|
| -
|
| - if (isMatrixAnimation) {
|
| - TransformationMatrix fromTransform, toTransform;
|
| - startValue->value()->apply(boxSize, fromTransform);
|
| - endValue->value()->apply(boxSize, toTransform);
|
| -
|
| - // FIXME: If any matrix is singular, CA won't animate it correctly.
|
| - // So fall back to software animation, But it's not sure in clutter case.
|
| - // We need to investigate it more.
|
| - if (!fromTransform.isInvertible() || !toTransform.isInvertible())
|
| - return false;
|
| -
|
| - basicAnim->setFromValue(fromTransform);
|
| - basicAnim->setToValue(toTransform);
|
| - } else {
|
| - if (isTransformTypeNumber(transformOpType)) {
|
| - float fromValue;
|
| - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
|
| - basicAnim->setFromValue(fromValue);
|
| -
|
| - float toValue;
|
| - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
|
| - basicAnim->setToValue(toValue);
|
| - } else if (isTransformTypeFloatPoint3D(transformOpType)) {
|
| - FloatPoint3D fromValue;
|
| - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
|
| - basicAnim->setFromValue(fromValue);
|
| -
|
| - FloatPoint3D toValue;
|
| - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
|
| - basicAnim->setToValue(toValue);
|
| - } else {
|
| - TransformationMatrix fromValue;
|
| - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
|
| - basicAnim->setFromValue(fromValue);
|
| -
|
| - TransformationMatrix toValue;
|
| - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
|
| - basicAnim->setToValue(toValue);
|
| - }
|
| - }
|
| -
|
| - // This codepath is used for 2-keyframe animations, so we still need to look in the start
|
| - // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
|
| - const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
|
| - basicAnim->setTimingFunction(timingFunction, !forwards);
|
| -
|
| - PlatformClutterAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
|
| - if (valueFunction != PlatformClutterAnimation::NoValueFunction)
|
| - basicAnim->setValueFunction(valueFunction);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::appendToUncommittedAnimations(const KeyframeValueList& valueList, const TransformOperations* operations, const Animation* animation, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation)
|
| -{
|
| - TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : operations->operations().at(animationIndex)->getOperationType();
|
| - bool additive = animationIndex > 0;
|
| - bool isKeyframe = valueList.size() > 2;
|
| -
|
| - RefPtr<PlatformClutterAnimation> clutterAnimation;
|
| - bool validMatrices = true;
|
| - if (isKeyframe) {
|
| - clutterAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
|
| - validMatrices = setTransformAnimationKeyframes(valueList, animation, clutterAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
|
| - } else {
|
| - clutterAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
|
| - validMatrices = setTransformAnimationEndpoints(valueList, animation, clutterAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
|
| - }
|
| -
|
| - if (!validMatrices)
|
| - return false;
|
| -
|
| - m_uncomittedAnimations.append(LayerPropertyAnimation(clutterAnimation, animationName, valueList.property(), animationIndex, timeOffset));
|
| - return true;
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
|
| -{
|
| - ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
|
| -
|
| - bool hasBigRotation;
|
| - int listIndex = validateTransformOperations(valueList, hasBigRotation);
|
| - const TransformOperations* operations = (listIndex >= 0) ? static_cast<const TransformAnimationValue*>(valueList.at(listIndex))->value() : 0;
|
| -
|
| - // We need to fall back to software animation if we don't have setValueFunction:, and
|
| - // we would need to animate each incoming transform function separately. This is the
|
| - // case if we have a rotation >= 180 or we have more than one transform function.
|
| - if ((hasBigRotation || (operations && operations->size() > 1)) && !PlatformClutterAnimation::supportsValueFunction())
|
| - return false;
|
| -
|
| - bool validMatrices = true;
|
| -
|
| - // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
|
| - // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
|
| - // if that's not true as well.
|
| - bool isMatrixAnimation = listIndex < 0 || !PlatformClutterAnimation::supportsValueFunction() || (operations->size() >= 2 && !PlatformClutterAnimation::supportsAdditiveValueFunction());
|
| - int numAnimations = isMatrixAnimation ? 1 : operations->size();
|
| -
|
| - for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
|
| - if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
|
| - validMatrices = false;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - return validMatrices;
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
|
| -{
|
| - ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
|
| -
|
| - bool isKeyframe = valueList.size() > 2;
|
| - bool valuesOK;
|
| -
|
| - bool additive = false;
|
| - int animationIndex = 0;
|
| -
|
| - RefPtr<PlatformClutterAnimation> clutterAnimation;
|
| -
|
| - if (isKeyframe) {
|
| - clutterAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
|
| - valuesOK = setAnimationKeyframes(valueList, animation, clutterAnimation.get());
|
| - } else {
|
| - clutterAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
|
| - valuesOK = setAnimationEndpoints(valueList, animation, clutterAnimation.get());
|
| - }
|
| -
|
| - if (!valuesOK)
|
| - return false;
|
| -
|
| - m_uncomittedAnimations.append(LayerPropertyAnimation(clutterAnimation, animationName, valueList.property(), animationIndex, timeOffset));
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
|
| -{
|
| - ASSERT(!animationName.isEmpty());
|
| -
|
| - if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
|
| - return false;
|
| -
|
| - // FIXME: ClutterTimeline seems to support steps timing function. So we need to improve here.
|
| - // See http://developer.gnome.org/clutter/stable/ClutterTimeline.html#ClutterAnimationMode
|
| - if (animationHasStepsTimingFunction(valueList, anim))
|
| - return false;
|
| -
|
| - bool createdAnimations = false;
|
| - if (valueList.property() == AnimatedPropertyWebkitTransform)
|
| - createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
|
| - else
|
| - createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
|
| -
|
| - if (createdAnimations)
|
| - noteLayerPropertyChanged(AnimationChanged);
|
| -
|
| - return createdAnimations;
|
| -}
|
| -
|
| -void GraphicsLayerClutter::removeAnimation(const String& animationName)
|
| -{
|
| - if (!animationIsRunning(animationName))
|
| - return;
|
| -
|
| - m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
|
| - noteLayerPropertyChanged(AnimationChanged);
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::removeClutterAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index)
|
| -{
|
| - GraphicsLayerActor* layer = animatedLayer(property);
|
| -
|
| - String animationID = animationIdentifier(animationName, property, index);
|
| -
|
| - PlatformClutterAnimation* existingAnimation = graphicsLayerActorGetAnimationForKey(layer, animationID);
|
| - if (!existingAnimation)
|
| - return false;
|
| -
|
| - existingAnimation->removeAnimationForKey(layer, animationID);
|
| - return true;
|
| -}
|
| -
|
| -void GraphicsLayerClutter::pauseClutterAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
|
| -{
|
| - notImplemented();
|
| -}
|
| -
|
| -void GraphicsLayerClutter::setAnimationOnLayer(PlatformClutterAnimation* clutterAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
|
| -{
|
| - GraphicsLayerActor* layer = animatedLayer(property);
|
| -
|
| - if (timeOffset)
|
| - clutterAnim->setBeginTime(g_get_real_time() - timeOffset);
|
| -
|
| - String animationID = animationIdentifier(animationName, property, index);
|
| -
|
| - PlatformClutterAnimation* existingAnimation = graphicsLayerActorGetAnimationForKey(layer, animationID);
|
| - if (existingAnimation)
|
| - existingAnimation->removeAnimationForKey(layer, animationID);
|
| -
|
| - clutterAnim->addAnimationForKey(layer, animationID);
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* basicAnim)
|
| -{
|
| - bool forwards = animation->directionIsForwards();
|
| -
|
| - unsigned fromIndex = !forwards;
|
| - unsigned toIndex = forwards;
|
| -
|
| - switch (valueList.property()) {
|
| - case AnimatedPropertyOpacity: {
|
| - basicAnim->setFromValue(static_cast<const FloatAnimationValue*>(valueList.at(fromIndex))->value());
|
| - basicAnim->setToValue(static_cast<const FloatAnimationValue*>(valueList.at(toIndex))->value());
|
| - break;
|
| - }
|
| - default:
|
| - ASSERT_NOT_REACHED(); // we don't animate color yet
|
| - break;
|
| - }
|
| -
|
| - // This codepath is used for 2-keyframe animations, so we still need to look in the start
|
| - // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
|
| - const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
|
| - if (timingFunction)
|
| - basicAnim->setTimingFunction(timingFunction, !forwards);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool GraphicsLayerClutter::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* keyframeAnim)
|
| -{
|
| - Vector<float> keyTimes;
|
| - Vector<float> values;
|
| - Vector<const TimingFunction*> timingFunctions;
|
| -
|
| - bool forwards = animation->directionIsForwards();
|
| -
|
| - for (unsigned i = 0; i < valueList.size(); ++i) {
|
| - unsigned index = forwards ? i : (valueList.size() - i - 1);
|
| - const AnimationValue* curValue = valueList.at(index);
|
| - keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
|
| -
|
| - switch (valueList.property()) {
|
| - case AnimatedPropertyOpacity: {
|
| - const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
|
| - values.append(floatValue->value());
|
| - break;
|
| - }
|
| - default:
|
| - ASSERT_NOT_REACHED(); // we don't animate color yet
|
| - break;
|
| - }
|
| -
|
| - if (i < (valueList.size() - 1))
|
| - timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
|
| - }
|
| -
|
| - keyframeAnim->setKeyTimes(keyTimes);
|
| - keyframeAnim->setValues(values);
|
| - keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -GraphicsLayerActor* GraphicsLayerClutter::layerForSuperlayer() const
|
| -{
|
| - return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
|
| -}
|
| -
|
| -GraphicsLayerActor* GraphicsLayerClutter::animatedLayer(AnimatedPropertyID property) const
|
| -{
|
| - return primaryLayer();
|
| -}
|
| -
|
| -} // namespace WebCore
|
| -
|
| -#endif // USE(ACCELERATED_COMPOSITING)
|
|
|