summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2012-03-01 11:33:01 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-03-01 11:33:01 -0800
commit56b4137d1b6400ff25b9d6b00c8f12846a616f95 (patch)
tree43c07d32d9e70f739cc3974d9694b14ac652ebd9 /Source
parenta0798fea895a9be431e9357b9a0481a189b69980 (diff)
parent00144be011338276839a08a66ae79b14629b268b (diff)
downloadexternal_webkit-56b4137d1b6400ff25b9d6b00c8f12846a616f95.zip
external_webkit-56b4137d1b6400ff25b9d6b00c8f12846a616f95.tar.gz
external_webkit-56b4137d1b6400ff25b9d6b00c8f12846a616f95.tar.bz2
Merge "Cleanup GL resource for HTML5 Video."
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp143
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.h18
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerManager.cpp107
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerManager.h26
-rw-r--r--Source/WebKit/android/nav/WebView.cpp10
5 files changed, 171 insertions, 133 deletions
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
index 46a8c1d..e48d36c 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
@@ -26,16 +26,18 @@
#include "config.h"
#include "VideoLayerAndroid.h"
-#include "RenderSkinMediaButton.h"
#include "TilesManager.h"
#include <GLES2/gl2.h>
+#include <cutils/log.h>
#include <gui/SurfaceTexture.h>
+#include <wtf/text/CString.h>
#if USE(ACCELERATED_COMPOSITING)
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerAndroid", __VA_ARGS__)
+
#ifdef DEBUG
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
#undef XLOG
#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerAndroid", __VA_ARGS__)
@@ -49,18 +51,8 @@
namespace WebCore {
-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;
-const IntRect VideoLayerAndroid::buttonRect(0, 0, IMAGESIZE, IMAGESIZE);
-
VideoLayerAndroid::VideoLayerAndroid()
: LayerAndroid((RenderLayer*)0)
{
@@ -89,93 +81,33 @@ void VideoLayerAndroid::setSurfaceTexture(sp<SurfaceTexture> texture,
TilesManager::instance()->videoLayerManager()->registerTexture(uniqueId(), textureName);
}
-GLuint VideoLayerAndroid::createSpinnerInnerTexture()
-{
- return createTextureFromImage(RenderSkinMediaButton::SPINNER_INNER);
-}
-
-GLuint VideoLayerAndroid::createSpinnerOuterTexture()
-{
- return createTextureFromImage(RenderSkinMediaButton::SPINNER_OUTER);
-}
-
-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);
- 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, 0,
- false);
-
- GLuint texture;
- glGenTextures(1, &texture);
-
- GLUtils::createTextureWithBitmap(texture, bitmap);
- bitmap.reset();
- return texture;
-}
-
-GLuint VideoLayerAndroid::createBackgroundTexture()
-{
- 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;
-}
-
void VideoLayerAndroid::showPreparingAnimation(const SkRect& rect,
const SkRect innerRect)
{
ShaderProgram* shader = TilesManager::instance()->shader();
- shader->drawLayerQuad(m_drawTransform, rect, m_backgroundTextureId, 1, true);
+ VideoLayerManager* manager = TilesManager::instance()->videoLayerManager();
+ // Paint the video content's background.
+ shader->drawLayerQuad(m_drawTransform, rect, 0, 1, true, GL_TEXTURE_2D,
+ Color(128, 128, 128, 255));
TransformationMatrix addReverseRotation;
TransformationMatrix addRotation = m_drawTransform;
addRotation.translate(innerRect.fLeft, innerRect.fTop);
- addRotation.translate(IMAGESIZE / 2, IMAGESIZE / 2);
+ double halfButtonSize = manager->getButtonSize() / 2;
+ addRotation.translate(halfButtonSize, halfButtonSize);
addReverseRotation = addRotation;
addRotation.rotate(m_rotateDegree);
- addRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
+ addRotation.translate(-halfButtonSize, -halfButtonSize);
SkRect size = SkRect::MakeWH(innerRect.width(), innerRect.height());
- shader->drawLayerQuad(addRotation, size, m_spinnerOuterTextureId, 1, true);
+ shader->drawLayerQuad(addRotation, size,
+ manager->getSpinnerOuterTextureId(), 1, true);
addReverseRotation.rotate(-m_rotateDegree);
- addReverseRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
+ addReverseRotation.translate(-halfButtonSize, -halfButtonSize);
- shader->drawLayerQuad(addReverseRotation, size, m_spinnerInnerTextureId, 1, true);
+ shader->drawLayerQuad(addReverseRotation, size,
+ manager->getSpinnerInnerTextureId(), 1, true);
m_rotateDegree += ROTATESTEP;
}
@@ -199,17 +131,11 @@ SkRect VideoLayerAndroid::calVideoRect(const SkRect& rect)
bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
{
// Lazily allocated the textures.
- if (!m_createdTexture) {
- m_backgroundTextureId = createBackgroundTexture();
- m_spinnerOuterTextureId = createSpinnerOuterTexture();
- m_spinnerInnerTextureId = createSpinnerInnerTexture();
- m_posterTextureId = createPosterTexture();
- m_playTextureId = createPlayTexture();
- m_pauseTextureId = createPauseTexture();
- m_createdTexture = true;
- }
+ TilesManager* tilesManager = TilesManager::instance();
+ VideoLayerManager* manager = tilesManager->videoLayerManager();
+ manager->initGLResourcesIfNeeded();
- ShaderProgram* shader = TilesManager::instance()->shader();
+ ShaderProgram* shader = tilesManager->shader();
SkRect rect = SkRect::MakeSize(getSize());
GLfloat surfaceMatrix[16];
@@ -224,11 +150,13 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
}
// Inner rect is for the progressing / play / pause animation.
- SkRect innerRect = SkRect(buttonRect);
+ SkRect innerRect = SkRect::MakeWH(manager->getButtonSize(),
+ manager->getButtonSize());
if (innerRect.contains(videoRect))
innerRect = videoRect;
- innerRect.offset(videoRect.fLeft + (videoRect.width() - IMAGESIZE) / 2,
- videoRect.fTop + (videoRect.height() - IMAGESIZE) / 2);
+ double buttonSize = manager->getButtonSize();
+ innerRect.offset(videoRect.fLeft + (videoRect.width() - buttonSize) / 2,
+ videoRect.fTop + (videoRect.height() - buttonSize) / 2);
// When we are drawing the animation of the play/pause button in the
// middle of the video, we need to ask for redraw.
@@ -236,7 +164,6 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
// Draw the poster image, the progressing image or the Video depending
// on the player's state.
- VideoLayerManager* manager = TilesManager::instance()->videoLayerManager();
if (m_playerState == PREPARING) {
// Show the progressing animation, with two rotating circles
showPreparingAnimation(videoRect, innerRect);
@@ -253,9 +180,10 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
// Use the scale to control the fading the sizing during animation
double scale = manager->drawIcon(uniqueId(), PlayIcon);
if (scale) {
- innerRect.inset(IMAGESIZE / 4 * scale, IMAGESIZE / 4 * scale);
+ innerRect.inset(manager->getButtonSize() / 4 * scale,
+ manager->getButtonSize() / 4 * scale);
shader->drawLayerQuad(m_drawTransform, innerRect,
- m_playTextureId, scale, true);
+ manager->getPlayTextureId(), scale, true);
needRedraw = true;
}
@@ -268,18 +196,19 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
videoRect, textureId);
} else {
// Show the static poster b/c there is no screen shot available.
- shader->drawLayerQuad(m_drawTransform, videoRect, m_backgroundTextureId,
- 1, true);
- shader->drawLayerQuad(m_drawTransform, innerRect, m_posterTextureId,
- 1, true);
+ shader->drawLayerQuad(m_drawTransform, rect, 0, 1, true, GL_TEXTURE_2D,
+ Color(128, 128, 128, 255));
+ shader->drawLayerQuad(m_drawTransform, innerRect,
+ manager->getPosterTextureId(), 1, true);
}
// Use the scale to control the fading and the sizing during animation.
double scale = manager->drawIcon(uniqueId(), PauseIcon);
if (scale) {
- innerRect.inset(IMAGESIZE / 4 * scale, IMAGESIZE / 4 * scale);
+ innerRect.inset(manager->getButtonSize() / 4 * scale,
+ manager->getButtonSize() / 4 * scale);
shader->drawLayerQuad(m_drawTransform, innerRect,
- m_pauseTextureId, scale, true);
+ manager->getPauseTextureId(), scale, true);
needRedraw = true;
}
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
index 8ec16d4..29b1bdc 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
@@ -59,15 +59,8 @@ public:
// The following 3 functions are called in UI thread only.
virtual bool drawGL(bool layerTilesDisabled);
void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, PlayerState playerState);
- GLuint createBackgroundTexture();
- 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);
@@ -78,20 +71,9 @@ private:
PlayerState m_playerState;
- // Texture for showing the static image will be created at native side.
- static bool m_createdTexture;
- static GLuint m_backgroundTextureId;
- static GLuint m_posterTextureId;
- static GLuint m_spinnerOuterTextureId;
- static GLuint m_spinnerInnerTextureId;
- static GLuint m_playTextureId;
- static GLuint m_pauseTextureId;
-
static double m_rotateDegree;
static const int ROTATESTEP = 12;
- static const int IMAGESIZE = 64;
- static const IntRect buttonRect;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
index 521b623..f957aed 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
+++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
@@ -26,13 +26,18 @@
#include "config.h"
#include "VideoLayerManager.h"
+#include "RenderSkinMediaButton.h"
+#include "SkCanvas.h"
+#include <cutils/log.h>
#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
#if USE(ACCELERATED_COMPOSITING)
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerManager", __VA_ARGS__)
+
#ifdef DEBUG
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
#undef XLOG
#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerManager", __VA_ARGS__)
@@ -59,11 +64,106 @@
// Assuming 16:9 by default, this will be corrected after video prepared.
#define DEFAULT_VIDEO_ASPECT_RATIO 1.78
+#define VIDEO_TEXTURE_NUMBER 5
+#define VIDEO_BUTTON_SIZE 64
+
namespace WebCore {
VideoLayerManager::VideoLayerManager()
+ : m_currentTimeStamp(0)
+ , m_createdTexture(false)
+ , m_posterTextureId(0)
+ , m_spinnerOuterTextureId(0)
+ , m_spinnerInnerTextureId(0)
+ , m_playTextureId(0)
+ , m_pauseTextureId(0)
+ , m_buttonRect(0, 0, VIDEO_BUTTON_SIZE, VIDEO_BUTTON_SIZE)
+{
+}
+
+int VideoLayerManager::getButtonSize()
+{
+ return VIDEO_BUTTON_SIZE;
+}
+
+GLuint VideoLayerManager::createTextureFromImage(int buttonType)
+{
+ SkRect rect = SkRect(m_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, m_buttonRect, buttonType, true, 0,
+ false);
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+
+ GLUtils::createTextureWithBitmap(texture, bitmap);
+ bitmap.reset();
+ return texture;
+}
+
+// Should be called at the VideoLayerAndroid::drawGL to make sure we allocate
+// the GL resources lazily.
+void VideoLayerManager::initGLResourcesIfNeeded()
+{
+ if (!m_createdTexture) {
+ XLOGC("Reinit GLResource for VideoLayer");
+ initGLResources();
+ }
+}
+
+void VideoLayerManager::initGLResources()
{
- m_currentTimeStamp = 0;
+ GLUtils::checkGlError("before initGLResources()");
+ if (!m_createdTexture) {
+ m_spinnerOuterTextureId =
+ createTextureFromImage(RenderSkinMediaButton::SPINNER_OUTER);
+ m_spinnerInnerTextureId =
+ createTextureFromImage(RenderSkinMediaButton::SPINNER_INNER);
+ m_posterTextureId =
+ createTextureFromImage(RenderSkinMediaButton::VIDEO);
+ m_playTextureId = createTextureFromImage(RenderSkinMediaButton::PLAY);
+ m_pauseTextureId = createTextureFromImage(RenderSkinMediaButton::PAUSE);
+ }
+ m_createdTexture = !GLUtils::checkGlError("initGLResources()");
+ return;
+}
+
+void VideoLayerManager::cleanupGLResources()
+{
+ if (m_createdTexture) {
+ GLuint videoTextures[VIDEO_TEXTURE_NUMBER] = { m_spinnerOuterTextureId,
+ m_spinnerInnerTextureId, m_posterTextureId, m_playTextureId,
+ m_pauseTextureId };
+
+ glDeleteTextures(VIDEO_TEXTURE_NUMBER, videoTextures);
+ m_createdTexture = false;
+ }
+ // Delete the texture in retired mode, but have not hit draw call to be
+ // removed.
+ deleteUnusedTextures();
+
+ // Go over the registered GL textures (screen shot textures) and delete them.
+ android::Mutex::Autolock lock(m_videoLayerInfoMapLock);
+ InfoIterator end = m_videoLayerInfoMap.end();
+ for (InfoIterator it = m_videoLayerInfoMap.begin(); it != end; ++it) {
+ // The map include every video has been played, so their textureId can
+ // be deleted already, like hitting onTrimMemory multiple times.
+ if (it->second->textureId) {
+ XLOG("delete texture from the map %d", it->second->textureId);
+ glDeleteTextures(1, &it->second->textureId);
+ // Set the textureID to 0 to show the video icon.
+ it->second->textureId = 0;
+ }
+ }
+
+ GLUtils::checkGlError("cleanupGLResources()");
+ return;
}
// Getting TextureId for GL draw call, in the UI thread.
@@ -233,6 +333,7 @@ void VideoLayerManager::deleteUnusedTextures()
m_retiredTextures.clear();
}
m_retiredTexturesLock.unlock();
+ GLUtils::checkGlError("deleteUnusedTextures");
return;
}
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/VideoLayerManager.h
index d554362..c8e420e 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.h
+++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.h
@@ -27,6 +27,7 @@
#define VideoLayerManager_h
#include "GLUtils.h"
+#include "IntRect.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
@@ -86,6 +87,17 @@ public:
void deleteUnusedTextures();
double drawIcon(const int layerId, IconType type);
+
+ GLuint getSpinnerInnerTextureId() { return m_spinnerInnerTextureId; }
+ GLuint getSpinnerOuterTextureId() { return m_spinnerOuterTextureId; }
+ GLuint getPosterTextureId() { return m_posterTextureId; }
+ GLuint getPlayTextureId() { return m_playTextureId; }
+ GLuint getPauseTextureId() { return m_pauseTextureId; }
+
+ void initGLResourcesIfNeeded();
+ void cleanupGLResources();
+
+ static int getButtonSize();
private:
// Get the sum of all the video size stored in m_videoLayerInfoMap.
int getTotalMemUsage();
@@ -93,7 +105,7 @@ private:
bool recycleTextureMem();
// The private function to remove layer.
void removeLayerInternal(const int layerId);
-
+ void initGLResources();
// Indexed by each layer's uniqueId, this map contains the important info
// used for showing the video when playing or the screenshot when paused.
HashMap<int, VideoLayerInfo*> m_videoLayerInfoMap;
@@ -107,6 +119,18 @@ private:
// thread, and really get deleted in the UI thread.
Vector<GLuint> m_retiredTextures;
android::Mutex m_retiredTexturesLock;
+
+ GLuint createTextureFromImage(int buttonType);
+
+ // Texture for showing the static image will be created at native side.
+ bool m_createdTexture;
+ GLuint m_posterTextureId;
+ GLuint m_spinnerOuterTextureId;
+ GLuint m_spinnerInnerTextureId;
+ GLuint m_playTextureId;
+ GLuint m_pauseTextureId;
+
+ IntRect m_buttonRect;
};
} // namespace WebCore
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 09b6c3d..ba6d121 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -1418,14 +1418,16 @@ static void nativeOnTrimMemory(JNIEnv *env, jobject obj, jint level)
// make sure the transfer queue is empty and then abandon the Surface
// Texture to avoid ANR b/c framework may destroy the EGL context.
// Refer to WindowManagerImpl.java for conditions we followed.
+ TilesManager* tilesManager = TilesManager::instance();
if (level >= TRIM_MEMORY_MODERATE
- && !TilesManager::instance()->highEndGfx()) {
- TilesManager::instance()->transferQueue()->emptyQueue();
- TilesManager::instance()->shader()->cleanupGLResources();
+ && !tilesManager->highEndGfx()) {
+ tilesManager->transferQueue()->emptyQueue();
+ tilesManager->shader()->cleanupGLResources();
+ tilesManager->videoLayerManager()->cleanupGLResources();
}
bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN), glTextures = true;
- TilesManager::instance()->discardTextures(freeAllTextures, glTextures);
+ tilesManager->discardTextures(freeAllTextures, glTextures);
}
}