diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2011-12-13 13:24:27 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-12-13 13:24:27 -0800 |
commit | 1377f4a8f71311042eb17f1f35e73fa9d6f05376 (patch) | |
tree | be1a880ac314cde0df6527fd8f1ca0871fe8f8a7 /Source/WebCore/platform | |
parent | a73147edbc9b8ff7fa1c8d464de999b552463de8 (diff) | |
parent | d649883ce629c0de432e075254b517a50685792e (diff) | |
download | external_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')
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(); |