diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2011-03-18 15:41:20 -0700 |
---|---|---|
committer | Teng-Hui Zhu <ztenghui@google.com> | 2011-03-21 10:36:34 -0700 |
commit | de89b1aa0a100f46600ed48b6b3b57759c446447 (patch) | |
tree | 20483b9dd04dad855710275a7674cf6fad37d967 /WebCore | |
parent | e1c3e59945c9789e93c417e064a9abed1057ce42 (diff) | |
download | external_webkit-de89b1aa0a100f46600ed48b6b3b57759c446447.zip external_webkit-de89b1aa0a100f46600ed48b6b3b57759c446447.tar.gz external_webkit-de89b1aa0a100f46600ed48b6b3b57759c446447.tar.bz2 |
Support drawing paused and loading image as GL texture
bug:4142131
Change-Id: I871924cb7587077f50fdf4f9a00056f795a8daea
Diffstat (limited to 'WebCore')
-rw-r--r-- | WebCore/platform/graphics/android/VideoLayerAndroid.cpp | 120 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/VideoLayerAndroid.h | 34 |
2 files changed, 131 insertions, 23 deletions
diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/WebCore/platform/graphics/android/VideoLayerAndroid.cpp index 697281c..32e518d 100644 --- a/WebCore/platform/graphics/android/VideoLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/VideoLayerAndroid.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "VideoLayerAndroid.h" +#include "RenderSkinMediaButton.h" #include "TilesManager.h" #include <GLES2/gl2.h> #include <gui/SurfaceTexture.h> @@ -47,8 +48,16 @@ #endif // DEBUG namespace WebCore { -GLuint VideoLayerAndroid::m_pauseTextureId = 0; -bool VideoLayerAndroid::m_createdPauseTexture = false; + +GLuint VideoLayerAndroid::m_spinnerOuterTextureId = 0; +GLuint VideoLayerAndroid::m_spinnerInnerTextureId = 0; +GLuint VideoLayerAndroid::m_posterTextureId = 0; +GLuint VideoLayerAndroid::m_backgroundTextureId = 0; +bool VideoLayerAndroid::m_createdTexture = false; + +double VideoLayerAndroid::m_rotateDegree = 0; + +const IntRect VideoLayerAndroid::buttonRect(0, 0, IMAGESIZE, IMAGESIZE); VideoLayerAndroid::VideoLayerAndroid() : LayerAndroid((RenderLayer*)0) @@ -67,21 +76,56 @@ 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_playerState = INITIALIZED; 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) + int textureName, PlayerState playerState) { m_surfaceTexture = texture; m_textureId = textureName; - m_useSurfTex = useSurfTex; + + m_playerState = playerState; +} + +GLuint VideoLayerAndroid::createSpinnerInnerTexture() +{ + return createTextureFromImage(RenderSkinMediaButton::SPINNER_INNER); +} + +GLuint VideoLayerAndroid::createSpinnerOuterTexture() +{ + return createTextureFromImage(RenderSkinMediaButton::SPINNER_OUTER); } -GLuint VideoLayerAndroid::createPauseTexture() +GLuint VideoLayerAndroid::createPosterTexture() +{ + return createTextureFromImage(RenderSkinMediaButton::VIDEO); +} + +GLuint VideoLayerAndroid::createTextureFromImage(int buttonType) +{ + SkRect rect = SkRect(buttonRect); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); + bitmap.allocPixels(); + bitmap.eraseColor(0); + + SkCanvas canvas(bitmap); + canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); + RenderSkinMediaButton::Draw(&canvas, buttonRect, buttonType, true); + + GLuint texture; + glGenTextures(1, &texture); + + GLUtils::createTextureWithBitmap(texture, bitmap); + bitmap.reset(); + return texture; +} + +GLuint VideoLayerAndroid::createBackgroundTexture() { GLuint texture; glGenTextures(1, &texture); @@ -103,28 +147,70 @@ GLuint VideoLayerAndroid::createPauseTexture() bool VideoLayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) { - // Lazy allocated the paused texture. - if (!m_createdPauseTexture) { - m_pauseTextureId = createPauseTexture(); - m_createdPauseTexture = true; + // Lazily allocated the textures. + if (!m_createdTexture) { + m_backgroundTextureId = createBackgroundTexture(); + m_spinnerOuterTextureId = createSpinnerOuterTexture(); + m_spinnerInnerTextureId = createSpinnerInnerTexture(); + m_posterTextureId = createPosterTexture(); + m_createdTexture = 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); + SkRect innerRect = SkRect(buttonRect); + if (innerRect.contains(rect)) + innerRect = rect; + + innerRect.offset((rect.width() - IMAGESIZE) / 2 , (rect.height() - IMAGESIZE) / 2); + + // 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(drawTransform(), rect, - m_pauseTextureId, + m_backgroundTextureId, 0.5, true); - } else { + + TransformationMatrix addReverseRotation; + TransformationMatrix addRotation = 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; + + } else if (m_playerState == PLAYING && m_surfaceTexture.get()) { + // Show the real video. m_surfaceTexture->updateTexImage(); m_surfaceTexture->getTransformMatrix(surfaceMatrix); TilesManager::instance()->shader()->drawVideoLayerQuad(drawTransform(), surfaceMatrix, rect, m_textureId); + } else { + // Show the poster + TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect, + m_backgroundTextureId, + 0.5, true); + + TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), innerRect, + m_posterTextureId, + 1, true); } return drawChildrenGL(glWebViewState, matrix); diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.h b/WebCore/platform/graphics/android/VideoLayerAndroid.h index d291dda..eac565e 100644 --- a/WebCore/platform/graphics/android/VideoLayerAndroid.h +++ b/WebCore/platform/graphics/android/VideoLayerAndroid.h @@ -38,6 +38,14 @@ class SurfaceTexture; namespace WebCore { +// state get from UI thread to decide which image to draw. +// PREPARING should be the progressing image +// PLAYING will be the Video (Surface Texture). +// Otherwise will draw a static image. +// NOTE: These values are matching the ones in HTML5VideoView.java +// Please keep them in sync when changed here. +typedef enum {INITIALIZED, PREPARING, PREPARED, PLAYING} PlayerState; + class VideoLayerAndroid : public LayerAndroid { public: @@ -49,22 +57,36 @@ public: // The following 3 functions are called in UI thread only. virtual bool drawGL(GLWebViewState*, SkMatrix& matrix); - void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, bool updateTexture); - GLuint createPauseTexture(); + void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, PlayerState playerState); + GLuint createBackgroundTexture(); + GLuint createSpinnerOuterTexture(); + GLuint createSpinnerInnerTexture(); + GLuint createPosterTexture(); private: + GLuint createTextureFromImage(int buttonType); 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. + PlayerState m_playerState; + + // Texture for showing the static 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; + static bool m_createdTexture; + static GLuint m_backgroundTextureId; + static GLuint m_posterTextureId; + static GLuint m_spinnerOuterTextureId; + static GLuint m_spinnerInnerTextureId; + + static double m_rotateDegree; + + static const int ROTATESTEP = 12; + static const int IMAGESIZE = 64; + static const IntRect buttonRect; }; } // namespace WebCore |