summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/android/RenderThemeAndroid.cpp50
-rw-r--r--WebCore/platform/graphics/android/AndroidAnimation.cpp187
-rw-r--r--WebCore/platform/graphics/android/AndroidAnimation.h27
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp7
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp26
-rw-r--r--WebCore/platform/graphics/android/ImageSourceAndroid.cpp2
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp38
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h7
-rw-r--r--WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h10
-rw-r--r--WebCore/platform/graphics/android/VideoLayerAndroid.cpp134
-rw-r--r--WebCore/platform/graphics/android/VideoLayerAndroid.h74
11 files changed, 421 insertions, 141 deletions
diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp
index 66f034d..5253219 100644
--- a/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -248,7 +248,7 @@ bool RenderThemeAndroid::shouldRenderMediaControlPart(ControlPart part, Element*
return false;
case MediaSeekBackButtonPart:
case MediaSeekForwardButtonPart:
- return true;
+ return false;
case MediaRewindButtonPart:
return mediaElement->movieLoadType() != MediaPlayer::LiveStream;
case MediaReturnToRealtimeButtonPart:
@@ -262,19 +262,34 @@ bool RenderThemeAndroid::shouldRenderMediaControlPart(ControlPart part, Element*
}
}
+bool paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PLAY, translucent);
+ return false;
+}
+
bool RenderThemeAndroid::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::MUTE);
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::MUTE, translucent);
return false;
}
bool RenderThemeAndroid::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
if (MediaControlPlayButtonElement* btn = static_cast<MediaControlPlayButtonElement*>(o->node())) {
if (btn->displayType() == MediaPlayButton)
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PLAY);
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PLAY, translucent);
else
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PAUSE);
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PAUSE, translucent);
return false;
}
return true;
@@ -282,31 +297,46 @@ bool RenderThemeAndroid::paintMediaPlayButton(RenderObject* o, const PaintInfo&
bool RenderThemeAndroid::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::REWIND);
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::REWIND, translucent);
return false;
}
bool RenderThemeAndroid::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::FORWARD);
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::FORWARD, translucent);
return false;
}
-bool RenderThemeAndroid::paintMediaControlsBackground(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+bool RenderThemeAndroid::paintMediaControlsBackground(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::BACKGROUND_SLIDER);
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::BACKGROUND_SLIDER, translucent);
return false;
}
bool RenderThemeAndroid::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::SLIDER_TRACK);
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::SLIDER_TRACK, translucent);
return false;
}
bool RenderThemeAndroid::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::SLIDER_THUMB);
+ bool translucent = false;
+ if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
+ translucent = true;
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::SLIDER_THUMB, translucent);
return false;
}
diff --git a/WebCore/platform/graphics/android/AndroidAnimation.cpp b/WebCore/platform/graphics/android/AndroidAnimation.cpp
index 3280d07..a064d05 100644
--- a/WebCore/platform/graphics/android/AndroidAnimation.cpp
+++ b/WebCore/platform/graphics/android/AndroidAnimation.cpp
@@ -54,17 +54,17 @@ long AndroidAnimation::instancesCount()
return gDebugAndroidAnimationInstances;
}
-AndroidAnimation::AndroidAnimation(AndroidAnimationType type,
+AndroidAnimation::AndroidAnimation(AnimatedPropertyID type,
const Animation* animation,
+ KeyframeValueList* operations,
double beginTime)
: m_beginTime(beginTime)
, m_duration(animation->duration())
, m_iterationCount(animation->iterationCount())
- , m_currentIteration(0)
, m_direction(animation->direction())
- , m_currentDirection(false)
, m_timingFunction(animation->timingFunction())
, m_type(type)
+ , m_operations(operations)
{
ASSERT(m_timingFunction);
@@ -78,11 +78,10 @@ AndroidAnimation::AndroidAnimation(AndroidAnimation* anim)
: m_beginTime(anim->m_beginTime)
, m_duration(anim->m_duration)
, m_iterationCount(anim->m_iterationCount)
- , m_currentIteration(0)
, m_direction(anim->m_direction)
- , m_currentDirection(false)
, m_timingFunction(anim->m_timingFunction)
, m_type(anim->m_type)
+ , m_operations(anim->m_operations)
{
gDebugAndroidAnimationInstances++;
}
@@ -92,7 +91,7 @@ AndroidAnimation::~AndroidAnimation()
gDebugAndroidAnimationInstances--;
}
-float AndroidAnimation::currentProgress(double time)
+double AndroidAnimation::elapsedTime(double time)
{
if (m_beginTime <= 0.000001) // overflow or not correctly set
m_beginTime = time;
@@ -105,37 +104,69 @@ float AndroidAnimation::currentProgress(double time)
if (m_elapsedTime < 0) // animation not yet started.
return 0;
- return m_elapsedTime / m_duration;
+ return m_elapsedTime;
}
bool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgress)
{
- float progress = currentProgress(time);
+ double progress = elapsedTime(time);
+ double dur = m_duration;
+ if (m_iterationCount > 0)
+ dur *= m_iterationCount;
- int currentIteration = static_cast<int>(progress);
- if (currentIteration != m_currentIteration)
- if (m_direction == Animation::AnimationDirectionAlternate)
- swapDirection();
-
- m_currentIteration = currentIteration;
- progress -= m_currentIteration;
+ if (m_duration <= 0)
+ return false;
- if ((m_currentIteration >= m_iterationCount)
- && (m_iterationCount != Animation::IterationCountInfinite))
+ // If not infinite, return false if we are done
+ if (m_iterationCount > 0 && progress > dur)
return false;
- if (m_timingFunction->isCubicBezierTimingFunction()) {
- CubicBezierTimingFunction* bezierFunction = static_cast<CubicBezierTimingFunction*>(m_timingFunction.get());
+ double fractionalTime = progress / m_duration;
+ int integralTime = static_cast<int>(fractionalTime);
+
+ fractionalTime -= integralTime;
+
+ if ((m_direction == Animation::AnimationDirectionAlternate) && (integralTime & 1))
+ fractionalTime = 1 - fractionalTime;
+
+ *finalProgress = fractionalTime;
+ return true;
+}
+
+double AndroidAnimation::applyTimingFunction(float from, float to, double progress,
+ const TimingFunction* tf)
+{
+ double fractionalTime = progress;
+ double offset = from;
+ double scale = 1.0 / (to - from);
+
+ if (scale != 1 || offset)
+ fractionalTime = (fractionalTime - offset) * scale;
+
+ const TimingFunction* timingFunction = tf;
+
+ if (!timingFunction)
+ timingFunction = m_timingFunction.get();
+
+ if (timingFunction && timingFunction->isCubicBezierTimingFunction()) {
+ const CubicBezierTimingFunction* bezierFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
UnitBezier bezier(bezierFunction->x1(),
bezierFunction->y1(),
bezierFunction->x2(),
bezierFunction->y2());
if (m_duration > 0)
- progress = bezier.solve(progress, 1.0f / (200.0f * m_duration));
+ fractionalTime = bezier.solve(fractionalTime, 1.0f / (200.0f * m_duration));
+ } else if (timingFunction && timingFunction->isStepsTimingFunction()) {
+ const StepsTimingFunction* stepFunction = static_cast<const StepsTimingFunction*>(timingFunction);
+ if (stepFunction->stepAtStart()) {
+ fractionalTime = (floor(stepFunction->numberOfSteps() * fractionalTime) + 1) / stepFunction->numberOfSteps();
+ if (fractionalTime > 1.0)
+ fractionalTime = 1.0;
+ } else {
+ fractionalTime = floor(stepFunction->numberOfSteps() * fractionalTime) / stepFunction->numberOfSteps();
+ }
}
-
- *finalProgress = progress;
- return true;
+ return fractionalTime;
}
PassRefPtr<AndroidOpacityAnimation> AndroidOpacityAnimation::create(
@@ -150,14 +181,12 @@ PassRefPtr<AndroidOpacityAnimation> AndroidOpacityAnimation::create(
AndroidOpacityAnimation::AndroidOpacityAnimation(const Animation* animation,
KeyframeValueList* operations,
double beginTime)
- : AndroidAnimation(AndroidAnimation::OPACITY, animation, beginTime)
- , m_operations(operations)
+ : AndroidAnimation(AnimatedPropertyOpacity, animation, operations, beginTime)
{
}
AndroidOpacityAnimation::AndroidOpacityAnimation(AndroidOpacityAnimation* anim)
: AndroidAnimation(anim)
- , m_operations(anim->m_operations)
{
}
@@ -166,41 +195,45 @@ PassRefPtr<AndroidAnimation> AndroidOpacityAnimation::copy()
return adoptRef(new AndroidOpacityAnimation(this));
}
-bool AndroidOpacityAnimation::evaluate(LayerAndroid* layer, double time)
+void AndroidAnimation::pickValues(double progress, int* start, int* end)
{
- float progress;
- if (!checkIterationsAndProgress(time, &progress))
- return false;
-
- if (progress < 0) // we still want to be evaluated until we get progress > 0
- return true;
-
- // First, we need to get the from and to values
-
- FloatAnimationValue* fromValue = 0;
- FloatAnimationValue* toValue = 0;
-
- float distance = 0;
+ float distance = -1;
unsigned int foundAt = 0;
for (unsigned int i = 0; i < m_operations->size(); i++) {
- FloatAnimationValue* value = (FloatAnimationValue*) m_operations->at(i);
- float opacity = (float) value->value();
+ const AnimationValue* value = m_operations->at(i);
float key = value->keyTime();
float d = progress - key;
- XLOG("[%d] Key %.2f, opacity %.4f", i, key, opacity);
- if (!fromValue || (d > 0 && d < distance && i + 1 < m_operations->size())) {
- fromValue = value;
+ if (distance == -1 || (d >= 0 && d < distance && i + 1 < m_operations->size())) {
distance = d;
foundAt = i;
}
}
+ *start = foundAt;
+
if (foundAt + 1 < m_operations->size())
- toValue = (FloatAnimationValue*) m_operations->at(foundAt + 1);
+ *end = foundAt + 1;
else
- toValue = fromValue;
+ *end = foundAt;
+}
- XLOG("[layer %d] fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
+bool AndroidOpacityAnimation::evaluate(LayerAndroid* layer, double time)
+{
+ float progress;
+ if (!checkIterationsAndProgress(time, &progress))
+ return false;
+
+ if (progress < 0) // we still want to be evaluated until we get progress > 0
+ return true;
+
+ // First, we need to get the from and to values
+
+ int from, to;
+ pickValues(progress, &from, &to);
+ FloatAnimationValue* fromValue = (FloatAnimationValue*) m_operations->at(from);
+ FloatAnimationValue* toValue = (FloatAnimationValue*) m_operations->at(to);
+
+ XLOG("[layer %d] opacity fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
layer->uniqueId(),
fromValue, fromValue->keyTime(),
toValue, toValue->keyTime(), progress);
@@ -208,18 +241,14 @@ bool AndroidOpacityAnimation::evaluate(LayerAndroid* layer, double time)
// We now have the correct two values to work with, let's compute the
// progress value
- float delta = toValue->keyTime() - fromValue->keyTime();
- float rprogress = (progress - fromValue->keyTime()) / delta;
- XLOG("We picked keys %.2f to %.2f for progress %.2f, real progress %.2f",
- fromValue->keyTime(), toValue->keyTime(), progress, rprogress);
- progress = rprogress;
-
- float from = (float) fromValue->value();
- float to = (float) toValue->value();
- float value = from + ((to - from) * progress);
+ const TimingFunction* timingFunction = fromValue->timingFunction();
+ progress = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(),
+ progress, timingFunction);
+ float value = fromValue->value() + ((toValue->value() - fromValue->value()) * progress);
layer->setOpacity(value);
- XLOG("AndroidOpacityAnimation::evaluate(%p, %p, %L) value=%.6f", this, layer, time, value);
+
+ XLOG("AndroidOpacityAnimation::evaluate(%p, %p, %.2f) value=%.6f", this, layer, time, value);
return true;
}
@@ -234,14 +263,12 @@ PassRefPtr<AndroidTransformAnimation> AndroidTransformAnimation::create(
AndroidTransformAnimation::AndroidTransformAnimation(const Animation* animation,
KeyframeValueList* operations,
double beginTime)
- : AndroidAnimation(AndroidAnimation::TRANSFORM, animation, beginTime)
- , m_operations(operations)
+ : AndroidAnimation(AnimatedPropertyWebkitTransform, animation, operations, beginTime)
{
}
AndroidTransformAnimation::AndroidTransformAnimation(AndroidTransformAnimation* anim)
: AndroidAnimation(anim)
- , m_operations(anim->m_operations)
{
}
@@ -269,28 +296,10 @@ bool AndroidTransformAnimation::evaluate(LayerAndroid* layer, double time)
// First, we need to get the from and to values
- TransformAnimationValue* fromValue = 0;
- TransformAnimationValue* toValue = 0;
-
- float distance = 0;
- unsigned int foundAt = 0;
- for (unsigned int i = 0; i < m_operations->size(); i++) {
- TransformAnimationValue* value = (TransformAnimationValue*) m_operations->at(i);
- TransformOperations* values = (TransformOperations*) value->value();
- float key = value->keyTime();
- float d = progress - key;
- XLOG("[%d] Key %.2f, %d values", i, key, values->size());
- if (!fromValue || (d > 0 && d < distance && i + 1 < m_operations->size())) {
- fromValue = value;
- distance = d;
- foundAt = i;
- }
- }
-
- if (foundAt + 1 < m_operations->size())
- toValue = (TransformAnimationValue*) m_operations->at(foundAt + 1);
- else
- toValue = fromValue;
+ int from, to;
+ pickValues(progress, &from, &to);
+ TransformAnimationValue* fromValue = (TransformAnimationValue*) m_operations->at(from);
+ TransformAnimationValue* toValue = (TransformAnimationValue*) m_operations->at(to);
XLOG("[layer %d] fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
layer->uniqueId(),
@@ -300,12 +309,12 @@ bool AndroidTransformAnimation::evaluate(LayerAndroid* layer, double time)
// We now have the correct two values to work with, let's compute the
// progress value
- float delta = toValue->keyTime() - fromValue->keyTime();
- float rprogress = (progress - fromValue->keyTime()) / delta;
- XLOG("We picked keys %.2f to %.2f for progress %.2f, real progress %.2f",
- fromValue->keyTime(), toValue->keyTime(), progress, rprogress);
- progress = rprogress;
-
+ const TimingFunction* timingFunction = fromValue->timingFunction();
+ float p = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(),
+ progress, timingFunction);
+ XLOG("progress %.2f => %.2f from: %.2f to: %.2f", progress, p, fromValue->keyTime(),
+ toValue->keyTime());
+ progress = p;
// With both values and the progress, we also need to check out that
// the operations are compatible (i.e. we are animating the same number
diff --git a/WebCore/platform/graphics/android/AndroidAnimation.h b/WebCore/platform/graphics/android/AndroidAnimation.h
index d682103..4f84799 100644
--- a/WebCore/platform/graphics/android/AndroidAnimation.h
+++ b/WebCore/platform/graphics/android/AndroidAnimation.h
@@ -35,38 +35,35 @@ class TimingFunction;
class AndroidAnimation : public RefCounted<AndroidAnimation> {
public:
- enum AndroidAnimationType {
- UNDEFINED,
- OPACITY,
- TRANSFORM
- };
- AndroidAnimation(AndroidAnimationType type,
+ AndroidAnimation(AnimatedPropertyID type,
const Animation* animation,
+ KeyframeValueList* operations,
double beginTime);
AndroidAnimation(AndroidAnimation* anim);
virtual ~AndroidAnimation();
virtual PassRefPtr<AndroidAnimation> copy() = 0;
- float currentProgress(double time);
+ double elapsedTime(double time);
+ void pickValues(double progress, int* start, int* end);
bool checkIterationsAndProgress(double time, float* finalProgress);
- virtual void swapDirection() { m_currentDirection = !m_currentDirection; }
+ double applyTimingFunction(float from, float to, double progress,
+ const TimingFunction* timingFunction);
virtual bool evaluate(LayerAndroid* layer, double time) = 0;
static long instancesCount();
void setName(const String& name) { m_name = name; }
String name() { return m_name; }
- AndroidAnimationType type() { return m_type; }
+ AnimatedPropertyID type() { return m_type; }
protected:
double m_beginTime;
double m_elapsedTime;
double m_duration;
int m_iterationCount;
- int m_currentIteration;
int m_direction;
- bool m_currentDirection;
RefPtr<TimingFunction> m_timingFunction;
String m_name;
- AndroidAnimationType m_type;
+ AnimatedPropertyID m_type;
+ KeyframeValueList* m_operations;
};
class AndroidOpacityAnimation : public AndroidAnimation {
@@ -81,9 +78,6 @@ class AndroidOpacityAnimation : public AndroidAnimation {
virtual PassRefPtr<AndroidAnimation> copy();
virtual bool evaluate(LayerAndroid* layer, double time);
-
- private:
- KeyframeValueList* m_operations;
};
class AndroidTransformAnimation : public AndroidAnimation {
@@ -100,9 +94,6 @@ class AndroidTransformAnimation : public AndroidAnimation {
virtual PassRefPtr<AndroidAnimation> copy();
virtual bool evaluate(LayerAndroid* layer, double time);
-
- private:
- KeyframeValueList* m_operations;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index 47be13b..4400ea5 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -381,6 +381,9 @@ void BaseTile::paintBitmap()
if (!m_currentDirtyArea->isEmpty())
m_dirty = true;
+ if (!m_dirty)
+ m_usable = true;
+
m_painting = false;
m_atomicSync.unlock();
@@ -398,6 +401,10 @@ int BaseTile::paintPartialBitmap(SkIRect r, float ptx, float pty,
fullRepaint = true;
}
+ if ((rect.width() > TilesManager::instance()->tileWidth()) ||
+ (rect.height() > TilesManager::instance()->tileHeight()))
+ fullRepaint = true;
+
if (fullRepaint) {
rect.set(0, 0, TilesManager::instance()->tileWidth(),
TilesManager::instance()->tileHeight());
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 54346e5..72aefa4 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -609,7 +609,7 @@ bool GraphicsLayerAndroid::repaint()
}
}
- TLOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
+ LOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
this, m_size.width(), m_size.height(),
m_contentLayer->getPosition().fX,
m_contentLayer->getPosition().fY,
@@ -722,23 +722,22 @@ bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList&
bool isKeyframe = valueList.size() > 2;
TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
isKeyframe, keyframesName.latin1().data(), beginTime);
- // TODO: handles keyframe animations correctly
switch (valueList.property()) {
case AnimatedPropertyInvalid: break;
case AnimatedPropertyWebkitTransform: break;
case AnimatedPropertyBackgroundColor: break;
-
case AnimatedPropertyOpacity: {
MLOG("ANIMATEDPROPERTYOPACITY");
KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyOpacity);
for (unsigned int i = 0; i < valueList.size(); i++) {
- FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i);
- FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(),
- originalValue->value(), 0);
- // TODO: pass the timing function originalValue->timingFunction());
- operationsList->insert(value);
+ FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i);
+ PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
+ FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(),
+ originalValue->value(),
+ timingFunction);
+ operationsList->insert(value);
}
RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(animation,
@@ -776,9 +775,10 @@ bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const Keyframe
KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyWebkitTransform);
for (unsigned int i = 0; i < valueList.size(); i++) {
TransformAnimationValue* originalValue = (TransformAnimationValue*)valueList.at(i);
+ PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
TransformAnimationValue* value = new TransformAnimationValue(originalValue->keyTime(),
- originalValue->value(), 0);
- // TODO: pass the timing function originalValue->timingFunction());
+ originalValue->value(),
+ timingFunction);
operationsList->insert(value);
}
@@ -801,14 +801,14 @@ bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const Keyframe
void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID)
{
TLOG("NRO removeAnimationsForProperty(%d)", anID);
- m_contentLayer->removeAnimation(propertyIdToString(anID));
+ m_contentLayer->removeAnimationsForProperty(anID);
askForSync();
}
void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName)
{
TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data());
- m_contentLayer->removeAnimation(keyframesName);
+ m_contentLayer->removeAnimationsForKeyframes(keyframesName);
askForSync();
}
@@ -852,9 +852,9 @@ void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer)
mediaLayer->setSize(m_contentLayer->getWidth(), m_contentLayer->getHeight());
mediaLayer->setDrawTransform(m_contentLayer->drawTransform());
+ mediaLayer->ref();
m_contentLayer->unref();
m_contentLayer = mediaLayer;
- m_contentLayer->ref();
// If the parent exists then notify it to re-sync it's children
if (m_parent) {
diff --git a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
index 728ea35..f7fc80c 100644
--- a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
+++ b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
@@ -59,7 +59,7 @@ SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src);
#define MIN_RLE_ALLOC_SIZE (8*1024*1024)
// see dox for computeMaxBitmapSizeForCache()
- #define MAX_SIZE_BEFORE_SUBSAMPLE (8*1024*1024)
+ #define MAX_SIZE_BEFORE_SUBSAMPLE (32*1024*1024)
// preserve quality for 24/32bit src
static const SkBitmap::Config gPrefConfigTable[6] = {
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 7d68f03..76fb2f2 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -132,8 +132,10 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
addChild(layer.getChild(i)->copy())->unref();
KeyframesMap::const_iterator end = layer.m_animations.end();
- for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it)
- m_animations.add((it->second)->name(), (it->second)->copy());
+ for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) {
+ pair<String, int> key((it->second)->name(), (it->second)->type());
+ m_animations.add(key, (it->second)->copy());
+ }
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("LayerAndroid");
@@ -243,15 +245,35 @@ bool LayerAndroid::evaluateAnimations(double time) const
void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim)
{
RefPtr<AndroidAnimation> anim = prpAnim;
- RefPtr<AndroidAnimation> currentAnim = m_animations.get(anim->name());
- if (currentAnim && currentAnim->type() == anim->type())
- removeAnimation(anim->name());
- m_animations.add(anim->name(), anim);
+ pair<String, int> key(anim->name(), anim->type());
+ removeAnimationsForProperty(anim->type());
+ m_animations.add(key, anim);
+}
+
+void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property)
+{
+ KeyframesMap::const_iterator end = m_animations.end();
+ Vector<pair<String, int> > toDelete;
+ for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
+ if ((it->second)->type() == property)
+ toDelete.append(it->first);
+ }
+
+ for (unsigned int i = 0; i < toDelete.size(); i++)
+ m_animations.remove(toDelete[i]);
}
-void LayerAndroid::removeAnimation(const String& name)
+void LayerAndroid::removeAnimationsForKeyframes(const String& name)
{
- m_animations.remove(name);
+ KeyframesMap::const_iterator end = m_animations.end();
+ Vector<pair<String, int> > toDelete;
+ for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
+ if ((it->second)->name() == name)
+ toDelete.append(it->first);
+ }
+
+ for (unsigned int i = 0; i < toDelete.size(); i++)
+ m_animations.remove(toDelete[i]);
}
// We only use the bounding rect of the layer as mask...
diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h
index 42356e9..3e00bfa 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/WebCore/platform/graphics/android/LayerAndroid.h
@@ -22,6 +22,7 @@
#include "FloatPoint.h"
#include "FloatPoint3D.h"
#include "FloatRect.h"
+#include "GraphicsLayerClient.h"
#include "LayerTexture.h"
#include "RefPtr.h"
#include "SkColor.h"
@@ -179,7 +180,8 @@ public:
SkPicture* recordContext();
void addAnimation(PassRefPtr<AndroidAnimation> anim);
- void removeAnimation(const String& name);
+ void removeAnimationsForProperty(AnimatedPropertyID property);
+ void removeAnimationsForKeyframes(const String& name);
bool evaluateAnimations() const;
bool evaluateAnimations(double time) const;
bool hasAnimations() const;
@@ -242,6 +244,7 @@ public:
void contentDraw(SkCanvas*);
virtual bool isMedia() const { return false; }
+ virtual bool isVideo() const { return false; }
RenderLayer* owningLayer() const { return m_owningLayer; }
@@ -301,7 +304,7 @@ private:
SkBitmapRef* m_contentsImage;
- typedef HashMap<String, RefPtr<AndroidAnimation> > KeyframesMap;
+ typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
KeyframesMap m_animations;
SkPicture* m_extra;
int m_uniqueId;
diff --git a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
index e8e29bf..66b35dd 100644
--- a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
+++ b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
@@ -32,6 +32,7 @@ class SkBitmap;
#include "MediaPlayerPrivate.h"
#include "TimeRanges.h"
+#include "VideoLayerAndroid.h"
namespace WebCore {
@@ -93,6 +94,14 @@ public:
virtual void onPosterFetched(SkBitmap*) { }
void onBuffering(int percent);
void onTimeupdate(int position);
+
+ // These following two functions are used to turn on inline video support
+ bool supportsAcceleratedRendering() const { return true; }
+ LayerAndroid* platformLayer() const
+ {
+ return m_videoLayer;
+ }
+
protected:
// Android-specific methods and fields.
static MediaPlayerPrivateInterface* create(MediaPlayer* player);
@@ -122,6 +131,7 @@ protected:
bool m_naturalSizeUnknown;
bool m_isVisible;
+ VideoLayerAndroid* m_videoLayer;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
new file mode 100644
index 0000000..2eced57
--- /dev/null
+++ b/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "VideoLayerAndroid.h"
+
+#include "TilesManager.h"
+#include <GLES2/gl2.h>
+#include <gui/SurfaceTexture.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#ifdef DEBUG
+#include <cutils/log.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerAndroid", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+GLuint VideoLayerAndroid::m_pauseTextureId = 0;
+bool VideoLayerAndroid::m_createdPauseTexture = false;
+
+VideoLayerAndroid::VideoLayerAndroid()
+ : LayerAndroid((RenderLayer*)0)
+{
+ init();
+}
+
+VideoLayerAndroid::VideoLayerAndroid(const VideoLayerAndroid& layer)
+ : LayerAndroid(layer)
+{
+ init();
+}
+
+void VideoLayerAndroid::init()
+{
+ // m_surfaceTexture is only useful on UI thread, no need to copy.
+ // And it will be set at setBaseLayer timeframe
+
+ // m_useSurfTex will be true only after the player is prepared
+ m_useSurfTex = false;
+ m_textureId = 0;
+}
+
+// We can use this function to set the Layer to point to surface texture.
+void VideoLayerAndroid::setSurfaceTexture(sp<SurfaceTexture> texture,
+ int textureName, bool useSurfTex)
+{
+ m_surfaceTexture = texture;
+ m_textureId = textureName;
+ m_useSurfTex = useSurfTex;
+}
+
+GLuint VideoLayerAndroid::createPauseTexture()
+{
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ GLubyte pixels[4 *3] = {
+ 128, 128, 128,
+ 128, 128, 128,
+ 128, 128, 128,
+ 128, 128, 128
+ };
+ glBindTexture(GL_TEXTURE_2D, texture);
+ GLUtils::checkGlError("glBindTexture");
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+ GLUtils::checkGlError("glTexImage2D");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ return texture;
+}
+
+bool VideoLayerAndroid::drawGL(SkMatrix& matrix)
+{
+ // Lazy allocated the paused texture.
+ if (!m_createdPauseTexture) {
+ m_pauseTextureId = createPauseTexture();
+ m_createdPauseTexture = true;
+ }
+
+ SkRect rect = SkRect::MakeSize(getSize());
+ GLfloat surfaceMatrix[16];
+
+ // Draw the paused image or the Video
+ if (!m_surfaceTexture.get() || !m_useSurfTex) {
+ TransformationMatrix identity;
+ GLUtils::toGLMatrix(surfaceMatrix, identity);
+ TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect,
+ m_pauseTextureId,
+ 0.5, true);
+ } else {
+ m_surfaceTexture->updateTexImage();
+ m_surfaceTexture->getTransformMatrix(surfaceMatrix);
+ TilesManager::instance()->shader()->drawVideoLayerQuad(drawTransform(),
+ surfaceMatrix,
+ rect, m_textureId);
+ }
+
+ return drawChildrenGL(matrix);
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.h b/WebCore/platform/graphics/android/VideoLayerAndroid.h
new file mode 100644
index 0000000..c2a962e
--- /dev/null
+++ b/WebCore/platform/graphics/android/VideoLayerAndroid.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VideoLayerAndroid_h
+#define VideoLayerAndroid_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GLUtils.h"
+#include "LayerAndroid.h"
+#include <jni.h>
+
+namespace android {
+class SurfaceTexture;
+}
+
+namespace WebCore {
+
+class VideoLayerAndroid : public LayerAndroid {
+
+public:
+ VideoLayerAndroid();
+ explicit VideoLayerAndroid(const VideoLayerAndroid& layer);
+
+ virtual bool isVideo() const { return true; }
+ virtual LayerAndroid* copy() const { return new VideoLayerAndroid(*this); }
+
+ // The following 3 functions are called in UI thread only.
+ virtual bool drawGL(SkMatrix& matrix);
+ void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, bool updateTexture);
+ GLuint createPauseTexture();
+
+private:
+ void init();
+ // Surface texture for showing the video is actually allocated in Java side
+ // and passed into this native code.
+ GLuint m_textureId;
+ sp<android::SurfaceTexture> m_surfaceTexture;
+ bool m_useSurfTex;
+
+ // Texture for showing the paused image will be created at native side.
+ // TODO: instead using a shared texture, we could make a texture pool to
+ // show different screen shots for different videos
+ static GLuint m_pauseTextureId;
+ static bool m_createdPauseTexture;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // VideoLayerAndroid_h