summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/graphics/chromium/cc
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/chromium/cc')
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.cpp55
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.h55
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.cpp93
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h59
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp8
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCGestureCurve.h50
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp319
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h74
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp34
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp66
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h14
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationDelegate.h39
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp50
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h55
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp62
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h49
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.cpp18
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.h7
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp189
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h30
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp24
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp164
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h46
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp121
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h27
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.cpp38
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.h26
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp21
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h7
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCProxy.cpp20
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCProxy.h9
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp59
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h19
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp13
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp16
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h5
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp69
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h13
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp284
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.h149
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp140
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h15
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp150
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h19
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp12
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.cpp96
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.h85
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h4
60 files changed, 2275 insertions, 748 deletions
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.cpp
new file mode 100644
index 000000000..556e46b4e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Google 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. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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"
+
+#include "cc/CCActiveGestureAnimation.h"
+
+#include "cc/CCGestureCurve.h"
+
+namespace WebCore {
+
+PassOwnPtr<CCActiveGestureAnimation> CCActiveGestureAnimation::create(double startTime, PassOwnPtr<CCGestureCurve> curve, CCGestureCurveTarget* target)
+{
+ return adoptPtr(new CCActiveGestureAnimation(startTime, curve, target));
+}
+
+CCActiveGestureAnimation::CCActiveGestureAnimation(double startTime, PassOwnPtr<CCGestureCurve> curve, CCGestureCurveTarget* target)
+ : m_startTime(startTime)
+ , m_gestureCurve(curve)
+ , m_gestureCurveTarget(target)
+{
+}
+
+CCActiveGestureAnimation::~CCActiveGestureAnimation()
+{
+}
+
+bool CCActiveGestureAnimation::animate(double time)
+{
+ // CCGestureCurves used zero-based time, so subtract start-time.
+ return m_gestureCurve->apply(time - m_startTime, m_gestureCurveTarget);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.h b/Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.h
new file mode 100644
index 000000000..c71b225df
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCActiveGestureAnimation.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Google 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. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 CCActiveGestureAnimation_h
+#define CCActiveGestureAnimation_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class CCGestureCurve;
+class CCGestureCurveTarget;
+
+class CCActiveGestureAnimation {
+ WTF_MAKE_NONCOPYABLE(CCActiveGestureAnimation);
+public:
+ static PassOwnPtr<CCActiveGestureAnimation> create(double startTime, PassOwnPtr<CCGestureCurve>, CCGestureCurveTarget*);
+ ~CCActiveGestureAnimation();
+
+ bool animate(double time);
+
+private:
+ CCActiveGestureAnimation(double startTime, PassOwnPtr<CCGestureCurve>, CCGestureCurveTarget*);
+
+ double m_startTime;
+ OwnPtr<CCGestureCurve> m_gestureCurve;
+ CCGestureCurveTarget* m_gestureCurveTarget;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.cpp
new file mode 100644
index 000000000..9f41844ca
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012 Google 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. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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"
+
+#include "cc/CCAnimationEvents.h"
+
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+CCAnimationEvent::CCAnimationEvent(int layerId)
+ : m_layerId(layerId)
+{
+}
+
+CCAnimationEvent::~CCAnimationEvent()
+{
+}
+
+const CCAnimationStartedEvent* CCAnimationEvent::toAnimationStartedEvent() const
+{
+ ASSERT(type() == Started);
+ return static_cast<const CCAnimationStartedEvent*>(this);
+}
+
+const CCAnimationFinishedEvent* CCAnimationEvent::toAnimationFinishedEvent() const
+{
+ ASSERT(type() == Finished);
+ return static_cast<const CCAnimationFinishedEvent*>(this);
+}
+
+PassOwnPtr<CCAnimationStartedEvent> CCAnimationStartedEvent::create(int layerId)
+{
+ return adoptPtr(new CCAnimationStartedEvent(layerId));
+}
+
+CCAnimationStartedEvent::CCAnimationStartedEvent(int layerId)
+ : CCAnimationEvent(layerId)
+{
+}
+
+CCAnimationStartedEvent::~CCAnimationStartedEvent()
+{
+}
+
+CCAnimationEvent::Type CCAnimationStartedEvent::type() const
+{
+ return Started;
+}
+
+PassOwnPtr<CCAnimationFinishedEvent> CCAnimationFinishedEvent::create(int layerId, int animationId)
+{
+ return adoptPtr(new CCAnimationFinishedEvent(layerId, animationId));
+}
+
+CCAnimationFinishedEvent::CCAnimationFinishedEvent(int layerId, int animationId)
+ : CCAnimationEvent(layerId)
+ , m_animationId(animationId)
+{
+}
+
+CCAnimationFinishedEvent::~CCAnimationFinishedEvent()
+{
+}
+
+CCAnimationEvent::Type CCAnimationFinishedEvent::type() const
+{
+ return Finished;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h b/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h
index b21a79e31..da94e1e27 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCAnimationEvents.h
@@ -25,20 +25,65 @@
#ifndef CCAnimationEvents_h
#define CCAnimationEvents_h
+#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
+class CCAnimationStartedEvent;
+class CCAnimationFinishedEvent;
+
+class CCAnimationEvent {
+public:
+ enum Type { Started, Finished };
+
+ virtual ~CCAnimationEvent();
+
+ virtual Type type() const = 0;
+
+ int layerId() const { return m_layerId; }
+
+ const CCAnimationStartedEvent* toAnimationStartedEvent() const;
+ const CCAnimationFinishedEvent* toAnimationFinishedEvent() const;
+
+protected:
+ CCAnimationEvent(int layerId);
+
+private:
+ int m_layerId;
+};
+
+// Indicates that an animation has started on a particular layer.
+class CCAnimationStartedEvent : public CCAnimationEvent {
+public:
+ static PassOwnPtr<CCAnimationStartedEvent> create(int layerId);
+
+ virtual ~CCAnimationStartedEvent();
+
+ virtual Type type() const;
+
+private:
+ explicit CCAnimationStartedEvent(int layerId);
+};
+
// Indicates that an animation has started on a particular layer.
-struct CCAnimationStartedEvent {
- CCAnimationStartedEvent(int layerID, double time)
- : layerID(layerID)
- , time(time) { }
- int layerID;
- double time;
+class CCAnimationFinishedEvent : public CCAnimationEvent {
+public:
+ static PassOwnPtr<CCAnimationFinishedEvent> create(int layerId, int animationId);
+
+ virtual ~CCAnimationFinishedEvent();
+
+ virtual Type type() const;
+
+ int animationId() const { return m_animationId; }
+
+private:
+ CCAnimationFinishedEvent(int layerId, int animationId);
+
+ int m_animationId;
};
-typedef Vector<CCAnimationStartedEvent> CCAnimationEventsVector;
+typedef Vector<OwnPtr<CCAnimationEvent> > CCAnimationEventsVector;
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
index 9126a7d44..c96af246e 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
@@ -34,9 +34,9 @@ namespace WebCore {
class CCCanvasLayerImpl : public CCLayerImpl {
public:
- static PassRefPtr<CCCanvasLayerImpl> create(int id)
+ static PassOwnPtr<CCCanvasLayerImpl> create(int id)
{
- return adoptRef(new CCCanvasLayerImpl(id));
+ return adoptPtr(new CCCanvasLayerImpl(id));
}
virtual ~CCCanvasLayerImpl();
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp
index 2d6f43f31..6a062caca 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp
@@ -56,7 +56,7 @@ CCDamageTracker::~CCDamageTracker()
{
}
-void CCDamageTracker::updateDamageTrackingState(const Vector<RefPtr<CCLayerImpl> >& layerList, int targetSurfaceLayerID, CCLayerImpl* targetSurfaceMaskLayer)
+void CCDamageTracker::updateDamageTrackingState(const Vector<CCLayerImpl*>& layerList, int targetSurfaceLayerID, CCLayerImpl* targetSurfaceMaskLayer)
{
//
// This function computes the "damage rect" of a target surface, and updates the state
@@ -130,7 +130,7 @@ void CCDamageTracker::updateDamageTrackingState(const Vector<RefPtr<CCLayerImpl>
// If the target surface already knows its entire region is damaged, we can return early.
// FIXME: this should go away, or will be cleaner, after refactoring into RenderPass/RenderSchedule.
- CCLayerImpl* layer = layerList[0].get();
+ CCLayerImpl* layer = layerList[0];
CCRenderSurface* targetSurface = layer->targetRenderSurface();
if (m_forceFullDamageNextUpdate || targetSurface->surfacePropertyChangedOnlyFromDescendant()) {
@@ -161,12 +161,12 @@ void CCDamageTracker::saveRectForNextFrame(int layerID, const FloatRect& targetS
m_nextRectHistory->set(layerID, targetSpaceRect);
}
-FloatRect CCDamageTracker::trackDamageFromActiveLayers(const Vector<RefPtr<CCLayerImpl> >& layerList, int targetSurfaceLayerID)
+FloatRect CCDamageTracker::trackDamageFromActiveLayers(const Vector<CCLayerImpl*>& layerList, int targetSurfaceLayerID)
{
FloatRect damageRect = FloatRect();
for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
- CCLayerImpl* layer = layerList[layerIndex].get();
+ CCLayerImpl* layer = layerList[layerIndex];
if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<CCLayerImpl>(layer, targetSurfaceLayerID))
extendDamageForRenderSurface(layer, damageRect);
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h b/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h
index d428f26d1..7a629c478 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h
@@ -44,13 +44,13 @@ public:
~CCDamageTracker();
void forceFullDamageNextUpdate() { m_forceFullDamageNextUpdate = true; }
- void updateDamageTrackingState(const Vector<RefPtr<CCLayerImpl> >& layerList, int targetSurfaceLayerID, CCLayerImpl* targetSurfaceMaskLayer);
+ void updateDamageTrackingState(const Vector<CCLayerImpl*>& layerList, int targetSurfaceLayerID, CCLayerImpl* targetSurfaceMaskLayer);
const FloatRect& currentDamageRect() { return m_currentDamageRect; }
private:
CCDamageTracker();
- FloatRect trackDamageFromActiveLayers(const Vector<RefPtr<CCLayerImpl> >& layerList, int targetSurfaceLayerID);
+ FloatRect trackDamageFromActiveLayers(const Vector<CCLayerImpl*>& layerList, int targetSurfaceLayerID);
FloatRect trackDamageFromSurfaceMask(CCLayerImpl* targetSurfaceMaskLayer);
FloatRect trackDamageFromLeftoverRects();
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCGestureCurve.h b/Source/WebCore/platform/graphics/chromium/cc/CCGestureCurve.h
new file mode 100644
index 000000000..3ef935b6a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCGestureCurve.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Google 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. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 CCGestureCurve_h
+#define CCGestureCurve_h
+
+namespace WebCore {
+
+class IntPoint;
+
+class CCGestureCurveTarget {
+public:
+ virtual void setScrollIncrement(const IntPoint&) = 0;
+ // FIXME: add interfaces for setScroll(), setPageScaleAndScroll(), etc.
+
+protected:
+ virtual ~CCGestureCurveTarget() { }
+};
+
+class CCGestureCurve {
+public:
+ virtual ~CCGestureCurve() { }
+
+ virtual bool apply(double time, CCGestureCurveTarget*) = 0;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h b/Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h
index 6c055994c..33721f1df 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h
@@ -72,8 +72,8 @@ public:
virtual void startPageScaleAnimation(const IntSize& targetPosition,
bool anchorPoint,
float pageScale,
- double startTimeMs,
- double durationMs) = 0;
+ double startTime,
+ double duration) = 0;
protected:
CCInputHandlerClient() { }
@@ -87,7 +87,7 @@ public:
virtual ~CCInputHandler() { }
virtual int identifier() const = 0;
- virtual void willDraw(double frameDisplayTimeMs) = 0;
+ virtual void willDraw(double monotonicTime) = 0;
protected:
CCInputHandler() { }
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp
index b615c736c..ae41fe069 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp
@@ -42,31 +42,173 @@ namespace WebCore {
namespace {
template <class Keyframe>
-bool keyframesAreSorted(const Vector<Keyframe>& keyframes)
+void insertKeyframe(PassOwnPtr<Keyframe> popKeyframe, Vector<OwnPtr<Keyframe> >& keyframes)
{
- if (!keyframes.size())
- return true;
-
- for (size_t i = 0; i < keyframes.size() - 1; ++i) {
- if (keyframes[i].time > keyframes[i+1].time)
- return false;
+ OwnPtr<Keyframe> keyframe = popKeyframe;
+
+ // Usually, the keyframes will be added in order, so this loop would be unnecessary and
+ // we should skip it if possible.
+ if (!keyframes.isEmpty() && keyframe->time() < keyframes.last()->time()) {
+ for (size_t i = 0; i < keyframes.size(); ++i) {
+ if (keyframe->time() < keyframes[i]->time()) {
+ keyframes.insert(i, keyframe.release());
+ return;
+ }
+ }
}
- return true;
+ keyframes.append(keyframe.release());
+}
+
+PassOwnPtr<CCTimingFunction> cloneTimingFunction(const CCTimingFunction* timingFunction)
+{
+ ASSERT(timingFunction);
+ OwnPtr<CCAnimationCurve> curve(timingFunction->clone());
+ return adoptPtr(static_cast<CCTimingFunction*>(curve.leakPtr()));
}
} // namespace
-PassOwnPtr<CCKeyframedFloatAnimationCurve> CCKeyframedFloatAnimationCurve::create(const Vector<CCFloatKeyframe>& keyframes)
+CCKeyframe::CCKeyframe(double time, PassOwnPtr<CCTimingFunction> timingFunction)
+ : m_time(time)
+ , m_timingFunction(timingFunction)
+{
+}
+
+CCKeyframe::~CCKeyframe()
+{
+}
+
+double CCKeyframe::time() const
+{
+ return m_time;
+}
+
+const CCTimingFunction* CCKeyframe::timingFunction() const
+{
+ return m_timingFunction.get();
+}
+
+PassOwnPtr<CCFloatKeyframe> CCFloatKeyframe::create(double time, float value, PassOwnPtr<CCTimingFunction> timingFunction)
+{
+ return adoptPtr(new CCFloatKeyframe(time, value, timingFunction));
+}
+
+CCFloatKeyframe::CCFloatKeyframe(double time, float value, PassOwnPtr<CCTimingFunction> timingFunction)
+ : CCKeyframe(time, timingFunction)
+ , m_value(value)
+{
+}
+
+CCFloatKeyframe::~CCFloatKeyframe()
+{
+}
+
+float CCFloatKeyframe::value() const
{
- if (!keyframes.size() || !keyframesAreSorted(keyframes))
- return nullptr;
+ return m_value;
+}
- return adoptPtr(new CCKeyframedFloatAnimationCurve(keyframes));
+PassOwnPtr<CCFloatKeyframe> CCFloatKeyframe::clone() const
+{
+ return CCFloatKeyframe::create(time(), value(), timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr);
}
-CCKeyframedFloatAnimationCurve::CCKeyframedFloatAnimationCurve(const Vector<CCFloatKeyframe>& keyframes)
- : m_keyframes(keyframes)
+PassOwnPtr<CCTransformKeyframe> CCTransformKeyframe::create(double time, const TransformOperations& value, PassOwnPtr<CCTimingFunction> timingFunction)
+{
+ return adoptPtr(new CCTransformKeyframe(time, value, timingFunction));
+}
+
+CCTransformKeyframe::CCTransformKeyframe(double time, const TransformOperations& value, PassOwnPtr<CCTimingFunction> timingFunction)
+ : CCKeyframe(time, timingFunction)
+ , m_value(value)
+{
+}
+
+CCTransformKeyframe::~CCTransformKeyframe()
+{
+}
+
+const TransformOperations& CCTransformKeyframe::value() const
+{
+ return m_value;
+}
+
+PassOwnPtr<CCTransformKeyframe> CCTransformKeyframe::clone() const
+{
+ // We need to do a deep copy the m_value may contain ref pointers to TransformOperation objects.
+ TransformOperations operations;
+ for (size_t j = 0; j < m_value.size(); ++j) {
+ TransformOperation::OperationType operationType = m_value.operations()[j]->getOperationType();
+ switch (operationType) {
+ case TransformOperation::SCALE_X:
+ case TransformOperation::SCALE_Y:
+ case TransformOperation::SCALE_Z:
+ case TransformOperation::SCALE_3D:
+ case TransformOperation::SCALE: {
+ ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(m_value.operations()[j].get());
+ operations.operations().append(ScaleTransformOperation::create(transform->x(), transform->y(), transform->z(), operationType));
+ break;
+ }
+ case TransformOperation::TRANSLATE_X:
+ case TransformOperation::TRANSLATE_Y:
+ case TransformOperation::TRANSLATE_Z:
+ case TransformOperation::TRANSLATE_3D:
+ case TransformOperation::TRANSLATE: {
+ TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(m_value.operations()[j].get());
+ operations.operations().append(TranslateTransformOperation::create(transform->x(), transform->y(), transform->z(), operationType));
+ break;
+ }
+ case TransformOperation::ROTATE_X:
+ case TransformOperation::ROTATE_Y:
+ case TransformOperation::ROTATE_3D:
+ case TransformOperation::ROTATE: {
+ RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(m_value.operations()[j].get());
+ operations.operations().append(RotateTransformOperation::create(transform->x(), transform->y(), transform->z(), transform->angle(), operationType));
+ break;
+ }
+ case TransformOperation::SKEW_X:
+ case TransformOperation::SKEW_Y:
+ case TransformOperation::SKEW: {
+ SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(m_value.operations()[j].get());
+ operations.operations().append(SkewTransformOperation::create(transform->angleX(), transform->angleY(), operationType));
+ break;
+ }
+ case TransformOperation::MATRIX: {
+ MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(m_value.operations()[j].get());
+ TransformationMatrix m = transform->matrix();
+ operations.operations().append(MatrixTransformOperation::create(m.a(), m.b(), m.c(), m.d(), m.e(), m.f()));
+ break;
+ }
+ case TransformOperation::MATRIX_3D: {
+ Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(m_value.operations()[j].get());
+ operations.operations().append(Matrix3DTransformOperation::create(transform->matrix()));
+ break;
+ }
+ case TransformOperation::PERSPECTIVE: {
+ PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(m_value.operations()[j].get());
+ operations.operations().append(PerspectiveTransformOperation::create(transform->perspective()));
+ break;
+ }
+ case TransformOperation::IDENTITY: {
+ operations.operations().append(IdentityTransformOperation::create());
+ break;
+ }
+ case TransformOperation::NONE:
+ // Do nothing.
+ break;
+ } // switch
+ } // for each operation
+
+ return CCTransformKeyframe::create(time(), operations, timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr);
+}
+
+PassOwnPtr<CCKeyframedFloatAnimationCurve> CCKeyframedFloatAnimationCurve::create()
+{
+ return adoptPtr(new CCKeyframedFloatAnimationCurve);
+}
+
+CCKeyframedFloatAnimationCurve::CCKeyframedFloatAnimationCurve()
{
}
@@ -74,159 +216,110 @@ CCKeyframedFloatAnimationCurve::~CCKeyframedFloatAnimationCurve()
{
}
+void CCKeyframedFloatAnimationCurve::addKeyframe(PassOwnPtr<CCFloatKeyframe> keyframe)
+{
+ insertKeyframe(keyframe, m_keyframes);
+}
+
double CCKeyframedFloatAnimationCurve::duration() const
{
- return m_keyframes.last().time - m_keyframes.first().time;
+ return m_keyframes.last()->time() - m_keyframes.first()->time();
}
PassOwnPtr<CCAnimationCurve> CCKeyframedFloatAnimationCurve::clone() const
{
- return adoptPtr(new CCKeyframedFloatAnimationCurve(*this));
+ OwnPtr<CCKeyframedFloatAnimationCurve> toReturn(CCKeyframedFloatAnimationCurve::create());
+ for (size_t i = 0; i < m_keyframes.size(); ++i)
+ toReturn->addKeyframe(m_keyframes[i]->clone());
+ return toReturn.release();
}
float CCKeyframedFloatAnimationCurve::getValue(double t) const
{
- if (t <= m_keyframes.first().time)
- return m_keyframes.first().value;
+ if (t <= m_keyframes.first()->time())
+ return m_keyframes.first()->value();
- if (t >= m_keyframes.last().time)
- return m_keyframes.last().value;
+ if (t >= m_keyframes.last()->time())
+ return m_keyframes.last()->value();
size_t i = 0;
for (; i < m_keyframes.size() - 1; ++i) {
- if (t < m_keyframes[i+1].time)
+ if (t < m_keyframes[i+1]->time())
break;
}
- float progress = static_cast<float>((t - m_keyframes[i].time) / (m_keyframes[i+1].time - m_keyframes[i].time));
- // FIXME: apply timing function here.
- return m_keyframes[i].value + (m_keyframes[i+1].value - m_keyframes[i].value) * progress;
+ float progress = static_cast<float>((t - m_keyframes[i]->time()) / (m_keyframes[i+1]->time() - m_keyframes[i]->time()));
+
+ if (m_keyframes[i]->timingFunction())
+ progress = m_keyframes[i]->timingFunction()->getValue(progress);
+
+ return m_keyframes[i]->value() + (m_keyframes[i+1]->value() - m_keyframes[i]->value()) * progress;
}
-PassOwnPtr<CCKeyframedTransformAnimationCurve> CCKeyframedTransformAnimationCurve::create(const Vector<CCTransformKeyframe>& keyframes)
+PassOwnPtr<CCKeyframedTransformAnimationCurve> CCKeyframedTransformAnimationCurve::create()
{
- if (!keyframes.size() || !keyframesAreSorted(keyframes))
- return nullptr;
+ return adoptPtr(new CCKeyframedTransformAnimationCurve);
+}
- return adoptPtr(new CCKeyframedTransformAnimationCurve(keyframes));
+CCKeyframedTransformAnimationCurve::CCKeyframedTransformAnimationCurve()
+{
}
-CCKeyframedTransformAnimationCurve::CCKeyframedTransformAnimationCurve(const Vector<CCTransformKeyframe>& keyframes)
- : m_keyframes(keyframes)
+CCKeyframedTransformAnimationCurve::~CCKeyframedTransformAnimationCurve()
{
}
-CCKeyframedTransformAnimationCurve::~CCKeyframedTransformAnimationCurve() { }
+void CCKeyframedTransformAnimationCurve::addKeyframe(PassOwnPtr<CCTransformKeyframe> keyframe)
+{
+ insertKeyframe(keyframe, m_keyframes);
+}
double CCKeyframedTransformAnimationCurve::duration() const
{
- return m_keyframes.last().time - m_keyframes.first().time;
+ return m_keyframes.last()->time() - m_keyframes.first()->time();
}
PassOwnPtr<CCAnimationCurve> CCKeyframedTransformAnimationCurve::clone() const
{
- Vector<CCTransformKeyframe> keyframes;
- // We need to do a deep copy of all of the keyframes since they contain ref
- // pointers to TransformOperation objects.
- for (size_t i = 0; i < m_keyframes.size(); ++i) {
- CCTransformKeyframe keyframe(m_keyframes[i].time);
- for (size_t j = 0; j < m_keyframes[i].value.size(); ++j) {
- TransformOperation::OperationType operationType = m_keyframes[i].value.operations()[j]->getOperationType();
- switch (operationType) {
- case TransformOperation::SCALE_X:
- case TransformOperation::SCALE_Y:
- case TransformOperation::SCALE_Z:
- case TransformOperation::SCALE_3D:
- case TransformOperation::SCALE: {
- ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(m_keyframes[i].value.operations()[j].get());
- keyframe.value.operations().append(ScaleTransformOperation::create(transform->x(), transform->y(), transform->z(), operationType));
- break;
- }
- case TransformOperation::TRANSLATE_X:
- case TransformOperation::TRANSLATE_Y:
- case TransformOperation::TRANSLATE_Z:
- case TransformOperation::TRANSLATE_3D:
- case TransformOperation::TRANSLATE: {
- TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(m_keyframes[i].value.operations()[j].get());
- keyframe.value.operations().append(TranslateTransformOperation::create(transform->x(), transform->y(), transform->z(), operationType));
- break;
- }
- case TransformOperation::ROTATE_X:
- case TransformOperation::ROTATE_Y:
- case TransformOperation::ROTATE_3D:
- case TransformOperation::ROTATE: {
- RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(m_keyframes[i].value.operations()[j].get());
- keyframe.value.operations().append(RotateTransformOperation::create(transform->x(), transform->y(), transform->z(), transform->angle(), operationType));
- break;
- }
- case TransformOperation::SKEW_X:
- case TransformOperation::SKEW_Y:
- case TransformOperation::SKEW: {
- SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(m_keyframes[i].value.operations()[j].get());
- keyframe.value.operations().append(SkewTransformOperation::create(transform->angleX(), transform->angleY(), operationType));
- break;
- }
- case TransformOperation::MATRIX: {
- MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(m_keyframes[i].value.operations()[j].get());
- TransformationMatrix m = transform->matrix();
- keyframe.value.operations().append(MatrixTransformOperation::create(m.a(), m.b(), m.c(), m.d(), m.e(), m.f()));
- break;
- }
- case TransformOperation::MATRIX_3D: {
- Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(m_keyframes[i].value.operations()[j].get());
- keyframe.value.operations().append(Matrix3DTransformOperation::create(transform->matrix()));
- break;
- }
- case TransformOperation::PERSPECTIVE: {
- PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(m_keyframes[i].value.operations()[j].get());
- keyframe.value.operations().append(PerspectiveTransformOperation::create(transform->perspective()));
- break;
- }
- case TransformOperation::IDENTITY: {
- keyframe.value.operations().append(IdentityTransformOperation::create());
- break;
- }
- case TransformOperation::NONE:
- // Do nothing.
- break;
- } // switch
- } // for each operation
- keyframes.append(keyframe);
- }
- return CCKeyframedTransformAnimationCurve::create(keyframes);
+ OwnPtr<CCKeyframedTransformAnimationCurve> toReturn(CCKeyframedTransformAnimationCurve::create());
+ for (size_t i = 0; i < m_keyframes.size(); ++i)
+ toReturn->addKeyframe(m_keyframes[i]->clone());
+ return toReturn.release();
}
TransformationMatrix CCKeyframedTransformAnimationCurve::getValue(double t, const IntSize& layerSize) const
{
TransformationMatrix transformMatrix;
- if (t <= m_keyframes.first().time) {
- m_keyframes.first().value.apply(layerSize, transformMatrix);
+ if (t <= m_keyframes.first()->time()) {
+ m_keyframes.first()->value().apply(layerSize, transformMatrix);
return transformMatrix;
}
- if (t >= m_keyframes.last().time) {
- m_keyframes.last().value.apply(layerSize, transformMatrix);
+ if (t >= m_keyframes.last()->time()) {
+ m_keyframes.last()->value().apply(layerSize, transformMatrix);
return transformMatrix;
}
size_t i = 0;
for (; i < m_keyframes.size() - 1; ++i) {
- if (t < m_keyframes[i+1].time)
+ if (t < m_keyframes[i+1]->time())
break;
}
- // FIXME: apply timing function here.
- double progress = (t - m_keyframes[i].time) / (m_keyframes[i+1].time - m_keyframes[i].time);
+ double progress = (t - m_keyframes[i]->time()) / (m_keyframes[i+1]->time() - m_keyframes[i]->time());
+
+ if (m_keyframes[i]->timingFunction())
+ progress = m_keyframes[i]->timingFunction()->getValue(progress);
- if (m_keyframes[i].value.operationsMatch(m_keyframes[i+1].value)) {
- for (size_t j = 0; j < m_keyframes[i+1].value.size(); ++j)
- m_keyframes[i+1].value.operations()[j]->blend(m_keyframes[i].value.at(j), progress)->apply(transformMatrix, layerSize);
+ if (m_keyframes[i]->value().operationsMatch(m_keyframes[i+1]->value())) {
+ for (size_t j = 0; j < m_keyframes[i+1]->value().size(); ++j)
+ m_keyframes[i+1]->value().operations()[j]->blend(m_keyframes[i]->value().at(j), progress)->apply(transformMatrix, layerSize);
} else {
TransformationMatrix source;
- m_keyframes[i].value.apply(layerSize, source);
- m_keyframes[i+1].value.apply(layerSize, transformMatrix);
+ m_keyframes[i]->value().apply(layerSize, source);
+ m_keyframes[i+1]->value().apply(layerSize, transformMatrix);
transformMatrix.blend(source, progress);
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h
index 1c4d64adb..c3073bf08 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h
@@ -27,46 +27,66 @@
#include "TransformOperations.h"
#include "cc/CCAnimationCurve.h"
+#include "cc/CCTimingFunction.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
namespace WebCore {
-struct CCFloatKeyframe {
- CCFloatKeyframe(double time, float value)
- : time(time)
- , value(value)
- {
- }
+class CCKeyframe {
+public:
+ double time() const;
+ const CCTimingFunction* timingFunction() const;
+
+protected:
+ CCKeyframe(double time, PassOwnPtr<CCTimingFunction>);
+ virtual ~CCKeyframe();
- double time;
- float value;
+private:
+ double m_time;
+ OwnPtr<CCTimingFunction> m_timingFunction;
};
-struct CCTransformKeyframe {
- explicit CCTransformKeyframe(double time)
- : time(time)
- {
- }
+class CCFloatKeyframe : public CCKeyframe {
+public:
+ static PassOwnPtr<CCFloatKeyframe> create(double time, float value, PassOwnPtr<CCTimingFunction>);
+ virtual ~CCFloatKeyframe();
+
+ float value() const;
- CCTransformKeyframe(double time, const TransformOperations& value)
- : time(time)
- , value(value)
- {
- }
+ PassOwnPtr<CCFloatKeyframe> clone() const;
- double time;
- TransformOperations value;
+private:
+ CCFloatKeyframe(double time, float value, PassOwnPtr<CCTimingFunction>);
+
+ float m_value;
+};
+
+class CCTransformKeyframe : public CCKeyframe {
+public:
+ static PassOwnPtr<CCTransformKeyframe> create(double time, const TransformOperations& value, PassOwnPtr<CCTimingFunction>);
+ virtual ~CCTransformKeyframe();
+
+ const TransformOperations& value() const;
+
+ PassOwnPtr<CCTransformKeyframe> clone() const;
+
+private:
+ CCTransformKeyframe(double time, const TransformOperations& value, PassOwnPtr<CCTimingFunction>);
+
+ TransformOperations m_value;
};
class CCKeyframedFloatAnimationCurve : public CCFloatAnimationCurve {
public:
// It is required that the keyframes be sorted by time.
- static PassOwnPtr<CCKeyframedFloatAnimationCurve> create(const Vector<CCFloatKeyframe>& keyframes);
+ static PassOwnPtr<CCKeyframedFloatAnimationCurve> create();
virtual ~CCKeyframedFloatAnimationCurve();
+ void addKeyframe(PassOwnPtr<CCFloatKeyframe>);
+
// CCAnimationCurve implementation
virtual double duration() const;
virtual PassOwnPtr<CCAnimationCurve> clone() const;
@@ -75,20 +95,22 @@ public:
virtual float getValue(double t) const;
private:
- explicit CCKeyframedFloatAnimationCurve(const Vector<CCFloatKeyframe>&);
+ CCKeyframedFloatAnimationCurve();
// Always sorted in order of increasing time. No two keyframes have the
// same time.
- Vector<CCFloatKeyframe> m_keyframes;
+ Vector<OwnPtr<CCFloatKeyframe> > m_keyframes;
};
class CCKeyframedTransformAnimationCurve : public CCTransformAnimationCurve {
public:
// It is required that the keyframes be sorted by time.
- static PassOwnPtr<CCKeyframedTransformAnimationCurve> create(const Vector<CCTransformKeyframe>& keyframes);
+ static PassOwnPtr<CCKeyframedTransformAnimationCurve> create();
virtual ~CCKeyframedTransformAnimationCurve();
+ void addKeyframe(PassOwnPtr<CCTransformKeyframe>);
+
// CCAnimationCurve implementation
virtual double duration() const;
virtual PassOwnPtr<CCAnimationCurve> clone() const;
@@ -97,11 +119,11 @@ public:
virtual TransformationMatrix getValue(double t, const IntSize&) const;
private:
- explicit CCKeyframedTransformAnimationCurve(const Vector<CCTransformKeyframe>&);
+ CCKeyframedTransformAnimationCurve();
// Always sorted in order of increasing time. No two keyframes have the
// same time.
- Vector<CCTransformKeyframe> m_keyframes;
+ Vector<OwnPtr<CCTransformKeyframe> > m_keyframes;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp
index d9e72efc4..335d3a58e 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp
@@ -37,16 +37,16 @@ namespace WebCore {
namespace {
-template <typename Keyframe, typename Value>
-void appendKeyframe(Vector<Keyframe>& keyframes, double keyTime, const Value* value)
+template <class Value, class Keyframe, class Curve>
+void appendKeyframe(Curve& curve, double keyTime, const Value* value, PassOwnPtr<CCTimingFunction> timingFunction)
{
- keyframes.append(Keyframe(keyTime, value->value()));
+ curve.addKeyframe(Keyframe::create(keyTime, value->value(), timingFunction));
}
template <>
-void appendKeyframe<CCTransformKeyframe, TransformAnimationValue>(Vector<CCTransformKeyframe>& keyframes, double keyTime, const TransformAnimationValue* value)
+void appendKeyframe<TransformAnimationValue, CCTransformKeyframe, CCKeyframedTransformAnimationCurve>(CCKeyframedTransformAnimationCurve& curve, double keyTime, const TransformAnimationValue* value, PassOwnPtr<CCTimingFunction> timingFunction)
{
- keyframes.append(CCTransformKeyframe(keyTime, *value->value()));
+ curve.addKeyframe(CCTransformKeyframe::create(keyTime, *value->value(), timingFunction));
}
template <class Value, class Keyframe, class Curve>
@@ -64,21 +64,33 @@ PassOwnPtr<CCActiveAnimation> createActiveAnimation(const KeyframeValueList& val
if (animation && animation->isFillModeSet() && (animation->fillsForwards() || animation->fillsBackwards()))
return nullptr;
+ OwnPtr<Curve> curve = Curve::create();
Vector<Keyframe> keyframes;
for (size_t i = 0; i < valueList.size(); i++) {
const Value* originalValue = static_cast<const Value*>(valueList.at(i));
- // FIXME: add support for timing functions.
- if (originalValue->timingFunction() && originalValue->timingFunction()->type() != TimingFunction::LinearFunction)
- return nullptr;
+ OwnPtr<CCTimingFunction> timingFunction;
+ if (originalValue->timingFunction()) {
+ switch (originalValue->timingFunction()->type()) {
+ case TimingFunction::StepsFunction:
+ // FIXME: add support for steps timing function.
+ return nullptr;
+ case TimingFunction::LinearFunction:
+ // Don't set the timing function. Keyframes are interpolated linearly if there is no timing function.
+ break;
+ case TimingFunction::CubicBezierFunction:
+ const CubicBezierTimingFunction* originalTimingFunction = static_cast<const CubicBezierTimingFunction*>(originalValue->timingFunction());
+ timingFunction = CCCubicBezierTimingFunction::create(originalTimingFunction->x1(), originalTimingFunction->y1(), originalTimingFunction->x2(), originalTimingFunction->y2());
+ break;
+ } // switch
+ } else
+ timingFunction = CCEaseTimingFunction::create();
double duration = (animation && animation->isDurationSet()) ? animation->duration() : 1;
- appendKeyframe(keyframes, originalValue->keyTime() * duration, originalValue);
+ appendKeyframe<Value, Keyframe, Curve>(*curve, originalValue->keyTime() * duration, originalValue, timingFunction.release());
}
- OwnPtr<Curve> curve = Curve::create(keyframes);
-
OwnPtr<CCActiveAnimation> anim = CCActiveAnimation::create(curve.release(), animationId, groupId, targetProperty);
ASSERT(anim.get());
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp
index 2096ce398..f09dcfae0 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp
@@ -49,15 +49,15 @@ CCLayerAnimationControllerImpl::~CCLayerAnimationControllerImpl()
{
}
-void CCLayerAnimationControllerImpl::animate(double frameBeginTimeSecs, CCAnimationEventsVector& events)
+void CCLayerAnimationControllerImpl::animate(double monotonicTime, CCAnimationEventsVector& events)
{
- startAnimationsWaitingForNextTick(frameBeginTimeSecs, events);
- startAnimationsWaitingForStartTime(frameBeginTimeSecs, events);
- startAnimationsWaitingForTargetAvailability(frameBeginTimeSecs, events);
- resolveConflicts(frameBeginTimeSecs);
- tickAnimations(frameBeginTimeSecs);
- purgeFinishedAnimations();
- startAnimationsWaitingForTargetAvailability(frameBeginTimeSecs, events);
+ startAnimationsWaitingForNextTick(monotonicTime, events);
+ startAnimationsWaitingForStartTime(monotonicTime, events);
+ startAnimationsWaitingForTargetAvailability(monotonicTime, events);
+ resolveConflicts(monotonicTime);
+ tickAnimations(monotonicTime);
+ purgeFinishedAnimations(events);
+ startAnimationsWaitingForTargetAvailability(monotonicTime, events);
}
void CCLayerAnimationControllerImpl::add(PassOwnPtr<CCActiveAnimation> anim)
@@ -83,28 +83,28 @@ bool CCLayerAnimationControllerImpl::hasActiveAnimation() const
return false;
}
-void CCLayerAnimationControllerImpl::startAnimationsWaitingForNextTick(double now, CCAnimationEventsVector& events)
+void CCLayerAnimationControllerImpl::startAnimationsWaitingForNextTick(double monotonicTime, CCAnimationEventsVector& events)
{
for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
if (m_activeAnimations[i]->runState() == CCActiveAnimation::WaitingForNextTick) {
- m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, now);
- m_activeAnimations[i]->setStartTime(now);
- events.append(CCAnimationStartedEvent(m_client->id(), now));
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, monotonicTime);
+ m_activeAnimations[i]->setStartTime(monotonicTime);
+ events.append(CCAnimationStartedEvent::create(m_client->id()));
}
}
}
-void CCLayerAnimationControllerImpl::startAnimationsWaitingForStartTime(double now, CCAnimationEventsVector& events)
+void CCLayerAnimationControllerImpl::startAnimationsWaitingForStartTime(double monotonicTime, CCAnimationEventsVector& events)
{
for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
- if (m_activeAnimations[i]->runState() == CCActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= now) {
- m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, now);
- events.append(CCAnimationStartedEvent(m_client->id(), now));
+ if (m_activeAnimations[i]->runState() == CCActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) {
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, monotonicTime);
+ events.append(CCAnimationStartedEvent::create(m_client->id()));
}
}
}
-void CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability(double now, CCAnimationEventsVector& events)
+void CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability(double monotonicTime, CCAnimationEventsVector& events)
{
// First collect running properties.
TargetProperties blockedProperties;
@@ -134,13 +134,13 @@ void CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability
// If the intersection is null, then we are free to start the animations in the group.
if (nullIntersection) {
- m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, now);
- m_activeAnimations[i]->setStartTime(now);
- events.append(CCAnimationStartedEvent(m_client->id(), now));
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, monotonicTime);
+ m_activeAnimations[i]->setStartTime(monotonicTime);
+ events.append(CCAnimationStartedEvent::create(m_client->id()));
for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
- m_activeAnimations[j]->setRunState(CCActiveAnimation::Running, now);
- m_activeAnimations[j]->setStartTime(now);
+ m_activeAnimations[j]->setRunState(CCActiveAnimation::Running, monotonicTime);
+ m_activeAnimations[j]->setStartTime(monotonicTime);
}
}
}
@@ -148,7 +148,7 @@ void CCLayerAnimationControllerImpl::startAnimationsWaitingForTargetAvailability
}
}
-void CCLayerAnimationControllerImpl::resolveConflicts(double now)
+void CCLayerAnimationControllerImpl::resolveConflicts(double monotonicTime)
{
// Find any animations that are animating the same property and resolve the
// confict. We could eventually blend, but for now we'll just abort the
@@ -160,16 +160,16 @@ void CCLayerAnimationControllerImpl::resolveConflicts(double now)
for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
if (m_activeAnimations[j]->runState() == CCActiveAnimation::Running && m_activeAnimations[i]->targetProperty() == m_activeAnimations[j]->targetProperty()) {
if (m_activeAnimations[i]->startTime() > m_activeAnimations[j]->startTime())
- m_activeAnimations[j]->setRunState(CCActiveAnimation::Aborted, now);
+ m_activeAnimations[j]->setRunState(CCActiveAnimation::Aborted, monotonicTime);
else
- m_activeAnimations[i]->setRunState(CCActiveAnimation::Aborted, now);
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Aborted, monotonicTime);
}
}
}
}
}
-void CCLayerAnimationControllerImpl::purgeFinishedAnimations()
+void CCLayerAnimationControllerImpl::purgeFinishedAnimations(CCAnimationEventsVector& events)
{
// Each iteration, m_activeAnimations.size() decreases or i increments,
// guaranteeing progress towards loop termination.
@@ -186,6 +186,7 @@ void CCLayerAnimationControllerImpl::purgeFinishedAnimations()
}
}
if (allAnimsWithSameIdAreFinished) {
+ events.append(CCAnimationFinishedEvent::create(m_client->id(), m_activeAnimations[i]->id()));
m_finishedAnimations.append(m_activeAnimations[i]->signature());
m_activeAnimations.remove(i);
} else
@@ -193,18 +194,19 @@ void CCLayerAnimationControllerImpl::purgeFinishedAnimations()
}
}
-void CCLayerAnimationControllerImpl::tickAnimations(double now)
+void CCLayerAnimationControllerImpl::tickAnimations(double monotonicTime)
{
for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
if (m_activeAnimations[i]->runState() == CCActiveAnimation::Running) {
- double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(now);
+ double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
+
switch (m_activeAnimations[i]->targetProperty()) {
case CCActiveAnimation::Transform: {
const CCTransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
const TransformationMatrix matrix = transformAnimationCurve->getValue(trimmed, m_client->bounds());
- if (m_activeAnimations[i]->isFinishedAt(now))
- m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, now);
+ if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, monotonicTime);
m_client->setTransform(matrix);
break;
@@ -213,8 +215,8 @@ void CCLayerAnimationControllerImpl::tickAnimations(double now)
case CCActiveAnimation::Opacity: {
const CCFloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
const float opacity = floatAnimationCurve->getValue(trimmed);
- if (m_activeAnimations[i]->isFinishedAt(now))
- m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, now);
+ if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, monotonicTime);
m_client->setOpacity(opacity);
break;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h
index 296066de0..6ac00e7ae 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h
@@ -61,7 +61,7 @@ public:
virtual ~CCLayerAnimationControllerImpl();
- void animate(double frameBeginTimeSecs, CCAnimationEventsVector&);
+ void animate(double monotonicTime, CCAnimationEventsVector&);
void add(PassOwnPtr<CCActiveAnimation>);
@@ -78,13 +78,13 @@ private:
// The animator is owned by the layer.
explicit CCLayerAnimationControllerImpl(CCLayerAnimationControllerImplClient*);
- void startAnimationsWaitingForNextTick(double now, CCAnimationEventsVector&);
- void startAnimationsWaitingForStartTime(double now, CCAnimationEventsVector&);
- void startAnimationsWaitingForTargetAvailability(double now, CCAnimationEventsVector&);
- void resolveConflicts(double now);
- void purgeFinishedAnimations();
+ void startAnimationsWaitingForNextTick(double monotonicTime, CCAnimationEventsVector&);
+ void startAnimationsWaitingForStartTime(double monotonicTime, CCAnimationEventsVector&);
+ void startAnimationsWaitingForTargetAvailability(double monotonicTime, CCAnimationEventsVector&);
+ void resolveConflicts(double monotonicTime);
+ void purgeFinishedAnimations(CCAnimationEventsVector&);
- void tickAnimations(double now);
+ void tickAnimations(double monotonicTime);
CCLayerAnimationControllerImplClient* m_client;
Vector<OwnPtr<CCActiveAnimation> > m_activeAnimations;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationDelegate.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationDelegate.h
new file mode 100644
index 000000000..a764cc37b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationDelegate.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 Google 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. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 CCLayerAnimationDelegate_h
+#define CCLayerAnimationDelegate_h
+
+namespace WebCore {
+
+// This class is used to send notifications when layer animations begin or end.
+class CCLayerAnimationDelegate {
+public:
+ virtual void notifyAnimationStarted(double time) = 0;
+ virtual void notifyAnimationFinished(int animationId) = 0;
+};
+
+} // namespace WebCore
+
+#endif // CCLayerAnimationDelegate_h
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
index 0589dca8a..8f6078097 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
@@ -42,10 +42,13 @@ namespace WebCore {
CCLayerImpl::CCLayerImpl(int id)
: m_parent(0)
+ , m_maskLayerId(-1)
+ , m_replicaLayerId(-1)
, m_layerId(id)
, m_anchorPoint(0.5, 0.5)
, m_anchorPointZ(0)
, m_scrollable(false)
+ , m_shouldScrollOnMainThread(false)
, m_haveWheelEventHandlers(false)
, m_backgroundCoversViewport(false)
, m_doubleSided(true)
@@ -73,7 +76,7 @@ CCLayerImpl::~CCLayerImpl()
ASSERT(CCProxy::isImplThread());
}
-void CCLayerImpl::addChild(PassRefPtr<CCLayerImpl> child)
+void CCLayerImpl::addChild(PassOwnPtr<CCLayerImpl> child)
{
child->setParent(this);
m_children.append(child);
@@ -83,13 +86,16 @@ void CCLayerImpl::removeFromParent()
{
if (!m_parent)
return;
- for (size_t i = 0; i < m_parent->m_children.size(); ++i) {
- if (m_parent->m_children[i].get() == this) {
- m_parent->m_children.remove(i);
- break;
+
+ CCLayerImpl* parent = m_parent;
+ m_parent = 0;
+
+ for (size_t i = 0; i < parent->m_children.size(); ++i) {
+ if (parent->m_children[i].get() == this) {
+ parent->m_children.remove(i);
+ return;
}
}
- m_parent = 0;
}
void CCLayerImpl::removeAllChildren()
@@ -188,12 +194,6 @@ void CCLayerImpl::scrollBy(const IntSize& scroll)
noteLayerPropertyChangedForSubtree();
}
-void CCLayerImpl::cleanupResources()
-{
- if (renderSurface())
- renderSurface()->cleanupResources();
-}
-
const IntRect CCLayerImpl::getDrawRect() const
{
// Form the matrix used by the shader to map the corners of the layer's
@@ -244,7 +244,7 @@ void CCLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
ts << "drawsContent: " << (m_drawsContent ? "yes" : "no") << "\n";
}
-void sortLayers(Vector<RefPtr<CCLayerImpl> >::iterator first, Vector<RefPtr<CCLayerImpl> >::iterator end, CCLayerSorter* layerSorter)
+void sortLayers(Vector<CCLayerImpl*>::iterator first, Vector<CCLayerImpl*>::iterator end, CCLayerSorter* layerSorter)
{
TRACE_EVENT("LayerRendererChromium::sortLayers", 0, 0);
layerSorter->sort(first, end);
@@ -260,7 +260,7 @@ String CCLayerImpl::layerTreeAsText() const
void CCLayerImpl::dumpLayer(TextStream& ts, int indent) const
{
writeIndent(ts, indent);
- ts << layerTypeAsString() << "(" << m_name << ")\n";
+ ts << layerTypeAsString() << "(" << m_debugName << ")\n";
dumpLayerProperties(ts, indent+2);
if (m_replicaLayer) {
writeIndent(ts, indent+2);
@@ -319,21 +319,27 @@ void CCLayerImpl::setBounds(const IntSize& bounds)
m_layerPropertyChanged = true;
}
-void CCLayerImpl::setMaskLayer(PassRefPtr<CCLayerImpl> maskLayer)
+void CCLayerImpl::setMaskLayer(PassOwnPtr<CCLayerImpl> maskLayer)
{
- if (m_maskLayer == maskLayer)
+ m_maskLayer = maskLayer;
+
+ int newLayerId = m_maskLayer ? m_maskLayer->id() : -1;
+ if (newLayerId == m_maskLayerId)
return;
- m_maskLayer = maskLayer;
+ m_maskLayerId = newLayerId;
noteLayerPropertyChangedForSubtree();
}
-void CCLayerImpl::setReplicaLayer(PassRefPtr<CCLayerImpl> replicaLayer)
+void CCLayerImpl::setReplicaLayer(PassOwnPtr<CCLayerImpl> replicaLayer)
{
- if (m_replicaLayer == replicaLayer)
+ m_replicaLayer = replicaLayer;
+
+ int newLayerId = m_replicaLayer ? m_replicaLayer->id() : -1;
+ if (newLayerId == m_replicaLayerId)
return;
- m_replicaLayer = replicaLayer;
+ m_replicaLayerId = newLayerId;
noteLayerPropertyChangedForSubtree();
}
@@ -523,6 +529,10 @@ void CCLayerImpl::setDoubleSided(bool doubleSided)
noteLayerPropertyChangedForSubtree();
}
+void CCLayerImpl::didLoseContext()
+{
+}
+
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
index c7a4f0856..f1c7b4ee5 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
@@ -30,6 +30,7 @@
#include "FilterOperations.h"
#include "FloatRect.h"
#include "IntRect.h"
+#include "Region.h"
#include "TextStream.h"
#include "TransformationMatrix.h"
#include "cc/CCLayerAnimationControllerImpl.h"
@@ -46,11 +47,11 @@ class CCLayerSorter;
class LayerChromium;
class LayerRendererChromium;
-class CCLayerImpl : public RefCounted<CCLayerImpl>, public CCLayerAnimationControllerImplClient {
+class CCLayerImpl : public CCLayerAnimationControllerImplClient {
public:
- static PassRefPtr<CCLayerImpl> create(int id)
+ static PassOwnPtr<CCLayerImpl> create(int id)
{
- return adoptRef(new CCLayerImpl(id));
+ return adoptPtr(new CCLayerImpl(id));
}
// CCLayerAnimationControllerImplClient implementation.
@@ -65,15 +66,15 @@ public:
// Tree structure.
CCLayerImpl* parent() const { return m_parent; }
- const Vector<RefPtr<CCLayerImpl> >& children() const { return m_children; }
- void addChild(PassRefPtr<CCLayerImpl>);
+ const Vector<OwnPtr<CCLayerImpl> >& children() const { return m_children; }
+ void addChild(PassOwnPtr<CCLayerImpl>);
void removeFromParent();
void removeAllChildren();
- void setMaskLayer(PassRefPtr<CCLayerImpl>);
+ void setMaskLayer(PassOwnPtr<CCLayerImpl>);
CCLayerImpl* maskLayer() const { return m_maskLayer.get(); }
- void setReplicaLayer(PassRefPtr<CCLayerImpl>);
+ void setReplicaLayer(PassOwnPtr<CCLayerImpl>);
CCLayerImpl* replicaLayer() const { return m_replicaLayer.get(); }
#ifndef NDEBUG
@@ -96,8 +97,6 @@ public:
// Returns true if any of the layer's descendants has content to draw.
bool descendantDrawsContent();
- void cleanupResources();
-
void setAnchorPoint(const FloatPoint&);
const FloatPoint& anchorPoint() const { return m_anchorPoint; }
@@ -134,9 +133,6 @@ public:
void setSublayerTransform(const TransformationMatrix&);
const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; }
- void setName(const String& name) { m_name = name; }
- const String& name() const { return m_name; }
-
// Debug layer border - visual effect only, do not change geometry/clipping/etc.
void setDebugBorderColor(Color);
Color debugBorderColor() const { return m_debugBorderColor; }
@@ -144,6 +140,10 @@ public:
float debugBorderWidth() const { return m_debugBorderWidth; }
bool hasDebugBorders() const;
+ // Debug layer name.
+ void setDebugName(const String& debugName) { m_debugName = debugName; }
+ String debugName() const { return m_debugName; }
+
CCRenderSurface* renderSurface() const { return m_renderSurface.get(); }
void createRenderSurface();
void clearRenderSurface() { m_renderSurface.clear(); }
@@ -181,9 +181,15 @@ public:
bool scrollable() const { return m_scrollable; }
void setScrollable(bool scrollable) { m_scrollable = scrollable; }
+ bool shouldScrollOnMainThread() const { return m_shouldScrollOnMainThread; }
+ void setShouldScrollOnMainThread(bool shouldScrollOnMainThread) { m_shouldScrollOnMainThread = shouldScrollOnMainThread; }
+
bool haveWheelEventHandlers() const { return m_haveWheelEventHandlers; }
void setHaveWheelEventHandlers(bool haveWheelEventHandlers) { m_haveWheelEventHandlers = haveWheelEventHandlers; }
+ const Region& nonFastScrollableRegion() const { return m_nonFastScrollableRegion; }
+ void setNonFastScrollableRegion(const Region& region) { m_nonFastScrollableRegion = region; }
+
const IntRect& visibleLayerRect() const { return m_visibleLayerRect; }
void setVisibleLayerRect(const IntRect& visibleLayerRect) { m_visibleLayerRect = visibleLayerRect; }
@@ -209,6 +215,13 @@ public:
CCLayerAnimationControllerImpl* layerAnimationController() { return m_layerAnimationController.get(); }
+ virtual Region opaqueContentsRegion() const { return Region(); };
+
+ // Indicates that the context previously used to render this layer
+ // was lost and that a new one has been created. Won't be called
+ // until the new context has been created successfully.
+ virtual void didLoseContext();
+
protected:
explicit CCLayerImpl(int);
@@ -236,9 +249,12 @@ private:
// Properties internal to CCLayerImpl
CCLayerImpl* m_parent;
- Vector<RefPtr<CCLayerImpl> > m_children;
- RefPtr<CCLayerImpl> m_maskLayer;
- RefPtr<CCLayerImpl> m_replicaLayer;
+ Vector<OwnPtr<CCLayerImpl> > m_children;
+ // m_maskLayer can be temporarily stolen during tree sync, we need this ID to confirm newly assigned layer is still the previous one
+ int m_maskLayerId;
+ OwnPtr<CCLayerImpl> m_maskLayer;
+ int m_replicaLayerId; // ditto
+ OwnPtr<CCLayerImpl> m_replicaLayer;
int m_layerId;
// Properties synchronized from the associated LayerChromium.
@@ -248,7 +264,9 @@ private:
IntSize m_contentBounds;
IntPoint m_scrollPosition;
bool m_scrollable;
+ bool m_shouldScrollOnMainThread;
bool m_haveWheelEventHandlers;
+ Region m_nonFastScrollableRegion;
Color m_backgroundColor;
bool m_backgroundCoversViewport;
@@ -282,8 +300,6 @@ private:
int m_debugID;
#endif
- String m_name;
-
// Render surface this layer draws into. This is a surface that can belong
// either to this layer (if m_targetRenderSurface == m_renderSurface) or
// to an ancestor of this layer. The target render surface determines the
@@ -299,6 +315,9 @@ private:
Color m_debugBorderColor;
float m_debugBorderWidth;
+ // Debug layer name.
+ String m_debugName;
+
FilterOperations m_filters;
TransformationMatrix m_drawTransform;
@@ -324,7 +343,7 @@ private:
OwnPtr<CCLayerAnimationControllerImpl> m_layerAnimationController;
};
-void sortLayers(Vector<RefPtr<CCLayerImpl> >::iterator first, Vector<RefPtr<CCLayerImpl> >::iterator end, CCLayerSorter*);
+void sortLayers(Vector<CCLayerImpl*>::iterator first, Vector<CCLayerImpl*>::iterator end, CCLayerSorter*);
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp
index 97d6d185a..2d6d2f7f7 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp
@@ -35,8 +35,8 @@
namespace WebCore {
-template <typename LayerType, typename RenderSurfaceType, typename ActionType>
-void CCLayerIteratorActions::BackToFront::begin(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>& it)
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+void CCLayerIteratorActions::BackToFront::begin(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>& it)
{
it.m_targetRenderSurfaceLayerIndex = 0;
it.m_currentLayerIndex = CCLayerIteratorValue::LayerIndexRepresentingTargetRenderSurface;
@@ -44,15 +44,15 @@ void CCLayerIteratorActions::BackToFront::begin(CCLayerIterator<LayerType, Rende
m_highestTargetRenderSurfaceLayer = 0;
}
-template <typename LayerType, typename RenderSurfaceType, typename ActionType>
-void CCLayerIteratorActions::BackToFront::end(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>& it)
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+void CCLayerIteratorActions::BackToFront::end(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>& it)
{
it.m_targetRenderSurfaceLayerIndex = CCLayerIteratorValue::InvalidTargetRenderSurfaceLayerIndex;
it.m_currentLayerIndex = 0;
}
-template <typename LayerType, typename RenderSurfaceType, typename ActionType>
-void CCLayerIteratorActions::BackToFront::next(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>& it)
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+void CCLayerIteratorActions::BackToFront::next(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>& it)
{
// If the current layer has a RS, move to its layer list. Otherwise, visit the next layer in the current RS layer list.
if (it.currentLayerRepresentsContributingRenderSurface()) {
@@ -85,23 +85,23 @@ void CCLayerIteratorActions::BackToFront::next(CCLayerIterator<LayerType, Render
}
}
-template <typename LayerType, typename RenderSurfaceType, typename ActionType>
-void CCLayerIteratorActions::FrontToBack::begin(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>& it)
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+void CCLayerIteratorActions::FrontToBack::begin(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>& it)
{
it.m_targetRenderSurfaceLayerIndex = 0;
it.m_currentLayerIndex = it.targetRenderSurfaceChildren().size() - 1;
goToHighestInSubtree(it);
}
-template <typename LayerType, typename RenderSurfaceType, typename ActionType>
-void CCLayerIteratorActions::FrontToBack::end(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>& it)
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+void CCLayerIteratorActions::FrontToBack::end(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>& it)
{
it.m_targetRenderSurfaceLayerIndex = CCLayerIteratorValue::InvalidTargetRenderSurfaceLayerIndex;
it.m_currentLayerIndex = 0;
}
-template <typename LayerType, typename RenderSurfaceType, typename ActionType>
-void CCLayerIteratorActions::FrontToBack::next(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>& it)
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+void CCLayerIteratorActions::FrontToBack::next(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>& it)
{
// Moves to the previous layer in the current RS layer list. Then we check if the
// new current layer has its own RS, in which case there are things in that RS layer list that are higher, so
@@ -128,8 +128,8 @@ void CCLayerIteratorActions::FrontToBack::next(CCLayerIterator<LayerType, Render
}
}
-template <typename LayerType, typename RenderSurfaceType, typename ActionType>
-void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>& it)
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>& it)
{
if (it.currentLayerRepresentsTargetRenderSurface())
return;
@@ -147,23 +147,23 @@ void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIterator<L
}
// Declare each of the above functions for LayerChromium and CCLayerImpl classes so that they are linked.
-template void CCLayerIteratorActions::BackToFront::begin(CCLayerIterator<LayerChromium, RenderSurfaceChromium, BackToFront> &);
-template void CCLayerIteratorActions::BackToFront::end(CCLayerIterator<LayerChromium, RenderSurfaceChromium, BackToFront>&);
-template void CCLayerIteratorActions::BackToFront::next(CCLayerIterator<LayerChromium, RenderSurfaceChromium, BackToFront>&);
-
-template void CCLayerIteratorActions::BackToFront::begin(CCLayerIterator<CCLayerImpl, CCRenderSurface, BackToFront>&);
-template void CCLayerIteratorActions::BackToFront::end(CCLayerIterator<CCLayerImpl, CCRenderSurface, BackToFront>&);
-template void CCLayerIteratorActions::BackToFront::next(CCLayerIterator<CCLayerImpl, CCRenderSurface, BackToFront>&);
-
-template void CCLayerIteratorActions::FrontToBack::next(CCLayerIterator<LayerChromium, RenderSurfaceChromium, FrontToBack>&);
-template void CCLayerIteratorActions::FrontToBack::end(CCLayerIterator<LayerChromium, RenderSurfaceChromium, FrontToBack>&);
-template void CCLayerIteratorActions::FrontToBack::begin(CCLayerIterator<LayerChromium, RenderSurfaceChromium, FrontToBack>&);
-template void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIterator<LayerChromium, RenderSurfaceChromium, FrontToBack>&);
-
-template void CCLayerIteratorActions::FrontToBack::next(CCLayerIterator<CCLayerImpl, CCRenderSurface, FrontToBack>&);
-template void CCLayerIteratorActions::FrontToBack::end(CCLayerIterator<CCLayerImpl, CCRenderSurface, FrontToBack>&);
-template void CCLayerIteratorActions::FrontToBack::begin(CCLayerIterator<CCLayerImpl, CCRenderSurface, FrontToBack>&);
-template void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIterator<CCLayerImpl, CCRenderSurface, FrontToBack>&);
+template void CCLayerIteratorActions::BackToFront::begin(CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, BackToFront> &);
+template void CCLayerIteratorActions::BackToFront::end(CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, BackToFront>&);
+template void CCLayerIteratorActions::BackToFront::next(CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, BackToFront>&);
+
+template void CCLayerIteratorActions::BackToFront::begin(CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, BackToFront>&);
+template void CCLayerIteratorActions::BackToFront::end(CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, BackToFront>&);
+template void CCLayerIteratorActions::BackToFront::next(CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, BackToFront>&);
+
+template void CCLayerIteratorActions::FrontToBack::next(CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, FrontToBack>&);
+template void CCLayerIteratorActions::FrontToBack::end(CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, FrontToBack>&);
+template void CCLayerIteratorActions::FrontToBack::begin(CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, FrontToBack>&);
+template void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, FrontToBack>&);
+
+template void CCLayerIteratorActions::FrontToBack::next(CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, FrontToBack>&);
+template void CCLayerIteratorActions::FrontToBack::end(CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, FrontToBack>&);
+template void CCLayerIteratorActions::FrontToBack::begin(CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, FrontToBack>&);
+template void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, FrontToBack>&);
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h
index be985e153..d89bd6912 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h
@@ -92,15 +92,15 @@ struct CCLayerIteratorValue {
};
// An iterator class for walking over layers in the RenderSurface-Layer tree.
-template <typename LayerType, typename RenderSurfaceType, typename IteratorActionType>
+template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename IteratorActionType>
class CCLayerIterator {
- typedef CCLayerIterator<LayerType, RenderSurfaceType, IteratorActionType> CCLayerIteratorType;
+ typedef CCLayerIterator<LayerType, LayerList, RenderSurfaceType, IteratorActionType> CCLayerIteratorType;
public:
CCLayerIterator() : m_renderSurfaceLayerList(0) { }
- static CCLayerIteratorType begin(const Vector<RefPtr<LayerType> >* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, true); }
- static CCLayerIteratorType end(const Vector<RefPtr<LayerType> >* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, false); }
+ static CCLayerIteratorType begin(const LayerList* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, true); }
+ static CCLayerIteratorType end(const LayerList* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, false); }
CCLayerIteratorType& operator++() { m_actions.next(*this); return *this; }
bool operator==(const CCLayerIterator& other) const
@@ -117,10 +117,10 @@ public:
bool representsContributingRenderSurface() const { return !representsTargetRenderSurface() && currentLayerRepresentsContributingRenderSurface(); }
bool representsItself() const { return !representsTargetRenderSurface() && !representsContributingRenderSurface(); }
- LayerType* targetRenderSurfaceLayer() const { return (*m_renderSurfaceLayerList)[m_targetRenderSurfaceLayerIndex].get(); }
+ LayerType* targetRenderSurfaceLayer() const { return getRawPtr((*m_renderSurfaceLayerList)[m_targetRenderSurfaceLayerIndex]); }
private:
- CCLayerIterator(const Vector<RefPtr<LayerType> >* renderSurfaceLayerList, bool start)
+ CCLayerIterator(const LayerList* renderSurfaceLayerList, bool start)
: m_renderSurfaceLayerList(renderSurfaceLayerList)
{
if (start && !renderSurfaceLayerList->isEmpty())
@@ -129,16 +129,19 @@ private:
m_actions.end(*this);
}
- inline LayerType* currentLayer() const { return currentLayerRepresentsTargetRenderSurface() ? targetRenderSurfaceLayer() : targetRenderSurfaceChildren()[m_currentLayerIndex].get(); }
+ inline static LayerChromium* getRawPtr(const RefPtr<LayerChromium>& ptr) { return ptr.get(); }
+ inline static CCLayerImpl* getRawPtr(CCLayerImpl* ptr) { return ptr; }
+
+ inline LayerType* currentLayer() const { return currentLayerRepresentsTargetRenderSurface() ? targetRenderSurfaceLayer() : getRawPtr(targetRenderSurfaceChildren()[m_currentLayerIndex]); }
inline bool currentLayerRepresentsContributingRenderSurface() const { return CCLayerTreeHostCommon::renderSurfaceContributesToTarget<LayerType>(currentLayer(), targetRenderSurfaceLayer()->id()); }
inline bool currentLayerRepresentsTargetRenderSurface() const { return m_currentLayerIndex == CCLayerIteratorValue::LayerIndexRepresentingTargetRenderSurface; }
inline RenderSurfaceType* targetRenderSurface() const { return targetRenderSurfaceLayer()->renderSurface(); }
- inline const Vector<RefPtr<LayerType> >& targetRenderSurfaceChildren() const { return targetRenderSurface()->layerList(); }
+ inline const LayerList& targetRenderSurfaceChildren() const { return targetRenderSurface()->layerList(); }
IteratorActionType m_actions;
- const Vector<RefPtr<LayerType> >* m_renderSurfaceLayerList;
+ const LayerList* m_renderSurfaceLayerList;
// The iterator's current position.
@@ -161,14 +164,14 @@ struct CCLayerIteratorActions {
// Walks layers sorted by z-order from back to front.
class BackToFront {
public:
- template <typename LayerType, typename RenderSurfaceType, typename ActionType>
- void begin(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>&);
+ template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+ void begin(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
- template <typename LayerType, typename RenderSurfaceType, typename ActionType>
- void end(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>&);
+ template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+ void end(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
- template <typename LayerType, typename RenderSurfaceType, typename ActionType>
- void next(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>&);
+ template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+ void next(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
private:
int m_highestTargetRenderSurfaceLayer;
@@ -177,18 +180,18 @@ struct CCLayerIteratorActions {
// Walks layers sorted by z-order from front to back
class FrontToBack {
public:
- template <typename LayerType, typename RenderSurfaceType, typename ActionType>
- void begin(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>&);
+ template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+ void begin(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
- template <typename LayerType, typename RenderSurfaceType, typename ActionType>
- void end(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>&);
+ template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+ void end(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
- template <typename LayerType, typename RenderSurfaceType, typename ActionType>
- void next(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>&);
+ template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+ void next(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
private:
- template <typename LayerType, typename RenderSurfaceType, typename ActionType>
- void goToHighestInSubtree(CCLayerIterator<LayerType, RenderSurfaceType, ActionType>&);
+ template <typename LayerType, typename LayerList, typename RenderSurfaceType, typename ActionType>
+ void goToHighestInSubtree(CCLayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>&);
};
};
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp
index 752855447..c434a1d95 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp
@@ -295,7 +295,7 @@ void CCLayerSorter::createGraphNodes(LayerList::iterator first, LayerList::itera
float minZ = FLT_MAX;
float maxZ = -FLT_MAX;
for (LayerList::const_iterator it = first; it < last; it++) {
- m_nodes.append(GraphNode(it->get()));
+ m_nodes.append(GraphNode(*it));
GraphNode& node = m_nodes.at(m_nodes.size() - 1);
CCRenderSurface* renderSurface = node.layer->renderSurface();
if (!node.layer->drawsContent() && !renderSurface)
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h
index 2c30d5dae..8ab9b7581 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h
@@ -39,7 +39,7 @@ class CCLayerSorter {
public:
CCLayerSorter();
- typedef Vector<RefPtr<CCLayerImpl> > LayerList;
+ typedef Vector<CCLayerImpl*> LayerList;
void sort(LayerList::iterator first, LayerList::iterator last);
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.cpp
index cfefbd2b8..19d0251dc 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.cpp
@@ -112,6 +112,24 @@ IntRect CCLayerTilingData::tileRect(const Tile* tile) const
return tileRect;
}
+Region CCLayerTilingData::opaqueRegionInLayerRect(const IntRect& layerRect) const
+{
+ Region opaqueRegion;
+ int left, top, right, bottom;
+ layerRectToTileIndices(layerRect, left, top, right, bottom);
+ for (int j = top; j <= bottom; ++j) {
+ for (int i = left; i <= right; ++i) {
+ Tile* tile = tileAt(i, j);
+ if (!tile)
+ continue;
+
+ IntRect tileOpaqueRect = intersection(layerRect, tile->opaqueRect());
+ opaqueRegion.unite(tileOpaqueRect);
+ }
+ }
+ return opaqueRegion;
+}
+
void CCLayerTilingData::setBounds(const IntSize& size)
{
m_tilingData.setTotalSize(size.width(), size.height());
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.h
index 869d42e15..9e18695e8 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.h
@@ -30,6 +30,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "IntRect.h"
+#include "Region.h"
#include "TilingData.h"
#include <wtf/HashMap.h>
#include <wtf/HashTraits.h>
@@ -69,9 +70,13 @@ public:
int i() const { return m_i; }
int j() const { return m_j; }
void moveTo(int i, int j) { m_i = i; m_j = j; }
+
+ const IntRect& opaqueRect() const { return m_opaqueRect; }
+ void setOpaqueRect(const IntRect& opaqueRect) { m_opaqueRect = opaqueRect; }
private:
int m_i;
int m_j;
+ IntRect m_opaqueRect;
};
// Default hash key traits for integers disallow 0 and -1 as a key, so
// use a custom hash trait which disallows -1 and -2 instead.
@@ -96,6 +101,8 @@ public:
void layerRectToTileIndices(const IntRect&, int &left, int &top, int &right, int &bottom) const;
IntRect tileRect(const Tile*) const;
+ Region opaqueRegionInLayerRect(const IntRect&) const;
+
void reset();
protected:
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
index 501ee17de..34bce1181 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
@@ -35,6 +35,7 @@
#include "cc/CCLayerIterator.h"
#include "cc/CCLayerTreeHostCommon.h"
#include "cc/CCLayerTreeHostImpl.h"
+#include "cc/CCOcclusionTracker.h"
#include "cc/CCSingleThreadProxy.h"
#include "cc/CCThread.h"
#include "cc/CCThreadProxy.h"
@@ -66,6 +67,9 @@ CCLayerTreeHost::CCLayerTreeHost(CCLayerTreeHostClient* client, const CCSettings
, m_client(client)
, m_frameNumber(0)
, m_layerRendererInitialized(false)
+ , m_contextLost(false)
+ , m_numTimesRecreateShouldFail(0)
+ , m_numFailedRecreateAttempts(0)
, m_settings(settings)
, m_visible(true)
, m_pageScaleFactor(1)
@@ -114,7 +118,7 @@ void CCLayerTreeHost::initializeLayerRenderer()
TRACE_EVENT("CCLayerTreeHost::initializeLayerRenderer", this, 0);
if (!m_proxy->initializeLayerRenderer()) {
// Uh oh, better tell the client that we can't do anything with this context.
- m_client->didRecreateGraphicsContext(false);
+ m_client->didRecreateContext(false);
return;
}
@@ -131,6 +135,40 @@ void CCLayerTreeHost::initializeLayerRenderer()
m_layerRendererInitialized = true;
}
+CCLayerTreeHost::RecreateResult CCLayerTreeHost::recreateContext()
+{
+ TRACE_EVENT0("cc", "CCLayerTreeHost::recreateContext");
+ ASSERT(m_contextLost);
+
+ bool recreated = false;
+ if (!m_numTimesRecreateShouldFail)
+ recreated = m_proxy->recreateContext();
+ else
+ m_numTimesRecreateShouldFail--;
+
+ if (recreated) {
+ m_client->didRecreateContext(true);
+ m_contextLost = false;
+ return RecreateSucceeded;
+ }
+
+ // Tolerate a certain number of recreation failures to work around races
+ // in the context-lost machinery.
+ m_numFailedRecreateAttempts++;
+ if (m_numFailedRecreateAttempts < 5) {
+ // FIXME: The single thread does not self-schedule context
+ // recreation. So force another recreation attempt to happen by requesting
+ // another commit.
+ if (!CCProxy::hasImplThread())
+ setNeedsCommit();
+ return RecreateFailedButTryAgain;
+ }
+
+ // We have tried too many times to recreate the context. Tell the host to fall
+ // back to software rendering.
+ m_client->didRecreateContext(false);
+ return RecreateFailedAndGaveUp;
+}
void CCLayerTreeHost::deleteContentsTexturesOnImplThread(TextureAllocator* allocator)
{
@@ -169,13 +207,11 @@ void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl)
{
ASSERT(CCProxy::isImplThread());
- // Synchronize trees, if one exists at all...
- if (rootLayer()) {
- hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->rootLayer()));
- // We may have added an animation during the tree sync. This will cause hostImpl to visit its controllers.
+ hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->releaseRootLayer()));
+
+ // We may have added an animation during the tree sync. This will cause hostImpl to visit its controllers.
+ if (rootLayer())
hostImpl->setNeedsAnimateLayers();
- } else
- hostImpl->setRootLayer(0);
hostImpl->setSourceFrameNumber(frameNumber());
hostImpl->setViewportSize(viewportSize());
@@ -191,9 +227,9 @@ void CCLayerTreeHost::commitComplete()
m_contentsTextureManager->unprotectAllTextures();
}
-PassRefPtr<GraphicsContext3D> CCLayerTreeHost::createLayerTreeHostContext3D()
+PassRefPtr<GraphicsContext3D> CCLayerTreeHost::createContext()
{
- return m_client->createLayerTreeHostContext3D();
+ return m_client->createContext();
}
PassOwnPtr<CCLayerTreeHostImpl> CCLayerTreeHost::createLayerTreeHostImpl(CCLayerTreeHostImplClient* client)
@@ -201,15 +237,18 @@ PassOwnPtr<CCLayerTreeHostImpl> CCLayerTreeHost::createLayerTreeHostImpl(CCLayer
return CCLayerTreeHostImpl::create(m_settings, client);
}
-void CCLayerTreeHost::didRecreateGraphicsContext(bool success)
+void CCLayerTreeHost::didLoseContext()
{
- m_client->didRecreateGraphicsContext(success);
+ TRACE_EVENT("CCLayerTreeHost::didLoseContext", 0, this);
+ ASSERT(CCProxy::isMainThread());
+ m_contextLost = true;
+ m_numFailedRecreateAttempts = 0;
+ setNeedsCommit();
}
// Temporary hack until WebViewImpl context creation gets simplified
GraphicsContext3D* CCLayerTreeHost::context()
{
- ASSERT(!CCProxy::hasImplThread());
return m_proxy->context();
}
@@ -220,6 +259,10 @@ bool CCLayerTreeHost::compositeAndReadback(void *pixels, const IntRect& rect)
if (!m_layerRendererInitialized)
return false;
}
+ if (m_contextLost) {
+ if (recreateContext() != RecreateSucceeded)
+ return false;
+ }
m_triggerIdlePaints = false;
bool ret = m_proxy->compositeAndReadback(pixels, rect);
m_triggerIdlePaints = true;
@@ -259,10 +302,10 @@ void CCLayerTreeHost::setNeedsRedraw()
m_client->scheduleComposite();
}
-void CCLayerTreeHost::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> events)
+void CCLayerTreeHost::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
{
ASSERT(CCThreadProxy::isMainThread());
- // FIXME: need to walk the tree.
+ setAnimationEventsRecursive(*events, m_rootLayer.get(), wallClockTime);
}
void CCLayerTreeHost::setRootLayer(PassRefPtr<LayerChromium> rootLayer)
@@ -309,10 +352,7 @@ void CCLayerTreeHost::setVisible(bool visible)
m_visible = visible;
- if (!m_layerRendererInitialized)
- return;
-
- if (!visible) {
+ if (!visible && m_layerRendererInitialized) {
m_contentsTextureManager->reduceMemoryToLimit(TextureManager::lowLimitBytes(viewportSize()));
m_contentsTextureManager->unprotectAllTextures();
}
@@ -326,6 +366,9 @@ void CCLayerTreeHost::setVisible(bool visible)
void CCLayerTreeHost::didBecomeInvisibleOnImplThread(CCLayerTreeHostImpl* hostImpl)
{
ASSERT(CCProxy::isImplThread());
+ if (!m_layerRendererInitialized)
+ return;
+
if (m_proxy->layerRendererCapabilities().contextHasCachedFrontBuffer)
contentsTextureManager()->evictAndDeleteAllTextures(hostImpl->contentsTextureAllocator());
else {
@@ -337,16 +380,15 @@ void CCLayerTreeHost::didBecomeInvisibleOnImplThread(CCLayerTreeHostImpl* hostIm
// If the frontbuffer is cached, then clobber the impl tree. Otherwise,
// push over the tree changes.
if (m_proxy->layerRendererCapabilities().contextHasCachedFrontBuffer) {
- hostImpl->setRootLayer(0);
+ hostImpl->setRootLayer(nullptr);
return;
}
- if (rootLayer()) {
- hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->rootLayer()));
- // We may have added an animation during the tree sync. This will cause hostImpl to visit its controllers.
+ hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->releaseRootLayer()));
+
+ // We may have added an animation during the tree sync. This will cause hostImpl to visit its controllers.
+ if (rootLayer())
hostImpl->setNeedsAnimateLayers();
- } else
- hostImpl->setRootLayer(0);
}
void CCLayerTreeHost::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec)
@@ -354,9 +396,11 @@ void CCLayerTreeHost::startPageScaleAnimation(const IntSize& targetPosition, boo
m_proxy->startPageScaleAnimation(targetPosition, useAnchor, scale, durationSec);
}
-void CCLayerTreeHost::loseCompositorContext(int numTimes)
+void CCLayerTreeHost::loseContext(int numTimes)
{
- m_proxy->loseCompositorContext(numTimes);
+ TRACE_EVENT1("cc", "CCLayerTreeHost::loseCompositorContext", "numTimes", numTimes);
+ m_numTimesRecreateShouldFail = numTimes - 1;
+ m_proxy->loseContext();
}
TextureManager* CCLayerTreeHost::contentsTextureManager() const
@@ -378,6 +422,10 @@ bool CCLayerTreeHost::updateLayers()
if (!m_layerRendererInitialized)
return false;
}
+ if (m_contextLost) {
+ if (recreateContext() != RecreateSucceeded)
+ return false;
+ }
if (!rootLayer())
return true;
@@ -440,7 +488,7 @@ void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer)
void CCLayerTreeHost::reserveTextures()
{
// Use BackToFront since it's cheap and this isn't order-dependent.
- typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
+ typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
CCLayerIteratorType end = CCLayerIteratorType::end(&m_updateList);
for (CCLayerIteratorType it = CCLayerIteratorType::begin(&m_updateList); it != end; ++it) {
@@ -458,7 +506,7 @@ void CCLayerTreeHost::paintContentsIfDirty(LayerChromium* layer, PaintType paint
if (PaintVisible == paintType)
layer->paintContentsIfDirty(occludedScreenSpace);
else
- layer->idlePaintContentsIfDirty();
+ layer->idlePaintContentsIfDirty(occludedScreenSpace);
}
void CCLayerTreeHost::paintMaskAndReplicaForRenderSurface(LayerChromium* renderSurfaceLayer, PaintType paintType)
@@ -486,90 +534,36 @@ void CCLayerTreeHost::paintMaskAndReplicaForRenderSurface(LayerChromium* renderS
}
}
-struct RenderSurfaceRegion {
- RenderSurfaceChromium* surface;
- Region occludedInScreen;
-};
-
-// Add the surface to the top of the stack and copy the occlusion from the old top of the stack to the new.
-static void enterTargetRenderSurface(Vector<RenderSurfaceRegion>& stack, RenderSurfaceChromium* newTarget)
-{
- if (stack.isEmpty()) {
- stack.append(RenderSurfaceRegion());
- stack.last().surface = newTarget;
- } else if (stack.last().surface != newTarget) {
- // If we are entering a subtree that is going to move pixels around, then the occlusion we've computed
- // so far won't apply to the pixels we're drawing here in the same way. We discard the occlusion thus
- // far to be safe, and ensure we don't cull any pixels that are moved such that they become visible.
- const RenderSurfaceChromium* oldAncestorThatMovesPixels = stack.last().surface->nearestAncestorThatMovesPixels();
- const RenderSurfaceChromium* newAncestorThatMovesPixels = newTarget->nearestAncestorThatMovesPixels();
- bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAncestorThatMovesPixels != oldAncestorThatMovesPixels;
-
- stack.append(RenderSurfaceRegion());
- stack.last().surface = newTarget;
- int lastIndex = stack.size() - 1;
- if (!enteringSubtreeThatMovesPixels)
- stack[lastIndex].occludedInScreen = stack[lastIndex - 1].occludedInScreen;
- }
-}
-
-// Pop the top of the stack off, push on the new surface, and merge the old top's occlusion into the new top surface.
-static void leaveTargetRenderSurface(Vector<RenderSurfaceRegion>& stack, RenderSurfaceChromium* newTarget)
-{
- int lastIndex = stack.size() - 1;
- bool surfaceWillBeAtTopAfterPop = stack.size() > 1 && stack[lastIndex - 1].surface == newTarget;
-
- if (surfaceWillBeAtTopAfterPop) {
- // Merge the top of the stack down.
- stack[lastIndex - 1].occludedInScreen.unite(stack[lastIndex].occludedInScreen);
- stack.removeLast();
- } else {
- // Replace the top of the stack with the new pushed surface. Copy the occluded region to the top.
- stack.last().surface = newTarget;
- }
-}
-
void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList, PaintType paintType)
{
// Use FrontToBack to allow for testing occlusion and performing culling during the tree walk.
- typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
+ typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
- // The stack holds occluded regions for subtrees in the RenderSurface-Layer tree, so that when we leave a subtree we may
- // apply a mask to it, but not to the parts outside the subtree.
- // - The first time we see a new subtree under a target, we add that target to the top of the stack. This can happen as a layer representing itself, or as a target surface.
- // - When we visit a target surface, we apply its mask to its subtree, which is at the top of the stack.
- // - When we visit a layer representing itself, we add its occlusion to the current subtree, which is at the top of the stack.
- // - When we visit a layer representing a contributing surface, the current target will never be the top of the stack since we just came from the contributing surface.
- // We merge the occlusion at the top of the stack with the new current subtree. This new target is pushed onto the stack if not already there.
- Vector<RenderSurfaceRegion> targetSurfaceStack;
+ CCOcclusionTracker occlusionTracker(IntRect(IntPoint(), viewportSize()));
+ occlusionTracker.setUsePaintTracking(false); // FIXME: Remove this to turn on paint tracking for paint culling
CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
if (it.representsTargetRenderSurface()) {
ASSERT(it->renderSurface()->drawOpacity());
- enterTargetRenderSurface(targetSurfaceStack, it->renderSurface());
+ occlusionTracker.finishedTargetRenderSurface(*it, it->renderSurface());
paintMaskAndReplicaForRenderSurface(*it, paintType);
- // FIXME: add the replica layer to the current occlusion
-
- if (it->maskLayer() || it->renderSurface()->drawOpacity() < 1 || it->renderSurface()->filters().hasFilterThatAffectsOpacity())
- targetSurfaceStack.last().occludedInScreen = Region();
} else if (it.representsItself()) {
ASSERT(!it->bounds().isEmpty());
- enterTargetRenderSurface(targetSurfaceStack, it->targetRenderSurface());
- paintContentsIfDirty(*it, paintType, targetSurfaceStack.last().occludedInScreen);
- it->addSelfToOccludedScreenSpace(targetSurfaceStack.last().occludedInScreen);
- } else {
- leaveTargetRenderSurface(targetSurfaceStack, it.targetRenderSurfaceLayer()->renderSurface());
- }
+ occlusionTracker.enterTargetRenderSurface(it->targetRenderSurface());
+ paintContentsIfDirty(*it, paintType, occlusionTracker.currentOcclusionInScreenSpace());
+ occlusionTracker.markOccludedBehindLayer(*it);
+ } else
+ occlusionTracker.leaveToTargetRenderSurface(it.targetRenderSurfaceLayer()->renderSurface());
}
}
void CCLayerTreeHost::updateCompositorResources(GraphicsContext3D* context, CCTextureUpdater& updater)
{
// Use BackToFront since it's cheap and this isn't order-dependent.
- typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
+ typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
CCLayerIteratorType end = CCLayerIteratorType::end(&m_updateList);
for (CCLayerIteratorType it = CCLayerIteratorType::begin(&m_updateList); it != end; ++it) {
@@ -647,4 +641,15 @@ void CCLayerTreeHost::deleteTextureAfterCommit(PassOwnPtr<ManagedTexture> textur
m_deleteTextureAfterCommitList.append(texture);
}
+void CCLayerTreeHost::setAnimationEventsRecursive(const CCAnimationEventsVector& events, LayerChromium* layer, double wallClockTime)
+{
+ for (size_t eventIndex = 0; eventIndex < events.size(); ++eventIndex) {
+ if (layer->id() == events[eventIndex]->layerId())
+ layer->setAnimationEvent(*events[eventIndex], wallClockTime);
+ }
+
+ for (size_t childIndex = 0; childIndex < layer->children().size(); ++childIndex)
+ setAnimationEventsRecursive(events, layer->children()[childIndex].get(), wallClockTime);
}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
index 1662f50c3..d5262262d 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
@@ -55,8 +55,8 @@ public:
virtual void updateAnimations(double frameBeginTime) = 0;
virtual void layout() = 0;
virtual void applyScrollAndScale(const IntSize& scrollDelta, float pageScale) = 0;
- virtual PassRefPtr<GraphicsContext3D> createLayerTreeHostContext3D() = 0;
- virtual void didRecreateGraphicsContext(bool success) = 0;
+ virtual PassRefPtr<GraphicsContext3D> createContext() = 0;
+ virtual void didRecreateContext(bool success) = 0;
virtual void didCommitAndDrawFrame() = 0;
virtual void didCompleteSwapBuffers() = 0;
@@ -130,13 +130,21 @@ public:
void beginCommitOnImplThread(CCLayerTreeHostImpl*);
void finishCommitOnImplThread(CCLayerTreeHostImpl*);
void commitComplete();
- PassRefPtr<GraphicsContext3D> createLayerTreeHostContext3D();
+ PassRefPtr<GraphicsContext3D> createContext();
virtual PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl(CCLayerTreeHostImplClient*);
void didBecomeInvisibleOnImplThread(CCLayerTreeHostImpl*);
- void didRecreateGraphicsContext(bool success);
+ void didLoseContext();
+ enum RecreateResult {
+ RecreateSucceeded,
+ RecreateFailedButTryAgain,
+ RecreateFailedAndGaveUp,
+ };
+ RecreateResult recreateContext();
void didCommitAndDrawFrame() { m_client->didCommitAndDrawFrame(); }
void didCompleteSwapBuffers() { m_client->didCompleteSwapBuffers(); }
void deleteContentsTexturesOnImplThread(TextureAllocator*);
+ // Returns false if we should abort this frame due to initialization failure.
+ bool updateLayers();
CCLayerTreeHostClient* client() { return m_client; }
@@ -145,6 +153,8 @@ public:
// Only used when compositing on the main thread.
void composite();
+ // NOTE: The returned value can only be used to make GL calls or make the
+ // context current on the thread the compositor is running on!
GraphicsContext3D* context();
// Composites and attempts to read back the result into the provided
@@ -159,14 +169,14 @@ public:
const LayerRendererCapabilities& layerRendererCapabilities() const;
// Test only hook
- void loseCompositorContext(int numTimes);
+ void loseContext(int numTimes);
void setNeedsAnimate();
// virtual for testing
virtual void setNeedsCommit();
void setNeedsRedraw();
- void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>);
+ void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime);
LayerChromium* rootLayer() { return m_rootLayer.get(); }
const LayerChromium* rootLayer() const { return m_rootLayer.get(); }
@@ -185,9 +195,6 @@ public:
bool visible() const { return m_visible; }
void setVisible(bool);
- // Returns false if we should abort this frame due to initialization failure.
- bool updateLayers();
-
void startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec);
void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&);
@@ -218,6 +225,8 @@ private:
void reserveTextures();
void clearPendingUpdate();
+ void setAnimationEventsRecursive(const CCAnimationEventsVector&, LayerChromium*, double wallClockTime);
+
int m_compositorIdentifier;
bool m_animating;
@@ -228,6 +237,9 @@ private:
OwnPtr<CCProxy> m_proxy;
bool m_layerRendererInitialized;
+ bool m_contextLost;
+ int m_numTimesRecreateShouldFail;
+ int m_numFailedRecreateAttempts;
RefPtr<LayerChromium> m_rootLayer;
OwnPtr<TextureManager> m_contentsTextureManager;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp
index 4fc869400..c86d74d86 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp
@@ -149,11 +149,9 @@ static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlig
// Recursively walks the layer tree starting at the given node and computes all the
// necessary transformations, clipRects, render surfaces, etc.
-template<typename LayerType, typename RenderSurfaceType, typename LayerSorter>
-static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, LayerType* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, RenderSurfaceType* nearestAncestorThatMovesPixels, Vector<RefPtr<LayerType> >& renderSurfaceLayerList, Vector<RefPtr<LayerType> >& layerList, LayerSorter* layerSorter, int maxTextureSize)
+template<typename LayerType, typename LayerList, typename RenderSurfaceType, typename LayerSorter>
+static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, LayerType* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceLayerList, LayerList& layerList, LayerSorter* layerSorter, int maxTextureSize)
{
- typedef Vector<RefPtr<LayerType> > LayerList;
-
// This function computes the new matrix transformations recursively for this
// layer and all its descendants. It also computes the appropriate render surfaces.
// Some important points to remember:
@@ -390,7 +388,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer
for (size_t i = 0; i < layer->children().size(); ++i) {
LayerType* child = layer->children()[i].get();
- bool drawsContent = calculateDrawTransformsAndVisibilityInternal<LayerType, RenderSurfaceType, LayerSorter>(child, rootLayer, sublayerMatrix, nextHierarchyMatrix, nearestAncestorThatMovesPixels, renderSurfaceLayerList, descendants, layerSorter, maxTextureSize);
+ bool drawsContent = calculateDrawTransformsAndVisibilityInternal<LayerType, LayerList, RenderSurfaceType, LayerSorter>(child, rootLayer, sublayerMatrix, nextHierarchyMatrix, nearestAncestorThatMovesPixels, renderSurfaceLayerList, descendants, layerSorter, maxTextureSize);
if (drawsContent) {
if (child->renderSurface()) {
@@ -495,11 +493,11 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer
// FIXME: Instead of using the following function to set visibility rects on a second
// tree pass, revise calculateVisibleLayerRect() so that this can be done in a single
// pass inside calculateDrawTransformsAndVisibilityInternal<>().
-template<typename LayerType, typename RenderSurfaceType>
-static void walkLayersAndCalculateVisibleLayerRects(const Vector<RefPtr<LayerType> >& renderSurfaceLayerList)
+template<typename LayerType, typename LayerList, typename RenderSurfaceType>
+static void walkLayersAndCalculateVisibleLayerRects(const LayerList& renderSurfaceLayerList)
{
// Use BackToFront since it's cheap and this isn't order-dependent.
- typedef CCLayerIterator<LayerType, RenderSurfaceType, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
+ typedef CCLayerIterator<LayerType, LayerList, RenderSurfaceType, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
@@ -512,14 +510,14 @@ static void walkLayersAndCalculateVisibleLayerRects(const Vector<RefPtr<LayerTyp
void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(LayerChromium* layer, LayerChromium* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize)
{
- WebCore::calculateDrawTransformsAndVisibilityInternal<LayerChromium, RenderSurfaceChromium, void*>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, 0, renderSurfaceLayerList, layerList, 0, maxTextureSize);
- walkLayersAndCalculateVisibleLayerRects<LayerChromium, RenderSurfaceChromium>(renderSurfaceLayerList);
+ WebCore::calculateDrawTransformsAndVisibilityInternal<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, void>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, 0, renderSurfaceLayerList, layerList, 0, maxTextureSize);
+ walkLayersAndCalculateVisibleLayerRects<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium>(renderSurfaceLayerList);
}
-void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(CCLayerImpl* layer, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<CCLayerImpl> >& renderSurfaceLayerList, Vector<RefPtr<CCLayerImpl> >& layerList, CCLayerSorter* layerSorter, int maxTextureSize)
+void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(CCLayerImpl* layer, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList, CCLayerSorter* layerSorter, int maxTextureSize)
{
- calculateDrawTransformsAndVisibilityInternal<CCLayerImpl, CCRenderSurface, CCLayerSorter>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, 0, renderSurfaceLayerList, layerList, layerSorter, maxTextureSize);
- walkLayersAndCalculateVisibleLayerRects<CCLayerImpl, CCRenderSurface>(renderSurfaceLayerList);
+ calculateDrawTransformsAndVisibilityInternal<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerSorter>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, 0, renderSurfaceLayerList, layerList, layerSorter, maxTextureSize);
+ walkLayersAndCalculateVisibleLayerRects<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface>(renderSurfaceLayerList);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h
index 2e0cbcf2c..df23cd01f 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h
@@ -43,7 +43,7 @@ public:
template<typename LayerType> static IntRect calculateVisibleLayerRect(LayerType*);
static void calculateDrawTransformsAndVisibility(LayerChromium*, LayerChromium* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize);
- static void calculateDrawTransformsAndVisibility(CCLayerImpl*, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<CCLayerImpl> >& renderSurfaceLayerList, Vector<RefPtr<CCLayerImpl> >& layerList, CCLayerSorter*, int maxTextureSize);
+ static void calculateDrawTransformsAndVisibility(CCLayerImpl*, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList, CCLayerSorter*, int maxTextureSize);
template<typename LayerType> static bool renderSurfaceContributesToTarget(LayerType*, int targetSurfaceLayerID);
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
index d30c68c37..002e7826d 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
@@ -31,6 +31,7 @@
#include "LayerRendererChromium.h"
#include "TraceEvent.h"
#include "cc/CCDamageTracker.h"
+#include "cc/CCDelayBasedTimeSource.h"
#include "cc/CCLayerIterator.h"
#include "cc/CCLayerTreeHost.h"
#include "cc/CCLayerTreeHostCommon.h"
@@ -39,8 +40,48 @@
#include "cc/CCThreadTask.h"
#include <wtf/CurrentTime.h>
+namespace {
+const double lowFrequencyAnimationInterval = 1;
+} // namespace
+
namespace WebCore {
+class CCLayerTreeHostImplTimeSourceAdapter : public CCTimeSourceClient {
+ WTF_MAKE_NONCOPYABLE(CCLayerTreeHostImplTimeSourceAdapter);
+public:
+ static PassOwnPtr<CCLayerTreeHostImplTimeSourceAdapter> create(CCLayerTreeHostImpl* layerTreeHostImpl, PassRefPtr<CCDelayBasedTimeSource> timeSource)
+ {
+ return adoptPtr(new CCLayerTreeHostImplTimeSourceAdapter(layerTreeHostImpl, timeSource));
+ }
+ virtual ~CCLayerTreeHostImplTimeSourceAdapter()
+ {
+ m_timeSource->setClient(0);
+ m_timeSource->setActive(false);
+ }
+
+ virtual void onTimerTick()
+ {
+ m_layerTreeHostImpl->animate(monotonicallyIncreasingTime(), currentTime());
+ }
+
+ void setActive(bool active)
+ {
+ if (active != m_timeSource->active())
+ m_timeSource->setActive(active);
+ }
+
+private:
+ CCLayerTreeHostImplTimeSourceAdapter(CCLayerTreeHostImpl* layerTreeHostImpl, PassRefPtr<CCDelayBasedTimeSource> timeSource)
+ : m_layerTreeHostImpl(layerTreeHostImpl)
+ , m_timeSource(timeSource)
+ {
+ m_timeSource->setClient(this);
+ }
+
+ CCLayerTreeHostImpl* m_layerTreeHostImpl;
+ RefPtr<CCDelayBasedTimeSource> m_timeSource;
+};
+
PassOwnPtr<CCLayerTreeHostImpl> CCLayerTreeHostImpl::create(const CCSettings& settings, CCLayerTreeHostImplClient* client)
{
return adoptPtr(new CCLayerTreeHostImpl(settings, client));
@@ -50,6 +91,7 @@ CCLayerTreeHostImpl::CCLayerTreeHostImpl(const CCSettings& settings, CCLayerTree
: m_client(client)
, m_sourceFrameNumber(-1)
, m_frameNumber(0)
+ , m_scrollLayerImpl(0)
, m_settings(settings)
, m_visible(true)
, m_pageScale(1)
@@ -59,6 +101,7 @@ CCLayerTreeHostImpl::CCLayerTreeHostImpl(const CCSettings& settings, CCLayerTree
, m_maxPageScale(0)
, m_needsAnimateLayers(false)
, m_pinchGestureActive(false)
+ , m_timeSourceClientAdapter(CCLayerTreeHostImplTimeSourceAdapter::create(this, CCDelayBasedTimeSource::create(lowFrequencyAnimationInterval * 1000.0, CCProxy::currentThread())))
{
ASSERT(CCProxy::isImplThread());
}
@@ -96,13 +139,13 @@ GraphicsContext3D* CCLayerTreeHostImpl::context()
return m_layerRenderer ? m_layerRenderer->context() : 0;
}
-void CCLayerTreeHostImpl::animate(double frameBeginTimeMs)
+void CCLayerTreeHostImpl::animate(double monotonicTime, double wallClockTime)
{
- animatePageScale(frameBeginTimeMs);
- animateLayers(frameBeginTimeMs);
+ animatePageScale(monotonicTime);
+ animateLayers(monotonicTime, wallClockTime);
}
-void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTimeMs, double durationMs)
+void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTime, double duration)
{
if (!m_scrollLayerImpl)
return;
@@ -113,15 +156,15 @@ void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition,
IntSize scaledContentSize = contentSize();
scaledContentSize.scale(m_pageScaleDelta);
- m_pageScaleAnimation = CCPageScaleAnimation::create(scrollTotal, scaleTotal, m_viewportSize, scaledContentSize, startTimeMs);
+ m_pageScaleAnimation = CCPageScaleAnimation::create(scrollTotal, scaleTotal, m_viewportSize, scaledContentSize, startTime);
if (anchorPoint) {
IntSize windowAnchor(targetPosition);
windowAnchor.scale(scaleTotal / pageScale);
windowAnchor -= scrollTotal;
- m_pageScaleAnimation->zoomWithAnchor(windowAnchor, pageScale, durationMs);
+ m_pageScaleAnimation->zoomWithAnchor(windowAnchor, pageScale, duration);
} else
- m_pageScaleAnimation->zoomTo(targetPosition, pageScale, durationMs);
+ m_pageScaleAnimation->zoomTo(targetPosition, pageScale, duration);
m_client->setNeedsRedrawOnImplThread();
m_client->setNeedsCommitOnImplThread();
@@ -134,7 +177,7 @@ void CCLayerTreeHostImpl::trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer,
// damage rect. The root damage rect is then used to scissor each surface.
for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
- CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
+ CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
ASSERT(renderSurface);
renderSurface->damageTracker()->updateDamageTrackingState(renderSurface->layerList(), renderSurfaceLayer->id(), renderSurfaceLayer->maskLayer());
@@ -198,7 +241,7 @@ void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLaye
m_rootDamageRect = rootLayer()->renderSurface()->damageTracker()->currentDamageRect();
for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
- CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
+ CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
OwnPtr<CCRenderPass> pass = CCRenderPass::create(renderSurface);
@@ -210,7 +253,7 @@ void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLaye
const CCLayerList& layerList = renderSurface->layerList();
for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
- CCLayerImpl* layer = layerList[layerIndex].get();
+ CCLayerImpl* layer = layerList[layerIndex];
if (layer->visibleLayerRect().isEmpty())
continue;
@@ -233,20 +276,27 @@ void CCLayerTreeHostImpl::optimizeRenderPasses(CCRenderPassList& passes)
bool haveDamageRect = layerRendererCapabilities().usingPartialSwap;
+ // FIXME: compute overdraw metrics only occasionally, not every frame.
+ CCOverdrawCounts overdrawCounts;
for (unsigned i = 0; i < passes.size(); ++i) {
- FloatRect damageRect = passes[i]->targetSurface()->damageTracker()->currentDamageRect();
- passes[i]->optimizeQuads(haveDamageRect, damageRect);
+ FloatRect damageRect = passes[i]->surfaceDamageRect();
+ passes[i]->optimizeQuads(haveDamageRect, damageRect, &overdrawCounts);
}
+
+ float normalization = 1000.f / (m_layerRenderer->viewportWidth() * m_layerRenderer->viewportHeight());
+ PlatformSupport::histogramCustomCounts("Renderer4.pixelOverdrawOpaque", static_cast<int>(normalization * overdrawCounts.m_pixelsDrawnOpaque), 100, 1000000, 50);
+ PlatformSupport::histogramCustomCounts("Renderer4.pixelOverdrawTransparent", static_cast<int>(normalization * overdrawCounts.m_pixelsDrawnTransparent), 100, 1000000, 50);
+ PlatformSupport::histogramCustomCounts("Renderer4.pixelOverdrawCulled", static_cast<int>(normalization * overdrawCounts.m_pixelsCulled), 100, 1000000, 50);
}
-void CCLayerTreeHostImpl::animateLayersRecursive(CCLayerImpl* current, double frameBeginTimeSecs, CCAnimationEventsVector& events, bool& didAnimate, bool& needsAnimateLayers)
+void CCLayerTreeHostImpl::animateLayersRecursive(CCLayerImpl* current, double monotonicTime, double wallClockTime, CCAnimationEventsVector& events, bool& didAnimate, bool& needsAnimateLayers)
{
bool subtreeNeedsAnimateLayers = false;
CCLayerAnimationControllerImpl* currentController = current->layerAnimationController();
bool hadActiveAnimation = currentController->hasActiveAnimation();
- currentController->animate(frameBeginTimeSecs, events);
+ currentController->animate(monotonicTime, events);
bool startedAnimation = events.size() > 0;
// We animated if we either ticked a running animation, or started a new animation.
@@ -259,7 +309,7 @@ void CCLayerTreeHostImpl::animateLayersRecursive(CCLayerImpl* current, double fr
for (size_t i = 0; i < current->children().size(); ++i) {
bool childNeedsAnimateLayers = false;
- animateLayersRecursive(current->children()[i].get(), frameBeginTimeSecs, events, didAnimate, childNeedsAnimateLayers);
+ animateLayersRecursive(current->children()[i].get(), monotonicTime, wallClockTime, events, didAnimate, childNeedsAnimateLayers);
if (childNeedsAnimateLayers)
subtreeNeedsAnimateLayers = true;
}
@@ -294,7 +344,7 @@ void CCLayerTreeHostImpl::drawLayers()
for (size_t i = 0; i < passes.size(); ++i)
m_layerRenderer->drawRenderPass(passes[i].get());
- typedef CCLayerIterator<CCLayerImpl, CCRenderSurface, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
+ typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
@@ -311,7 +361,8 @@ void CCLayerTreeHostImpl::drawLayers()
void CCLayerTreeHostImpl::finishAllRendering()
{
- m_layerRenderer->finish();
+ if (m_layerRenderer)
+ m_layerRenderer->finish();
}
bool CCLayerTreeHostImpl::isContextLost()
@@ -331,10 +382,15 @@ TextureAllocator* CCLayerTreeHostImpl::contentsTextureAllocator() const
void CCLayerTreeHostImpl::swapBuffers()
{
- ASSERT(m_layerRenderer && !isContextLost());
+ ASSERT(m_layerRenderer);
m_layerRenderer->swapBuffers(enclosingIntRect(m_rootDamageRect));
}
+void CCLayerTreeHostImpl::didLoseContext()
+{
+ m_client->didLoseContextOnImplThread();
+}
+
void CCLayerTreeHostImpl::onSwapBuffersComplete()
{
m_client->onSwapBuffersCompleteOnImplThread();
@@ -342,7 +398,7 @@ void CCLayerTreeHostImpl::onSwapBuffersComplete()
void CCLayerTreeHostImpl::readback(void* pixels, const IntRect& rect)
{
- ASSERT(m_layerRenderer && !isContextLost());
+ ASSERT(m_layerRenderer);
m_layerRenderer->getFramebufferPixels(pixels, rect);
}
@@ -363,7 +419,7 @@ static CCLayerImpl* findScrollLayer(CCLayerImpl* layer)
return 0;
}
-void CCLayerTreeHostImpl::setRootLayer(PassRefPtr<CCLayerImpl> layer)
+void CCLayerTreeHostImpl::setRootLayer(PassOwnPtr<CCLayerImpl> layer)
{
m_rootLayerImpl = layer;
@@ -377,8 +433,18 @@ void CCLayerTreeHostImpl::setVisible(bool visible)
return;
m_visible = visible;
- if (m_layerRenderer)
- m_layerRenderer->setVisible(visible);
+ if (!m_layerRenderer)
+ return;
+
+ m_layerRenderer->setVisible(visible);
+
+ // Reset the damage tracker because the front/back buffers may have been damaged by the GPU
+ // process on visibility change.
+ if (visible && m_layerRenderer->capabilities().usingPartialSwap)
+ setFullRootLayerDamage();
+
+ const bool shouldTickInBackground = !visible && m_needsAnimateLayers;
+ m_timeSourceClientAdapter->setActive(shouldTickInBackground);
}
bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> context)
@@ -386,10 +452,16 @@ bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D>
OwnPtr<LayerRendererChromium> layerRenderer;
layerRenderer = LayerRendererChromium::create(this, context);
- if (m_layerRenderer)
+ if (m_layerRenderer) {
m_layerRenderer->close();
+ sendDidLoseContextRecursive(m_rootLayerImpl.get());
+ }
m_layerRenderer = layerRenderer.release();
+
+ if (!m_visible && m_layerRenderer)
+ m_layerRenderer->setVisible(m_visible);
+
return m_layerRenderer;
}
@@ -470,6 +542,10 @@ void CCLayerTreeHostImpl::updateMaxScrollPosition()
return;
FloatSize viewBounds = m_viewportSize;
+ if (CCLayerImpl* clipLayer = m_scrollLayerImpl->parent()) {
+ if (clipLayer->masksToBounds())
+ viewBounds = clipLayer->bounds();
+ }
viewBounds.scale(1 / m_pageScaleDelta);
IntSize maxScroll = contentSize() - expandedIntSize(viewBounds);
@@ -487,7 +563,7 @@ void CCLayerTreeHostImpl::setNeedsRedraw()
m_client->setNeedsRedrawOnImplThread();
}
-CCInputHandlerClient::ScrollStatus CCLayerTreeHostImpl::scrollBegin(const IntPoint& point, CCInputHandlerClient::ScrollInputType type)
+CCInputHandlerClient::ScrollStatus CCLayerTreeHostImpl::scrollBegin(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType type)
{
// TODO: Check for scrollable sublayers.
if (!m_scrollLayerImpl || !m_scrollLayerImpl->scrollable()) {
@@ -495,6 +571,17 @@ CCInputHandlerClient::ScrollStatus CCLayerTreeHostImpl::scrollBegin(const IntPoi
return ScrollIgnored;
}
+ if (m_scrollLayerImpl->shouldScrollOnMainThread()) {
+ TRACE_EVENT("scrollBegin Failed shouldScrollOnMainThread", this, 0);
+ return ScrollFailed;
+ }
+
+ IntPoint scrollLayerContentPoint(m_scrollLayerImpl->screenSpaceTransform().inverse().mapPoint(viewportPoint));
+ if (m_scrollLayerImpl->nonFastScrollableRegion().contains(scrollLayerContentPoint)) {
+ TRACE_EVENT("scrollBegin Failed nonFastScrollableRegion", this, 0);
+ return ScrollFailed;
+ }
+
if (type == CCInputHandlerClient::Wheel && m_scrollLayerImpl->haveWheelEventHandlers()) {
TRACE_EVENT("scrollBegin Failed wheelEventHandlers", this, 0);
return ScrollFailed;
@@ -643,26 +730,26 @@ void CCLayerTreeHostImpl::setFullRootLayerDamage()
}
}
-void CCLayerTreeHostImpl::animatePageScale(double frameBeginTimeMs)
+void CCLayerTreeHostImpl::animatePageScale(double monotonicTime)
{
if (!m_pageScaleAnimation)
return;
IntSize scrollTotal = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
- setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(frameBeginTimeMs) / m_pageScale);
- IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(frameBeginTimeMs);
+ setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(monotonicTime) / m_pageScale);
+ IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime);
nextScroll.scale(1 / m_pageScaleDelta);
m_scrollLayerImpl->scrollBy(nextScroll - scrollTotal);
m_client->setNeedsRedrawOnImplThread();
- if (m_pageScaleAnimation->isAnimationCompleteAtTime(frameBeginTimeMs)) {
+ if (m_pageScaleAnimation->isAnimationCompleteAtTime(monotonicTime)) {
m_pageScaleAnimation.clear();
m_client->setNeedsCommitOnImplThread();
}
}
-void CCLayerTreeHostImpl::animateLayers(double frameBeginTimeMs)
+void CCLayerTreeHostImpl::animateLayers(double monotonicTime, double wallClockTime)
{
if (!m_settings.threadedAnimationEnabled || !m_needsAnimateLayers || !m_rootLayerImpl)
return;
@@ -672,13 +759,28 @@ void CCLayerTreeHostImpl::animateLayers(double frameBeginTimeMs)
OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
bool didAnimate = false;
- animateLayersRecursive(m_rootLayerImpl.get(), frameBeginTimeMs / 1000, *events, didAnimate, m_needsAnimateLayers);
+ animateLayersRecursive(m_rootLayerImpl.get(), monotonicTime, wallClockTime, *events, didAnimate, m_needsAnimateLayers);
if (!events->isEmpty())
- m_client->postAnimationEventsToMainThreadOnImplThread(events.release());
+ m_client->postAnimationEventsToMainThreadOnImplThread(events.release(), wallClockTime);
if (didAnimate)
m_client->setNeedsRedrawOnImplThread();
+
+ const bool shouldTickInBackground = m_needsAnimateLayers && !m_visible;
+ m_timeSourceClientAdapter->setActive(shouldTickInBackground);
+}
+
+void CCLayerTreeHostImpl::sendDidLoseContextRecursive(CCLayerImpl* current)
+{
+ if (!current)
+ return;
+
+ current->didLoseContext();
+ sendDidLoseContextRecursive(current->maskLayer());
+ sendDidLoseContextRecursive(current->replicaLayer());
+ for (size_t i = 0; i < current->children().size(); ++i)
+ sendDidLoseContextRecursive(current->children()[i].get());
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
index e438db0c4..1cfd0fb67 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
@@ -25,6 +25,7 @@
#ifndef CCLayerTreeHostImpl_h
#define CCLayerTreeHostImpl_h
+#include "LayerRendererChromium.h"
#include "cc/CCAnimationEvents.h"
#include "cc/CCInputHandler.h"
#include "cc/CCLayerSorter.h"
@@ -39,6 +40,7 @@ namespace WebCore {
class CCCompletionEvent;
class CCPageScaleAnimation;
class CCLayerImpl;
+class CCLayerTreeHostImplTimeSourceAdapter;
class LayerRendererChromium;
class TextureAllocator;
struct LayerRendererCapabilities;
@@ -47,14 +49,15 @@ class TransformationMatrix;
// CCLayerTreeHost->CCProxy callback interface.
class CCLayerTreeHostImplClient {
public:
+ virtual void didLoseContextOnImplThread() = 0;
virtual void onSwapBuffersCompleteOnImplThread() = 0;
virtual void setNeedsRedrawOnImplThread() = 0;
virtual void setNeedsCommitOnImplThread() = 0;
- virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>) = 0;
+ virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) = 0;
};
// CCLayerTreeHostImpl owns the CCLayerImpl tree as well as associated rendering state
-class CCLayerTreeHostImpl : public CCInputHandlerClient {
+class CCLayerTreeHostImpl : public CCInputHandlerClient, LayerRendererChromiumClient {
WTF_MAKE_NONCOPYABLE(CCLayerTreeHostImpl);
public:
static PassOwnPtr<CCLayerTreeHostImpl> create(const CCSettings&, CCLayerTreeHostImplClient*);
@@ -68,14 +71,23 @@ public:
virtual void pinchGestureBegin();
virtual void pinchGestureUpdate(float, const IntPoint&);
virtual void pinchGestureEnd();
- virtual void startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTimeMs, double durationMs);
+ virtual void startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTime, double duration);
// Virtual for testing.
virtual void beginCommit();
virtual void commitComplete();
- virtual void animate(double frameDisplayTimeMs);
+ virtual void animate(double monotonicTime, double wallClockTime);
virtual void drawLayers();
+ // LayerRendererChromiumClient implementation
+ virtual const IntSize& viewportSize() const { return m_viewportSize; }
+ virtual const CCSettings& settings() const { return m_settings; }
+ virtual CCLayerImpl* rootLayer() { return m_rootLayerImpl.get(); }
+ virtual const CCLayerImpl* rootLayer() const { return m_rootLayerImpl.get(); }
+ virtual void didLoseContext();
+ virtual void onSwapBuffersComplete();
+
+ // Implementation
bool canDraw();
GraphicsContext3D* context();
@@ -89,14 +101,13 @@ public:
TextureAllocator* contentsTextureAllocator() const;
void swapBuffers();
- void onSwapBuffersComplete();
void readback(void* pixels, const IntRect&);
- CCLayerImpl* rootLayer() const { return m_rootLayerImpl.get(); }
- void setRootLayer(PassRefPtr<CCLayerImpl>);
+ void setRootLayer(PassOwnPtr<CCLayerImpl>);
+ PassOwnPtr<CCLayerImpl> releaseRootLayer() { return m_rootLayerImpl.release(); }
- CCLayerImpl* scrollLayer() const { return m_scrollLayerImpl.get(); }
+ CCLayerImpl* scrollLayer() const { return m_scrollLayerImpl; }
bool visible() const { return m_visible; }
void setVisible(bool);
@@ -105,13 +116,10 @@ public:
void setSourceFrameNumber(int frameNumber) { m_sourceFrameNumber = frameNumber; }
void setViewportSize(const IntSize&);
- const IntSize& viewportSize() const { return m_viewportSize; }
void setPageScaleFactorAndLimits(float pageScale, float minPageScale, float maxPageScale);
float pageScale() const { return m_pageScale; }
- const CCSettings& settings() const { return m_settings; }
-
PassOwnPtr<CCScrollAndScaleSet> processScrollDeltas();
// Where possible, redraws are scissored to a damage region calculated from changes to
@@ -126,17 +134,17 @@ public:
protected:
CCLayerTreeHostImpl(const CCSettings&, CCLayerTreeHostImplClient*);
- void animatePageScale(double frameBeginTimeMs);
+ void animatePageScale(double monotonicTime);
// Virtual for testing.
- virtual void animateLayers(double frameBeginTimeMs);
+ virtual void animateLayers(double monotonicTime, double wallClockTime);
CCLayerTreeHostImplClient* m_client;
int m_sourceFrameNumber;
int m_frameNumber;
private:
- typedef Vector<RefPtr<CCLayerImpl> > CCLayerList;
+ typedef Vector<CCLayerImpl*> CCLayerList;
void computeDoubleTapZoomDeltas(CCScrollAndScaleSet* scrollInfo);
void computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo);
@@ -149,12 +157,13 @@ private:
void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList);
void calculateRenderPasses(CCRenderPassList&, CCLayerList& renderSurfaceLayerList);
void optimizeRenderPasses(CCRenderPassList&);
- void animateLayersRecursive(CCLayerImpl*, double frameBeginTimeSecs, CCAnimationEventsVector&, bool& didAnimate, bool& needsAnimateLayers);
+ void animateLayersRecursive(CCLayerImpl*, double monotonicTime, double wallClockTime, CCAnimationEventsVector&, bool& didAnimate, bool& needsAnimateLayers);
IntSize contentSize() const;
+ void sendDidLoseContextRecursive(CCLayerImpl*);
OwnPtr<LayerRendererChromium> m_layerRenderer;
- RefPtr<CCLayerImpl> m_rootLayerImpl;
- RefPtr<CCLayerImpl> m_scrollLayerImpl;
+ OwnPtr<CCLayerImpl> m_rootLayerImpl;
+ CCLayerImpl* m_scrollLayerImpl;
CCSettings m_settings;
IntSize m_viewportSize;
bool m_visible;
@@ -171,6 +180,9 @@ private:
OwnPtr<CCPageScaleAnimation> m_pageScaleAnimation;
+ // This is used for ticking animations slowly when hidden.
+ OwnPtr<CCLayerTreeHostImplTimeSourceAdapter> m_timeSourceClientAdapter;
+
CCLayerSorter m_layerSorter;
FloatRect m_rootDamageRect;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp
index c5611ac27..f1c933882 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp
@@ -39,6 +39,22 @@ using namespace std;
namespace WebCore {
template<typename LayerType, typename RenderSurfaceType>
+CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace)
+ : m_scissorRectInScreenSpace(scissorRectInScreenSpace)
+ , m_surfaceDamageClient(0)
+ , m_usePaintTracking(true) // FIXME: Remove this when paint tracking is on for paint culling.
+{
+}
+
+template<typename LayerType, typename RenderSurfaceType>
+CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, const DamageClientType* surfaceDamageClient)
+ : m_scissorRectInScreenSpace(scissorRectInScreenSpace)
+ , m_surfaceDamageClient(surfaceDamageClient)
+ , m_usePaintTracking(true) // FIXME: Remove this when paint tracking is on for paint culling.
+{
+}
+
+template<typename LayerType, typename RenderSurfaceType>
void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterTargetRenderSurface(const RenderSurfaceType* newTarget)
{
if (!m_stack.isEmpty() && m_stack.last().surface == newTarget)
@@ -170,8 +186,9 @@ static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerTy
return transform;
}
+// FIXME: Remove usePaintTracking when paint tracking is on for paint culling.
template<typename LayerType>
-static inline Region computeOcclusionBehindLayer(const LayerType* layer, const TransformationMatrix& transform)
+static inline Region computeOcclusionBehindLayer(const LayerType* layer, const TransformationMatrix& transform, bool usePaintTracking)
{
Region opaqueRegion;
@@ -182,7 +199,14 @@ static inline Region computeOcclusionBehindLayer(const LayerType* layer, const T
if (layer->opaque())
opaqueRegion = enclosedIntRect(unoccludedQuad.boundingBox());
- // FIXME: Capture opaque paints: else opaqueRegion = layer->opaqueContentsRegion(transform);
+ else if (usePaintTracking && transform.isIdentity())
+ opaqueRegion = layer->opaqueContentsRegion();
+ else if (usePaintTracking) {
+ Region contentRegion = layer->opaqueContentsRegion();
+ Vector<IntRect> contentRects = contentRegion.rects();
+ for (size_t i = 0; i < contentRects.size(); ++i)
+ opaqueRegion.unite(enclosedIntRect(transform.mapRect(FloatRect(contentRects[i]))));
+ }
return opaqueRegion;
}
@@ -191,6 +215,8 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay
{
ASSERT(!m_stack.isEmpty());
ASSERT(layer->targetRenderSurface() == m_stack.last().surface);
+ if (m_stack.isEmpty())
+ return;
if (layer->drawOpacity() != 1)
return;
@@ -198,45 +224,31 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay
TransformationMatrix contentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer);
TransformationMatrix contentToTargetSurface = contentToTargetSurfaceTransform<LayerType>(layer);
- m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpace));
- m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurface));
+ // FIXME: Remove m_usePaintTracking when paint tracking is on for paint culling.
+ m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpace, m_usePaintTracking));
+ m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurface, m_usePaintTracking));
}
-static inline bool testContentRectOccluded(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const Region& occlusion)
+static inline bool testContentRectOccluded(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion)
{
- FloatQuad transformedQuad = contentSpaceTransform.mapQuad(FloatQuad(contentRect));
- return occlusion.contains(transformedQuad.enclosingBoundingBox());
+ FloatRect transformedRect = contentSpaceTransform.mapRect(FloatRect(contentRect));
+ // Take the enclosingIntRect, as we want to include partial pixels in the test.
+ IntRect targetRect = intersection(enclosingIntRect(transformedRect), scissorRect);
+ return targetRect.isEmpty() || occlusion.contains(targetRect);
}
template<typename LayerType, typename RenderSurfaceType>
bool CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerType* layer, const IntRect& contentRect) const
{
+ ASSERT(!m_stack.isEmpty());
if (m_stack.isEmpty())
return false;
ASSERT(layer->targetRenderSurface() == m_stack.last().surface);
- if (testContentRectOccluded(contentRect, contentToScreenSpaceTransform<LayerType>(layer), m_stack.last().occlusionInScreen))
+ if (testContentRectOccluded(contentRect, contentToScreenSpaceTransform<LayerType>(layer), m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen))
return true;
- if (testContentRectOccluded(contentRect, contentToTargetSurfaceTransform<LayerType>(layer), m_stack.last().occlusionInTarget))
- return true;
- return false;
-}
-
-template<typename LayerType, typename RenderSurfaceType>
-bool CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::surfaceOccluded(const LayerType* layer, const IntRect& surfaceContentRect) const
-{
- // A surface is not occluded by layers drawing into itself, so we need to use occlusion from one spot down on the stack.
- if (m_stack.size() < 2)
- return false;
-
- ASSERT(layer->renderSurface());
- ASSERT(layer->renderSurface() == m_stack.last().surface);
-
- TransformationMatrix surfaceContentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer);
-
- const StackObject& secondLast = m_stack[m_stack.size()-2];
- if (testContentRectOccluded(surfaceContentRect, surfaceContentToScreenSpace, secondLast.occlusionInScreen))
+ if (testContentRectOccluded(contentRect, contentToTargetSurfaceTransform<LayerType>(layer), layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget))
return true;
return false;
}
@@ -256,22 +268,20 @@ static inline IntRect rectSubtractRegion(const IntRect& rect, const Region& regi
return boundsRect;
}
-static IntRect computeUnoccludedContentRect(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const Region& occlusion)
+static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion)
{
- FloatQuad transformedQuad = contentSpaceTransform.mapQuad(FloatQuad(contentRect));
- if (!transformedQuad.isRectilinear())
- return contentRect;
- // Take the enclosingIntRect at each step here, as we want to contain any unoccluded partial pixels in the resulting IntRect.
- IntRect shrunkRect = rectSubtractRegion(enclosingIntRect(transformedQuad.boundingBox()), occlusion);
+ FloatRect transformedRect = contentSpaceTransform.mapRect(FloatRect(contentRect));
+ // Take the enclosingIntRect at each step, as we want to contain any unoccluded partial pixels in the resulting IntRect.
+ IntRect shrunkRect = rectSubtractRegion(intersection(enclosingIntRect(transformedRect), scissorRect), occlusion);
IntRect unoccludedRect = enclosingIntRect(contentSpaceTransform.inverse().mapRect(FloatRect(shrunkRect)));
- // The use of enclosingIntRect, with floating point rounding, can give us a result that is not a sub-rect of contentRect, but our
- // return value should be a sub-rect.
+ // The rect back in content space is a bounding box and may extend outside of the original contentRect, so clamp it to the contentRectBounds.
return intersection(unoccludedRect, contentRect);
}
template<typename LayerType, typename RenderSurfaceType>
IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentRect(const LayerType* layer, const IntRect& contentRect) const
{
+ ASSERT(!m_stack.isEmpty());
if (m_stack.isEmpty())
return contentRect;
@@ -281,31 +291,24 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR
TransformationMatrix contentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer);
TransformationMatrix contentToTargetSurface = contentToTargetSurfaceTransform<LayerType>(layer);
- IntRect unoccludedInScreen = computeUnoccludedContentRect(contentRect, contentToScreenSpace, m_stack.last().occlusionInScreen);
- IntRect unoccludedInTarget = computeUnoccludedContentRect(contentRect, contentToTargetSurface, m_stack.last().occlusionInTarget);
+ IntRect unoccludedInScreen = computeUnoccludedContentRect(contentRect, contentToScreenSpace, m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen);
+ if (unoccludedInScreen.isEmpty())
+ return IntRect();
+ IntRect unoccludedInTarget = computeUnoccludedContentRect(contentRect, contentToTargetSurface, layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget);
return intersection(unoccludedInScreen, unoccludedInTarget);
}
template<typename LayerType, typename RenderSurfaceType>
-IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::surfaceUnoccludedContentRect(const LayerType* layer, const IntRect& surfaceContentRect) const
+IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerScissorRectInTargetSurface(const LayerType* layer) const
{
- // A surface is not occluded by layers drawing into itself, so we need to use occlusion from one spot down on the stack.
- if (m_stack.size() < 2)
- return surfaceContentRect;
-
- ASSERT(layer->renderSurface());
- ASSERT(layer->renderSurface() == m_stack.last().surface);
-
- // We want to return a rect that contains all the visible parts of |contentRect| in both screen space and in the target surface.
- // So we find the visible parts of |contentRect| in each space, and take the intersection.
-
- TransformationMatrix contentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer);
-
- const StackObject& secondLast = m_stack[m_stack.size()-2];
- IntRect unoccludedInScreen = computeUnoccludedContentRect(surfaceContentRect, contentToScreenSpace, secondLast.occlusionInScreen);
-
- return unoccludedInScreen;
+ const RenderSurfaceType* targetSurface = m_stack.last().surface;
+ FloatRect totalScissor = targetSurface->contentRect();
+ if (m_surfaceDamageClient)
+ totalScissor.intersect(m_surfaceDamageClient->damageRect(targetSurface));
+ if (!layer->clipRect().isEmpty())
+ totalScissor.intersect(layer->clipRect());
+ return enclosingIntRect(totalScissor);
}
template<typename LayerType, typename RenderSurfaceType>
@@ -324,27 +327,29 @@ const Region& CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::currentOcclu
// Declare the possible functions here for the linker.
+template CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace);
+template CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, const CCOcclusionTrackerDamageClient* surfaceDamageClient);
template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::enterTargetRenderSurface(const RenderSurfaceChromium* newTarget);
template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::finishedTargetRenderSurface(const LayerChromium* owningLayer, const RenderSurfaceChromium* finishedTarget);
template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leaveToTargetRenderSurface(const RenderSurfaceChromium* newTarget);
template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::markOccludedBehindLayer(const LayerChromium*);
template bool CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::occluded(const LayerChromium*, const IntRect& contentRect) const;
-template bool CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::surfaceOccluded(const LayerChromium*, const IntRect& surfaceContentRect) const;
template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContentRect(const LayerChromium*, const IntRect& contentRect) const;
-template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::surfaceUnoccludedContentRect(const LayerChromium*, const IntRect& surfaceContentRect) const;
template const Region& CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::currentOcclusionInScreenSpace() const;
template const Region& CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::currentOcclusionInTargetSurface() const;
+template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::layerScissorRectInTargetSurface(const LayerChromium*) const;
+template CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace);
+template CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, const CCOcclusionTrackerDamageClientImpl* surfaceDamageClient);
template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterTargetRenderSurface(const CCRenderSurface* newTarget);
template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::finishedTargetRenderSurface(const CCLayerImpl* owningLayer, const CCRenderSurface* finishedTarget);
template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveToTargetRenderSurface(const CCRenderSurface* newTarget);
template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::markOccludedBehindLayer(const CCLayerImpl*);
template bool CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::occluded(const CCLayerImpl*, const IntRect& contentRect) const;
-template bool CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::surfaceOccluded(const CCLayerImpl*, const IntRect& surfaceContentRect) const;
template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContentRect(const CCLayerImpl*, const IntRect& contentRect) const;
-template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::surfaceUnoccludedContentRect(const CCLayerImpl*, const IntRect& surfaceContentRect) const;
template const Region& CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::currentOcclusionInScreenSpace() const;
template const Region& CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::currentOcclusionInTargetSurface() const;
+template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::layerScissorRectInTargetSurface(const CCLayerImpl*) const;
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h
index d1c833e1a..19fc2c1dd 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h
@@ -36,6 +36,15 @@ class CCRenderSurface;
class LayerChromium;
class RenderSurfaceChromium;
+template<typename RenderSurfaceType>
+class CCOcclusionTrackerDamageClientBase {
+public:
+ virtual FloatRect damageRect(const RenderSurfaceType*) const = 0;
+};
+
+typedef CCOcclusionTrackerDamageClientBase<RenderSurfaceChromium> CCOcclusionTrackerDamageClient;
+typedef CCOcclusionTrackerDamageClientBase<CCRenderSurface> CCOcclusionTrackerDamageClientImpl;
+
// This class is used to track occlusion of layers while traversing them in a front-to-back order. As each layer is visited, one of the
// methods in this class is called to notify it about the current target surface.
// Then, occlusion in the content space of the current layer may be queried, via methods such as occluded() and unoccludedContentRect().
@@ -43,8 +52,11 @@ class RenderSurfaceChromium;
// Finally, once finished with the layer, occlusion behind the layer should be marked by calling markOccludedBehindLayer().
template<typename LayerType, typename RenderSurfaceType>
class CCOcclusionTrackerBase {
+ WTF_MAKE_NONCOPYABLE(CCOcclusionTrackerBase);
+ typedef CCOcclusionTrackerDamageClientBase<RenderSurfaceType> DamageClientType;
public:
- CCOcclusionTrackerBase() { }
+ CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace);
+ CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, const DamageClientType*);
// Called when visiting a layer representing itself. If the target was not already current, then this indicates we have entered a new surface subtree.
void enterTargetRenderSurface(const RenderSurfaceType* newTarget);
@@ -65,10 +77,8 @@ public:
// Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Used when considering occlusion for a layer that paints/draws something.
IntRect unoccludedContentRect(const LayerType*, const IntRect& contentRect) const;
- // Returns true if the given rect in content space for the RenderSurface owned by the layer is fully occluded in either screen space or the layer's target surface.
- bool surfaceOccluded(const LayerType*, const IntRect& contentRect) const;
- // Gives an unoccluded sub-rect of |contentRect| in the content space of the RenderSurface owned by the layer. Used when considering occlusion for a target surface.
- IntRect surfaceUnoccludedContentRect(const LayerType*, const IntRect& contentRect) const;
+ // FIXME: Remove this when paint tracking is on for paint culling.
+ void setUsePaintTracking(bool use) { m_usePaintTracking = use; }
// FIXME: Remove these in future, they are to make CLs for transitioning to this easier.
const Region& currentOcclusionInScreenSpace() const;
@@ -90,8 +100,13 @@ protected:
// We merge the occlusion at the top of the stack with the new current subtree. This new target is pushed onto the stack if not already there.
Vector<StackObject, 1> m_stack;
+ // Allow tests to override this.
+ virtual IntRect layerScissorRectInTargetSurface(const LayerType*) const;
+
private:
- WTF_MAKE_NONCOPYABLE(CCOcclusionTrackerBase);
+ IntRect m_scissorRectInScreenSpace;
+ const DamageClientType* m_surfaceDamageClient;
+ bool m_usePaintTracking; // FIXME: Remove this when paint tracking is on for paint culling.
};
typedef CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium> CCOcclusionTracker;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.cpp
index 33b6f22fb..49a125d23 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.cpp
@@ -22,7 +22,7 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -36,13 +36,13 @@
namespace WebCore {
-PassOwnPtr<CCPageScaleAnimation> CCPageScaleAnimation::create(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTimeMs)
+PassOwnPtr<CCPageScaleAnimation> CCPageScaleAnimation::create(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTime)
{
- return adoptPtr(new CCPageScaleAnimation(scrollStart, pageScaleStart, windowSize, contentSize, startTimeMs));
+ return adoptPtr(new CCPageScaleAnimation(scrollStart, pageScaleStart, windowSize, contentSize, startTime));
}
-CCPageScaleAnimation::CCPageScaleAnimation(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTimeMs)
+CCPageScaleAnimation::CCPageScaleAnimation(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTime)
: m_scrollStart(scrollStart)
, m_pageScaleStart(pageScaleStart)
, m_windowSize(windowSize)
@@ -50,11 +50,11 @@ CCPageScaleAnimation::CCPageScaleAnimation(const IntSize& scrollStart, float pag
, m_anchorMode(false)
, m_scrollEnd(scrollStart)
, m_pageScaleEnd(pageScaleStart)
- , m_startTimeMs(startTimeMs)
+ , m_startTime(startTime)
{
}
-void CCPageScaleAnimation::zoomTo(const IntSize& finalScroll, float finalPageScale, double durationMs)
+void CCPageScaleAnimation::zoomTo(const IntSize& finalScroll, float finalPageScale, double duration)
{
if (m_pageScaleStart != finalPageScale) {
// For uniform-looking zooming, infer the anchor (point that remains in
@@ -78,18 +78,18 @@ void CCPageScaleAnimation::zoomTo(const IntSize& finalScroll, float finalPageSca
float ratioY = (startRect.y() - endRect.y()) / (endRect.height() - startRect.height());
IntSize anchor(m_windowSize.width() * ratioX, m_windowSize.height() * ratioY);
- zoomWithAnchor(anchor, finalPageScale, durationMs);
+ zoomWithAnchor(anchor, finalPageScale, duration);
} else {
// If this is a pure translation, then there exists no anchor. Linearly
// interpolate the scroll offset instead.
m_scrollEnd = finalScroll;
m_pageScaleEnd = finalPageScale;
- m_durationMs = durationMs;
+ m_duration = duration;
m_anchorMode = false;
}
}
-void CCPageScaleAnimation::zoomWithAnchor(const IntSize& anchor, float finalPageScale, double durationMs)
+void CCPageScaleAnimation::zoomWithAnchor(const IntSize& anchor, float finalPageScale, double duration)
{
m_scrollEnd = m_scrollStart + anchor;
m_scrollEnd.scale(finalPageScale / m_pageScaleStart);
@@ -103,31 +103,31 @@ void CCPageScaleAnimation::zoomWithAnchor(const IntSize& anchor, float finalPage
m_anchor = anchor;
m_pageScaleEnd = finalPageScale;
- m_durationMs = durationMs;
+ m_duration = duration;
m_anchorMode = true;
}
-IntSize CCPageScaleAnimation::scrollOffsetAtTime(double timeMs) const
+IntSize CCPageScaleAnimation::scrollOffsetAtTime(double time) const
{
- return scrollOffsetAtRatio(progressRatioForTime(timeMs));
+ return scrollOffsetAtRatio(progressRatioForTime(time));
}
-float CCPageScaleAnimation::pageScaleAtTime(double timeMs) const
+float CCPageScaleAnimation::pageScaleAtTime(double time) const
{
- return pageScaleAtRatio(progressRatioForTime(timeMs));
+ return pageScaleAtRatio(progressRatioForTime(time));
}
-bool CCPageScaleAnimation::isAnimationCompleteAtTime(double timeMs) const
+bool CCPageScaleAnimation::isAnimationCompleteAtTime(double time) const
{
- return timeMs >= endTimeMs();
+ return time >= endTime();
}
-float CCPageScaleAnimation::progressRatioForTime(double timeMs) const
+float CCPageScaleAnimation::progressRatioForTime(double time) const
{
- if (isAnimationCompleteAtTime(timeMs))
+ if (isAnimationCompleteAtTime(time))
return 1;
- return (timeMs - m_startTimeMs) / m_durationMs;
+ return (time - m_startTime) / m_duration;
}
IntSize CCPageScaleAnimation::scrollOffsetAtRatio(float ratio) const
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.h b/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.h
index f4b1bf47a..d9acb4911 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPageScaleAnimation.h
@@ -39,39 +39,39 @@ public:
// Construct with the starting page scale and scroll offset (which is in
// pageScaleStart space). The window size is the user-viewable area
// in pixels.
- static PassOwnPtr<CCPageScaleAnimation> create(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTimeMs);
+ static PassOwnPtr<CCPageScaleAnimation> create(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTime);
// The following methods initialize the animation. Call one of them
// immediately after construction to set the final scroll and page scale.
// Zoom while explicitly specifying the top-left scroll position. The
// scroll offset is in finalPageScale coordinates.
- void zoomTo(const IntSize& finalScroll, float finalPageScale, double durationMs);
+ void zoomTo(const IntSize& finalScroll, float finalPageScale, double duration);
// Zoom based on a specified onscreen anchor, which will remain at the same
// position on the screen throughout the animation. The anchor is in local
// space relative to scrollStart.
- void zoomWithAnchor(const IntSize& anchor, float finalPageScale, double durationMs);
+ void zoomWithAnchor(const IntSize& anchor, float finalPageScale, double duration);
// Call these functions while the animation is in progress to output the
// current state.
- IntSize scrollOffsetAtTime(double timeMs) const;
- float pageScaleAtTime(double timeMs) const;
- bool isAnimationCompleteAtTime(double timeMs) const;
+ IntSize scrollOffsetAtTime(double time) const;
+ float pageScaleAtTime(double time) const;
+ bool isAnimationCompleteAtTime(double time) const;
// The following methods return state which is invariant throughout the
// course of the animation.
- double startTimeMs() const { return m_startTimeMs; }
- double durationMs() const { return m_durationMs; }
- double endTimeMs() const { return m_startTimeMs + m_durationMs; }
+ double startTime() const { return m_startTime; }
+ double duration() const { return m_duration; }
+ double endTime() const { return m_startTime + m_duration; }
const IntSize& finalScrollOffset() const { return m_scrollEnd; }
float finalPageScale() const { return m_pageScaleEnd; }
protected:
- CCPageScaleAnimation(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTimeMs);
+ CCPageScaleAnimation(const IntSize& scrollStart, float pageScaleStart, const IntSize& windowSize, const IntSize& contentSize, double startTime);
private:
- float progressRatioForTime(double timeMs) const;
+ float progressRatioForTime(double time) const;
IntSize scrollOffsetAtRatio(float ratio) const;
float pageScaleAtRatio(float ratio) const;
@@ -85,8 +85,8 @@ private:
IntSize m_scrollEnd;
float m_pageScaleEnd;
- double m_startTimeMs;
- double m_durationMs;
+ double m_startTime;
+ double m_duration;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
index 5e4aca6d9..74538168e 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
@@ -53,7 +53,9 @@ CCPluginLayerImpl::CCPluginLayerImpl(int id)
CCPluginLayerImpl::~CCPluginLayerImpl()
{
- cleanupResources();
+ // FIXME: it seems there is no layer renderer / GraphicsContext3D available here. Ideally we
+ // would like to delete m_ioSurfaceTextureId.
+ m_ioSurfaceTextureId = 0;
}
void CCPluginLayerImpl::willDraw(LayerRendererChromium* layerRenderer)
@@ -101,6 +103,16 @@ void CCPluginLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
CCLayerImpl::dumpLayerProperties(ts, indent);
}
+void CCPluginLayerImpl::didLoseContext()
+{
+ if (m_ioSurfaceId) {
+ // We don't have a valid texture ID in the new context; however,
+ // the IOSurface is still valid.
+ m_ioSurfaceTextureId = 0;
+ m_ioSurfaceChanged = true;
+ }
+}
+
void CCPluginLayerImpl::setIOSurfaceProperties(int width, int height, uint32_t ioSurfaceId)
{
if (m_ioSurfaceId != ioSurfaceId)
@@ -111,13 +123,6 @@ void CCPluginLayerImpl::setIOSurfaceProperties(int width, int height, uint32_t i
m_ioSurfaceId = ioSurfaceId;
}
-void CCPluginLayerImpl::cleanupResources()
-{
- // FIXME: it seems there is no layer renderer / GraphicsContext3D available here. Ideally we
- // would like to delete m_ioSurfaceTextureId.
- m_ioSurfaceTextureId = 0;
-}
-
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
index 39a95951d..370e09d94 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
@@ -35,9 +35,9 @@ namespace WebCore {
class CCPluginLayerImpl : public CCLayerImpl {
public:
- static PassRefPtr<CCPluginLayerImpl> create(int id)
+ static PassOwnPtr<CCPluginLayerImpl> create(int id)
{
- return adoptRef(new CCPluginLayerImpl(id));
+ return adoptPtr(new CCPluginLayerImpl(id));
}
virtual ~CCPluginLayerImpl();
@@ -50,6 +50,7 @@ public:
typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexRectFlipAlpha> TexRectProgramFlip;
virtual void dumpLayerProperties(TextStream&, int indent) const;
+ virtual void didLoseContext();
void setTextureId(unsigned id) { m_textureId = id; }
void setFlipped(bool flipped) { m_flipped = flipped; }
@@ -61,8 +62,6 @@ private:
virtual const char* layerTypeAsString() const { return "PluginLayer"; }
- void cleanupResources();
-
unsigned m_textureId;
bool m_flipped;
FloatRect m_uvRect;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCProxy.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCProxy.cpp
index e4d601451..9ebb71dc7 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCProxy.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCProxy.cpp
@@ -69,28 +69,38 @@ CCThread* CCProxy::implThread()
return s_implThread;
}
+CCThread* CCProxy::currentThread()
+{
+ ThreadIdentifier currentThreadIdentifier = WTF::currentThread();
+ if (s_mainThread && s_mainThread->threadID() == currentThreadIdentifier)
+ return s_mainThread;
+ if (s_implThread && s_implThread->threadID() == currentThreadIdentifier)
+ return s_implThread;
+ return 0;
+}
+
#ifndef NDEBUG
bool CCProxy::isMainThread()
{
ASSERT(s_mainThread);
- if (implThreadIsOverridden && currentThread() == threadIDOverridenToBeImplThread)
+ if (implThreadIsOverridden && WTF::currentThread() == threadIDOverridenToBeImplThread)
return false;
- return currentThread() == s_mainThread->threadID();
+ return WTF::currentThread() == s_mainThread->threadID();
}
bool CCProxy::isImplThread()
{
WTF::ThreadIdentifier implThreadID = s_implThread ? s_implThread->threadID() : 0;
- if (implThreadIsOverridden && currentThread() == threadIDOverridenToBeImplThread)
+ if (implThreadIsOverridden && WTF::currentThread() == threadIDOverridenToBeImplThread)
return true;
- return currentThread() == implThreadID;
+ return WTF::currentThread() == implThreadID;
}
void CCProxy::setCurrentThreadIsImplThread(bool isImplThread)
{
implThreadIsOverridden = isImplThread;
if (isImplThread)
- threadIDOverridenToBeImplThread = currentThread();
+ threadIDOverridenToBeImplThread = WTF::currentThread();
}
#endif
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h b/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h
index b4358aadd..016226ca5 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h
@@ -53,6 +53,9 @@ public:
static void setImplThread(CCThread*);
static CCThread* implThread();
+ // Returns 0 if the current thread is neither the main thread nor the impl thread.
+ static CCThread* currentThread();
+
virtual ~CCProxy();
virtual bool compositeAndReadback(void *pixels, const IntRect&) = 0;
@@ -70,6 +73,10 @@ public:
// Attempts to initialize the layer renderer. Returns false if the context isn't usable for compositing.
virtual bool initializeLayerRenderer() = 0;
+ // Attempts to recreate the context and layer renderer after a context lost. Returns false if the renderer couldn't be
+ // reinitialized.
+ virtual bool recreateContext() = 0;
+
virtual int compositorIdentifier() const = 0;
virtual const LayerRendererCapabilities& layerRendererCapabilities() const = 0;
@@ -95,7 +102,7 @@ public:
virtual GraphicsContext3D* context() = 0;
// Testing hooks
- virtual void loseCompositorContext(int numTimes) = 0;
+ virtual void loseContext() = 0;
#ifndef NDEBUG
static void setCurrentThreadIsImplThread(bool);
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp
index 4f6435dc0..1c4a499cc 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp
@@ -75,7 +75,22 @@ static IntRect rectSubtractRegion(const Region& region, const IntRect& rect)
return rect;
}
-void CCQuadCuller::cullOccludedQuads(CCQuadList& quadList, bool haveDamageRect, const FloatRect& damageRect)
+static float wedgeProduct(const FloatPoint& p1, const FloatPoint& p2)
+{
+ return p1.x() * p2.y() - p1.y() * p2.x();
+}
+
+// Computes area of quads that are possibly non-rectangular. Can
+// be easily extended to polygons.
+static float quadArea(const FloatQuad& quad)
+{
+ return fabs(0.5 * (wedgeProduct(quad.p1(), quad.p2()) +
+ wedgeProduct(quad.p2(), quad.p3()) +
+ wedgeProduct(quad.p3(), quad.p4()) +
+ wedgeProduct(quad.p4(), quad.p1())));
+}
+
+void CCQuadCuller::cullOccludedQuads(CCQuadList& quadList, bool haveDamageRect, const FloatRect& damageRect, CCOverdrawCounts* overdrawMetrics)
{
if (!quadList.size())
return;
@@ -96,21 +111,43 @@ void CCQuadCuller::cullOccludedQuads(CCQuadList& quadList, bool haveDamageRect,
IntRect transformedVisibleQuadRect = rectSubtractRegion(opaqueCoverageThusFar, transformedQuadRect);
bool keepQuad = !transformedVisibleQuadRect.isEmpty();
- if (!keepQuad)
- continue;
// See if we can reduce the number of pixels to draw by reducing the size of the draw
// quad - we do this by changing its visible rect.
- if (transformedVisibleQuadRect != transformedQuadRect && drawQuad->isLayerAxisAlignedIntRect())
- drawQuad->setQuadVisibleRect(drawQuad->quadTransform().inverse().mapRect(transformedVisibleQuadRect));
-
- // When adding rect to opaque region, deflate it to stay conservative.
- if (drawQuad->isLayerAxisAlignedIntRect() && !drawQuad->opaqueRect().isEmpty()) {
- FloatRect floatOpaqueRect = drawQuad->quadTransform().mapRect(FloatRect(drawQuad->opaqueRect()));
- opaqueCoverageThusFar.unite(Region(enclosedIntRect(floatOpaqueRect)));
+ bool didReduceQuadSize = false;
+ if (keepQuad) {
+ if (transformedVisibleQuadRect != transformedQuadRect && drawQuad->isLayerAxisAlignedIntRect()) {
+ drawQuad->setQuadVisibleRect(drawQuad->quadTransform().inverse().mapRect(transformedVisibleQuadRect));
+ didReduceQuadSize = true;
+ }
+
+ // When adding rect to opaque region, deflate it to stay conservative.
+ if (drawQuad->isLayerAxisAlignedIntRect() && !drawQuad->opaqueRect().isEmpty()) {
+ FloatRect floatOpaqueRect = drawQuad->quadTransform().mapRect(FloatRect(drawQuad->opaqueRect()));
+ opaqueCoverageThusFar.unite(Region(enclosedIntRect(floatOpaqueRect)));
+ }
+
+ culledList.append(quadList[i].release());
}
- culledList.append(quadList[i].release());
+ if (overdrawMetrics) {
+ // We compute the area of the transformed quad, as this should be in pixels.
+ float area = quadArea(drawQuad->quadTransform().mapQuad(FloatQuad(drawQuad->quadRect())));
+ if (keepQuad) {
+ if (didReduceQuadSize) {
+ float visibleQuadRectArea = quadArea(drawQuad->quadTransform().mapQuad(FloatQuad(drawQuad->quadVisibleRect())));
+ overdrawMetrics->m_pixelsCulled += area - visibleQuadRectArea;
+ area = visibleQuadRectArea;
+ }
+ IntRect visibleOpaqueRect(drawQuad->quadVisibleRect());
+ visibleOpaqueRect.intersect(drawQuad->opaqueRect());
+ FloatQuad visibleOpaqueQuad = drawQuad->quadTransform().mapQuad(FloatQuad(visibleOpaqueRect));
+ float opaqueArea = quadArea(visibleOpaqueQuad);
+ overdrawMetrics->m_pixelsDrawnOpaque += opaqueArea;
+ overdrawMetrics->m_pixelsDrawnTransparent += area - opaqueArea;
+ } else
+ overdrawMetrics->m_pixelsCulled += area;
+ }
}
quadList.clear(); // Release anything that remains.
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h
index 3cc315ec4..89582573b 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h
@@ -32,7 +32,9 @@ namespace WebCore {
class CCQuadCuller {
public:
- static void cullOccludedQuads(CCQuadList&, bool haveDamageRect, const FloatRect& damageRect);
+ // Passing 0 for CCOverdrawCounts* is valid, and disable the extra computation
+ // done to estimate over draw statistics.
+ static void cullOccludedQuads(CCQuadList&, bool haveDamageRect, const FloatRect& damageRect, CCOverdrawCounts*);
private:
// Make non-instantiable.
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp
index da4b2222c..bd877ec30 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp
@@ -65,9 +65,9 @@ void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer)
m_sharedQuadStateList.append(sharedQuadState.release());
}
-void CCRenderPass::optimizeQuads(bool haveDamageRect, const FloatRect& damageRect)
+void CCRenderPass::optimizeQuads(bool haveDamageRect, const FloatRect& damageRect, CCOverdrawCounts* overdraw)
{
- CCQuadCuller::cullOccludedQuads(m_quadList, haveDamageRect, damageRect);
+ CCQuadCuller::cullOccludedQuads(m_quadList, haveDamageRect, damageRect, overdraw);
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h
index 11fbd4016..2affce541 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h
@@ -38,6 +38,22 @@ class CCSharedQuadState;
typedef Vector<OwnPtr<CCDrawQuad> > CCQuadList;
+struct CCOverdrawCounts {
+ CCOverdrawCounts()
+ : m_pixelsDrawnOpaque(0)
+ , m_pixelsDrawnTransparent(0)
+ , m_pixelsCulled(0)
+ {
+ }
+ // Count of pixels that are opaque (and thus occlude). Ideally this is no more
+ // than wiewport width x height.
+ float m_pixelsDrawnOpaque;
+ // Count of pixels that are possibly transparent, and cannot occlude.
+ float m_pixelsDrawnTransparent;
+ // Count of pixels not drawn as they are occluded by somthing opaque.
+ float m_pixelsCulled;
+};
+
class CCRenderPass {
WTF_MAKE_NONCOPYABLE(CCRenderPass);
public:
@@ -46,7 +62,8 @@ public:
void appendQuadsForLayer(CCLayerImpl*);
void appendQuadsForRenderSurfaceLayer(CCLayerImpl*);
- void optimizeQuads(bool haveDamageRect, const FloatRect& damageRect);
+ // Passing in 0 for CCOverdrawCounts is valid, and disables performing overdraw calculations.
+ void optimizeQuads(bool haveDamageRect, const FloatRect& damageRect, CCOverdrawCounts*);
const CCQuadList& quadList() const { return m_quadList; }
CCRenderSurface* targetSurface() const { return m_targetSurface; }
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp
index 169999808..25ac8fa9b 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp
@@ -58,15 +58,6 @@ CCRenderSurface::CCRenderSurface(CCLayerImpl* owningLayer)
CCRenderSurface::~CCRenderSurface()
{
- cleanupResources();
-}
-
-void CCRenderSurface::cleanupResources()
-{
- if (!m_contentsTexture)
- return;
-
- m_contentsTexture.clear();
}
FloatRect CCRenderSurface::drawableContentRect() const
@@ -216,7 +207,7 @@ void CCRenderSurface::drawSurface(LayerRendererChromium* layerRenderer, CCLayerI
float edge[24];
layerQuad.toFloatArray(edge);
deviceRect.toFloatArray(&edge[12]);
- GLC(context3D, context3D->uniform3fv(shaderEdgeLocation, edge, 8));
+ GLC(context3D, context3D->uniform3fv(shaderEdgeLocation, 8, edge));
}
// Map device space quad to layer space.
@@ -239,7 +230,7 @@ SkBitmap CCRenderSurface::applyFilters(LayerRendererChromium* layerRenderer)
String CCRenderSurface::name() const
{
- return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->id(), m_owningLayer->name().utf8().data());
+ return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->id(), m_owningLayer->debugName().utf8().data());
}
static void writeIndent(TextStream& ts, int indent)
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h
index 1bcec9260..141ed2d24 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h
@@ -55,7 +55,7 @@ public:
bool prepareContentsTexture(LayerRendererChromium*);
void releaseContentsTexture();
- void cleanupResources();
+
void draw(LayerRendererChromium*, const FloatRect& surfaceDamageRect);
String name() const;
@@ -95,7 +95,7 @@ public:
bool skipsDraw() const { return m_skipsDraw; }
void clearLayerList() { m_layerList.clear(); }
- Vector<RefPtr<CCLayerImpl> >& layerList() { return m_layerList; }
+ Vector<CCLayerImpl*>& layerList() { return m_layerList; }
void setMaskLayer(CCLayerImpl* maskLayer) { m_maskLayer = maskLayer; }
@@ -133,7 +133,7 @@ private:
TransformationMatrix m_originTransform;
FilterOperations m_filters;
IntRect m_clipRect;
- Vector<RefPtr<CCLayerImpl> > m_layerList;
+ Vector<CCLayerImpl*> m_layerList;
// The nearest ancestor target surface that will contain the contents of this surface, and that is going
// to move pixels within the surface (such as with a blur). This can point to itself.
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp
index 8580467f0..633f21d47 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp
@@ -86,10 +86,19 @@ void CCScheduler::didSwapBuffersComplete()
m_frameRateController->didFinishFrame();
}
-void CCScheduler::didSwapBuffersAbort()
+void CCScheduler::didLoseContext()
{
- TRACE_EVENT("CCScheduler::didSwapBuffersAbort", this, 0);
+ TRACE_EVENT("CCScheduler::didLoseContext", this, 0);
m_frameRateController->didAbortAllPendingFrames();
+ m_stateMachine.didLoseContext();
+ processScheduledActions();
+}
+
+void CCScheduler::didRecreateContext()
+{
+ TRACE_EVENT("CCScheduler::didRecreateContext", this, 0);
+ m_stateMachine.didRecreateContext();
+ processScheduledActions();
}
void CCScheduler::beginFrame()
@@ -151,6 +160,9 @@ void CCScheduler::processScheduledActions()
m_client->scheduledActionDrawAndSwap();
m_frameRateController->didBeginFrame();
break;
+ case CCSchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION:
+ m_client->scheduledActionBeginContextRecreation();
+ break;
}
} while (action != CCSchedulerStateMachine::ACTION_NONE);
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h b/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h
index 7310581b1..f8ba21f99 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h
@@ -44,6 +44,7 @@ public:
virtual void scheduledActionDrawAndSwap() = 0;
virtual void scheduledActionUpdateMoreResources() = 0;
virtual void scheduledActionCommit() = 0;
+ virtual void scheduledActionBeginContextRecreation() = 0;
protected:
virtual ~CCSchedulerClient() { }
@@ -71,7 +72,9 @@ public:
void setMaxFramesPending(int);
void didSwapBuffersComplete();
- void didSwapBuffersAbort();
+
+ void didLoseContext();
+ void didRecreateContext();
bool commitPending() const { return m_stateMachine.commitPending(); }
bool redrawPending() const { return m_stateMachine.redrawPending(); }
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp
index d1aa5ccdc..054a4edd7 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp
@@ -38,27 +38,60 @@ CCSchedulerStateMachine::CCSchedulerStateMachine()
, m_updateMoreResourcesPending(false)
, m_insideVSync(false)
, m_visible(false)
- , m_canDraw(true) { }
+ , m_canDraw(true)
+ , m_contextState(CONTEXT_ACTIVE)
+{
+}
+
+bool CCSchedulerStateMachine::hasDrawnThisFrame() const
+{
+ return m_currentFrameNumber == m_lastFrameNumberWhereDrawWasCalled;
+}
+
+bool CCSchedulerStateMachine::shouldDraw() const
+{
+ if (m_needsForcedRedraw)
+ return true;
+
+ if (!m_needsRedraw)
+ return false;
+ if (!m_insideVSync)
+ return false;
+ if (!m_visible)
+ return false;
+ if (hasDrawnThisFrame())
+ return false;
+ if (!m_canDraw)
+ return false;
+ if (m_contextState != CONTEXT_ACTIVE)
+ return false;
+ return true;
+}
CCSchedulerStateMachine::Action CCSchedulerStateMachine::nextAction() const
{
- bool canDraw = m_currentFrameNumber != m_lastFrameNumberWhereDrawWasCalled;
- bool shouldDraw = (m_needsRedraw && m_insideVSync && m_visible && canDraw && m_canDraw) || m_needsForcedRedraw;
+
switch (m_commitState) {
case COMMIT_STATE_IDLE:
- if (shouldDraw)
+ if (m_contextState != CONTEXT_ACTIVE && m_needsForcedRedraw)
+ return ACTION_DRAW;
+ if (m_contextState == CONTEXT_LOST)
+ return ACTION_BEGIN_CONTEXT_RECREATION;
+ if (m_contextState == CONTEXT_RECREATING)
+ return ACTION_NONE;
+ if (shouldDraw())
return ACTION_DRAW;
if (m_needsCommit && m_visible)
return ACTION_BEGIN_FRAME;
return ACTION_NONE;
case COMMIT_STATE_FRAME_IN_PROGRESS:
- if (shouldDraw)
+ if (shouldDraw())
return ACTION_DRAW;
return ACTION_NONE;
case COMMIT_STATE_UPDATING_RESOURCES:
- if (shouldDraw)
+ if (shouldDraw())
return ACTION_DRAW;
if (!m_updateMoreResourcesPending)
return ACTION_BEGIN_UPDATE_MORE_RESOURCES;
@@ -68,7 +101,7 @@ CCSchedulerStateMachine::Action CCSchedulerStateMachine::nextAction() const
return ACTION_COMMIT;
case COMMIT_STATE_WAITING_FOR_FIRST_DRAW:
- if (shouldDraw)
+ if (shouldDraw() || m_contextState == CONTEXT_LOST)
return ACTION_DRAW;
// COMMIT_STATE_WAITING_FOR_FIRST_DRAW wants to enforce a draw. If m_canDraw is false,
// proceed to the next step (similar as in COMMIT_STATE_IDLE).
@@ -115,12 +148,18 @@ void CCSchedulerStateMachine::updateState(Action action)
m_commitState = COMMIT_STATE_IDLE;
}
return;
+
+ case ACTION_BEGIN_CONTEXT_RECREATION:
+ ASSERT(m_commitState == COMMIT_STATE_IDLE);
+ ASSERT(m_contextState == CONTEXT_LOST);
+ m_contextState = CONTEXT_RECREATING;
+ return;
}
}
bool CCSchedulerStateMachine::vsyncCallbackNeeded() const
{
- if (!m_visible) {
+ if (!m_visible || m_contextState != CONTEXT_ACTIVE) {
if (m_needsForcedRedraw)
return true;
@@ -176,4 +215,18 @@ void CCSchedulerStateMachine::beginUpdateMoreResourcesComplete(bool morePending)
m_commitState = COMMIT_STATE_READY_TO_COMMIT;
}
+void CCSchedulerStateMachine::didLoseContext()
+{
+ if (m_contextState == CONTEXT_LOST || m_contextState == CONTEXT_RECREATING)
+ return;
+ m_contextState = CONTEXT_LOST;
+}
+
+void CCSchedulerStateMachine::didRecreateContext()
+{
+ ASSERT(m_contextState == CONTEXT_RECREATING);
+ m_contextState = CONTEXT_ACTIVE;
+ setNeedsCommit();
+}
+
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h b/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h
index 7de718846..22fcdf422 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h
@@ -51,6 +51,11 @@ public:
COMMIT_STATE_WAITING_FOR_FIRST_DRAW,
};
+ enum ContextState {
+ CONTEXT_ACTIVE,
+ CONTEXT_LOST,
+ CONTEXT_RECREATING,
+ };
bool commitPending() const
{
return m_commitState != COMMIT_STATE_IDLE;
@@ -64,6 +69,7 @@ public:
ACTION_BEGIN_UPDATE_MORE_RESOURCES,
ACTION_COMMIT,
ACTION_DRAW,
+ ACTION_BEGIN_CONTEXT_RECREATION
};
Action nextAction() const;
void updateState(Action);
@@ -107,7 +113,13 @@ public:
// when such behavior would be undesirable.
void setCanDraw(bool can) { m_canDraw = can; }
+ void didLoseContext();
+ void didRecreateContext();
+
protected:
+ bool shouldDraw() const;
+ bool hasDrawnThisFrame() const;
+
CommitState m_commitState;
int m_currentFrameNumber;
@@ -119,6 +131,7 @@ protected:
bool m_insideVSync;
bool m_visible;
bool m_canDraw;
+ ContextState m_contextState;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp
new file mode 100644
index 000000000..872a35832
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2012 Google 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 AND ITS CONTRIBUTORS "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 OR ITS 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 "CCScrollbarLayerImpl.h"
+
+#include "CCTileDrawQuad.h"
+#include "LayerRendererChromium.h"
+#include "ManagedTexture.h"
+#include "PlatformCanvas.h"
+#include "ScrollbarTheme.h"
+
+namespace WebCore {
+
+PassOwnPtr<CCScrollbarLayerImpl> CCScrollbarLayerImpl::create(int id)
+{
+ return adoptPtr(new CCScrollbarLayerImpl(id));
+}
+
+CCScrollbarLayerImpl::CCScrollbarLayerImpl(int id)
+ : CCLayerImpl(id)
+ , m_scrollLayer(0)
+ , m_scrollbar(this)
+{
+}
+
+void CCScrollbarLayerImpl::willDraw(LayerRendererChromium* layerRenderer)
+{
+ if (bounds().isEmpty() || contentBounds().isEmpty())
+ return;
+
+ if (!m_texture)
+ m_texture = ManagedTexture::create(layerRenderer->renderSurfaceTextureManager());
+
+ IntSize textureSize = contentBounds();
+ if (!m_texture->reserve(textureSize, GraphicsContext3D::RGBA))
+ return;
+
+ PlatformCanvas canvas;
+ canvas.resize(textureSize);
+ {
+ PlatformCanvas::Painter painter(&canvas, PlatformCanvas::Painter::GrayscaleText);
+ paint(painter.context());
+ }
+
+ {
+ PlatformCanvas::AutoLocker locker(&canvas);
+ GraphicsContext3D* context = layerRenderer->context();
+ m_texture->bindTexture(context, layerRenderer->renderSurfaceTextureAllocator());
+
+ // FIXME: Skia uses BGRA actually, we correct that with the swizzle pixel shader.
+ GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, m_texture->format(), canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels()));
+ }
+}
+
+void CCScrollbarLayerImpl::appendQuads(CCQuadList& quadList, const CCSharedQuadState* sharedQuadState)
+{
+ if (!m_texture->isReserved())
+ return;
+
+ IntRect quadRect(IntPoint(), bounds());
+ quadList.append(CCTileDrawQuad::create(sharedQuadState, quadRect, quadRect, m_texture->textureId(), IntPoint(), m_texture->size(), GraphicsContext3D::NEAREST, true, true, true, true, true));
+}
+
+void CCScrollbarLayerImpl::didDraw()
+{
+ m_texture->unreserve();
+}
+
+void CCScrollbarLayerImpl::paint(GraphicsContext* context)
+{
+ ScrollbarTheme* theme = ScrollbarTheme::theme(); // FIXME: should make impl-side clone if needed
+
+ context->clearRect(IntRect(IntPoint(), contentBounds()));
+ theme->paint(&m_scrollbar, context, IntRect(IntPoint(), contentBounds()));
+}
+
+
+int CCScrollbarLayerImpl::CCScrollbar::x() const
+{
+ return frameRect().x();
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::y() const
+{
+ return frameRect().y();
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::width() const
+{
+ return frameRect().width();
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::height() const
+{
+ return frameRect().height();
+}
+
+IntSize CCScrollbarLayerImpl::CCScrollbar::size() const
+{
+ return frameRect().size();
+}
+
+IntPoint CCScrollbarLayerImpl::CCScrollbar::location() const
+{
+ return frameRect().location();
+}
+
+ScrollView* CCScrollbarLayerImpl::CCScrollbar::parent() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+ScrollView* CCScrollbarLayerImpl::CCScrollbar::root() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void CCScrollbarLayerImpl::CCScrollbar::setFrameRect(const IntRect&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+IntRect CCScrollbarLayerImpl::CCScrollbar::frameRect() const
+{
+ return IntRect(IntPoint(), m_owner->contentBounds());
+}
+
+void CCScrollbarLayerImpl::CCScrollbar::invalidate()
+{
+ invalidateRect(frameRect());
+}
+
+void CCScrollbarLayerImpl::CCScrollbar::invalidateRect(const IntRect&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+ScrollbarOverlayStyle CCScrollbarLayerImpl::CCScrollbar::scrollbarOverlayStyle() const
+{
+ return m_owner->m_scrollbarOverlayStyle;
+}
+
+void CCScrollbarLayerImpl::CCScrollbar::getTickmarks(Vector<IntRect>& tickmarks) const
+{
+ tickmarks = m_owner->m_tickmarks;
+}
+
+bool CCScrollbarLayerImpl::CCScrollbar::isScrollableAreaActive() const
+{
+ return m_owner->m_isScrollableAreaActive;
+}
+
+bool CCScrollbarLayerImpl::CCScrollbar::isScrollViewScrollbar() const
+{
+ return m_owner->m_isScrollViewScrollbar;
+}
+
+IntPoint CCScrollbarLayerImpl::CCScrollbar::convertFromContainingWindow(const IntPoint& windowPoint)
+{
+ ASSERT_NOT_REACHED();
+ return windowPoint;
+}
+
+bool CCScrollbarLayerImpl::CCScrollbar::isCustomScrollbar() const
+{
+ return false;
+}
+
+ScrollbarOrientation CCScrollbarLayerImpl::CCScrollbar::orientation() const
+{
+ return m_owner->m_orientation;
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::value() const
+{
+ if (!m_owner->m_scrollLayer)
+ return 0;
+ if (orientation() == HorizontalScrollbar)
+ return m_owner->m_scrollLayer->scrollPosition().x() + m_owner->m_scrollLayer->scrollDelta().width();
+ return m_owner->m_scrollLayer->scrollPosition().y() + m_owner->m_scrollLayer->scrollDelta().height();
+}
+
+float CCScrollbarLayerImpl::CCScrollbar::currentPos() const
+{
+ return value();
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::visibleSize() const
+{
+ return totalSize() - maximum();
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::totalSize() const
+{
+ if (!m_owner->m_scrollLayer || !m_owner->m_scrollLayer->children().size())
+ return 0;
+ // Copy & paste from CCLayerTreeHostImpl...
+ // FIXME: Hardcoding the first child here is weird. Think of
+ // a cleaner way to get the contentBounds on the Impl side.
+ if (orientation() == HorizontalScrollbar)
+ return m_owner->m_scrollLayer->children()[0]->contentBounds().width();
+ return m_owner->m_scrollLayer->children()[0]->contentBounds().height();
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::maximum() const
+{
+ if (!m_owner->m_scrollLayer)
+ return 0;
+ if (orientation() == HorizontalScrollbar)
+ return m_owner->m_scrollLayer->maxScrollPosition().width();
+ return m_owner->m_scrollLayer->maxScrollPosition().height();
+}
+
+ScrollbarControlSize CCScrollbarLayerImpl::CCScrollbar::controlSize() const
+{
+ return m_owner->m_controlSize;
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::lineStep() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+int CCScrollbarLayerImpl::CCScrollbar::pageStep() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+ScrollbarPart CCScrollbarLayerImpl::CCScrollbar::pressedPart() const
+{
+ return m_owner->m_pressedPart;
+}
+
+ScrollbarPart CCScrollbarLayerImpl::CCScrollbar::hoveredPart() const
+{
+ return m_owner->m_hoveredPart;
+}
+
+void CCScrollbarLayerImpl::CCScrollbar::styleChanged()
+{
+}
+
+bool CCScrollbarLayerImpl::CCScrollbar::enabled() const
+{
+ return m_owner->m_enabled;
+}
+
+void CCScrollbarLayerImpl::CCScrollbar::setEnabled(bool)
+{
+ ASSERT_NOT_REACHED();
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.h
new file mode 100644
index 000000000..f6f005360
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2012 Google 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 AND ITS CONTRIBUTORS "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 OR ITS 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 CCScrollbarLayerImpl_h
+#define CCScrollbarLayerImpl_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "CCLayerImpl.h"
+#include "ManagedTexture.h"
+#include "ScrollbarThemeClient.h"
+
+namespace WebCore {
+
+class GraphicsContext;
+class ScrollView;
+
+class CCScrollbarLayerImpl : public CCLayerImpl {
+public:
+ static PassOwnPtr<CCScrollbarLayerImpl> create(int id);
+
+ void setScrollbarOverlayStyle(ScrollbarOverlayStyle scrollbarOverlayStyle) { m_scrollbarOverlayStyle = scrollbarOverlayStyle; }
+ void setTickmarks(const Vector<IntRect>& tickmarks) { m_tickmarks = tickmarks; }
+ void setIsScrollableAreaActive(bool isScrollableAreaActive) { m_isScrollableAreaActive = isScrollableAreaActive; }
+ void setIsScrollViewScrollbar(bool isScrollViewScrollbar) { m_isScrollViewScrollbar = isScrollViewScrollbar; }
+
+ void setOrientation(ScrollbarOrientation orientation) { m_orientation = orientation; }
+
+ void setControlSize(ScrollbarControlSize controlSize) { m_controlSize = controlSize; }
+
+ void setPressedPart(ScrollbarPart pressedPart) { m_pressedPart = pressedPart; }
+ void setHoveredPart(ScrollbarPart hoveredPart) { m_hoveredPart = hoveredPart; }
+
+ void setEnabled(bool enabled) { m_enabled = enabled; }
+
+
+ CCLayerImpl* scrollLayer() const { return m_scrollLayer; }
+ void setScrollLayer(CCLayerImpl* scrollLayer) { m_scrollLayer = scrollLayer; }
+
+ virtual void willDraw(LayerRendererChromium*);
+ virtual void appendQuads(CCQuadList&, const CCSharedQuadState*);
+ virtual void didDraw();
+
+protected:
+ explicit CCScrollbarLayerImpl(int id);
+
+private:
+ void paint(GraphicsContext*);
+
+ CCLayerImpl* m_scrollLayer;
+ OwnPtr<ManagedTexture> m_texture;
+
+ // nested class only to avoid namespace problem
+ class CCScrollbar : public ScrollbarThemeClient {
+ public:
+ explicit CCScrollbar(CCScrollbarLayerImpl* owner) : m_owner(owner) { }
+
+ // ScrollbarThemeClient implementation
+ virtual int x() const;
+ virtual int y() const;
+ virtual int width() const;
+ virtual int height() const;
+ virtual IntSize size() const;
+ virtual IntPoint location() const;
+
+ virtual ScrollView* parent() const;
+ virtual ScrollView* root() const;
+
+ virtual void setFrameRect(const IntRect&);
+ virtual IntRect frameRect() const;
+
+ virtual void invalidate();
+ virtual void invalidateRect(const IntRect&);
+
+ virtual ScrollbarOverlayStyle scrollbarOverlayStyle() const;
+ virtual void getTickmarks(Vector<IntRect>&) const;
+ virtual bool isScrollableAreaActive() const;
+ virtual bool isScrollViewScrollbar() const;
+
+ virtual IntPoint convertFromContainingWindow(const IntPoint& windowPoint);
+
+ virtual bool isCustomScrollbar() const;
+ virtual ScrollbarOrientation orientation() const;
+
+ virtual int value() const;
+ virtual float currentPos() const;
+ virtual int visibleSize() const;
+ virtual int totalSize() const;
+ virtual int maximum() const;
+ virtual ScrollbarControlSize controlSize() const;
+
+ virtual int lineStep() const;
+ virtual int pageStep() const;
+
+ virtual ScrollbarPart pressedPart() const;
+ virtual ScrollbarPart hoveredPart() const;
+
+ virtual void styleChanged();
+
+ virtual bool enabled() const;
+ virtual void setEnabled(bool);
+
+ private:
+ CCScrollbarLayerImpl* m_owner;
+
+ };
+ CCScrollbar m_scrollbar;
+
+ ScrollbarOverlayStyle m_scrollbarOverlayStyle;
+ Vector<IntRect> m_tickmarks;
+ bool m_isScrollableAreaActive;
+ bool m_isScrollViewScrollbar;
+
+ ScrollbarOrientation m_orientation;
+
+ ScrollbarControlSize m_controlSize;
+
+ ScrollbarPart m_pressedPart;
+ ScrollbarPart m_hoveredPart;
+
+ bool m_enabled;
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
index ea8c40f12..b6fc76b52 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
@@ -45,11 +45,9 @@ PassOwnPtr<CCProxy> CCSingleThreadProxy::create(CCLayerTreeHost* layerTreeHost)
CCSingleThreadProxy::CCSingleThreadProxy(CCLayerTreeHost* layerTreeHost)
: m_layerTreeHost(layerTreeHost)
+ , m_contextLost(false)
, m_compositorIdentifier(-1)
, m_layerRendererInitialized(false)
- , m_numFailedRecreateAttempts(0)
- , m_graphicsContextLost(false)
- , m_timesRecreateShouldFail(0)
, m_nextFrameIsNewlyCommittedFrame(false)
{
TRACE_EVENT("CCSingleThreadProxy::CCSingleThreadProxy", this, 0);
@@ -74,11 +72,6 @@ bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect
TRACE_EVENT("CCSingleThreadProxy::compositeAndReadback", this, 0);
ASSERT(CCProxy::isMainThread());
- if (!recreateContextIfNeeded()) {
- TRACE_EVENT("compositeAndReadback_EarlyOut_ContextLost", this, 0);
- return false;
- }
-
if (!commitIfNeeded())
return false;
@@ -90,12 +83,15 @@ bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect
if (m_layerTreeHostImpl->isContextLost())
return false;
+ m_layerTreeHostImpl->swapBuffers();
+ didSwapFrame();
+
return true;
}
-void CCSingleThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec)
+void CCSingleThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
{
- m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime() * 1000.0, durationSec * 1000.0);
+ m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime(), duration);
}
GraphicsContext3D* CCSingleThreadProxy::context()
@@ -125,7 +121,7 @@ bool CCSingleThreadProxy::isStarted() const
bool CCSingleThreadProxy::initializeContext()
{
ASSERT(CCProxy::isMainThread());
- RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D();
+ RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
if (!context)
return false;
ASSERT(context->hasOneRef());
@@ -148,6 +144,33 @@ bool CCSingleThreadProxy::initializeLayerRenderer()
}
}
+bool CCSingleThreadProxy::recreateContext()
+{
+ TRACE_EVENT0("cc", "CCSingleThreadProxy::recreateContext");
+ ASSERT(CCProxy::isMainThread());
+ ASSERT(m_contextLost);
+
+ RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
+ if (!context)
+ return false;
+
+ ASSERT(context->hasOneRef());
+ bool initialized;
+ {
+ DebugScopedSetImplThread impl;
+ m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
+ initialized = m_layerTreeHostImpl->initializeLayerRenderer(context);
+ if (initialized) {
+ m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
+ }
+ }
+
+ if (initialized)
+ m_contextLost = false;
+
+ return initialized;
+}
+
const LayerRendererCapabilities& CCSingleThreadProxy::layerRendererCapabilities() const
{
ASSERT(m_layerRendererInitialized);
@@ -155,10 +178,11 @@ const LayerRendererCapabilities& CCSingleThreadProxy::layerRendererCapabilities(
return m_layerRendererCapabilitiesForMainThread;
}
-void CCSingleThreadProxy::loseCompositorContext(int numTimes)
+void CCSingleThreadProxy::loseContext()
{
- m_graphicsContextLost = true;
- m_timesRecreateShouldFail = numTimes - 1;
+ ASSERT(CCProxy::isMainThread());
+ m_layerTreeHost->didLoseContext();
+ m_contextLost = true;
}
void CCSingleThreadProxy::setNeedsAnimate()
@@ -212,12 +236,14 @@ void CCSingleThreadProxy::setNeedsRedraw()
void CCSingleThreadProxy::setVisible(bool visible)
{
+ m_layerTreeHostImpl->setVisible(visible);
+
if (!visible) {
DebugScopedSetImplThread impl;
m_layerTreeHost->didBecomeInvisibleOnImplThread(m_layerTreeHostImpl.get());
- m_layerTreeHostImpl->setVisible(false);
return;
}
+
setNeedsCommit();
}
@@ -233,72 +259,23 @@ void CCSingleThreadProxy::stop()
m_layerTreeHost = 0;
}
-void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events)
+void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
{
ASSERT(CCProxy::isImplThread());
DebugScopedSetMainThread main;
- m_layerTreeHost->setAnimationEvents(events);
+ m_layerTreeHost->setAnimationEvents(events, wallClockTime);
}
// Called by the legacy scheduling path (e.g. where render_widget does the scheduling)
void CCSingleThreadProxy::compositeImmediately()
{
- if (!recreateContextIfNeeded())
- return;
-
if (!commitIfNeeded())
return;
- if (doComposite())
+ if (doComposite()) {
m_layerTreeHostImpl->swapBuffers();
-}
-
-bool CCSingleThreadProxy::recreateContextIfNeeded()
-{
- ASSERT(CCProxy::isMainThread());
-
- if (!m_graphicsContextLost && m_layerTreeHostImpl->isContextLost()) {
- m_graphicsContextLost = true;
- m_numFailedRecreateAttempts = 0;
- }
-
- if (!m_graphicsContextLost)
- return true;
- RefPtr<GraphicsContext3D> context;
- if (!m_timesRecreateShouldFail)
- context = m_layerTreeHost->createLayerTreeHostContext3D();
- else
- m_timesRecreateShouldFail--;
-
- if (context) {
- ASSERT(context->hasOneRef());
- bool ok;
- {
- DebugScopedSetImplThread impl;
- m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
- ok = m_layerTreeHostImpl->initializeLayerRenderer(context);
- if (ok)
- m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
- }
- if (ok) {
- m_layerTreeHost->didRecreateGraphicsContext(true);
- m_graphicsContextLost = false;
- return true;
- }
+ didSwapFrame();
}
-
- // Tolerate a certain number of recreation failures to work around races
- // in the context-lost machinery.
- m_numFailedRecreateAttempts++;
- if (m_numFailedRecreateAttempts < 5) {
- setNeedsCommit();
- return false;
- }
-
- // We have tried too many times to recreate the context. Tell the host to fall
- // back to software rendering.
- m_layerTreeHost->didRecreateGraphicsContext(false);
- return false;
}
bool CCSingleThreadProxy::commitIfNeeded()
@@ -314,34 +291,31 @@ bool CCSingleThreadProxy::commitIfNeeded()
bool CCSingleThreadProxy::doComposite()
{
- ASSERT(!m_graphicsContextLost);
-
+ ASSERT(!m_contextLost);
{
DebugScopedSetImplThread impl;
- double frameDisplayTimeMs = monotonicallyIncreasingTime() * 1000.0;
- m_layerTreeHostImpl->animate(frameDisplayTimeMs);
+ double monotonicTime = monotonicallyIncreasingTime();
+ double wallClockTime = currentTime();
+
+ m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
m_layerTreeHostImpl->drawLayers();
}
if (m_layerTreeHostImpl->isContextLost()) {
- // Trying to recover the context right here will not work if GPU process
- // died. This is because GpuChannelHost::OnErrorMessage will only be
- // called at the next iteration of the message loop, reverting our
- // recovery attempts here. Instead, we detach the root layer from the
- // renderer, recreate the renderer at the next message loop iteration
- // and request a repaint yet again.
- m_graphicsContextLost = true;
- m_numFailedRecreateAttempts = 0;
- setNeedsCommit();
+ m_contextLost = true;
+ m_layerTreeHost->didLoseContext();
return false;
}
+ return true;
+}
+
+void CCSingleThreadProxy::didSwapFrame()
+{
if (m_nextFrameIsNewlyCommittedFrame) {
m_nextFrameIsNewlyCommittedFrame = false;
m_layerTreeHost->didCommitAndDrawFrame();
}
-
- return true;
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
index 71b5e99b2..ebbd96e2c 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
@@ -43,15 +43,16 @@ public:
// CCProxy implementation
virtual bool compositeAndReadback(void *pixels, const IntRect&);
- virtual void startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec);
+ virtual void startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration);
virtual GraphicsContext3D* context();
virtual void finishAllRendering();
virtual bool isStarted() const;
virtual bool initializeContext();
virtual bool initializeLayerRenderer();
+ virtual bool recreateContext();
virtual int compositorIdentifier() const { return m_compositorIdentifier; }
virtual const LayerRendererCapabilities& layerRendererCapabilities() const;
- virtual void loseCompositorContext(int numTimes);
+ virtual void loseContext();
virtual void setNeedsAnimate();
virtual void setNeedsCommit();
virtual void setNeedsRedraw();
@@ -61,23 +62,26 @@ public:
virtual size_t maxPartialTextureUpdates() const { return std::numeric_limits<size_t>::max(); }
// CCLayerTreeHostImplClient implementation
+ virtual void didLoseContextOnImplThread() { }
virtual void onSwapBuffersCompleteOnImplThread() { ASSERT_NOT_REACHED(); }
virtual void setNeedsRedrawOnImplThread() { m_layerTreeHost->setNeedsCommit(); }
virtual void setNeedsCommitOnImplThread() { m_layerTreeHost->setNeedsCommit(); }
- virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>);
+ virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime);
// Called by the legacy path where RenderWidget does the scheduling.
void compositeImmediately();
private:
explicit CCSingleThreadProxy(CCLayerTreeHost*);
- bool recreateContextIfNeeded();
+
bool commitIfNeeded();
void doCommit();
bool doComposite();
+ void didSwapFrame();
// Accessed on main thread only.
CCLayerTreeHost* m_layerTreeHost;
+ bool m_contextLost;
int m_compositorIdentifier;
// Holds on to the context between initializeContext() and initializeLayerRenderer() calls. Shouldn't
@@ -89,9 +93,6 @@ private:
bool m_layerRendererInitialized;
LayerRendererCapabilities m_layerRendererCapabilitiesForMainThread;
- int m_numFailedRecreateAttempts;
- bool m_graphicsContextLost;
- int m_timesRecreateShouldFail; // Used during testing.
bool m_nextFrameIsNewlyCommittedFrame;
};
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h
index c7edc18b2..2e7441666 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h
@@ -35,9 +35,9 @@ class LayerRendererChromium;
class CCSolidColorLayerImpl : public CCLayerImpl {
public:
- static PassRefPtr<CCSolidColorLayerImpl> create(int id)
+ static PassOwnPtr<CCSolidColorLayerImpl> create(int id)
{
- return adoptRef(new CCSolidColorLayerImpl(id));
+ return adoptPtr(new CCSolidColorLayerImpl(id));
}
virtual ~CCSolidColorLayerImpl();
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
index 75ef13623..8454e21ff 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
@@ -59,6 +59,7 @@ PassOwnPtr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost)
CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost)
: m_animateRequested(false)
, m_commitRequested(false)
+ , m_contextLost(false)
, m_layerTreeHost(layerTreeHost)
, m_compositorIdentifier(-1)
, m_layerRendererInitialized(false)
@@ -133,17 +134,17 @@ void CCThreadProxy::requestReadbackOnImplThread(ReadbackRequest* request)
m_schedulerOnImplThread->setNeedsForcedRedraw();
}
-void CCThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec)
+void CCThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
{
ASSERT(CCProxy::isMainThread());
- CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::requestStartPageScaleAnimationOnImplThread, targetPosition, useAnchor, scale, durationSec));
+ CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::requestStartPageScaleAnimationOnImplThread, targetPosition, useAnchor, scale, duration));
}
-void CCThreadProxy::requestStartPageScaleAnimationOnImplThread(IntSize targetPosition, bool useAnchor, float scale, double durationSec)
+void CCThreadProxy::requestStartPageScaleAnimationOnImplThread(IntSize targetPosition, bool useAnchor, float scale, double duration)
{
ASSERT(CCProxy::isImplThread());
if (m_layerTreeHostImpl)
- m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime() * 1000.0, durationSec * 1000.0);
+ m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime(), duration);
}
GraphicsContext3D* CCThreadProxy::context()
@@ -170,7 +171,7 @@ bool CCThreadProxy::isStarted() const
bool CCThreadProxy::initializeContext()
{
TRACE_EVENT("CCThreadProxy::initializeContext", this, 0);
- RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D();
+ RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
if (!context)
return false;
ASSERT(context->hasOneRef());
@@ -193,9 +194,9 @@ bool CCThreadProxy::initializeLayerRenderer()
bool initializeSucceeded = false;
LayerRendererCapabilities capabilities;
CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnImplThread,
- AllowCrossThreadAccess(&completion),
- AllowCrossThreadAccess(&initializeSucceeded),
- AllowCrossThreadAccess(&capabilities)));
+ AllowCrossThreadAccess(&completion),
+ AllowCrossThreadAccess(&initializeSucceeded),
+ AllowCrossThreadAccess(&capabilities)));
completion.wait();
if (initializeSucceeded) {
@@ -205,6 +206,39 @@ bool CCThreadProxy::initializeLayerRenderer()
return initializeSucceeded;
}
+bool CCThreadProxy::recreateContext()
+{
+ TRACE_EVENT0("cc", "CCThreadProxy::recreateContext");
+ ASSERT(isMainThread());
+
+ // Try to create the context.
+ RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
+ if (!context)
+ return false;
+ ASSERT(context->hasOneRef());
+
+ // Leak the context pointer so we can transfer ownership of it to the other side...
+ GraphicsContext3D* contextPtr = context.release().leakRef();
+ ASSERT(contextPtr->hasOneRef());
+
+ // Make a blocking call to recreateContextOnImplThread. The results of that
+ // call are pushed into the recreateSucceeded and capabilities local
+ // variables.
+ CCCompletionEvent completion;
+ bool recreateSucceeded = false;
+ LayerRendererCapabilities capabilities;
+ CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::recreateContextOnImplThread,
+ AllowCrossThreadAccess(&completion),
+ AllowCrossThreadAccess(contextPtr),
+ AllowCrossThreadAccess(&recreateSucceeded),
+ AllowCrossThreadAccess(&capabilities)));
+ completion.wait();
+
+ if (recreateSucceeded)
+ m_layerRendererCapabilitiesMainThreadCopy = capabilities;
+ return recreateSucceeded;
+}
+
int CCThreadProxy::compositorIdentifier() const
{
ASSERT(isMainThread());
@@ -217,9 +251,9 @@ const LayerRendererCapabilities& CCThreadProxy::layerRendererCapabilities() cons
return m_layerRendererCapabilitiesMainThreadCopy;
}
-void CCThreadProxy::loseCompositorContext(int numTimes)
+void CCThreadProxy::loseContext()
{
- ASSERT_NOT_REACHED();
+ CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::didLoseContextOnImplThread));
}
void CCThreadProxy::setNeedsAnimate()
@@ -244,6 +278,13 @@ void CCThreadProxy::setNeedsCommit()
CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnImplThread));
}
+void CCThreadProxy::didLoseContextOnImplThread()
+{
+ ASSERT(isImplThread());
+ TRACE_EVENT0("cc", "CCThreadProxy::didLoseContextOnImplThread");
+ m_schedulerOnImplThread->didLoseContext();
+}
+
void CCThreadProxy::onSwapBuffersCompleteOnImplThread()
{
ASSERT(isImplThread());
@@ -259,11 +300,11 @@ void CCThreadProxy::setNeedsCommitOnImplThread()
m_schedulerOnImplThread->setNeedsCommit();
}
-void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events)
+void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
{
ASSERT(isImplThread());
TRACE_EVENT("CCThreadProxy::postAnimationEventsToMainThreadOnImplThread", this, 0);
- m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnimationEvents, events));
+ m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnimationEvents, events, wallClockTime));
}
void CCThreadProxy::setNeedsRedraw()
@@ -511,6 +552,12 @@ void CCThreadProxy::scheduledActionCommit()
m_commitCompletionEventOnImplThread = 0;
}
+void CCThreadProxy::scheduledActionBeginContextRecreation()
+{
+ ASSERT(isImplThread());
+ m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginContextRecreation));
+}
+
void CCThreadProxy::scheduledActionDrawAndSwap()
{
TRACE_EVENT("CCThreadProxy::scheduledActionDrawAndSwap", this, 0);
@@ -519,26 +566,23 @@ void CCThreadProxy::scheduledActionDrawAndSwap()
return;
// FIXME: compute the frame display time more intelligently
- double frameDisplayTimeMs = monotonicallyIncreasingTime() * 1000.0;
+ double monotonicTime = monotonicallyIncreasingTime();
+ double wallClockTime = currentTime();
- m_inputHandlerOnImplThread->willDraw(frameDisplayTimeMs);
- m_layerTreeHostImpl->animate(frameDisplayTimeMs);
+ m_inputHandlerOnImplThread->willDraw(monotonicTime);
+ m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
m_layerTreeHostImpl->drawLayers();
// Check for a pending compositeAndReadback.
if (m_readbackRequestOnImplThread) {
- m_layerTreeHostImpl->readback(m_readbackRequestOnImplThread->pixels, m_readbackRequestOnImplThread->rect);
- m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isContextLost();
- m_readbackRequestOnImplThread->completion.signal();
- m_readbackRequestOnImplThread = 0;
+ m_layerTreeHostImpl->readback(m_readbackRequestOnImplThread->pixels, m_readbackRequestOnImplThread->rect);
+ m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isContextLost();
+ m_readbackRequestOnImplThread->completion.signal();
+ m_readbackRequestOnImplThread = 0;
}
m_layerTreeHostImpl->swapBuffers();
- // FIXME: handle case where m_layerTreeHostImpl->isContextLost.
- // FIXME: pass didSwapBuffersAbort if m_layerTreeHostImpl->isContextLost.
- ASSERT(!m_layerTreeHostImpl->isContextLost());
-
// Process any finish request
if (m_finishAllRenderingCompletionEventOnImplThread) {
m_layerTreeHostImpl->finishAllRendering();
@@ -569,12 +613,55 @@ void CCThreadProxy::didCompleteSwapBuffers()
m_layerTreeHost->didCompleteSwapBuffers();
}
-void CCThreadProxy::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> events)
+void CCThreadProxy::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
{
+ TRACE_EVENT0("cc", "CCThreadProxy::setAnimationEvents");
ASSERT(isMainThread());
if (!m_layerTreeHost)
return;
- m_layerTreeHost->setAnimationEvents(events);
+ m_layerTreeHost->setAnimationEvents(events, wallClockTime);
+}
+
+class CCThreadProxyContextRecreationTimer : public CCTimer, CCTimerClient {
+public:
+ static PassOwnPtr<CCThreadProxyContextRecreationTimer> create(CCThreadProxy* proxy) { return adoptPtr(new CCThreadProxyContextRecreationTimer(proxy)); }
+
+ virtual void onTimerFired()
+ {
+ m_proxy->tryToRecreateContext();
+ }
+
+ enum Recreation { RecreationTickRateMs = 30 };
+
+private:
+ explicit CCThreadProxyContextRecreationTimer(CCThreadProxy* proxy)
+ : CCTimer(CCProxy::mainThread(), this)
+ , m_proxy(proxy)
+ {
+ }
+
+ CCThreadProxy* m_proxy;
+};
+
+void CCThreadProxy::beginContextRecreation()
+{
+ TRACE_EVENT0("cc", "CCThreadProxy::beginContextRecreation");
+ ASSERT(isMainThread());
+ ASSERT(!m_contextRecreationTimer);
+ m_contextRecreationTimer = CCThreadProxyContextRecreationTimer::create(this);
+ m_layerTreeHost->didLoseContext();
+ m_contextRecreationTimer->startOneShot(CCThreadProxyContextRecreationTimer::RecreationTickRateMs);
+}
+
+void CCThreadProxy::tryToRecreateContext()
+{
+ ASSERT(isMainThread());
+ ASSERT(m_layerTreeHost);
+ CCLayerTreeHost::RecreateResult result = m_layerTreeHost->recreateContext();
+ if (result == CCLayerTreeHost::RecreateFailedButTryAgain)
+ m_contextRecreationTimer->startOneShot(CCThreadProxyContextRecreationTimer::RecreationTickRateMs);
+ else if (result == CCLayerTreeHost::RecreateSucceeded)
+ m_contextRecreationTimer.clear();
}
void CCThreadProxy::initializeImplOnImplThread(CCCompletionEvent* completion)
@@ -637,4 +724,17 @@ size_t CCThreadProxy::maxPartialTextureUpdates() const
return textureUpdatesPerFrame;
}
+void CCThreadProxy::recreateContextOnImplThread(CCCompletionEvent* completion, GraphicsContext3D* contextPtr, bool* recreateSucceeded, LayerRendererCapabilities* capabilities)
+{
+ TRACE_EVENT0("cc", "CCThreadProxy::recreateContextOnImplThread");
+ ASSERT(isImplThread());
+ m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
+ *recreateSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(adoptRef(contextPtr));
+ if (*recreateSucceeded) {
+ *capabilities = m_layerTreeHostImpl->layerRendererCapabilities();
+ m_schedulerOnImplThread->didRecreateContext();
+ }
+ completion->signal();
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h
index 330ef51ca..057691213 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h
@@ -31,6 +31,7 @@
#include "cc/CCProxy.h"
#include "cc/CCScheduler.h"
#include "cc/CCThread.h"
+#include "cc/CCTimer.h"
#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -41,6 +42,7 @@ class CCScheduler;
class CCScopedThreadProxy;
class CCTextureUpdater;
class CCThread;
+class CCThreadProxyContextRecreationTimer;
class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClient {
public:
@@ -50,15 +52,16 @@ public:
// CCProxy implementation
virtual bool compositeAndReadback(void *pixels, const IntRect&);
- virtual void startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec);
+ virtual void startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration);
virtual GraphicsContext3D* context();
virtual void finishAllRendering();
virtual bool isStarted() const;
virtual bool initializeContext();
virtual bool initializeLayerRenderer();
+ virtual bool recreateContext();
virtual int compositorIdentifier() const;
virtual const LayerRendererCapabilities& layerRendererCapabilities() const;
- virtual void loseCompositorContext(int numTimes);
+ virtual void loseContext();
virtual void setNeedsAnimate();
virtual void setNeedsCommit();
virtual void setNeedsRedraw();
@@ -68,10 +71,11 @@ public:
virtual size_t maxPartialTextureUpdates() const;
// CCLayerTreeHostImplClient implementation
+ virtual void didLoseContextOnImplThread();
virtual void onSwapBuffersCompleteOnImplThread();
virtual void setNeedsRedrawOnImplThread();
virtual void setNeedsCommitOnImplThread();
- virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>);
+ virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime);
// CCSchedulerClient implementation
virtual bool canDraw();
@@ -80,15 +84,19 @@ public:
virtual void scheduledActionDrawAndSwap();
virtual void scheduledActionUpdateMoreResources();
virtual void scheduledActionCommit();
+ virtual void scheduledActionBeginContextRecreation();
private:
explicit CCThreadProxy(CCLayerTreeHost*);
+ friend class CCThreadProxyContextRecreationTimer;
// Called on main thread
void beginFrameAndCommit(int sequenceNumber, double frameBeginTime, PassOwnPtr<CCScrollAndScaleSet>);
void didCommitAndDrawFrame();
void didCompleteSwapBuffers();
- void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>);
+ void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime);
+ void beginContextRecreation();
+ void tryToRecreateContext();
// Called on impl thread
struct ReadbackRequest {
@@ -109,10 +117,13 @@ private:
void setVisibleOnImplThread(CCCompletionEvent*, bool visible);
void layerTreeHostClosedOnImplThread(CCCompletionEvent*);
void setFullRootLayerDamageOnImplThread();
+ void recreateContextOnImplThread(CCCompletionEvent*, GraphicsContext3D*, bool* recreateSucceeded, LayerRendererCapabilities*);
// Accessed on main thread only.
bool m_animateRequested;
bool m_commitRequested;
+ bool m_contextLost;
+ OwnPtr<CCThreadProxyContextRecreationTimer> m_contextRecreationTimer;
CCLayerTreeHost* m_layerTreeHost;
int m_compositorIdentifier;
bool m_layerRendererInitialized;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp
index 47d0a708c..e8d2a6c45 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp
@@ -52,14 +52,10 @@ public:
Platform3DObject textureId() const { return m_textureId; }
void setTextureId(Platform3DObject textureId) { m_textureId = textureId; }
- const IntRect& opaqueRect() const { return m_opaqueRect; }
- void setOpaqueRect(const IntRect& opaqueRect) { m_opaqueRect = opaqueRect; }
-
private:
DrawableTile() : m_textureId(0) { }
Platform3DObject m_textureId;
- IntRect m_opaqueRect;
};
CCTiledLayerImpl::CCTiledLayerImpl(int id)
@@ -203,6 +199,14 @@ void CCTiledLayerImpl::pushTileProperties(int i, int j, Platform3DObject texture
tile->setOpaqueRect(opaqueRect);
}
+Region CCTiledLayerImpl::opaqueContentsRegion() const
+{
+ if (m_skipsDraw)
+ return Region();
+
+ return m_tiler->opaqueRegionInLayerRect(visibleLayerRect());
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h
index 7ad71599b..84fe47621 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h
@@ -37,9 +37,9 @@ class DrawableTile;
class CCTiledLayerImpl : public CCLayerImpl {
public:
- static PassRefPtr<CCTiledLayerImpl> create(int id)
+ static PassOwnPtr<CCTiledLayerImpl> create(int id)
{
- return adoptRef(new CCTiledLayerImpl(id));
+ return adoptPtr(new CCTiledLayerImpl(id));
}
virtual ~CCTiledLayerImpl();
@@ -56,6 +56,8 @@ public:
void setContentsSwizzled(bool contentsSwizzled) { m_contentsSwizzled = contentsSwizzled; }
bool contentsSwizzled() const { return m_contentsSwizzled; }
+ virtual Region opaqueContentsRegion() const;
+
typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexAlpha> Program;
// Shader program that swaps red and blue components of texture.
// Used when texture format does not match native color format.
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.cpp
new file mode 100644
index 000000000..decc00c8f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2012 Google 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. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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"
+
+#include "cc/CCTimingFunction.h"
+
+#include <wtf/OwnPtr.h>
+
+namespace {
+const double epsilon = 1e-6;
+} // namespace
+
+namespace WebCore {
+
+CCTimingFunction::CCTimingFunction()
+{
+}
+
+CCTimingFunction::~CCTimingFunction()
+{
+}
+
+double CCTimingFunction::duration() const
+{
+ return 1.0;
+}
+
+PassOwnPtr<CCCubicBezierTimingFunction> CCCubicBezierTimingFunction::create(double x1, double y1, double x2, double y2)
+{
+ return adoptPtr(new CCCubicBezierTimingFunction(x1, y1, x2, y2));
+}
+
+CCCubicBezierTimingFunction::CCCubicBezierTimingFunction(double x1, double y1, double x2, double y2)
+ : m_curve(x1, y1, x2, y2)
+{
+}
+
+CCCubicBezierTimingFunction::~CCCubicBezierTimingFunction()
+{
+}
+
+float CCCubicBezierTimingFunction::getValue(double x) const
+{
+ UnitBezier temp(m_curve);
+ return static_cast<float>(temp.solve(x, epsilon));
+}
+
+PassOwnPtr<CCAnimationCurve> CCCubicBezierTimingFunction::clone() const
+{
+ return adoptPtr(new CCCubicBezierTimingFunction(*this));
+}
+
+// These numbers come from http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag.
+PassOwnPtr<CCTimingFunction> CCEaseTimingFunction::create()
+{
+ return CCCubicBezierTimingFunction::create(0.25, 0.1, 0.25, 1);
+}
+
+PassOwnPtr<CCTimingFunction> CCEaseInTimingFunction::create()
+{
+ return CCCubicBezierTimingFunction::create(0.42, 0, 1.0, 1);
+}
+
+PassOwnPtr<CCTimingFunction> CCEaseOutTimingFunction::create()
+{
+ return CCCubicBezierTimingFunction::create(0, 0, 0.58, 1);
+}
+
+PassOwnPtr<CCTimingFunction> CCEaseInOutTimingFunction::create()
+{
+ return CCCubicBezierTimingFunction::create(0.42, 0, 0.58, 1);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.h b/Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.h
new file mode 100644
index 000000000..77e5c43c5
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCTimingFunction.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012 Google 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. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 CCTimingFunction_h
+#define CCTimingFunction_h
+
+#include "UnitBezier.h"
+#include "cc/CCAnimationCurve.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+// See http://www.w3.org/TR/css3-transitions/.
+class CCTimingFunction : public CCFloatAnimationCurve {
+public:
+ virtual ~CCTimingFunction();
+
+ // Partial implementation of CCFloatAnimationCurve.
+ virtual double duration() const;
+
+protected:
+ CCTimingFunction();
+};
+
+class CCCubicBezierTimingFunction : public CCTimingFunction {
+public:
+ static PassOwnPtr<CCCubicBezierTimingFunction> create(double x1, double y1, double x2, double y2);
+ virtual ~CCCubicBezierTimingFunction();
+
+ // Partial implementation of CCFloatAnimationCurve.
+ virtual float getValue(double time) const;
+ virtual PassOwnPtr<CCAnimationCurve> clone() const;
+
+protected:
+ CCCubicBezierTimingFunction(double x1, double y1, double x2, double y2);
+
+ UnitBezier m_curve;
+};
+
+class CCEaseTimingFunction {
+public:
+ static PassOwnPtr<CCTimingFunction> create();
+};
+
+class CCEaseInTimingFunction {
+public:
+ static PassOwnPtr<CCTimingFunction> create();
+};
+
+class CCEaseOutTimingFunction {
+public:
+ static PassOwnPtr<CCTimingFunction> create();
+};
+
+class CCEaseInOutTimingFunction {
+public:
+ static PassOwnPtr<CCTimingFunction> create();
+};
+
+} // namespace WebCore
+
+#endif // CCTimingFunction_h
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
index 35f269f50..fd53e41d3 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
@@ -34,6 +34,7 @@
#include "LayerRendererChromium.h"
#include "NotImplemented.h"
#include "ProgramBinding.h"
+#include "cc/CCLayerTreeHostImpl.h"
#include "cc/CCProxy.h"
#include "cc/CCVideoDrawQuad.h"
#include <wtf/text/WTFString.h>
@@ -89,7 +90,6 @@ CCVideoLayerImpl::~CCVideoLayerImpl()
}
for (unsigned i = 0; i < MaxPlanes; ++i)
m_textures[i].m_texture.clear();
- cleanupResources();
}
void CCVideoLayerImpl::stopUsingProvider()
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
index caa72dfb9..4c4e23102 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
@@ -43,9 +43,9 @@ template<class VertexShader, class FragmentShader> class ProgramBinding;
class CCVideoLayerImpl : public CCLayerImpl
, public VideoFrameProvider::Client {
public:
- static PassRefPtr<CCVideoLayerImpl> create(int id, VideoFrameProvider* provider)
+ static PassOwnPtr<CCVideoLayerImpl> create(int id, VideoFrameProvider* provider)
{
- return adoptRef(new CCVideoLayerImpl(id, provider));
+ return adoptPtr(new CCVideoLayerImpl(id, provider));
}
virtual ~CCVideoLayerImpl();