summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2011-12-13 13:24:27 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-12-13 13:24:27 -0800
commit1377f4a8f71311042eb17f1f35e73fa9d6f05376 (patch)
treebe1a880ac314cde0df6527fd8f1ca0871fe8f8a7 /Source/WebCore/platform
parenta73147edbc9b8ff7fa1c8d464de999b552463de8 (diff)
parentd649883ce629c0de432e075254b517a50685792e (diff)
downloadexternal_webkit-1377f4a8f71311042eb17f1f35e73fa9d6f05376.zip
external_webkit-1377f4a8f71311042eb17f1f35e73fa9d6f05376.tar.gz
external_webkit-1377f4a8f71311042eb17f1f35e73fa9d6f05376.tar.bz2
Merge "Tap to play/pause for html5 video with UI"
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/android/RenderThemeAndroid.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp132
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.h7
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerManager.cpp36
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerManager.h15
5 files changed, 147 insertions, 51 deletions
diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.cpp b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
index 93c99a4..843068a 100644
--- a/Source/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -336,7 +336,9 @@ bool RenderThemeAndroid::paintMediaControlsBackground(RenderObject* o, const Pai
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::BACKGROUND_SLIDER, translucent);
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
+ RenderSkinMediaButton::BACKGROUND_SLIDER,
+ translucent, 0, false);
return false;
}
@@ -355,7 +357,9 @@ bool RenderThemeAndroid::paintMediaSliderThumb(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::SLIDER_THUMB, translucent);
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
+ RenderSkinMediaButton::SLIDER_THUMB,
+ translucent, 0, false);
return false;
}
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
index 482d711..3ec28e2 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
@@ -53,6 +53,8 @@ GLuint VideoLayerAndroid::m_spinnerOuterTextureId = 0;
GLuint VideoLayerAndroid::m_spinnerInnerTextureId = 0;
GLuint VideoLayerAndroid::m_posterTextureId = 0;
GLuint VideoLayerAndroid::m_backgroundTextureId = 0;
+GLuint VideoLayerAndroid::m_playTextureId = 0;
+GLuint VideoLayerAndroid::m_pauseTextureId = 0;
bool VideoLayerAndroid::m_createdTexture = false;
double VideoLayerAndroid::m_rotateDegree = 0;
@@ -102,6 +104,16 @@ GLuint VideoLayerAndroid::createPosterTexture()
return createTextureFromImage(RenderSkinMediaButton::VIDEO);
}
+GLuint VideoLayerAndroid::createPlayTexture()
+{
+ return createTextureFromImage(RenderSkinMediaButton::PLAY);
+}
+
+GLuint VideoLayerAndroid::createPauseTexture()
+{
+ return createTextureFromImage(RenderSkinMediaButton::PAUSE);
+}
+
GLuint VideoLayerAndroid::createTextureFromImage(int buttonType)
{
SkRect rect = SkRect(buttonRect);
@@ -112,7 +124,8 @@ GLuint VideoLayerAndroid::createTextureFromImage(int buttonType)
SkCanvas canvas(bitmap);
canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
- RenderSkinMediaButton::Draw(&canvas, buttonRect, buttonType, true);
+ RenderSkinMediaButton::Draw(&canvas, buttonRect, buttonType, true, 0,
+ false);
GLuint texture;
glGenTextures(1, &texture);
@@ -142,6 +155,31 @@ GLuint VideoLayerAndroid::createBackgroundTexture()
return texture;
}
+void VideoLayerAndroid::showPreparingAnimation(const SkRect& rect,
+ const SkRect innerRect)
+{
+ ShaderProgram* shader = TilesManager::instance()->shader();
+ shader->drawLayerQuad(m_drawTransform, rect, m_backgroundTextureId, 1, true);
+
+ TransformationMatrix addReverseRotation;
+ TransformationMatrix addRotation = m_drawTransform;
+ addRotation.translate(innerRect.fLeft, innerRect.fTop);
+ addRotation.translate(IMAGESIZE / 2, IMAGESIZE / 2);
+ addReverseRotation = addRotation;
+ addRotation.rotate(m_rotateDegree);
+ addRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
+
+ SkRect size = SkRect::MakeWH(innerRect.width(), innerRect.height());
+ shader->drawLayerQuad(addRotation, size, m_spinnerOuterTextureId, 1, true);
+
+ addReverseRotation.rotate(-m_rotateDegree);
+ addReverseRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
+
+ shader->drawLayerQuad(addReverseRotation, size, m_spinnerInnerTextureId, 1, true);
+
+ m_rotateDegree += ROTATESTEP;
+}
+
bool VideoLayerAndroid::drawGL()
{
// Lazily allocated the textures.
@@ -150,6 +188,8 @@ bool VideoLayerAndroid::drawGL()
m_spinnerOuterTextureId = createSpinnerOuterTexture();
m_spinnerInnerTextureId = createSpinnerInnerTexture();
m_posterTextureId = createPosterTexture();
+ m_playTextureId = createPlayTexture();
+ m_pauseTextureId = createPauseTexture();
m_createdTexture = true;
}
@@ -162,69 +202,63 @@ bool VideoLayerAndroid::drawGL()
innerRect.offset((rect.width() - IMAGESIZE) / 2 , (rect.height() - IMAGESIZE) / 2);
+ ShaderProgram* shader = TilesManager::instance()->shader();
+ VideoLayerManager* manager = TilesManager::instance()->videoLayerManager();
+
+ // When we are drawing the animation of the play/pause button in the
+ // middle of the video, we need to ask for redraw.
+ bool needRedraw = false;
+
// Draw the poster image, the progressing image or the Video depending
// on the player's state.
if (m_playerState == PREPARING) {
// Show the progressing animation, with two rotating circles
- TilesManager::instance()->shader()->drawLayerQuad(m_drawTransform, rect,
- m_backgroundTextureId,
- 1, true);
-
- TransformationMatrix addReverseRotation;
- TransformationMatrix addRotation = m_drawTransform;
- addRotation.translate(innerRect.fLeft, innerRect.fTop);
- addRotation.translate(IMAGESIZE / 2, IMAGESIZE / 2);
- addReverseRotation = addRotation;
- addRotation.rotate(m_rotateDegree);
- addRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
-
- SkRect size = SkRect::MakeWH(innerRect.width(), innerRect.height());
- TilesManager::instance()->shader()->drawLayerQuad(addRotation, size,
- m_spinnerOuterTextureId,
- 1, true);
-
- addReverseRotation.rotate(-m_rotateDegree);
- addReverseRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
-
- TilesManager::instance()->shader()->drawLayerQuad(addReverseRotation, size,
- m_spinnerInnerTextureId,
- 1, true);
-
- m_rotateDegree += ROTATESTEP;
-
+ showPreparingAnimation(rect, innerRect);
} else if (m_playerState == PLAYING && m_surfaceTexture.get()) {
// Show the real video.
m_surfaceTexture->updateTexImage();
m_surfaceTexture->getTransformMatrix(surfaceMatrix);
- GLuint textureId =
- TilesManager::instance()->videoLayerManager()->getTextureId(uniqueId());
- TilesManager::instance()->shader()->drawVideoLayerQuad(m_drawTransform,
- surfaceMatrix,
- rect, textureId);
- TilesManager::instance()->videoLayerManager()->updateMatrix(uniqueId(),
- surfaceMatrix);
+ GLuint textureId = manager->getTextureId(uniqueId());
+ shader->drawVideoLayerQuad(m_drawTransform, surfaceMatrix,
+ rect, textureId);
+ manager->updateMatrix(uniqueId(), surfaceMatrix);
+
+ // Use the scale to control the fading the sizing during animation
+ double scale = manager->drawIcon(uniqueId(), PlayIcon);
+ if (scale != 0) {
+ innerRect.inset(IMAGESIZE / 4 * scale, IMAGESIZE / 4 * scale);
+ shader->drawLayerQuad(m_drawTransform, innerRect,
+ m_playTextureId, scale, true);
+ needRedraw = true;
+ }
+
} else {
- GLuint textureId =
- TilesManager::instance()->videoLayerManager()->getTextureId(uniqueId());
- GLfloat* matrix =
- TilesManager::instance()->videoLayerManager()->getMatrix(uniqueId());
+ GLuint textureId = manager->getTextureId(uniqueId());
+ GLfloat* matrix = manager->getMatrix(uniqueId());
if (textureId && matrix) {
// Show the screen shot for each video.
- TilesManager::instance()->shader()->drawVideoLayerQuad(m_drawTransform,
- matrix,
- rect, textureId);
+ shader->drawVideoLayerQuad(m_drawTransform, matrix,
+ rect, textureId);
} else {
// Show the static poster b/c there is no screen shot available.
- TilesManager::instance()->shader()->drawLayerQuad(m_drawTransform, rect,
- m_backgroundTextureId,
- 1, true);
- TilesManager::instance()->shader()->drawLayerQuad(m_drawTransform, innerRect,
- m_posterTextureId,
- 1, true);
+ shader->drawLayerQuad(m_drawTransform, rect, m_backgroundTextureId,
+ 1, true);
+ shader->drawLayerQuad(m_drawTransform, innerRect, m_posterTextureId,
+ 1, true);
}
- }
- return drawChildrenGL();
+ // Use the scale to control the fading and the sizing during animation.
+ double scale = manager->drawIcon(uniqueId(), PauseIcon);
+ if (scale != 0) {
+ innerRect.inset(IMAGESIZE / 4 * scale, IMAGESIZE / 4 * scale);
+ shader->drawLayerQuad(m_drawTransform, innerRect,
+ m_pauseTextureId, scale, true);
+ needRedraw = true;
+ }
+
+ }
+ // Don't short circuit here since we still want to draw the children.
+ return drawChildrenGL() || needRedraw;
}
}
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
index 8a064bb..cdb37f3 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
@@ -30,6 +30,7 @@
#include "GLUtils.h"
#include "LayerAndroid.h"
+#include "ShaderProgram.h"
#include <jni.h>
namespace android {
@@ -62,10 +63,14 @@ public:
GLuint createSpinnerOuterTexture();
GLuint createSpinnerInnerTexture();
GLuint createPosterTexture();
+ GLuint createPlayTexture();
+ GLuint createPauseTexture();
private:
GLuint createTextureFromImage(int buttonType);
void init();
+ void showPreparingAnimation(const SkRect& rect,
+ const SkRect innerRect);
// Surface texture for showing the video is actually allocated in Java side
// and passed into this native code.
sp<android::SurfaceTexture> m_surfaceTexture;
@@ -78,6 +83,8 @@ private:
static GLuint m_posterTextureId;
static GLuint m_spinnerOuterTextureId;
static GLuint m_spinnerInnerTextureId;
+ static GLuint m_playTextureId;
+ static GLuint m_pauseTextureId;
static double m_rotateDegree;
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
index cec4d67..d0fc873 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
+++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "VideoLayerManager.h"
+#include <wtf/CurrentTime.h>
#if USE(ACCELERATED_COMPOSITING)
@@ -42,6 +43,10 @@
#endif // DEBUG
+// The animation of the play/pause icon will last for PLAY_PAUSE_ICON_SHOW_TIME
+// seconds.
+#define PLAY_PAUSE_ICON_SHOW_TIME 1
+
// Define the max sum of all the video's sizes.
// Note that video_size = width * height. If there is no compression, then the
// maximum memory consumption could be 4 * video_size.
@@ -105,6 +110,8 @@ void VideoLayerManager::registerTexture(const int layerId, const GLuint textureI
pInfo->videoSize = 0;
m_currentTimeStamp++;
pInfo->timeStamp = m_currentTimeStamp;
+ pInfo->lastIconShownTime = 0;
+ pInfo->iconState = Registered;
m_videoLayerInfoMap.add(layerId, pInfo);
XLOG("GL texture %d regisered for layerId %d", textureId, layerId);
@@ -238,5 +245,34 @@ void VideoLayerManager::removeLayerInternal(const int layerId)
return;
}
+double VideoLayerManager::drawIcon(const int layerId, IconType type)
+{
+ // When ratio 0 is returned, the Icon should not be drawn.
+ double ratio = 0;
+
+ android::Mutex::Autolock lock(m_videoLayerInfoMapLock);
+ if (m_videoLayerInfoMap.contains(layerId)) {
+ VideoLayerInfo* pInfo = m_videoLayerInfoMap.get(layerId);
+ // If this is state switching moment, reset the time and state
+ if ((type == PlayIcon && pInfo->iconState != PlayIconShown)
+ ||(type == PauseIcon && pInfo->iconState != PauseIconShown)) {
+ pInfo->lastIconShownTime = WTF::currentTime();
+ pInfo->iconState = (type == PlayIcon) ? PlayIconShown : PauseIconShown;
+ }
+
+ // After switching the state, we calculate the ratio depending on the
+ // time interval.
+ if ((type == PlayIcon && pInfo->iconState == PlayIconShown)
+ || (type == PauseIcon && pInfo->iconState == PauseIconShown)) {
+ double delta = WTF::currentTime() - pInfo->lastIconShownTime;
+ ratio = 1.0 - (delta / PLAY_PAUSE_ICON_SHOW_TIME);
+ }
+ }
+
+ if (ratio > 1 || ratio < 0 )
+ ratio = 0;
+ return ratio;
+}
+
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/VideoLayerManager.h
index de2dafc..a427269 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.h
+++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.h
@@ -34,6 +34,17 @@
namespace WebCore {
+enum IconState {
+ Registered,
+ PlayIconShown,
+ PauseIconShown
+};
+
+enum IconType {
+ PlayIcon,
+ PauseIcon
+};
+
// Every video layer can use its uniqueId to query VideoLayerManager about such
// info globally.
struct VideoLayerInfo {
@@ -41,6 +52,9 @@ struct VideoLayerInfo {
int videoSize; // The size of the video.
int timeStamp; // Used to decide which VideoLayerInfo is the oldest one.
GLfloat surfaceMatrix[16];
+
+ double lastIconShownTime;
+ IconState iconState;
};
@@ -68,6 +82,7 @@ public:
// Delete the GL textures
void deleteUnusedTextures();
+ double drawIcon(const int layerId, IconType type);
private:
// Get the sum of all the video size stored in m_videoLayerInfoMap.
int getTotalMemUsage();