summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics')
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp15
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h6
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp30
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp17
-rw-r--r--WebCore/platform/graphics/android/GLUtils.cpp122
-rw-r--r--WebCore/platform/graphics/android/GLUtils.h54
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.h2
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp26
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.h1
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp288
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h59
-rw-r--r--WebCore/platform/graphics/android/LayerTexture.cpp51
-rw-r--r--WebCore/platform/graphics/android/LayerTexture.h61
-rw-r--r--WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h4
-rw-r--r--WebCore/platform/graphics/android/PaintLayerOperation.cpp61
-rw-r--r--WebCore/platform/graphics/android/PaintLayerOperation.h62
-rw-r--r--WebCore/platform/graphics/android/QueuedOperation.h12
-rw-r--r--WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp8
-rw-r--r--WebCore/platform/graphics/android/ScrollableLayerAndroid.h8
-rw-r--r--WebCore/platform/graphics/android/ShaderProgram.cpp43
-rw-r--r--WebCore/platform/graphics/android/ShaderProgram.h48
-rw-r--r--WebCore/platform/graphics/android/SharedTexture.cpp64
-rw-r--r--WebCore/platform/graphics/android/SharedTexture.h12
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.cpp7
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.h4
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp83
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h15
27 files changed, 943 insertions, 220 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
index 7bfbc4e..12e0436 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
@@ -25,10 +25,11 @@
#include "config.h"
#include "BackedDoubleBufferedTexture.h"
+
#include "BaseTile.h"
#include "DeleteTextureOperation.h"
-#include "TilesManager.h"
#include "GLUtils.h"
+#include "TilesManager.h"
#define LOG_NDEBUG 1
#define LOG_TAG "BackedDoubleBufferedTexture.cpp"
@@ -61,7 +62,7 @@ BackedDoubleBufferedTexture::~BackedDoubleBufferedTexture()
void BackedDoubleBufferedTexture::destroyTextures(SharedTexture** textures)
{
int x = 0;
- while (textures[x] != 0) {
+ while (textures[x]) {
// We need to delete the source texture and EGLImage in the texture
// generation thread. In theory we should be able to delete the EGLImage
// from either thread, but it currently throws an error if not deleted
@@ -121,6 +122,11 @@ bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner)
if (m_owner == owner)
return true;
+ return setOwner(owner);
+}
+
+bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner)
+{
// if the writable texture is busy (i.e. currently being written to) then we
// can't change the owner out from underneath that texture
android::Mutex::Autolock lock(m_busyLock);
@@ -139,9 +145,4 @@ void BackedDoubleBufferedTexture::release(TextureOwner* owner)
m_owner = 0;
}
-void BackedDoubleBufferedTexture::release()
-{
- m_owner = 0;
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
index 4ffdc07..844715d 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
@@ -53,7 +53,7 @@ public:
// updates the texture with current bitmap and releases (and if needed also
// swaps) the texture.
- void producerUpdate(TextureInfo* textureInfo);
+ virtual void producerUpdate(TextureInfo* textureInfo);
// The level can be one of the following values:
// * -1 for an unused texture.
@@ -68,7 +68,9 @@ public:
// returns false if ownership cannot be transferred because the tile is busy
bool acquire(TextureOwner* owner);
void release(TextureOwner* owner);
- void release();
+
+ // set the texture owner if not busy. Return false if busy, true otherwise.
+ bool setOwner(TextureOwner* owner);
// private member accessor functions
TextureOwner* owner() { return m_owner; } // only used by the consumer thread
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 996b272..040f63e 100644
--- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -75,6 +75,9 @@ BaseLayerAndroid::BaseLayerAndroid()
BaseLayerAndroid::~BaseLayerAndroid()
{
+#if USE(ACCELERATED_COMPOSITING)
+ TilesManager::instance()->removeOperationsForBaseLayer(this);
+#endif
m_content.clear();
#ifdef DEBUG_COUNT
gBaseLayerAndroidCount--;
@@ -256,6 +259,33 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
ret = drawBasePictureInGL(visibleRect, scale);
+ if (countChildren() >= 1) {
+ LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0));
+ TransformationMatrix ident;
+ compositedRoot->updateFixedLayersPositions(visibleRect);
+ compositedRoot->updateGLPositions(ident, 1);
+ SkMatrix matrix;
+ matrix.setTranslate(left, top);
+
+ // At this point, the previous LayerAndroid* root has been destroyed,
+ // which will have removed the layers as owners of the textures.
+ // Let's now do a pass to reserve the textures for the current tree;
+ // it will only reserve existing textures, not create them on demand.
+#ifdef DEBUG
+ TilesManager::instance()->printLayersTextures("reserve");
+#endif
+ compositedRoot->reserveGLTextures();
+ // Now that we marked the textures being used, we delete the unnecessary
+ // ones to make space...
+ TilesManager::instance()->cleanupLayersTextures();
+ // Finally do another pass to create new textures if needed
+ compositedRoot->createGLTextures();
+
+ if (compositedRoot->drawGL(matrix))
+ ret = true;
+ }
+ glDisable(GL_SCISSOR_TEST);
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_previousVisible = visibleRect;
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index 5701486..789cbe0 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -168,8 +168,12 @@ void BaseTile::draw(float transparency, SkRect& rect)
}
// Early return if set to un-usable in purpose!
- if (!m_usable) {
- XLOG("early return at BaseTile::draw b/c tile set to unusable !");
+ m_atomicSync.lock();
+ bool usable = m_usable;
+ bool isTexturePainted = m_lastPaintedPicture;
+ m_atomicSync.unlock();
+ if (!usable || !isTexturePainted) {
+ XLOG("early return at BaseTile::draw b/c tile set to unusable or not painted !");
return;
}
@@ -180,13 +184,8 @@ void BaseTile::draw(float transparency, SkRect& rect)
return;
}
- m_atomicSync.lock();
- bool isTexturePainted = m_lastPaintedPicture;
- m_atomicSync.unlock();
-
- if (isTexturePainted)
- TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId,
- transparency);
+ TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId,
+ transparency);
m_texture->consumerRelease();
}
diff --git a/WebCore/platform/graphics/android/GLUtils.cpp b/WebCore/platform/graphics/android/GLUtils.cpp
index 739dafc..2200d05 100644
--- a/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/WebCore/platform/graphics/android/GLUtils.cpp
@@ -45,7 +45,8 @@ using namespace android;
// Matrix utilities
/////////////////////////////////////////////////////////////////////////////////////////
-void GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m) {
+void GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m)
+{
flattened[0] = m.m11(); // scaleX
flattened[1] = m.m12(); // skewY
flattened[2] = m.m13();
@@ -64,7 +65,8 @@ void GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m) {
flattened[15] = m.m44(); // persp2
}
-void GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m) {
+void GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m)
+{
matrix[0] = m.m11(); // scaleX
matrix[1] = m.m21(); // skewX
matrix[2] = m.m41(); // transX
@@ -77,7 +79,8 @@ void GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m) {
}
void GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
- float right, float bottom, float nearZ, float farZ) {
+ float right, float bottom, float nearZ, float farZ)
+{
float deltaX = right - left;
float deltaY = top - bottom;
float deltaZ = farZ - nearZ;
@@ -96,19 +99,19 @@ void GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, flo
// GL & EGL error checks
/////////////////////////////////////////////////////////////////////////////////////////
-void GLUtils::checkEglError(const char* op, EGLBoolean returnVal) {
- if (returnVal != EGL_TRUE) {
+void GLUtils::checkEglError(const char* op, EGLBoolean returnVal)
+{
+ if (returnVal != EGL_TRUE)
XLOG("EGL ERROR - %s() returned %d\n", op, returnVal);
- } else {
+ else
XLOG("EGL OK - %s() returned %d\n", op, returnVal);
- }
- for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
+ for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError())
XLOG("after %s() eglError (0x%x)\n", op, error);
- }
}
-bool GLUtils::checkGlError(const char* op) {
+bool GLUtils::checkGlError(const char* op)
+{
bool ret = false;
for (GLint error = glGetError(); error; error = glGetError()) {
XLOG("GL ERROR - after %s() glError (0x%x)\n", op, error);
@@ -117,7 +120,8 @@ bool GLUtils::checkGlError(const char* op) {
return ret;
}
-bool GLUtils::checkGlErrorOn(void* p, const char* op) {
+bool GLUtils::checkGlErrorOn(void* p, const char* op)
+{
bool ret = false;
for (GLint error = glGetError(); error; error = glGetError()) {
XLOG("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
@@ -130,17 +134,19 @@ bool GLUtils::checkGlErrorOn(void* p, const char* op) {
// GL & EGL extension checks
/////////////////////////////////////////////////////////////////////////////////////////
-bool GLUtils::isEGLImageSupported() {
+bool GLUtils::isEGLImageSupported()
+{
const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
- return eglExtensions && glExtensions &&
- strstr(eglExtensions, "EGL_KHR_image_base") &&
- strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") &&
- strstr(glExtensions, "GL_OES_EGL_image");
+ return eglExtensions && glExtensions
+ && strstr(eglExtensions, "EGL_KHR_image_base")
+ && strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image")
+ && strstr(glExtensions, "GL_OES_EGL_image");
}
-bool GLUtils::isEGLFenceSyncSupported() {
+bool GLUtils::isEGLFenceSyncSupported()
+{
const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync");
}
@@ -151,39 +157,40 @@ bool GLUtils::isEGLFenceSyncSupported() {
static GLenum getInternalFormat(SkBitmap::Config config)
{
- switch(config) {
- case SkBitmap::kA8_Config:
- return GL_ALPHA;
- case SkBitmap::kARGB_4444_Config:
- return GL_RGBA;
- case SkBitmap::kARGB_8888_Config:
- return GL_RGBA;
- case SkBitmap::kRGB_565_Config:
- return GL_RGB;
- default:
- return -1;
+ switch (config) {
+ case SkBitmap::kA8_Config:
+ return GL_ALPHA;
+ case SkBitmap::kARGB_4444_Config:
+ return GL_RGBA;
+ case SkBitmap::kARGB_8888_Config:
+ return GL_RGBA;
+ case SkBitmap::kRGB_565_Config:
+ return GL_RGB;
+ default:
+ return -1;
}
}
static GLenum getType(SkBitmap::Config config)
{
- switch(config) {
- case SkBitmap::kA8_Config:
- return GL_UNSIGNED_BYTE;
- case SkBitmap::kARGB_4444_Config:
- return GL_UNSIGNED_SHORT_4_4_4_4;
- case SkBitmap::kARGB_8888_Config:
- return GL_UNSIGNED_BYTE;
- case SkBitmap::kIndex8_Config:
- return -1; // No type for compressed data.
- case SkBitmap::kRGB_565_Config:
- return GL_UNSIGNED_SHORT_5_6_5;
- default:
- return -1;
+ switch (config) {
+ case SkBitmap::kA8_Config:
+ return GL_UNSIGNED_BYTE;
+ case SkBitmap::kARGB_4444_Config:
+ return GL_UNSIGNED_SHORT_4_4_4_4;
+ case SkBitmap::kARGB_8888_Config:
+ return GL_UNSIGNED_BYTE;
+ case SkBitmap::kIndex8_Config:
+ return -1; // No type for compressed data.
+ case SkBitmap::kRGB_565_Config:
+ return GL_UNSIGNED_SHORT_5_6_5;
+ default:
+ return -1;
}
}
-static EGLConfig defaultPbufferConfig(EGLDisplay display) {
+static EGLConfig defaultPbufferConfig(EGLDisplay display)
+{
EGLConfig config;
EGLint numConfigs;
@@ -195,15 +202,15 @@ static EGLConfig defaultPbufferConfig(EGLDisplay display) {
eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
GLUtils::checkEglError("eglPbufferConfig");
- if(numConfigs != 1) {
+ if (numConfigs != 1)
LOGI("eglPbufferConfig failed (%d)\n", numConfigs);
- }
return config;
}
static EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& config,
- EGLint* errorCode) {
+ EGLint* errorCode)
+{
const EGLint attribList[] = {
EGL_WIDTH, 1,
EGL_HEIGHT, 1,
@@ -222,7 +229,8 @@ static EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& conf
return surface;
}
-EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext) {
+EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
+{
checkEglError("<init>");
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
checkEglError("eglGetDisplay");
@@ -246,8 +254,8 @@ EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext) {
EGLint surfaceConfigId;
EGLBoolean success = eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &surfaceConfigId);
- EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
- EGLContext context = eglCreateContext(display, config, sharedContext, context_attribs);
+ EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ EGLContext context = eglCreateContext(display, config, sharedContext, contextAttribs);
checkEglError("eglCreateContext");
if (context == EGL_NO_CONTEXT) {
XLOG("eglCreateContext failed\n");
@@ -264,13 +272,15 @@ EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext) {
return context;
}
-void GLUtils::deleteTexture(GLuint* texture) {
+void GLUtils::deleteTexture(GLuint* texture)
+{
glDeleteTextures(1, texture);
GLUtils::checkGlError("glDeleteTexture");
*texture = 0;
}
-GLuint GLUtils::createSampleTexture() {
+GLuint GLUtils::createSampleTexture()
+{
GLuint texture;
glGenTextures(1, &texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -289,7 +299,8 @@ GLuint GLUtils::createSampleTexture() {
return texture;
}
-void GLUtils::createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter) {
+void GLUtils::createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter)
+{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
GLUtils::checkGlError("glBindTexture");
@@ -305,7 +316,8 @@ void GLUtils::createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint fi
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
}
-void GLUtils::updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter) {
+void GLUtils::updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter)
+{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
GLUtils::checkGlError("glBindTexture");
@@ -321,7 +333,8 @@ void GLUtils::updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint fi
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
}
-void GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image) {
+void GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image)
+{
EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture);
static const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
*image = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(),
@@ -329,7 +342,8 @@ void GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image) {
GLUtils::checkEglError("eglCreateImage", (*image != EGL_NO_IMAGE_KHR));
}
-void GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter) {
+void GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter)
+{
glBindTexture(GL_TEXTURE_2D, texture);
GLUtils::checkGlError("glBindTexture");
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
diff --git a/WebCore/platform/graphics/android/GLUtils.h b/WebCore/platform/graphics/android/GLUtils.h
index 1b2e823..3e7b800 100644
--- a/WebCore/platform/graphics/android/GLUtils.h
+++ b/WebCore/platform/graphics/android/GLUtils.h
@@ -23,50 +23,50 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef GLUTILS_H_
-#define GLUTILS_H_
+#ifndef GLUtils_h
+#define GLUtils_h
#if USE(ACCELERATED_COMPOSITING)
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
#include "SkBitmap.h"
#include "SkMatrix.h"
#include "TransformationMatrix.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
namespace WebCore {
class GLUtils {
public:
- // Matrix utilities
- static void toGLMatrix(GLfloat* flattened, const TransformationMatrix& matrix);
- static void toSkMatrix(SkMatrix& skmatrix, const TransformationMatrix& matrix);
- static void setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
- float right, float bottom, float nearZ, float farZ);
+ // Matrix utilities
+ static void toGLMatrix(GLfloat* flattened, const TransformationMatrix& matrix);
+ static void toSkMatrix(SkMatrix& skmatrix, const TransformationMatrix& matrix);
+ static void setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
+ float right, float bottom, float nearZ, float farZ);
- // GL & EGL error checks
- static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
- static bool checkGlErrorOn(void* p, const char* op);
- static bool checkGlError(const char* op);
+ // GL & EGL error checks
+ static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
+ static bool checkGlErrorOn(void* p, const char* op);
+ static bool checkGlError(const char* op);
- // GL & EGL extension checks
- static bool isEGLImageSupported();
- static bool isEGLFenceSyncSupported();
+ // GL & EGL extension checks
+ static bool isEGLImageSupported();
+ static bool isEGLFenceSyncSupported();
- // Texture utilities
- static EGLContext createBackgroundContext(EGLContext sharedContext);
- static void deleteTexture(GLuint* texture);
- static GLuint createSampleTexture();
- static void createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
- static void updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
- static void createEGLImageFromTexture(GLuint texture, EGLImageKHR* image);
- static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR);
+ // Texture utilities
+ static EGLContext createBackgroundContext(EGLContext sharedContext);
+ static void deleteTexture(GLuint* texture);
+ static GLuint createSampleTexture();
+ static void createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
+ static void updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
+ static void createEGLImageFromTexture(GLuint texture, EGLImageKHR* image);
+ static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR);
};
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
-#endif // GLUTILS_H_
+#endif // GLUtils_h
diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h
index 698eb4a..3b6f1d1 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/WebCore/platform/graphics/android/GLWebViewState.h
@@ -170,7 +170,7 @@ public:
unsigned int paintBaseLayerContent(SkCanvas* canvas);
void setBaseLayer(BaseLayerAndroid* layer, const IntRect& rect);
- void setExtra(BaseLayerAndroid* , SkPicture& , const IntRect& );
+ void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&);
void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale);
TiledPage* frontPage();
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 5d1c86a..1efbecc 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -276,12 +276,23 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
askForSync();
}
+void GraphicsLayerAndroid::setPreserves3D(bool preserves3D)
+{
+ if (preserves3D == m_preserves3D)
+ return;
+
+ GraphicsLayer::setPreserves3D(preserves3D);
+ m_contentLayer->setPreserves3D(preserves3D);
+ askForSync();
+}
+
void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
{
if (point == m_anchorPoint)
return;
GraphicsLayer::setAnchorPoint(point);
m_contentLayer->setAnchorPoint(point.x(), point.y());
+ m_contentLayer->setAnchorPointZ(point.z());
askForSync();
}
@@ -303,7 +314,6 @@ void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t)
GraphicsLayer::setTransform(t);
m_contentLayer->setTransform(t);
-
askForSync();
}
@@ -314,6 +324,7 @@ void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
LOG("(%x) setChildrenTransform", this);
GraphicsLayer::setChildrenTransform(t);
+ m_contentLayer->setChildrenTransform(t);
for (unsigned int i = 0; i < m_children.size(); i++) {
GraphicsLayer* layer = m_children[i];
layer->setTransform(t);
@@ -523,6 +534,7 @@ bool GraphicsLayerAndroid::repaint()
m_contentLayer->getSize().width(),
m_contentLayer->getSize().height());
+ m_contentLayer->needsRepaint();
m_needsRepaint = false;
m_invalidatedRects.clear();
@@ -549,6 +561,14 @@ bool GraphicsLayerAndroid::paintContext(SkPicture* context,
void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
{
+ for (unsigned int i = 0; i < m_children.size(); i++) {
+ GraphicsLayer* layer = m_children[i];
+ if (layer) {
+ FloatRect childrenRect = m_transform.mapRect(rect);
+ layer->setNeedsDisplayInRect(childrenRect);
+ }
+ }
+
if (!m_haveImage && !drawsContent()) {
LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
this, rect.x(), rect.y(), rect.width(), rect.height());
@@ -565,8 +585,8 @@ void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
}
#ifdef LAYER_DEBUG
- LOG("(%x) setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this,
- m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height());
+ LOG("(%x) layer %d setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this,
+ m_contentLayer->uniqueId(), m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height());
#endif
if (addInval) {
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 1e17f47..a243d65 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -55,6 +55,7 @@ public:
virtual void removeFromParent();
virtual void setPosition(const FloatPoint&);
+ virtual void setPreserves3D(bool b);
virtual void setAnchorPoint(const FloatPoint3D&);
virtual void setSize(const FloatSize&);
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index b71f525..69822b5 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -6,17 +6,34 @@
#include "AndroidAnimation.h"
#include "DrawExtra.h"
#include "GLUtils.h"
+#include "PaintLayerOperation.h"
#include "ParseCanvas.h"
#include "SkBitmapRef.h"
#include "SkBounder.h"
#include "SkDrawFilter.h"
#include "SkPaint.h"
#include "SkPicture.h"
+#include "TilesManager.h"
#include <wtf/CurrentTime.h>
#define LAYER_DEBUG // Add diagonals for debugging
#undef LAYER_DEBUG
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "LayerAndroid", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
namespace WebCore {
static int gDebugLayerAndroidInstances;
@@ -51,13 +68,20 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(),
m_isRootLayer(isRootLayer),
m_haveClip(false),
m_isFixed(false),
+ m_preserves3D(false),
+ m_anchorPointZ(0),
m_recordingPicture(0),
m_contentsImage(0),
m_extra(0),
- m_uniqueId(++gUniqueId)
+ m_uniqueId(++gUniqueId),
+ m_texture(0),
+ m_pictureUsed(0)
{
m_backgroundColor = 0;
+ m_preserves3D = false;
+ m_dirty = false;
+
gDebugLayerAndroidInstances++;
}
@@ -65,7 +89,8 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_isRootLayer(layer.m_isRootLayer),
m_haveClip(layer.m_haveClip),
m_extra(0), // deliberately not copied
- m_uniqueId(layer.m_uniqueId)
+ m_uniqueId(layer.m_uniqueId),
+ m_texture(0)
{
m_isFixed = layer.m_isFixed;
m_contentsImage = layer.m_contentsImage;
@@ -87,6 +112,13 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_recordingPicture = layer.m_recordingPicture;
SkSafeRef(m_recordingPicture);
+ m_preserves3D = layer.m_preserves3D;
+ m_anchorPointZ = layer.m_anchorPointZ;
+ m_drawTransform = layer.m_drawTransform;
+ m_childrenTransform = layer.m_childrenTransform;
+ m_dirty = layer.m_dirty;
+ m_pictureUsed = layer.m_pictureUsed;
+
for (int i = 0; i < layer.countChildren(); i++)
addChild(layer.getChild(i)->copy())->unref();
@@ -104,15 +136,19 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
m_recordingPicture(picture),
m_contentsImage(0),
m_extra(0),
- m_uniqueId(-1)
+ m_uniqueId(-1),
+ m_texture(0)
{
m_backgroundColor = 0;
+ m_dirty = false;
SkSafeRef(m_recordingPicture);
gDebugLayerAndroidInstances++;
}
LayerAndroid::~LayerAndroid()
{
+ if (m_texture)
+ m_texture->release(this);
removeChildren();
m_contentsImage->safeUnref();
m_recordingPicture->safeUnref();
@@ -158,6 +194,8 @@ bool LayerAndroid::evaluateAnimations(double time) const
void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> anim)
{
+ if (m_animations.get(anim->name()))
+ removeAnimation(anim->name());
m_animations.add(anim->name(), anim);
}
@@ -316,10 +354,11 @@ public:
bool drewText() { return m_findCheck.drewText(); }
- void setBest(const LayerAndroid* best) {
+ void setBest(const LayerAndroid* best, int x, int y)
+ {
m_best = best;
- m_bestX = m_x;
- m_bestY = m_y;
+ m_bestX = x;
+ m_bestY = y;
}
int x() const { return m_x; }
int y() const { return m_y; }
@@ -354,12 +393,14 @@ void LayerAndroid::findInner(LayerAndroid::FindState& state) const
for (int i = 0; i < countChildren(); i++)
getChild(i)->findInner(state);
// Move back into the parent coordinates.
+ int testX = state.x();
+ int testY = state.y();
state.setLocation(x + localBounds.fLeft, y + localBounds.fTop);
if (!m_recordingPicture)
return;
- if (!state.drew(m_recordingPicture, localBounds))
+ if (!contentIsScrollable() && !state.drew(m_recordingPicture, localBounds))
return;
- state.setBest(this); // set last match (presumably on top)
+ state.setBest(this, testX, testY); // set last match (presumably on top)
}
const LayerAndroid* LayerAndroid::find(int* xPtr, int* yPtr, SkPicture* root) const
@@ -414,13 +455,12 @@ void LayerAndroid::updateFixedLayersPositions(const SkRect& viewport)
void LayerAndroid::updatePositions()
{
// apply the viewport to us
- SkMatrix matrix;
if (!m_isFixed) {
// turn our fields into a matrix.
//
// TODO: this should happen in the caller, and we should remove these
// fields from our subclass
- matrix.reset();
+ SkMatrix matrix;
GLUtils::toSkMatrix(matrix, m_transform);
this->setMatrix(matrix);
}
@@ -431,30 +471,214 @@ void LayerAndroid::updatePositions()
this->getChild(i)->updatePositions();
}
+void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix, float opacity)
+{
+ IntSize bounds(getSize().width(), getSize().height());
+ FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY);
+ FloatPoint position(getPosition().fX, getPosition().fY);
+ float centerOffsetX = (0.5f - anchorPoint.x()) * bounds.width();
+ float centerOffsetY = (0.5f - anchorPoint.y()) * bounds.height();
+ float originX = anchorPoint.x() * bounds.width();
+ float originY = anchorPoint.y() * bounds.height();
+ TransformationMatrix localMatrix = parentMatrix;
+ localMatrix.translate3d(originX + position.x(),
+ originY + position.y(),
+ anchorPointZ());
+ FloatPoint p(0, 0);
+ p = localMatrix.mapPoint(p);
+ p = m_transform.mapPoint(p);
+
+ localMatrix.multLeft(m_transform);
+ localMatrix.translate3d(-originX,
+ -originY,
+ -anchorPointZ());
+ p = localMatrix.mapPoint(p);
+
+ setDrawTransform(localMatrix);
+ opacity *= getOpacity();
+ setDrawOpacity(opacity);
+
+ int count = this->countChildren();
+ if (!count)
+ return;
+
+ // Flatten to 2D if the layer doesn't preserve 3D.
+ if (!preserves3D()) {
+ localMatrix.setM13(0);
+ localMatrix.setM23(0);
+ localMatrix.setM31(0);
+ localMatrix.setM32(0);
+ localMatrix.setM33(1);
+ localMatrix.setM34(0);
+ localMatrix.setM43(0);
+ }
+ // now apply it to our children
+
+ if (!m_childrenTransform.isIdentity()) {
+ localMatrix.translate(getSize().width() * 0.5f, getSize().height() * 0.5f);
+ localMatrix.multLeft(m_childrenTransform);
+ localMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f);
+ }
+ for (int i = 0; i < count; i++)
+ this->getChild(i)->updateGLPositions(localMatrix, opacity);
+}
+
void LayerAndroid::setContentsImage(SkBitmapRef* img)
{
SkRefCnt_SafeAssign(m_contentsImage, img);
}
-void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
+bool LayerAndroid::needsTexture()
{
- if (m_haveClip) {
- SkRect r;
- r.set(0, 0, getSize().width(), getSize().height());
- canvas->clipRect(r);
+ return !m_isRootLayer && prepareContext() && m_recordingPicture->width() && m_recordingPicture->height();
+}
+
+void LayerAndroid::reserveGLTextures()
+{
+ int count = this->countChildren();
+ for (int i = 0; i < count; i++)
+ this->getChild(i)->reserveGLTextures();
+
+ if (needsTexture()) {
+ LayerTexture* texture;
+ texture = TilesManager::instance()->getExistingTextureForLayer(this);
+ // SMP flush
+ android::AutoMutex lock(m_atomicSync);
+ m_texture = texture;
+ }
+}
+
+void LayerAndroid::createGLTextures()
+{
+ int count = this->countChildren();
+ for (int i = 0; i < count; i++)
+ this->getChild(i)->createGLTextures();
+
+ if (needsTexture() && !m_texture) {
+ LayerTexture* texture;
+ texture = TilesManager::instance()->createTextureForLayer(this);
+ // SMP flush + keep dirty bit in sync
+ android::AutoMutex lock(m_atomicSync);
+ m_texture = texture;
+ m_dirty = true;
+ }
+
+ checkForObsolescence();
+}
+
+void LayerAndroid::checkForObsolescence()
+{
+ m_atomicSync.lock();
+ if (!m_texture) {
+ m_atomicSync.unlock();
return;
}
- if (!prepareContext())
+ if (!m_pictureUsed || m_texture->pictureUsed() != m_pictureUsed) {
+ XLOG("We mark layer %d as dirty because: m_pictureUsed(%d == 0?), texture picture used %x",
+ uniqueId(), m_pictureUsed, m_texture->pictureUsed());
+ m_texture->setPictureUsed(m_pictureUsed);
+ m_dirty = true;
+ }
+
+ if (!m_texture->isReady())
+ m_dirty = true;
+
+ bool dirty = m_dirty;
+ m_atomicSync.unlock();
+
+ if (!dirty)
return;
- // we just have this save/restore for opacity...
- SkAutoCanvasRestore restore(canvas, true);
+ XLOG("We schedule a paint for layer %d, because isReady %d or m_dirty %d",
+ uniqueId(), m_texture->isReady(), m_dirty);
+ PaintLayerOperation* operation = new PaintLayerOperation(this);
+ TilesManager::instance()->scheduleOperation(operation);
+}
- int canvasOpacity = SkScalarRound(opacity * 255);
- if (canvasOpacity < 255)
- canvas->setDrawFilter(new OpacityDrawFilter(canvasOpacity));
+static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
+{
+ const TransformationMatrix& transformA = a->drawTransform();
+ const TransformationMatrix& transformB = b->drawTransform();
+
+ return transformA.m43() < transformB.m43();
+}
+
+bool LayerAndroid::drawGL(SkMatrix& matrix)
+{
+ if (prepareContext() && m_texture) {
+ TextureInfo* textureInfo = m_texture->consumerLock();
+ if (textureInfo && m_texture->isReady()) {
+ SkRect rect;
+ rect.set(0, 0, getSize().width(), getSize().height());
+ TransformationMatrix m = drawTransform();
+ TilesManager::instance()->shader()->drawLayerQuad(m, rect,
+ textureInfo->m_textureId,
+ m_drawOpacity);
+ }
+ m_texture->consumerRelease();
+ }
+
+ bool askPaint = false;
+ int count = this->countChildren();
+ if (count > 0) {
+ Vector <LayerAndroid*> sublayers;
+ for (int i = 0; i < count; i++)
+ sublayers.append(this->getChild(i));
+
+ // now we sort for the transparency
+ std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
+ for (int i = 0; i < count; i++) {
+ LayerAndroid* layer = sublayers[i];
+ askPaint |= layer->drawGL(matrix);
+ }
+ }
+
+ return askPaint;
+}
+
+// This is called from the texture generation thread
+void LayerAndroid::paintBitmapGL()
+{
+ XLOG("LayerAndroid paintBitmapGL (layer %d)", uniqueId());
+ // We acquire the values below atomically. This ensures that we are reading
+ // values correctly across cores. Further, once we have these values they
+ // can be updated by other threads without consequence.
+ m_atomicSync.lock();
+ LayerTexture* texture = m_texture;
+ m_atomicSync.unlock();
+
+ if (!texture) {
+ XLOG("Layer %d doesn't have a texture!", uniqueId());
+ return;
+ }
+
+ texture->producerAcquireContext();
+ TextureInfo* textureInfo = texture->producerLock();
+
+ // at this point we can safely check the ownership (if the texture got
+ // transferred to another BaseTile under us)
+ if (texture->owner() != this) {
+ texture->producerRelease();
+ return;
+ }
+
+ XLOG("LayerAndroid %d paintBitmapGL WE ARE PAINTING", uniqueId());
+ SkCanvas* canvas = texture->canvas();
+ canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+ contentDraw(canvas);
+
+ XLOG("LayerAndroid %d paintBitmapGL PAINTING DONE, updating the texture", uniqueId());
+ m_atomicSync.lock();
+ m_dirty = false;
+ m_atomicSync.unlock();
+ texture->producerUpdate(textureInfo);
+ XLOG("LayerAndroid %d paintBitmapGL UPDATING DONE", uniqueId());
+}
+
+void LayerAndroid::contentDraw(SkCanvas* canvas)
+{
if (m_contentsImage) {
SkRect dest;
dest.set(0, 0, getSize().width(), getSize().height());
@@ -488,6 +712,28 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
#endif
}
+void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
+{
+ if (m_haveClip) {
+ SkRect r;
+ r.set(0, 0, getSize().width(), getSize().height());
+ canvas->clipRect(r);
+ return;
+ }
+
+ if (!prepareContext())
+ return;
+
+ // we just have this save/restore for opacity...
+ SkAutoCanvasRestore restore(canvas, true);
+
+ int canvasOpacity = SkScalarRound(opacity * 255);
+ if (canvasOpacity < 255)
+ canvas->setDrawFilter(new OpacityDrawFilter(canvasOpacity));
+
+ contentDraw(canvas);
+}
+
SkPicture* LayerAndroid::recordContext()
{
if (prepareContext(true))
diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h
index 1269a1d..3d1c5af 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/WebCore/platform/graphics/android/LayerAndroid.h
@@ -19,9 +19,13 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "FloatPoint.h"
+#include "FloatPoint3D.h"
+#include "LayerTexture.h"
#include "RefPtr.h"
#include "SkColor.h"
#include "SkLayer.h"
+#include "TextureOwner.h"
#include "TransformationMatrix.h"
#include <wtf/HashMap.h>
@@ -76,8 +80,11 @@ struct SkLength {
namespace WebCore {
class AndroidAnimation;
+class BackedDoubleBufferedTexture;
+class LayerAndroidFindState;
+class TiledPage;
-class LayerAndroid : public SkLayer {
+class LayerAndroid : public SkLayer, public TextureOwner {
public:
LayerAndroid(bool isRootLayer);
@@ -85,11 +92,39 @@ public:
LayerAndroid(SkPicture*);
virtual ~LayerAndroid();
+ // TextureOwner methods
+ virtual void removeTexture()
+ {
+ android::AutoMutex lock(m_atomicSync);
+ m_texture = 0;
+ }
+ virtual TiledPage* page() { return 0; }
+
static int instancesCount();
void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
FloatPoint translation() const;
SkRect bounds() const;
+ // called on the root layer
+ void reserveGLTextures();
+ void createGLTextures();
+
+ bool needsTexture();
+ void checkForObsolescence();
+
+ bool drawGL(SkMatrix&);
+ void paintBitmapGL();
+ void updateGLPositions(const TransformationMatrix& parentMatrix, float opacity);
+ void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
+
+ bool preserves3D() { return m_preserves3D; }
+ void setPreserves3D(bool value) { m_preserves3D = value; }
+ void setAnchorPointZ(float z) { m_anchorPointZ = z; }
+ float anchorPointZ() { return m_anchorPointZ; }
+ void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; }
+ const TransformationMatrix& drawTransform() const { return m_drawTransform; }
+ void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; }
+
void setFixedPosition(SkLength left, // CSS left property
SkLength top, // CSS top property
SkLength right, // CSS right property
@@ -177,12 +212,17 @@ public:
m_recordingPicture and m_contentsImage.
*/
void setContentsImage(SkBitmapRef* img);
+ bool hasContentsImage() { return m_contentsImage; }
void bounds(SkRect*) const;
virtual bool contentIsScrollable() const { return false; }
virtual LayerAndroid* copy() const { return new LayerAndroid(*this); }
+ void needsRepaint() { m_pictureUsed++; }
+ unsigned int pictureUsed() { return m_pictureUsed; }
+ void contentDraw(SkCanvas*);
+
protected:
virtual void onDraw(SkCanvas*, SkScalar opacity);
@@ -216,6 +256,12 @@ private:
SkColor m_backgroundColor;
+ bool m_preserves3D;
+ float m_anchorPointZ;
+ float m_drawOpacity;
+ TransformationMatrix m_drawTransform;
+ TransformationMatrix m_childrenTransform;
+
// Note that m_recordingPicture and m_contentsImage are mutually exclusive;
// m_recordingPicture is used when WebKit is asked to paint the layer's
// content, while m_contentsImage contains an image that we directly
@@ -231,6 +277,17 @@ private:
DrawExtra* m_extra;
int m_uniqueId;
+ // GL textures management
+ LayerTexture* m_texture;
+ // used to signal that the tile is out-of-date and needs to be redrawn
+ bool m_dirty;
+ unsigned int m_pictureUsed;
+
+ // This mutex serves two purposes. (1) It ensures that certain operations
+ // happen atomically and (2) it makes sure those operations are synchronized
+ // across all threads and cores.
+ android::Mutex m_atomicSync;
+
typedef SkLayer INHERITED;
};
diff --git a/WebCore/platform/graphics/android/LayerTexture.cpp b/WebCore/platform/graphics/android/LayerTexture.cpp
new file mode 100644
index 0000000..294c3d3
--- /dev/null
+++ b/WebCore/platform/graphics/android/LayerTexture.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LayerTexture.h"
+
+#define DOUBLE_BUFFERED_TEXTURE_MINIMUM_ACCESS 3
+
+void LayerTexture::producerUpdate(TextureInfo* textureInfo)
+{
+ update();
+ BackedDoubleBufferedTexture::producerUpdate(textureInfo);
+}
+
+void LayerTexture::update()
+{
+ // FIXME: fix the double buffered texture class instead of doing this
+ // this is a stop gap measure and should be removed.
+ // Right now we have to update the textures 3 times (one create, two
+ // updates) before we can be sure to have a non-corrupted texture
+ // to display.
+ if (m_textureUpdates < DOUBLE_BUFFERED_TEXTURE_MINIMUM_ACCESS)
+ m_textureUpdates++;
+}
+
+bool LayerTexture::isReady()
+{
+ return m_textureUpdates == DOUBLE_BUFFERED_TEXTURE_MINIMUM_ACCESS;
+}
diff --git a/WebCore/platform/graphics/android/LayerTexture.h b/WebCore/platform/graphics/android/LayerTexture.h
new file mode 100644
index 0000000..959978f
--- /dev/null
+++ b/WebCore/platform/graphics/android/LayerTexture.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LayerTexture_h
+#define LayerTexture_h
+
+#include "BackedDoubleBufferedTexture.h"
+
+namespace WebCore {
+
+class LayerTexture : public BackedDoubleBufferedTexture {
+ public:
+ LayerTexture(uint32_t w, uint32_t h,
+ SkBitmap::Config config = SkBitmap::kARGB_8888_Config)
+ : BackedDoubleBufferedTexture(w, h, config)
+ , m_id(0)
+ , m_pictureUsed(0)
+ , m_textureUpdates(0)
+ {}
+
+ int id() { return m_id; }
+ void setId(int id) { m_id = id; }
+
+ unsigned int pictureUsed() { return m_pictureUsed; }
+ void setPictureUsed(unsigned pictureUsed) { m_pictureUsed = pictureUsed; }
+ bool isReady();
+ virtual void producerUpdate(TextureInfo* textureInfo);
+
+ private:
+ void update();
+
+ int m_id;
+ unsigned int m_pictureUsed;
+ unsigned int m_textureUpdates;
+};
+
+} // namespace WebCore
+
+#endif // LayerTexture_h
diff --git a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
index 49aafec..e8e29bf 100644
--- a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
+++ b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
@@ -115,7 +115,7 @@ protected:
MediaPlayer::ReadyState m_readyState;
MediaPlayer::NetworkState m_networkState;
- SkBitmap* m_poster; // not owned
+ SkBitmap* m_poster; // not owned
String m_posterUrl;
IntSize m_naturalSize;
@@ -124,7 +124,7 @@ protected:
bool m_isVisible;
};
-} // namespace WebCore
+} // namespace WebCore
#endif
diff --git a/WebCore/platform/graphics/android/PaintLayerOperation.cpp b/WebCore/platform/graphics/android/PaintLayerOperation.cpp
new file mode 100644
index 0000000..a3ef148
--- /dev/null
+++ b/WebCore/platform/graphics/android/PaintLayerOperation.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PaintLayerOperation.h"
+
+#include "LayerAndroid.h"
+
+bool PaintLayerOperation::operator==(const QueuedOperation* operation)
+{
+ if (operation->type() != type())
+ return false;
+ const PaintLayerOperation* op = static_cast<const PaintLayerOperation*>(operation);
+ return op->m_layer == m_layer;
+}
+
+void PaintLayerOperation::run()
+{
+ if (m_layer)
+ m_layer->paintBitmapGL();
+}
+
+SkLayer* PaintLayerOperation::baseLayer()
+{
+ if (!m_layer)
+ return 0;
+
+ return m_layer->getRootLayer();
+}
+
+bool PaintLayerFilter::check(QueuedOperation* operation)
+{
+ if (operation->type() == QueuedOperation::PaintLayer) {
+ PaintLayerOperation* op = static_cast<PaintLayerOperation*>(operation);
+ if (op->baseLayer() == m_baseLayer)
+ return true;
+ }
+ return false;
+}
diff --git a/WebCore/platform/graphics/android/PaintLayerOperation.h b/WebCore/platform/graphics/android/PaintLayerOperation.h
new file mode 100644
index 0000000..d393ac5
--- /dev/null
+++ b/WebCore/platform/graphics/android/PaintLayerOperation.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PaintLayerOperation_h
+#define PaintLayerOperation_h
+
+#include "QueuedOperation.h"
+
+class SkLayer;
+
+namespace WebCore {
+
+class LayerAndroid;
+
+class PaintLayerOperation : public QueuedOperation {
+ public:
+ PaintLayerOperation(LayerAndroid* layer)
+ : QueuedOperation(QueuedOperation::PaintLayer, 0)
+ , m_layer(layer) {}
+ virtual ~PaintLayerOperation() {}
+ virtual bool operator==(const QueuedOperation* operation);
+ virtual void run();
+ SkLayer* baseLayer();
+
+ private:
+ LayerAndroid* m_layer;
+};
+
+class PaintLayerFilter : public OperationFilter {
+ public:
+ PaintLayerFilter(SkLayer* layer) : m_baseLayer(layer) {}
+ virtual bool check(QueuedOperation* operation);
+
+ private:
+ SkLayer* m_baseLayer;
+};
+
+}
+
+#endif // PaintLayerOperation_h
diff --git a/WebCore/platform/graphics/android/QueuedOperation.h b/WebCore/platform/graphics/android/QueuedOperation.h
index 7472db7..089483d 100644
--- a/WebCore/platform/graphics/android/QueuedOperation.h
+++ b/WebCore/platform/graphics/android/QueuedOperation.h
@@ -32,7 +32,7 @@ namespace WebCore {
class QueuedOperation {
public:
- enum OperationType { Undefined, PaintTileSet, DeleteTexture };
+ enum OperationType { Undefined, PaintTileSet, PaintLayer, DeleteTexture };
QueuedOperation(OperationType type, TiledPage* page)
: m_type(type)
, m_page(page) {}
@@ -46,15 +46,13 @@ class QueuedOperation {
TiledPage* m_page;
};
-class OperationFilter
-{
+class OperationFilter {
public:
- virtual ~OperationFilter() {}
- virtual bool check(QueuedOperation* operation) = 0;
+ virtual ~OperationFilter() {}
+ virtual bool check(QueuedOperation* operation) = 0;
};
-class PageFilter : public OperationFilter
-{
+class PageFilter : public OperationFilter {
public:
PageFilter(TiledPage* page) : m_page(page) {}
virtual bool check(QueuedOperation* operation)
diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
index 7b40b8d..ca8f03c 100644
--- a/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
@@ -5,10 +5,11 @@
namespace WebCore {
-bool ScrollableLayerAndroid::scrollTo(int x, int y) {
+bool ScrollableLayerAndroid::scrollTo(int x, int y)
+{
SkIRect scrollBounds;
getScrollRect(&scrollBounds);
- if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0)
+ if (!scrollBounds.fRight && !scrollBounds.fBottom)
return false;
SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight);
@@ -24,7 +25,8 @@ bool ScrollableLayerAndroid::scrollTo(int x, int y) {
return true;
}
-void ScrollableLayerAndroid::getScrollRect(SkIRect* out) const {
+void ScrollableLayerAndroid::getScrollRect(SkIRect* out) const
+{
const SkPoint& pos = getPosition();
out->fLeft = m_scrollLimits.fLeft - pos.fX;
out->fTop = m_scrollLimits.fTop - pos.fY;
diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
index 25f9900..697fe74 100644
--- a/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
+++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
@@ -32,7 +32,8 @@ public:
: LayerAndroid(layer)
, m_scrollLimits(layer.m_scrollLimits) {}
ScrollableLayerAndroid(const LayerAndroid& layer)
- : LayerAndroid(layer) {
+ : LayerAndroid(layer)
+ {
m_scrollLimits.setEmpty();
}
virtual ~ScrollableLayerAndroid() {};
@@ -51,7 +52,8 @@ public:
// fBottom = maxY
void getScrollRect(SkIRect* out) const;
- void setScrollLimits(float x, float y, float width, float height) {
+ void setScrollLimits(float x, float y, float width, float height)
+ {
m_scrollLimits.set(x, y, x + width, y + height);
}
@@ -63,4 +65,4 @@ private:
#endif // USE(ACCELERATED_COMPOSITING)
-#endif // LayerAndroid_h
+#endif // LayerAndroid_h
diff --git a/WebCore/platform/graphics/android/ShaderProgram.cpp b/WebCore/platform/graphics/android/ShaderProgram.cpp
index 2195bd4..ac6375d 100644
--- a/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/WebCore/platform/graphics/android/ShaderProgram.cpp
@@ -28,9 +28,9 @@
#if USE(ACCELERATED_COMPOSITING)
-#include <GLES2/gl2.h>
#include "GLUtils.h"
+#include <GLES2/gl2.h>
#include <cutils/log.h>
#include <wtf/CurrentTime.h>
#include <wtf/text/CString.h>
@@ -59,10 +59,11 @@ static const char gFragmentShader[] =
" gl_FragColor.a *= alpha; "
"}\n";
-GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource) {
+GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource)
+{
GLuint shader = glCreateShader(shaderType);
if (shader) {
- glShaderSource(shader, 1, &pSource, NULL);
+ glShaderSource(shader, 1, &pSource, 0);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
@@ -72,7 +73,7 @@ GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource) {
if (infoLen) {
char* buf = (char*) malloc(infoLen);
if (buf) {
- glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ glGetShaderInfoLog(shader, infoLen, 0, buf);
XLOG("could not compile shader %d:\n%s\n", shaderType, buf);
free(buf);
}
@@ -84,16 +85,15 @@ GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource) {
return shader;
}
-GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragmentSource) {
+GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragmentSource)
+{
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
- if (!vertexShader) {
+ if (!vertexShader)
return 0;
- }
GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
- if (!pixelShader) {
+ if (!pixelShader)
return 0;
- }
GLuint program = glCreateProgram();
if (program) {
@@ -110,7 +110,7 @@ GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFrag
if (bufLength) {
char* buf = (char*) malloc(bufLength);
if (buf) {
- glGetProgramInfoLog(program, bufLength, NULL, buf);
+ glGetProgramInfoLog(program, bufLength, 0, buf);
XLOG("could not link program:\n%s\n", buf);
free(buf);
}
@@ -122,7 +122,8 @@ GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFrag
return program;
}
-ShaderProgram::ShaderProgram() {
+ShaderProgram::ShaderProgram()
+{
m_program = createProgram(gVertexShader, gFragmentShader);
m_hProjectionMatrix = glGetUniformLocation(m_program, "projectionMatrix");
@@ -130,10 +131,10 @@ ShaderProgram::ShaderProgram() {
m_hTexSampler = glGetUniformLocation(m_program, "s_texture");
const GLfloat coord[] = {
- 0.0f, 0.0f, //C
- 1.0f, 0.0f, //D
- 0.0f, 1.0f, //A
- 1.0f, 1.0f //B
+ 0.0f, 0.0f, // C
+ 1.0f, 0.0f, // D
+ 0.0f, 1.0f, // A
+ 1.0f, 1.0f // B
};
glGenBuffers(1, m_textureBuffer);
@@ -145,14 +146,16 @@ ShaderProgram::ShaderProgram() {
// Drawing
/////////////////////////////////////////////////////////////////////////////////////////
-void ShaderProgram::setViewport(SkRect& viewport) {
+void ShaderProgram::setViewport(SkRect& viewport)
+{
TransformationMatrix ortho;
GLUtils::setOrthographicMatrix(ortho, viewport.fLeft, viewport.fTop,
viewport.fRight, viewport.fBottom, -1000, 1000);
m_projectionMatrix = ortho;
}
-void ShaderProgram::setProjectionMatrix(SkRect& geometry) {
+void ShaderProgram::setProjectionMatrix(SkRect& geometry)
+{
TransformationMatrix translate;
translate.translate3d(geometry.fLeft, geometry.fTop, 0.0);
TransformationMatrix scale;
@@ -167,7 +170,8 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry) {
glUniformMatrix4fv(m_hProjectionMatrix, 1, GL_FALSE, projectionMatrix);
}
-void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity) {
+void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity)
+{
setProjectionMatrix(geometry);
glActiveTexture(GL_TEXTURE0);
@@ -185,7 +189,8 @@ void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity) {
}
void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
- SkRect& geometry, int textureId, float opacity) {
+ SkRect& geometry, int textureId, float opacity)
+{
TransformationMatrix renderMatrix = drawMatrix;
renderMatrix.scale3d(geometry.width(), geometry.height(), 1);
diff --git a/WebCore/platform/graphics/android/ShaderProgram.h b/WebCore/platform/graphics/android/ShaderProgram.h
index 93a6d4c..785b42d 100644
--- a/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/WebCore/platform/graphics/android/ShaderProgram.h
@@ -14,48 +14,48 @@
* limitations under the License.
*/
-#ifndef SHADERPROGRAM_H_
-#define SHADERPROGRAM_H_
+#ifndef ShaderProgram_h
+#define ShaderProgram_h
#if USE(ACCELERATED_COMPOSITING)
-#include <GLES2/gl2.h>
#include "SkRect.h"
#include "TransformationMatrix.h"
+#include <GLES2/gl2.h>
namespace WebCore {
class ShaderProgram {
public:
- ShaderProgram();
- int projectionMatrix() { return m_hProjectionMatrix; }
- int alpha() { return m_hAlpha; }
- int textureSampler() { return m_hTexSampler; }
- int program() { return m_program; }
-
- // Drawing
- void setViewport(SkRect& viewport);
- void drawQuad(SkRect& geometry, int textureId, float opacity);
- void drawLayerQuad(const TransformationMatrix& drawMatrix,
+ ShaderProgram();
+ int projectionMatrix() { return m_hProjectionMatrix; }
+ int alpha() { return m_hAlpha; }
+ int textureSampler() { return m_hTexSampler; }
+ int program() { return m_program; }
+
+ // Drawing
+ void setViewport(SkRect& viewport);
+ void drawQuad(SkRect& geometry, int textureId, float opacity);
+ void drawLayerQuad(const TransformationMatrix& drawMatrix,
SkRect& geometry, int textureId, float opacity);
private:
- GLuint loadShader(GLenum shaderType, const char* pSource);
- GLuint createProgram(const char* vertexSource, const char* fragmentSource);
- void setProjectionMatrix(SkRect& geometry);
+ GLuint loadShader(GLenum shaderType, const char* pSource);
+ GLuint createProgram(const char* vertexSource, const char* fragmentSource);
+ void setProjectionMatrix(SkRect& geometry);
- int m_program;
+ int m_program;
- TransformationMatrix m_projectionMatrix;
- GLuint m_textureBuffer[1];
+ TransformationMatrix m_projectionMatrix;
+ GLuint m_textureBuffer[1];
- // uniforms
- int m_hProjectionMatrix;
- int m_hAlpha;
- int m_hTexSampler;
+ // uniforms
+ int m_hProjectionMatrix;
+ int m_hAlpha;
+ int m_hTexSampler;
};
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
-#endif // SHADERPROGRAM_H_
+#endif // ShaderProgram_h
diff --git a/WebCore/platform/graphics/android/SharedTexture.cpp b/WebCore/platform/graphics/android/SharedTexture.cpp
index 16ec97f..76d6da0 100644
--- a/WebCore/platform/graphics/android/SharedTexture.cpp
+++ b/WebCore/platform/graphics/android/SharedTexture.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "SharedTexture.h"
+
#include "GLUtils.h"
#define LOG_NDEBUG 1
@@ -33,30 +34,35 @@
namespace WebCore {
-TextureInfo::TextureInfo() {
+TextureInfo::TextureInfo()
+{
m_textureId = GL_NO_TEXTURE;
m_width = 0;
m_height = 0;
m_internalFormat = 0;
}
-bool TextureInfo::equalsAttributes(const TextureInfo* otherTexture) {
- return otherTexture->m_width == m_width &&
- otherTexture->m_height == m_height &&
- otherTexture->m_internalFormat == m_internalFormat;
+bool TextureInfo::equalsAttributes(const TextureInfo* otherTexture)
+{
+ return otherTexture->m_width == m_width
+ && otherTexture->m_height == m_height
+ && otherTexture->m_internalFormat == m_internalFormat;
}
-void TextureInfo::copyAttributes(const TextureInfo* sourceTexture) {
+void TextureInfo::copyAttributes(const TextureInfo* sourceTexture)
+{
m_width = sourceTexture->m_width;
m_height = sourceTexture->m_height;
m_internalFormat = sourceTexture->m_internalFormat;
}
-bool TextureInfo::operator==(const TextureInfo& otherTexture) {
+bool TextureInfo::operator==(const TextureInfo& otherTexture)
+{
return otherTexture.m_textureId == m_textureId && equalsAttributes(&otherTexture);
}
-SharedTexture::SharedTexture() {
+SharedTexture::SharedTexture()
+{
m_display = eglGetCurrentDisplay();
m_eglImage = EGL_NO_IMAGE_KHR;
m_isNewImage = true;
@@ -64,7 +70,7 @@ SharedTexture::SharedTexture() {
m_supportsEGLImage = GLUtils::isEGLImageSupported();
m_supportsEGLFenceSyncKHR = GLUtils::isEGLFenceSyncSupported();
- //TODO temporarily disable fence sync until nvidia implementation is complete
+ // TODO temporarily disable fence sync until nvidia implementation is complete
m_supportsEGLFenceSyncKHR = false;
LOGI("imageEGL: %d syncKHR: %d", m_supportsEGLImage, m_supportsEGLFenceSyncKHR);
@@ -74,28 +80,29 @@ SharedTexture::SharedTexture() {
// terminated all providers. If EGLImages are used, the deletion of the
// source texture and EGLImage is the responsibility of the caller. In the case
// of double buffered textures this is handled in the onDestroy(...) method.
-SharedTexture::~SharedTexture() {
- if (m_supportsEGLImage) {
+SharedTexture::~SharedTexture()
+{
+ if (m_supportsEGLImage)
GLUtils::deleteTexture(&m_targetTexture.m_textureId);
- } else {
+ else
GLUtils::deleteTexture(&m_sourceTexture.m_textureId);
- }
}
-void SharedTexture::initSourceTexture() {
+void SharedTexture::initSourceTexture()
+{
glGenTextures(1, &m_sourceTexture.m_textureId);
}
-TextureInfo* SharedTexture::lockSource() {
+TextureInfo* SharedTexture::lockSource()
+{
m_lock.lock();
if (m_supportsEGLFenceSyncKHR && m_syncObject != EGL_NO_SYNC_KHR) {
EGLint status = eglClientWaitSyncKHR(m_display, m_syncObject, 0, 1000000);
- if (status == EGL_TIMEOUT_EXPIRED_KHR) {
+ if (status == EGL_TIMEOUT_EXPIRED_KHR)
LOGE("Sync timeout for shared texture (%d)", m_sourceTexture.m_textureId);
- }
eglDestroySyncKHR(m_display, m_syncObject);
m_syncObject = EGL_NO_SYNC_KHR;
@@ -104,8 +111,8 @@ TextureInfo* SharedTexture::lockSource() {
return &m_sourceTexture;
}
-void SharedTexture::releaseSource() {
-
+void SharedTexture::releaseSource()
+{
if (m_supportsEGLImage) {
// delete the existing image if needed
if (!m_sourceTexture.equalsAttributes(&m_targetTexture)) {
@@ -138,19 +145,20 @@ void SharedTexture::releaseSource() {
m_lock.unlock();
}
-TextureInfo* SharedTexture::lockTarget() {
+TextureInfo* SharedTexture::lockTarget()
+{
m_lock.lock();
- if ((!m_supportsEGLImage && m_targetTexture.m_textureId == GL_NO_TEXTURE) ||
- (m_supportsEGLImage && m_eglImage == EGL_NO_IMAGE_KHR)) {
+ if ((!m_supportsEGLImage && m_targetTexture.m_textureId == GL_NO_TEXTURE)
+ || (m_supportsEGLImage && m_eglImage == EGL_NO_IMAGE_KHR)) {
m_lock.unlock();
return 0;
}
if (m_supportsEGLImage && (m_isNewImage || m_targetTexture.m_textureId == GL_NO_TEXTURE)) {
- if (m_targetTexture.m_textureId == GL_NO_TEXTURE) {
+ if (m_targetTexture.m_textureId == GL_NO_TEXTURE)
glGenTextures(1, &m_targetTexture.m_textureId);
- }
+
GLUtils::createTextureFromEGLImage(m_targetTexture.m_textureId, m_eglImage);
LOGV("Generating Consumer Texture from 0x%x", m_eglImage);
m_isNewImage = false;
@@ -159,13 +167,13 @@ TextureInfo* SharedTexture::lockTarget() {
return &m_targetTexture;
}
-void SharedTexture::releaseTarget() {
+void SharedTexture::releaseTarget()
+{
if (m_supportsEGLFenceSyncKHR) {
- if (m_syncObject != EGL_NO_SYNC_KHR) {
+ if (m_syncObject != EGL_NO_SYNC_KHR)
eglDestroySyncKHR(m_display, m_syncObject);
- }
- m_syncObject = eglCreateSyncKHR(m_display, EGL_SYNC_FENCE_KHR, NULL);
+ m_syncObject = eglCreateSyncKHR(m_display, EGL_SYNC_FENCE_KHR, 0);
} else {
// TODO the flush currently prevents the screen from getting partial
// updates but the only way to guarantee this is to call glFinish. Until
diff --git a/WebCore/platform/graphics/android/SharedTexture.h b/WebCore/platform/graphics/android/SharedTexture.h
index 581ad77..e654c5c 100644
--- a/WebCore/platform/graphics/android/SharedTexture.h
+++ b/WebCore/platform/graphics/android/SharedTexture.h
@@ -23,14 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SharedTexture__DEFINED
-#define SharedTexture__DEFINED
+#ifndef SharedTexture_h
+#define SharedTexture_h
-#include <utils/threads.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <utils/threads.h>
namespace WebCore {
@@ -132,4 +132,4 @@ private:
} // namespace WebCore
-#endif // SharedTexture__DEFINED
+#endif // SharedTexture_h
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp
index 234c7f9..289665d 100644
--- a/WebCore/platform/graphics/android/TexturesGenerator.cpp
+++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp
@@ -28,7 +28,9 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "BaseLayerAndroid.h"
#include "GLUtils.h"
+#include "PaintLayerOperation.h"
#include "TilesManager.h"
#ifdef DEBUG
@@ -76,6 +78,11 @@ void TexturesGenerator::removeOperationsForPage(TiledPage* page)
removeOperationsForFilter(new PageFilter(page));
}
+void TexturesGenerator::removeOperationsForBaseLayer(BaseLayerAndroid* layer)
+{
+ removeOperationsForFilter(new PaintLayerFilter(layer));
+}
+
void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
{
mRequestedOperationsLock.lock();
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.h b/WebCore/platform/graphics/android/TexturesGenerator.h
index 84dbeab..0e40e4a 100644
--- a/WebCore/platform/graphics/android/TexturesGenerator.h
+++ b/WebCore/platform/graphics/android/TexturesGenerator.h
@@ -37,6 +37,9 @@ namespace WebCore {
using namespace android;
+class BaseLayerAndroid;
+class LayerAndroid;
+
class TexturesGenerator : public Thread {
public:
TexturesGenerator() : Thread()
@@ -46,6 +49,7 @@ public:
virtual status_t readyToRun();
void removeOperationsForPage(TiledPage* page);
+ void removeOperationsForBaseLayer(BaseLayerAndroid* layer);
void removeOperationsForFilter(OperationFilter* filter);
void scheduleOperation(QueuedOperation* operation);
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index 38dd282..3e174d1 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -30,6 +30,7 @@
#include "BaseTile.h"
#include "SkCanvas.h"
+#include "SkDevice.h"
#include "SkPaint.h"
#include <cutils/atomic.h>
@@ -59,20 +60,27 @@
#define TILE_WIDTH 300
#define TILE_HEIGHT 300
+// Define a maximum amount of ram used by layers
+#define MAX_LAYERS_ALLOCATION 20971520 // 20Mb
+#define BYTES_PER_PIXEL 4 // 8888 config
+
namespace WebCore {
TilesManager::TilesManager()
- : m_generatorReady(false)
+ : m_layersMemoryUsage(0)
+ , m_generatorReady(false)
{
+ XLOG("TilesManager ctor");
m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
for (int i = 0; i < MAX_TEXTURE_ALLOCATION; i++) {
BackedDoubleBufferedTexture* texture = new BackedDoubleBufferedTexture(
tileWidth(), tileHeight());
// the atomic load ensures that the texture has been fully initialized
// before we pass a pointer for other threads to operate on
- m_textures.append(
- (BackedDoubleBufferedTexture*)android_atomic_acquire_load((int32_t*)&texture));
+ m_textures.append(reinterpret_cast<BackedDoubleBufferedTexture*>(
+ android_atomic_acquire_load(reinterpret_cast<int32_t*>(&texture))));
}
+ XLOG("TilesManager ctor");
m_pixmapsGenerationThread = new TexturesGenerator();
m_pixmapsGenerationThread->run("TexturesGenerator");
@@ -86,6 +94,7 @@ void TilesManager::enableTextures()
BackedDoubleBufferedTexture* texture = m_textures[i];
texture->producerAcquireContext();
}
+ XLOG("enableTextures");
}
void TilesManager::printTextures()
@@ -217,6 +226,74 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner)
return 0;
}
+LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer)
+{
+ android::Mutex::Autolock lock(m_texturesLock);
+ for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
+ if (m_layersTextures[i]->id() != layer->uniqueId())
+ continue;
+ if (layer->getSize() != m_layersTextures[i]->getSize())
+ continue;
+
+ XLOG("return layer %d (%x) for tile %d (%x)",
+ i, m_layersTextures[i],
+ layer->uniqueId(), layer);
+
+ if (m_layersTextures[i]->acquire(layer))
+ return m_layersTextures[i];
+ }
+ return 0;
+}
+
+void TilesManager::printLayersTextures(const char* s)
+{
+#ifdef DEBUG
+ for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
+ XLOG("[%d] %s, texture %x for layer %d, owner: %x", i, s, m_layersTextures[i],
+ m_layersTextures[i]->id(), m_layersTextures[i]->owner());
+ }
+#endif
+}
+
+void TilesManager::cleanupLayersTextures(bool forceCleanup)
+{
+ android::Mutex::Autolock lock(m_texturesLock);
+#ifdef DEBUG
+ printLayersTextures("cleanup");
+#endif
+ for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
+ LayerTexture* texture = m_layersTextures[i];
+
+ if (forceCleanup)
+ texture->setOwner(0);
+
+ if (!texture->owner()) {
+ m_layersMemoryUsage -= (int) texture->getSize().fWidth
+ * (int) texture->getSize().fHeight * BYTES_PER_PIXEL;
+ m_layersTextures.remove(i);
+ delete texture;
+ }
+ }
+}
+
+LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer)
+{
+ int w = layer->getWidth();
+ int h = layer->getHeight();
+ int size = w * h * BYTES_PER_PIXEL;
+
+ if (m_layersMemoryUsage + size > MAX_LAYERS_ALLOCATION)
+ cleanupLayersTextures(true);
+
+ android::Mutex::Autolock lock(m_texturesLock);
+ LayerTexture* texture = new LayerTexture(w, h);
+ texture->setId(layer->uniqueId());
+ m_layersTextures.append(texture);
+ texture->acquire(layer);
+ m_layersMemoryUsage += size;
+ return texture;
+}
+
int TilesManager::maxTextureCount()
{
return MAX_TEXTURE_ALLOCATION;
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
index f855738..e69db4c 100644
--- a/WebCore/platform/graphics/android/TilesManager.h
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -30,6 +30,8 @@
#include "BackedDoubleBufferedTexture.h"
#include "BaseTile.h"
+#include "LayerAndroid.h"
+#include "LayerTexture.h"
#include "ShaderProgram.h"
#include "TexturesGenerator.h"
#include "TiledPage.h"
@@ -48,6 +50,11 @@ public:
m_pixmapsGenerationThread->removeOperationsForPage(page);
}
+ void removeOperationsForBaseLayer(BaseLayerAndroid* layer)
+ {
+ m_pixmapsGenerationThread->removeOperationsForBaseLayer(layer);
+ }
+
void scheduleOperation(QueuedOperation* operation)
{
m_pixmapsGenerationThread->scheduleOperation(operation);
@@ -57,6 +64,11 @@ public:
BackedDoubleBufferedTexture* getAvailableTexture(BaseTile* owner);
+ void printLayersTextures(const char* s);
+ void cleanupLayersTextures(bool forceCleanup = false);
+ LayerTexture* getExistingTextureForLayer(LayerAndroid* layer);
+ LayerTexture* createTextureForLayer(LayerAndroid* layer);
+
void markGeneratorAsReady()
{
android::Mutex::Autolock lock(m_generatorLock);
@@ -84,6 +96,9 @@ private:
}
Vector<BackedDoubleBufferedTexture*> m_textures;
+ Vector<LayerTexture*> m_layersTextures;
+
+ unsigned int m_layersMemoryUsage;
bool m_generatorReady;