summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2011-03-18 15:41:20 -0700
committerTeng-Hui Zhu <ztenghui@google.com>2011-03-21 10:36:34 -0700
commitde89b1aa0a100f46600ed48b6b3b57759c446447 (patch)
tree20483b9dd04dad855710275a7674cf6fad37d967
parente1c3e59945c9789e93c417e064a9abed1057ce42 (diff)
downloadexternal_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
-rw-r--r--WebCore/platform/graphics/android/VideoLayerAndroid.cpp120
-rw-r--r--WebCore/platform/graphics/android/VideoLayerAndroid.h34
-rw-r--r--WebKit/android/RenderSkinMediaButton.cpp17
-rw-r--r--WebKit/android/RenderSkinMediaButton.h5
-rw-r--r--WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp6
5 files changed, 150 insertions, 32 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
diff --git a/WebKit/android/RenderSkinMediaButton.cpp b/WebKit/android/RenderSkinMediaButton.cpp
index 6a11eda..745fa88 100644
--- a/WebKit/android/RenderSkinMediaButton.cpp
+++ b/WebKit/android/RenderSkinMediaButton.cpp
@@ -54,9 +54,12 @@ static const PatchData gFiles[] =
{ "ic_media_rew.png", 0, 0 }, // REWIND
{ "ic_media_ff.png", 0, 0 }, // FORWARD
{ "ic_media_fullscreen.png", 0, 0 }, // FULLSCREEN
+ { "spinner_76_outer_holo.png", 0, 0 }, // SPINNER_OUTER
+ { "spinner_76_inner_holo.png", 0, 0 }, // SPINNER_INNER
+ { "ic_media_video_poster.png", 0, 0 }, // VIDEO
{ "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER
- { "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK
- { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB
+ { "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK
+ { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB
};
static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])];
@@ -124,6 +127,14 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT
paint.setColor(backgroundColor);
break;
}
+ case SPINNER_OUTER:
+ case SPINNER_INNER:
+ case VIDEO:
+ {
+ drawsBackgroundColor = false;
+ imageIndex = buttonType + 1;
+ break;
+ }
case BACKGROUND_SLIDER:
{
drawsBackgroundColor = false;
@@ -200,4 +211,4 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT
}
}
-} //WebCore
+} // WebCore
diff --git a/WebKit/android/RenderSkinMediaButton.h b/WebKit/android/RenderSkinMediaButton.h
index 026f538..6aa9c4e 100644
--- a/WebKit/android/RenderSkinMediaButton.h
+++ b/WebKit/android/RenderSkinMediaButton.h
@@ -34,8 +34,7 @@ namespace WebCore {
class IntRect;
class RenderObject;
-class RenderSkinMediaButton
-{
+class RenderSkinMediaButton {
public:
/**
* Initialize the class before use. Uses the AssetManager to initialize any
@@ -51,7 +50,7 @@ public:
/**
* Button types
*/
- enum { PAUSE, PLAY, MUTE, REWIND, FORWARD, FULLSCREEN, BACKGROUND_SLIDER, SLIDER_TRACK, SLIDER_THUMB };
+ enum { PAUSE, PLAY, MUTE, REWIND, FORWARD, FULLSCREEN, SPINNER_OUTER, SPINNER_INNER , VIDEO, BACKGROUND_SLIDER, SLIDER_TRACK, SLIDER_THUMB };
/**
* Slider dimensions
*/
diff --git a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
index 4cc9cf4..d61b0dd 100644
--- a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
@@ -567,7 +567,7 @@ static void OnTimeupdate(JNIEnv* env, jobject obj, int position, int pointer)
// Return value: true when the video layer is found.
static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex,
int baseLayer, int videoLayerId,
- int textureName, bool updateTexture) {
+ int textureName, int playerState) {
if (!surfTex)
return false;
@@ -590,7 +590,7 @@ static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex,
return false;
// Set the SurfaceTexture to the layer we found
- videoLayer->setSurfaceTexture(texture, textureName, updateTexture);
+ videoLayer->setSurfaceTexture(texture, textureName, static_cast<PlayerState>(playerState));
return true;
}
@@ -607,7 +607,7 @@ static JNINativeMethod g_MediaPlayerMethods[] = {
(void*) OnPaused },
{ "nativeOnPosterFetched", "(Landroid/graphics/Bitmap;I)V",
(void*) OnPosterFetched },
- { "nativeSendSurfaceTexture", "(Landroid/graphics/SurfaceTexture;IIIZ)Z",
+ { "nativeSendSurfaceTexture", "(Landroid/graphics/SurfaceTexture;IIII)Z",
(void*) SendSurfaceTexture },
{ "nativeOnTimeupdate", "(II)V",
(void*) OnTimeupdate },