summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Roard <nicolas@android.com>2010-10-04 13:37:38 -0700
committerNicolas Roard <nicolas@android.com>2010-10-13 11:05:25 -0700
commita5ffb7c279df240a07658953e1bd5df6d0480cb6 (patch)
tree6df2820d0158915b646d9d2fa4969713f1674d8d
parenta8dc96a2bf5512decc072f69093f006739c04fd2 (diff)
downloadexternal_webkit-a5ffb7c279df240a07658953e1bd5df6d0480cb6.zip
external_webkit-a5ffb7c279df240a07658953e1bd5df6d0480cb6.tar.gz
external_webkit-a5ffb7c279df240a07658953e1bd5df6d0480cb6.tar.bz2
GL rendering (without layers)
This is a two-parts CL, Its counterpart is https://android-git.corp.google.com/g/#change,64863 Change-Id: I40fcf3b7b6d28b887b101219c973070aeefbb777
-rw-r--r--Android.mk7
-rw-r--r--CleanSpec.mk1
-rw-r--r--WebCore/Android.mk12
-rw-r--r--WebCore/config.h1
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp164
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h120
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp214
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.h29
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp229
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h83
-rw-r--r--WebCore/platform/graphics/android/DoubleBufferedTexture.cpp45
-rw-r--r--WebCore/platform/graphics/android/DoubleBufferedTexture.h31
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp219
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.h218
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.cpp118
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.h57
-rw-r--r--WebCore/platform/graphics/android/TiledPage.cpp257
-rw-r--r--WebCore/platform/graphics/android/TiledPage.h64
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp254
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h97
-rw-r--r--WebCore/platform/graphics/android/TilesSet.cpp104
-rw-r--r--WebCore/platform/graphics/android/TilesSet.h76
-rw-r--r--WebKit/android/nav/WebView.cpp76
23 files changed, 2428 insertions, 48 deletions
diff --git a/Android.mk b/Android.mk
index d0a1813..074e087 100644
--- a/Android.mk
+++ b/Android.mk
@@ -292,6 +292,9 @@ LOCAL_CFLAGS += -DGOOGLEURL
LOCAL_CFLAGS += -DWTF_USE_CHROME_NETWORK_STACK
endif # HTTP_STACK == chrome
+# Adds GL and EGL extensions for the GL backend
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
# Enable JSC JIT if JSC is used and ENABLE_JSC_JIT environment
# variable is set to true
ifeq ($(JAVASCRIPT_ENGINE),jsc)
@@ -344,7 +347,9 @@ LOCAL_SHARED_LIBRARIES := \
libicuuc \
libicui18n \
libmedia \
- libsurfaceflinger_client
+ libsurfaceflinger_client \
+ libEGL \
+ libGLESv2
ifeq ($(WEBCORE_INSTRUMENTATION),true)
LOCAL_SHARED_LIBRARIES += libhardware_legacy
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 587af0f..e35aa64 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -66,6 +66,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_int
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_intermediates)
# ************************************************
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index a7c3754..9f84b10 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -556,12 +556,18 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/WidthIterator.cpp \
\
platform/graphics/android/AndroidAnimation.cpp \
+ platform/graphics/android/BackedDoubleBufferedTexture.cpp \
+ platform/graphics/android/BaseLayerAndroid.cpp \
+ platform/graphics/android/BaseTile.cpp \
platform/graphics/android/BitmapAllocatorAndroid.cpp \
+ platform/graphics/android/DoubleBufferedTexture.cpp \
platform/graphics/android/FontAndroid.cpp \
platform/graphics/android/FontCacheAndroid.cpp \
platform/graphics/android/FontCustomPlatformData.cpp \
platform/graphics/android/FontDataAndroid.cpp \
platform/graphics/android/FontPlatformDataAndroid.cpp \
+ platform/graphics/android/GLUtils.cpp \
+ platform/graphics/android/GLWebViewState.cpp \
platform/graphics/android/GlyphMapAndroid.cpp \
platform/graphics/android/GradientAndroid.cpp \
platform/graphics/android/GraphicsContextAndroid.cpp \
@@ -574,6 +580,12 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/PatternAndroid.cpp \
platform/graphics/android/PlatformGraphicsContext.cpp \
platform/graphics/android/SharedBufferStream.cpp \
+ platform/graphics/android/ShaderProgram.cpp \
+ platform/graphics/android/SharedTexture.cpp \
+ platform/graphics/android/TexturesGenerator.cpp \
+ platform/graphics/android/TilesManager.cpp \
+ platform/graphics/android/TiledPage.cpp \
+ platform/graphics/android/TilesSet.cpp \
platform/graphics/android/android_graphics.cpp \
ifeq ($(ENABLE_SVG), true)
diff --git a/WebCore/config.h b/WebCore/config.h
index b259f9e..70f8a20 100644
--- a/WebCore/config.h
+++ b/WebCore/config.h
@@ -99,7 +99,6 @@
#ifndef ENABLE_SVG
#define ENABLE_SVG 0
#endif
-#define ENABLE_3D_RENDERING 0
#define ENABLE_VIDEO 1
#if ENABLE_SVG
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
new file mode 100644
index 0000000..448be78
--- /dev/null
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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 "BackedDoubleBufferedTexture.h"
+
+#include "BaseTile.h"
+#include "GLUtils.h"
+
+#define LOG_NDEBUG 1
+#define LOG_TAG "BackedDoubleBufferedTexture.cpp"
+#include <utils/Log.h>
+
+namespace WebCore {
+
+BackedDoubleBufferedTexture::BackedDoubleBufferedTexture(uint32_t w, uint32_t h,
+ SkBitmap::Config config)
+ : DoubleBufferedTexture(eglGetCurrentContext()),
+ m_canvas(0),
+ m_width(0),
+ m_height(0),
+ m_usedLevel(-1),
+ m_owner(0),
+ m_painter(0),
+ m_busy(false)
+{
+ setBitmap(w, h, config);
+}
+
+BackedDoubleBufferedTexture::~BackedDoubleBufferedTexture()
+{
+ m_bitmap.reset();
+ delete m_canvas;
+}
+
+void BackedDoubleBufferedTexture::setBitmap(uint32_t w, uint32_t h, SkBitmap::Config config)
+{
+ if ((m_width == w) && (m_height == h))
+ return;
+ m_width = w;
+ m_height = h;
+ m_bitmap.reset();
+ m_bitmap.setConfig(config, m_width, m_height);
+ m_bitmap.allocPixels();
+ m_bitmap.eraseColor(0);
+ m_bitmap.eraseARGB(255, 255, 0, 0);
+ delete m_canvas;
+ m_canvas = new SkCanvas(m_bitmap);
+}
+
+void BackedDoubleBufferedTexture::update(TextureInfo* textureInfo, PaintingInfo& info)
+{
+ if (!m_width && !m_height)
+ return;
+
+ if (textureInfo && textureInfo->m_textureId) {
+ if (textureInfo->m_width && textureInfo->m_height
+ && (m_width != textureInfo->m_width)
+ && (m_height != textureInfo->m_height)) {
+ GLUtils::deleteTexture(&textureInfo->m_textureId);
+ glGenTextures(1, &textureInfo->m_textureId);
+ textureInfo->m_width = 0;
+ textureInfo->m_height = 0;
+ }
+
+ if (!textureInfo->m_width && !textureInfo->m_height)
+ GLUtils::createTextureWithBitmap(textureInfo->m_textureId, m_bitmap);
+ else
+ GLUtils::updateTextureWithBitmap(textureInfo->m_textureId, m_bitmap);
+
+ if ((m_width != textureInfo->m_width)
+ && (m_height != textureInfo->m_height)) {
+ textureInfo->m_width = m_width;
+ textureInfo->m_height = m_height;
+ }
+ }
+ m_varLock.lock();
+ if (textureInfo->m_textureId == m_textureA.getSourceTextureId())
+ m_paintingInfoA = info;
+ if (textureInfo->m_textureId == m_textureB.getSourceTextureId())
+ m_paintingInfoB = info;
+ m_varLock.unlock();
+}
+
+// Compare the current texture displayed with some PaintingInfo.
+bool BackedDoubleBufferedTexture::consumerTextureUpToDate(PaintingInfo& info)
+{
+ android::Mutex::Autolock lock(m_varLock);
+ if (getReadableTexture() == &m_textureA)
+ return info == m_paintingInfoA;
+ return info == m_paintingInfoB;
+}
+
+bool BackedDoubleBufferedTexture::consumerTextureSimilar(PaintingInfo& info)
+{
+ android::Mutex::Autolock lock(m_varLock);
+ if (getReadableTexture() == &m_textureA)
+ return info.similar(m_paintingInfoA);
+ return info.similar(m_paintingInfoB);
+}
+
+void BackedDoubleBufferedTexture::setOwner(BaseTile* owner)
+{
+ android::Mutex::Autolock lock(m_varLock);
+ if (m_owner != owner) {
+ if (m_owner)
+ m_owner->removeTexture();
+ m_owner = owner;
+ }
+}
+
+bool BackedDoubleBufferedTexture::acquire(BaseTile* owner)
+{
+ android::Mutex::Autolock lock(m_varLock);
+ if (m_busy)
+ return false;
+
+ if (m_owner != owner) {
+ if (m_owner)
+ m_owner->removeTexture();
+ m_owner = owner;
+ }
+ return true;
+}
+
+void BackedDoubleBufferedTexture::setPainter(BaseTile* painter)
+{
+ android::Mutex::Autolock lock(m_varLock);
+ m_painter = painter;
+}
+
+bool BackedDoubleBufferedTexture::acquireForPainting()
+{
+ android::Mutex::Autolock lock(m_varLock);
+ if (!m_busy) {
+ m_busy = true;
+ return true;
+ }
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
new file mode 100644
index 0000000..d59cc52
--- /dev/null
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
@@ -0,0 +1,120 @@
+/*
+ * 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 BackedDoubleBufferedTexture_h
+#define BackedDoubleBufferedTexture_h
+
+#include "DoubleBufferedTexture.h"
+#include <SkBitmap.h>
+
+class SkCanvas;
+
+namespace WebCore {
+
+class BaseTile;
+class GLWebViewState;
+
+class PaintingInfo {
+public:
+ PaintingInfo() : m_x(-1), m_y(-1), m_webview(0), m_picture(0) { }
+ PaintingInfo(int x, int y, GLWebViewState* webview, unsigned int picture)
+ : m_x(x)
+ , m_y(y)
+ , m_webview(webview)
+ , m_picture(picture)
+ {
+ }
+ bool operator==(const PaintingInfo& info)
+ {
+ return m_webview == info.m_webview
+ && m_x == info.m_x
+ && m_y == info.m_y
+ && m_picture == info.m_picture;
+ }
+ bool similar(const PaintingInfo& info)
+ {
+ return m_webview == info.m_webview
+ && m_x == info.m_x
+ && m_y == info.m_y;
+ }
+ void setPosition(int x, int y) { m_x = x; m_y = y; }
+ void setGLWebViewState(GLWebViewState* webview) { m_webview = webview; }
+ void setPictureUsed(unsigned int picture) { m_picture = picture; }
+
+private:
+ int m_x;
+ int m_y;
+ GLWebViewState* m_webview;
+ unsigned int m_picture;
+};
+
+// DoubleBufferedTexture using a SkBitmap as backing mechanism
+class BackedDoubleBufferedTexture : public DoubleBufferedTexture {
+public:
+ // ctor called on consumer thread
+ BackedDoubleBufferedTexture(uint32_t w, uint32_t h,
+ SkBitmap::Config config = SkBitmap::kARGB_8888_Config);
+ virtual ~BackedDoubleBufferedTexture();
+
+ void setBitmap(uint32_t w, uint32_t h, SkBitmap::Config config = SkBitmap::kARGB_8888_Config);
+ void update(TextureInfo* textureInfo, PaintingInfo& info);
+ SkCanvas* canvas() { return m_canvas; }
+
+ // Level can be -1 (unused texture), 0 (the 9 tiles intersecting with the
+ // viewport), then the distance between the viewport and the tile.
+ // we use this to prioritize which texture we want to pick (see
+ // TilesManager::getAvailableTexture())
+ int usedLevel() { android::Mutex::Autolock lock(m_varLock); return m_usedLevel; }
+ void setUsedLevel(int used) { android::Mutex::Autolock lock(m_varLock); m_usedLevel = used; }
+
+ BaseTile* owner() { android::Mutex::Autolock lock(m_varLock); return m_owner; }
+ void setOwner(BaseTile* owner);
+ BaseTile* painter() { return m_painter; }
+ void setPainter(BaseTile* painter);
+ bool busy() { android::Mutex::Autolock lock(m_varLock); return m_busy; }
+ void setBusy(bool value) { android::Mutex::Autolock lock(m_varLock); m_busy = value; }
+ uint32_t width() { return m_width; }
+ uint32_t height() { return m_height; }
+ bool consumerTextureUpToDate(PaintingInfo& info);
+ bool consumerTextureSimilar(PaintingInfo& info);
+ bool acquire(BaseTile* owner);
+ bool acquireForPainting();
+
+private:
+ SkBitmap m_bitmap;
+ SkCanvas* m_canvas;
+ uint32_t m_width;
+ uint32_t m_height;
+ int m_usedLevel;
+ BaseTile* m_owner;
+ BaseTile* m_painter;
+ PaintingInfo m_paintingInfoA;
+ PaintingInfo m_paintingInfoB;
+ bool m_busy;
+};
+
+} // namespace WebCore
+
+#endif // BackedDoubleBufferedTexture_h
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
new file mode 100644
index 0000000..0bb2928
--- /dev/null
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -0,0 +1,214 @@
+/*
+ * 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 "BaseLayerAndroid.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "GLUtils.h"
+#include "ShaderProgram.h"
+#include "SkCanvas.h"
+#include "TilesManager.h"
+#include <GLES2/gl2.h>
+#include <wtf/CurrentTime.h>
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseLayerAndroid", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+using namespace android;
+
+#ifdef DEBUG_COUNT
+static int gBaseLayerAndroidCount = 0;
+int BaseLayerAndroid::count()
+{
+ return gBaseLayerAndroidCount;
+}
+#endif
+
+BaseLayerAndroid::BaseLayerAndroid()
+{
+#ifdef DEBUG_COUNT
+ gBaseLayerAndroidCount++;
+#endif
+}
+
+BaseLayerAndroid::~BaseLayerAndroid()
+{
+ m_content.clear();
+#ifdef DEBUG_COUNT
+ gBaseLayerAndroidCount--;
+#endif
+}
+
+void BaseLayerAndroid::setContent(const PictureSet& src)
+{
+ m_content.set(src);
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale)
+{
+ if (m_content.isEmpty())
+ return false;
+ if (!m_glWebViewState)
+ return false;
+
+ double currentTime = WTF::currentTime();
+ bool goingDown = m_previousVisible.fTop - viewport.fTop <= 0;
+ bool goingLeft = m_previousVisible.fLeft - viewport.fLeft >= 0;
+
+ m_glWebViewState->setViewport(viewport, scale);
+
+ int firstTileX = m_glWebViewState->firstTileX();
+ int firstTileY = m_glWebViewState->firstTileY();
+
+ XLOG("drawBasePicture, TX: %d, TY: %d scale %.2f", firstTileX, firstTileY, scale);
+ if (scale == m_glWebViewState->currentScale()) {
+ m_glWebViewState->setOriginalTilesPosX(firstTileX);
+ m_glWebViewState->setOriginalTilesPosY(firstTileY);
+ }
+
+ // If we have a different scale than the current one, we have to
+ // decide what to do. The current behaviour is to delay an update,
+ // so that we do not slow down zooming unnecessarily.
+ if (m_glWebViewState->currentScale() != scale
+ && (m_glWebViewState->scaleRequestState() == GLWebViewState::kNoScaleRequest
+ || m_glWebViewState->scaleRequestState() == GLWebViewState::kWillScheduleRequest
+ || m_glWebViewState->futureScale() != scale)) {
+ m_glWebViewState->scheduleUpdate(currentTime, scale);
+ }
+
+ float transparency = 1;
+ bool doSwap = false;
+
+ // Here we have to schedule the painting of the tiles corresponding
+ // to the new tiles for the new scale factor (see above)
+ if (m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale
+ || m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) {
+ TiledPage* nextTiledPage = m_glWebViewState->backPage();
+ nextTiledPage->setScale(scale);
+
+ // Check if the page is ready...
+ if (m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale
+ && nextTiledPage->ready(firstTileX, firstTileY)) {
+ m_glWebViewState->setScaleRequestState(GLWebViewState::kReceivedNewScale);
+ }
+
+ // If the page is ready, display it. We do a short transition between
+ // the two pages (current one and future one with the new scale factor)
+ if (m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) {
+ double transitionTime = m_glWebViewState->transitionTime(currentTime);
+ transparency = m_glWebViewState->transparency(currentTime);
+
+ float newTilesTransparency = 1;
+ if (scale < m_glWebViewState->currentScale())
+ newTilesTransparency = 1 - transparency;
+
+ nextTiledPage->draw(newTilesTransparency, viewport,
+ firstTileX, firstTileY);
+
+ // The transition between the two pages is finished, swap them
+ if (currentTime > transitionTime) {
+ m_glWebViewState->setCurrentScale(scale);
+ m_glWebViewState->resetTransitionTime();
+ doSwap = true;
+ }
+ } else {
+ // If the page is not ready, schedule it if needed.
+ nextTiledPage->prepare(goingDown, goingLeft, firstTileX, firstTileY);
+ }
+ }
+
+ // Display the current page
+ TiledPage* tiledPage = m_glWebViewState->frontPage();
+ tiledPage->setScale(m_glWebViewState->currentScale());
+ int originalTX = m_glWebViewState->originalTilesPosX();
+ int originalTY = m_glWebViewState->originalTilesPosY();
+ tiledPage->prepare(goingDown, goingLeft, originalTX, originalTY);
+ tiledPage->draw(transparency, viewport, originalTX, originalTY);
+
+ bool ret = false;
+ if (!tiledPage->ready(originalTX, originalTY)
+ || m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest)
+ ret = true;
+
+ if (doSwap)
+ m_glWebViewState->swapPages();
+
+ return ret;
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
+ float scale, SkColor color)
+{
+ bool ret = false;
+#if USE(ACCELERATED_COMPOSITING)
+ int left = viewRect.x();
+ int top = viewRect.y();
+ int width = viewRect.width();
+ int height = viewRect.height();
+ XLOG("drawBasePicture drawGL() viewRect: %d, %d, %d, %d",
+ left, top, width, height);
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glScissor(left, top, width, height);
+ glClearColor((float)SkColorGetR(color) / 255.0,
+ (float)SkColorGetG(color) / 255.0,
+ (float)SkColorGetB(color) / 255.0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport(left, top, width, height);
+ ShaderProgram* shader = TilesManager::instance()->shader();
+ glUseProgram(shader->program());
+ glUniform1i(shader->textureSampler(), 0);
+
+ ret = drawBasePictureInGL(visibleRect, scale);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ m_previousVisible = visibleRect;
+#endif // USE(ACCELERATED_COMPOSITING)
+ return ret;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.h b/WebCore/platform/graphics/android/BaseLayerAndroid.h
index b9e2f4e..408549a 100644
--- a/WebCore/platform/graphics/android/BaseLayerAndroid.h
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.h
@@ -23,9 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef BASELAYERANDROID_H_
-#define BASELAYERANDROID_H_
+#ifndef BaseLayerAndroid_h
+#define BaseLayerAndroid_h
+#include "GLWebViewState.h"
+#include "IntRect.h"
#include "PictureSet.h"
#include "SkLayer.h"
@@ -34,16 +36,31 @@ namespace WebCore {
class BaseLayerAndroid : public SkLayer {
public:
- BaseLayerAndroid() { }
- virtual ~BaseLayerAndroid() { }
+#ifdef DEBUG_COUNT
+ static int count();
+#endif
+ BaseLayerAndroid();
+ virtual ~BaseLayerAndroid();
- void setContent(const android::PictureSet& src) { m_content.set(src); }
+#if USE(ACCELERATED_COMPOSITING)
+ void setGLWebViewState(GLWebViewState* infos) { m_glWebViewState = infos; }
+#endif
+ void setContent(const android::PictureSet& src);
android::PictureSet* content() { return &m_content; }
+ bool drawGL(IntRect& rect, SkRect& viewport,
+ float scale, SkColor color = SK_ColorWHITE);
+
private:
+#if USE(ACCELERATED_COMPOSITING)
+ bool drawBasePictureInGL(SkRect& viewport, float scale);
+
+ GLWebViewState* m_glWebViewState;
+#endif
android::PictureSet m_content;
+ SkRect m_previousVisible;
};
} // namespace WebCore
-#endif /* BASELAYERANDROID_H_ */
+#endif // BaseLayerAndroid_h
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
new file mode 100644
index 0000000..6f20643
--- /dev/null
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -0,0 +1,229 @@
+/*
+ * 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 "BaseTile.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GLUtils.h"
+#include "SkBitmap.h"
+#include "SkBitmapRef.h"
+#include "SkCanvas.h"
+#include "TilesManager.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+#ifdef DEBUG_COUNT
+static int gBaseTextureCount = 0;
+int BaseTile::count()
+{
+ return gBaseTextureCount;
+}
+#endif
+
+BaseTile::BaseTile(TiledPage* page, int x, int y, int quality)
+ : m_page(page)
+ , m_texture(0)
+ , m_x(x)
+ , m_y(y)
+ , m_quality(quality)
+ , m_scale(1)
+{
+#ifdef DEBUG_COUNT
+ gBaseTextureCount++;
+#endif
+}
+
+BaseTile::~BaseTile()
+{
+ removeTexture();
+ setUsedLevel(-1);
+#ifdef DEBUG_COUNT
+ gBaseTextureCount--;
+#endif
+}
+
+void BaseTile::reserveTexture()
+{
+ android::Mutex::Autolock lock(m_varLock);
+ m_texture = TilesManager::instance()->getAvailableTexture(this);
+ XLOG("%x (%d, %d) reserveTexture res: %x...", this, x(), y(), m_texture);
+}
+
+void BaseTile::removeTexture()
+{
+ android::Mutex::Autolock lock(m_varLock);
+ XLOG("%x removeTexture res: %x...", this, m_texture);
+ m_texture = 0;
+}
+
+void BaseTile::setUsedLevel(int usedLevel)
+{
+ if (m_texture)
+ m_texture->setUsedLevel(usedLevel);
+}
+
+// Called from the main GL thread
+void BaseTile::draw(float transparency, SkRect& rect)
+{
+ m_varLock.lock();
+ BackedDoubleBufferedTexture* texture = m_texture;
+ m_varLock.unlock();
+
+ if (!m_texture) {
+ XLOG("%x (%d, %d) trying to draw, but no m_texture!", this, x(), y());
+ return;
+ }
+
+ PaintingInfo info(m_x, m_y, m_page->glWebViewState(),
+ m_page->currentPictureCounter());
+
+ TextureInfo* textureInfo = texture->consumerLock();
+ if (!textureInfo) {
+ XLOG("%x (%d, %d) trying to draw, but no textureInfo!", this, x(), y());
+ texture->consumerRelease();
+ return;
+ }
+
+ if (texture->consumerTextureSimilar(info)) {
+ TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId,
+ transparency);
+ }
+
+ texture->consumerRelease();
+}
+
+bool BaseTile::isBitmapReady()
+{
+ if (!m_texture)
+ return false;
+ if (m_texture->owner() != this)
+ return false;
+ PaintingInfo info(m_x, m_y, m_page->glWebViewState(),
+ m_page->currentPictureCounter());
+ return m_texture->consumerTextureUpToDate(info);
+}
+
+// Called from the texture generation thread
+bool BaseTile::paintBitmap()
+{
+ m_varLock.lock();
+ BackedDoubleBufferedTexture* texture = m_texture;
+ bool available = false;
+ if (texture)
+ available = texture->acquireForPainting();
+ m_varLock.unlock();
+
+ if (!texture || !available)
+ return false;
+
+ // at this point we can safely check the ownership
+ // (if the texture got transferred to another BaseTile
+ // under us)
+ if (texture->owner() != this
+ || texture->usedLevel() > 1) {
+ texture->setBusy(false);
+ return false;
+ }
+
+ int pictureUsed = m_page->currentPictureCounter();
+ PaintingInfo info(m_x, m_y, m_page->glWebViewState(), pictureUsed);
+ if (texture->consumerTextureUpToDate(info)) {
+ texture->setBusy(false);
+ return true;
+ }
+
+ TextureInfo* textureInfo = texture->producerLock();
+
+ if (!textureInfo) {
+ texture->setBusy(false);
+ return false;
+ }
+
+ float tileWidth = textureInfo->m_width;
+ float tileHeight = textureInfo->m_height;
+
+ float scale = m_scale / m_quality;
+ float invScale = 1 / scale;
+
+ float w = tileWidth * invScale;
+ float h = tileHeight * invScale;
+
+ SkCanvas* canvas = texture->canvas();
+
+ canvas->save();
+
+ canvas->scale(scale, scale);
+ canvas->translate(-m_x*w, -m_y*h);
+
+ bool didPaint = m_page->paintBaseLayerContent(canvas);
+
+ canvas->restore();
+
+#ifdef DEBUG
+ SkPaint paint;
+ paint.setARGB(128, 255, 0, 0);
+ paint.setStrokeWidth(3);
+ canvas->drawLine(0, 0, tileWidth, tileHeight, paint);
+ paint.setARGB(128, 0, 255, 0);
+ canvas->drawLine(0, tileHeight, tileWidth, 0, paint);
+ paint.setARGB(128, 0, 0, 255);
+ canvas->drawLine(0, 0, tileWidth, 0, paint);
+ canvas->drawLine(tileWidth, 0, tileWidth, tileHeight, paint);
+#endif
+
+ texture->update(textureInfo, info);
+ texture->setPainter(this);
+ texture->setBusy(false);
+ texture->producerRelease();
+
+ return didPaint;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h
new file mode 100644
index 0000000..38f5b10
--- /dev/null
+++ b/WebCore/platform/graphics/android/BaseTile.h
@@ -0,0 +1,83 @@
+/*
+ * 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 BaseTile_h
+#define BaseTile_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "BackedDoubleBufferedTexture.h"
+#include "HashMap.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkRect.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+class TiledPage;
+
+class BaseTile {
+public:
+#ifdef DEBUG_COUNT
+ static int count();
+#endif
+ BaseTile(TiledPage* page, int x, int y, int quality = 1);
+ ~BaseTile();
+
+ void reserveTexture();
+ void removeTexture();
+ void setUsedLevel(int);
+ bool paintBitmap();
+ bool isBitmapReady();
+ float scale() const { return m_scale; }
+ void setScale(float scale) { m_scale = scale; }
+ void draw(float transparency, SkRect& rect);
+ TiledPage* page() { return m_page; }
+ int quality() const { return m_quality; }
+ int x() const { return m_x; }
+ int y() const { return m_y; }
+ BackedDoubleBufferedTexture* texture() { return m_texture; }
+
+private:
+ TiledPage* m_page;
+ BackedDoubleBufferedTexture* m_texture;
+ int m_x;
+ int m_y;
+ int m_quality;
+ float m_scale;
+ android::Mutex m_varLock;
+};
+
+typedef std::pair<int, int> TileKey;
+typedef HashMap<TileKey, BaseTile*> TileMap;
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // BaseTile_h
diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
index 7746603..7cd69d6 100644
--- a/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "DoubleBufferedTexture.h"
+
#include "GLUtils.h"
#define LOG_NDEBUG 1
@@ -33,28 +34,31 @@
namespace WebCore {
-DoubleBufferedTexture::DoubleBufferedTexture(EGLContext sharedContext) {
-
+DoubleBufferedTexture::DoubleBufferedTexture(EGLContext sharedContext)
+{
// the mutex ensures that the variables are not used in any other thread
// until the constructor has the opportunity to initialize them
android::Mutex::Autolock lock(m_varLock);
m_display = eglGetCurrentDisplay();
m_pContext = EGL_NO_CONTEXT;
m_cContext = sharedContext;
- m_frontTexture = GL_NO_TEXTURE;
+ m_writeableTexture = GL_NO_TEXTURE;
m_lockedConsumerTexture = GL_NO_TEXTURE;
m_supportsEGLImage = GLUtils::isEGLImageSupported();
}
-SharedTexture* DoubleBufferedTexture::getFrontTexture() {
- return (m_frontTexture == &m_textureA) ? &m_textureA : &m_textureB;
+SharedTexture* DoubleBufferedTexture::getWriteableTexture()
+{
+ return (m_writeableTexture == &m_textureA) ? &m_textureA : &m_textureB;
}
-SharedTexture* DoubleBufferedTexture::getBackTexture() {
- return (m_frontTexture != &m_textureA) ? &m_textureA : &m_textureB;
+SharedTexture* DoubleBufferedTexture::getReadableTexture()
+{
+ return (m_writeableTexture != &m_textureA) ? &m_textureA : &m_textureB;
}
-EGLContext DoubleBufferedTexture::producerAcquireContext() {
+EGLContext DoubleBufferedTexture::producerAcquireContext()
+{
// ensure that the constructor has completed and all values are initialized
android::Mutex::Autolock lock(m_varLock);
@@ -88,14 +92,15 @@ EGLContext DoubleBufferedTexture::producerAcquireContext() {
m_textureB.unlock();
// select a front buffer
- m_frontTexture = &m_textureA;
+ m_writeableTexture = &m_textureA;
m_pContext = context;
return context;
}
-TextureInfo* DoubleBufferedTexture::producerLock() {
- SharedTexture* sharedTex = getFrontTexture();
+TextureInfo* DoubleBufferedTexture::producerLock()
+{
+ SharedTexture* sharedTex = getWriteableTexture();
LOGV("Acquiring P Lock (%d)", sharedTex->getSourceTextureId());
TextureInfo* texInfo = sharedTex->lockSource();
LOGV("Acquired P Lock");
@@ -103,23 +108,25 @@ TextureInfo* DoubleBufferedTexture::producerLock() {
return texInfo;
}
-void DoubleBufferedTexture::producerRelease() {
+void DoubleBufferedTexture::producerRelease()
+{
// get the front texture and cache the id
- SharedTexture* sharedTex = getFrontTexture();
+ SharedTexture* sharedTex = getWriteableTexture();
LOGV("Releasing P Lock (%d)", sharedTex->getSourceTextureId());
sharedTex->releaseSource();
// swap the front and back buffers
m_varLock.lock();
- m_frontTexture = (sharedTex == &m_textureA) ? &m_textureB : &m_textureA;
+ m_writeableTexture = (sharedTex == &m_textureA) ? &m_textureB : &m_textureA;
LOGV("Released P Lock (%d)", sharedTex->getSourceTextureId());
m_varLock.unlock();
}
-TextureInfo* DoubleBufferedTexture::consumerLock() {
+TextureInfo* DoubleBufferedTexture::consumerLock()
+{
m_varLock.lock();
- SharedTexture* sharedTex = getBackTexture();
+ SharedTexture* sharedTex = getReadableTexture();
LOGV("Acquiring C Lock (%d)", sharedTex->getSourceTextureId());
m_lockedConsumerTexture = sharedTex;
m_varLock.unlock();
@@ -127,14 +134,14 @@ TextureInfo* DoubleBufferedTexture::consumerLock() {
TextureInfo* texInfo = sharedTex->lockTarget();
LOGV("Acquired C Lock");
- if (!texInfo) {
+ if (!texInfo)
LOGV("Released C Lock (Empty)");
- }
return texInfo;
}
-void DoubleBufferedTexture::consumerRelease() {
+void DoubleBufferedTexture::consumerRelease()
+{
android::Mutex::Autolock lock(m_varLock);
// we must check to see what texture the consumer had locked since the
// producer may have swapped out the front buffer
diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.h b/WebCore/platform/graphics/android/DoubleBufferedTexture.h
index 1c629a7..d6d06ab 100644
--- a/WebCore/platform/graphics/android/DoubleBufferedTexture.h
+++ b/WebCore/platform/graphics/android/DoubleBufferedTexture.h
@@ -23,16 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DoubleBufferedTexture__DEFINED
-#define DoubleBufferedTexture__DEFINED
-
-#include <utils/threads.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
+#ifndef DoubleBufferedTexture_h
+#define DoubleBufferedTexture_h
#include "SharedTexture.h"
+#include <EGL/egl.h>
namespace WebCore {
@@ -40,6 +35,7 @@ class DoubleBufferedTexture {
public:
// consumer thread functions
DoubleBufferedTexture(EGLContext sharedContext);
+ virtual ~DoubleBufferedTexture() { }
// provider thread functions
TextureInfo* producerLock();
@@ -50,26 +46,27 @@ public:
TextureInfo* consumerLock();
void consumerRelease();
+protected:
+ SharedTexture m_textureA;
+ SharedTexture m_textureB;
+ SharedTexture* m_writeableTexture;
+ android::Mutex m_varLock;
+
+ SharedTexture* getReadableTexture();
+
private:
- SharedTexture* getFrontTexture();
- SharedTexture* getBackTexture();
+ SharedTexture* getWriteableTexture();
EGLDisplay m_display;
EGLContext m_pContext;
EGLContext m_cContext;
- SharedTexture m_textureA;
- SharedTexture m_textureB;
- SharedTexture* m_frontTexture;
SharedTexture* m_lockedConsumerTexture; // only used by the consumer
- android::Mutex m_varLock;
-
bool m_supportsEGLImage;
};
-
} // namespace WebCore
-#endif // DoubleBufferedTexture__DEFINED
+#endif // DoubleBufferedTexture_h
diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp
new file mode 100644
index 0000000..1a7ba6c
--- /dev/null
+++ b/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -0,0 +1,219 @@
+/*
+ * 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 "GLWebViewState.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "BaseLayerAndroid.h"
+#include "LayerAndroid.h"
+#include "TilesManager.h"
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLWebViewState", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+#define FIRST_TILED_PAGE_ID 1
+#define SECOND_TILED_PAGE_ID 2
+
+namespace WebCore {
+
+using namespace android;
+
+GLWebViewState::GLWebViewState()
+ : m_scaleRequestState(kNoScaleRequest)
+ , m_currentScale(1)
+ , m_futureScale(1)
+ , m_updateTime(-1)
+ , m_transitionTime(-1)
+ , m_originalTilesPosX(0)
+ , m_originalTilesPosY(0)
+ , m_nbTilesWidth(0)
+ , m_nbTilesHeight(0)
+ , m_firstTileX(0)
+ , m_firstTileY(0)
+ , m_baseLayer(0)
+ , m_currentPictureCounter(0)
+ , m_usePageA(true)
+ , m_extra(0)
+ , m_navLayer(0)
+{
+ m_invalidatedRect.setEmpty();
+ m_tiledPageA = new TiledPage(FIRST_TILED_PAGE_ID, this);
+ m_tiledPageB = new TiledPage(SECOND_TILED_PAGE_ID, this);
+}
+
+GLWebViewState::~GLWebViewState()
+{
+ delete m_tiledPageA;
+ delete m_tiledPageB;
+ delete m_navLayer;
+}
+
+void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, IntRect& rect)
+{
+ android::Mutex::Autolock lock(m_baseLayerLock);
+ m_baseLayer = layer;
+ m_baseLayer->setGLWebViewState(this);
+ m_invalidatedRect.set(rect);
+ m_currentPictureCounter++;
+ m_extra = 0;
+ delete m_navLayer;
+ m_navLayer = 0;
+ XLOG("%x setBaseLayer %x (%d)", this, layer, m_currentPictureCounter);
+}
+
+void GLWebViewState::setExtra(android::DrawExtra* extra, LayerAndroid* navLayer)
+{
+ android::Mutex::Autolock lock(m_baseLayerLock);
+ m_extra = extra;
+ delete m_navLayer;
+ m_navLayer = navLayer;
+ m_currentPictureCounter++;
+}
+
+void GLWebViewState::resetExtra(bool repaint)
+{
+ android::Mutex::Autolock lock(m_baseLayerLock);
+ if (m_extra && repaint)
+ m_currentPictureCounter++;
+ m_extra = 0;
+ delete m_navLayer;
+ m_navLayer = 0;
+}
+
+bool GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
+{
+ android::Mutex::Autolock lock(m_baseLayerLock);
+ if (m_baseLayer && m_baseLayer->content()
+ && !m_baseLayer->content()->isEmpty()) {
+ m_baseLayer->content()->draw(canvas);
+ if (m_extra && m_navLayer)
+ m_extra->draw(canvas, m_navLayer);
+ return true;
+ }
+ return false;
+}
+
+void GLWebViewState::scheduleUpdate(const double& currentTime, float scale)
+{
+ // if no update time, set it
+ if (updateTime() == -1) {
+ m_scaleRequestState = kWillScheduleRequest;
+ setUpdateTime(currentTime + s_updateInitialDelay);
+ setFutureScale(scale);
+ return;
+ }
+
+ if (currentTime < updateTime())
+ return;
+
+ // we reached the scheduled update time, check if we can update
+ if (futureScale() == scale) {
+ // we are still with the previous scale, let's go
+ // with the update
+ m_scaleRequestState = kRequestNewScale;
+ setUpdateTime(-1);
+ } else {
+ // we reached the update time, but the planned update was for
+ // a different scale factor -- meaning the user is still probably
+ // in the process of zooming. Let's push the update time a bit.
+ setUpdateTime(currentTime + s_updateDelay);
+ setFutureScale(scale);
+ }
+}
+
+double GLWebViewState::transitionTime(double currentTime)
+{
+ if (m_transitionTime == -1)
+ m_transitionTime = currentTime + s_transitionDelay;
+ return m_transitionTime;
+}
+
+float GLWebViewState::transparency(double currentTime)
+{
+ float t = transitionTime(currentTime) - currentTime;
+ t *= s_invTransitionDelay;
+ return fmin(1, fmax(0, t));
+}
+
+TiledPage* GLWebViewState::frontPage()
+{
+ android::Mutex::Autolock lock(m_tiledPageLock);
+ return m_usePageA ? m_tiledPageA : m_tiledPageB;
+}
+
+TiledPage* GLWebViewState::backPage()
+{
+ android::Mutex::Autolock lock(m_tiledPageLock);
+ return m_usePageA ? m_tiledPageB : m_tiledPageA;
+}
+
+void GLWebViewState::swapPages()
+{
+ android::Mutex::Autolock lock(m_tiledPageLock);
+ m_usePageA ^= true;
+ TiledPage* working = m_usePageA ? m_tiledPageB : m_tiledPageA;
+ TilesManager::instance()->resetTextureUsage(working);
+
+ m_scaleRequestState = kNoScaleRequest;
+}
+
+void GLWebViewState::setViewport(SkRect& viewport, float scale)
+{
+ if (m_viewport == viewport)
+ return;
+
+ m_viewport = viewport;
+ float fnbw = m_viewport.width() * scale / TilesManager::instance()->tileWidth();
+ int nbw = static_cast<int>(ceilf(fnbw));
+ float fnbh = m_viewport.height() * scale / TilesManager::instance()->tileHeight();
+ int nbh = static_cast<int>(ceilf(fnbh));
+ m_nbTilesWidth = nbw + 1;
+ m_nbTilesHeight = nbh + 1;
+ XLOG("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f), nbw: %d nbh: %d",
+ m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom,
+ m_viewport.width(), m_viewport.height(), scale,
+ m_nbTilesWidth, m_nbTilesHeight);
+ m_firstTileX = static_cast<int>(m_viewport.fLeft * scale / TilesManager::instance()->tileWidth());
+ m_firstTileY = static_cast<int>(m_viewport.fTop * scale / TilesManager::instance()->tileHeight());
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h
new file mode 100644
index 0000000..ac3943e
--- /dev/null
+++ b/WebCore/platform/graphics/android/GLWebViewState.h
@@ -0,0 +1,218 @@
+/*
+ * 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 GLWebViewState_h
+#define GLWebViewState_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "DrawExtra.h"
+#include "IntRect.h"
+#include "SkCanvas.h"
+#include "SkRect.h"
+#include "TiledPage.h"
+#include <utils/threads.h>
+
+namespace WebCore {
+
+class BaseLayerAndroid;
+class LayerAndroid;
+
+/////////////////////////////////////////////////////////////////////////////////
+// GL Architecture
+/////////////////////////////////////////////////////////////////////////////////
+//
+// To draw things, WebView use a tree of layers. The root of that tree is a
+// BaseLayerAndroid, which may have numerous LayerAndroid over it. The content
+// of those layers are SkPicture, the content of the BaseLayer is an PictureSet.
+//
+// When drawing, we therefore have one large "surface" that is the BaseLayer,
+// and (possibly) additional surfaces (usually smaller), which are the
+// LayerAndroids. The BaseLayer usually corresponds to the normal web page
+// content, the Layers are used for some parts such as specific divs (e.g. fixed
+// position divs, or elements using CSS3D transforms, or containing video,
+// plugins, etc.).
+//
+// *** NOTE: The GL drawing architecture only paints the BaseLayer for now.
+//
+// The rendering model is to use tiles to display the BaseLayer (as obviously a
+// BaseLayer's area can be arbitrarly large). The idea is to compute a set of
+// tiles covering the viewport's area, paint those tiles using the webview's
+// content (i.e. the BaseLayer's PictureSet), then display those tiles.
+// We check which tile we should use at every frame.
+//
+// Overview
+// ---------
+//
+// The tiles are grouped into a TiledPage -- basically a map of tiles covering
+// the BaseLayer's surface. When drawing, we ask the TiledPage to prepare()
+// itself then draw itself on screen. The prepare() function is the one
+// that schedules tiles to be painted -- i.e. the subset of tiles that intersect
+// with the current viewport. When they are ready, we can display
+// the TiledPage.
+//
+// Note that BaseLayerAndroid::drawGL() will return true to the java side if
+// there is a need to be called again (i.e. if we do not have up to date
+// textures or a transition is going on).
+//
+// Tiles are implemented as a BaseTile. It knows how to paint itself with the
+// PictureSet, and to display itself. A GL texture is usually associated to it.
+//
+// We also works with two TiledPages -- one to display the page at the
+// current scale factor, and another we use to paint the page at a different
+// scale factor. I.e. when we zoom, we use TiledPage A, with its tiles scaled
+// accordingly (and therefore possible loss of quality): this is fast as it's
+// purely a hardware operation. When the user is done zooming, we ask for
+// TiledPage B to be painted at the new scale factor, covering the
+// viewport's area. When B is ready, we swap it with A.
+//
+// Texture allocation
+// ------------------
+//
+// Obviously we cannot have every BaseTile having a GL texture -- we need to
+// get the GL textures from an existing pool, and reuse them.
+//
+// The way we do it is that when we call TiledPage::prepare(), we group the
+// tiles we need into a TilesSet, call TilesSet::reserveTextures() (which
+// associates the GL textures to the BaseTiles).
+//
+// reserveTexture() will ask the TilesManager for a texture. The allocation
+// mechanism goal is to (in order):
+// - prefers to allocate the same texture as the previous time
+// - prefers to allocate textures that are as far from the viewport as possible
+// - prefers to allocate textures that are used by different TiledPages
+//
+// Note that to compute the distance of tiles, each time we prepare() a
+// TiledPage, we compute the distance of the tiles in it from the viewport.
+//
+// Painting scheduling
+// -------------------
+//
+// The next operation is to schedule this TilesSet to be painted
+// (TilesManager::schedulePaintForTilesSet()). TexturesGenerator
+// will get the TilesSet and ask the BaseTiles in it to be painted.
+//
+// BaseTile::paintBitmap() will paint the texture using the BaseLayer's
+// PictureSet (calling TiledPage::paintBaseLayerContent() which in turns
+// calls GLWebViewState::paintBaseLayerContent()).
+//
+// Note that TexturesGenerator is running in a separate thread, the textures
+// are shared using EGLImages (this is necessary to not slow down the rendering
+// speed -- updating GL textures in the main GL thread would slow things down).
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+class GLWebViewState {
+public:
+ enum GLScaleStates {
+ kNoScaleRequest = 0,
+ kWillScheduleRequest = 1,
+ kRequestNewScale = 2,
+ kReceivedNewScale = 3
+ };
+ typedef int32_t GLScaleState;
+
+ GLWebViewState();
+ ~GLWebViewState();
+ GLScaleState scaleRequestState() const { return m_scaleRequestState; }
+ void setScaleRequestState(GLScaleState state) { m_scaleRequestState = state; }
+ float currentScale() const { return m_currentScale; }
+ void setCurrentScale(float scale) { m_currentScale = scale; }
+ float futureScale() const { return m_futureScale; }
+ void setFutureScale(float scale) { m_futureScale = scale; }
+ double updateTime() const { return m_updateTime; }
+ void setUpdateTime(double value) { m_updateTime = value; }
+ double transitionTime(double currentTime);
+ float transparency(double currentTime);
+ void resetTransitionTime() { m_transitionTime = -1; }
+ int originalTilesPosX() const { return m_originalTilesPosX; }
+ void setOriginalTilesPosX(int pos) { m_originalTilesPosX = pos; }
+ int originalTilesPosY() const { return m_originalTilesPosY; }
+ void setOriginalTilesPosY(int pos) { m_originalTilesPosY = pos; }
+
+ bool paintBaseLayerContent(SkCanvas* canvas);
+ void setBaseLayer(BaseLayerAndroid* layer, IntRect& rect);
+ void setExtra(android::DrawExtra* extra, LayerAndroid* navLayer);
+ void resetExtra(bool repaint);
+
+ void scheduleUpdate(const double& currentTime, float scale);
+
+ TiledPage* frontPage();
+ TiledPage* backPage();
+ void swapPages();
+
+ void setViewport(SkRect& viewport, float scale);
+
+ // returns the number of tiles needed to cover the viewport
+ int nbTilesWidth() const { return m_nbTilesWidth; }
+ int nbTilesHeight() const { return m_nbTilesHeight; }
+
+ int firstTileX() const { return m_firstTileX; }
+ int firstTileY() const { return m_firstTileY; }
+
+ unsigned int currentPictureCounter() const { return m_currentPictureCounter; }
+ SkRect& invalidatedRect() { return m_invalidatedRect; }
+
+private:
+
+ // Delay between scheduling a new page when the scale
+ // factor changes (i.e. zooming in or out)
+ static const double s_updateInitialDelay = 0.3; // 300 ms
+ // If the scale factor continued to change and we completed
+ // the original delay, we push back the update by this value
+ static const double s_updateDelay = 0.1; // 100 ms
+
+ // Delay for the transition between the two pages
+ static const double s_transitionDelay = 0.5; // 500 ms
+ static const double s_invTransitionDelay = 2;
+
+ GLScaleState m_scaleRequestState;
+ float m_currentScale;
+ float m_futureScale;
+ double m_updateTime;
+ double m_transitionTime;
+ int m_originalTilesPosX;
+ int m_originalTilesPosY;
+ android::Mutex m_tiledPageLock;
+ SkRect m_viewport;
+ int m_nbTilesWidth;
+ int m_nbTilesHeight;
+ int m_firstTileX;
+ int m_firstTileY;
+ android::Mutex m_baseLayerLock;
+ BaseLayerAndroid* m_baseLayer;
+ unsigned int m_currentPictureCounter;
+ SkRect m_invalidatedRect;
+ bool m_usePageA;
+ TiledPage* m_tiledPageA;
+ TiledPage* m_tiledPageB;
+ android::DrawExtra* m_extra;
+ LayerAndroid* m_navLayer;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // GLWebViewState_h
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp
new file mode 100644
index 0000000..ca05d10
--- /dev/null
+++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 "TexturesGenerator.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GLUtils.h"
+#include "TilesManager.h"
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TexturesGenerator", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+void TexturesGenerator::schedulePaintForTilesSet(TilesSet* set)
+{
+ android::Mutex::Autolock lock(mRequestedPixmapsLock);
+ for (unsigned int i = 0; i < mRequestedPixmaps.size(); i++) {
+ TilesSet* s = mRequestedPixmaps[i];
+ if (s && *s == *set) {
+ // Similar set already in the queue
+ delete set;
+ return;
+ }
+ }
+
+ XLOG("%x schedulePaintForTilesSet (%x) %d, %d, %d, %d", this, set,
+ set->firstTileX(), set->firstTileY(), set->nbRows(), set->nbCols());
+ mRequestedPixmaps.append(set);
+ m_newRequestLock.lock();
+ m_newRequestCond.signal();
+ m_newRequestLock.unlock();
+}
+
+status_t TexturesGenerator::readyToRun()
+{
+ TilesManager::instance()->enableTextures();
+ XLOG("Textures enabled (context acquired...)");
+ TilesManager::instance()->paintTexturesDefault();
+ XLOG("Textures painted");
+ TilesManager::instance()->markGeneratorAsReady();
+ XLOG("Thread ready to run");
+ return NO_ERROR;
+}
+
+bool TexturesGenerator::threadLoop()
+{
+ XLOG("threadLoop, waiting for signal");
+ m_newRequestLock.lock();
+ m_newRequestCond.wait(m_newRequestLock);
+ m_newRequestLock.unlock();
+ XLOG("threadLoop, got signal");
+
+ bool stop = false;
+ while (!stop) {
+ mRequestedPixmapsLock.lock();
+ TilesSet* set = 0;
+ if (mRequestedPixmaps.size())
+ set = mRequestedPixmaps.first();
+ mRequestedPixmapsLock.unlock();
+
+ if (set) {
+ set->paint();
+ mRequestedPixmapsLock.lock();
+ mRequestedPixmaps.remove(0);
+ mRequestedPixmapsLock.unlock();
+ delete set;
+ }
+
+ mRequestedPixmapsLock.lock();
+ if (!mRequestedPixmaps.size())
+ stop = true;
+ mRequestedPixmapsLock.unlock();
+ }
+
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.h b/WebCore/platform/graphics/android/TexturesGenerator.h
new file mode 100644
index 0000000..b68fcb1
--- /dev/null
+++ b/WebCore/platform/graphics/android/TexturesGenerator.h
@@ -0,0 +1,57 @@
+/*
+ * 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 TexturesGenerator_h
+#define TexturesGenerator_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "TilesSet.h"
+#include <utils/threads.h>
+
+namespace WebCore {
+
+using namespace android;
+
+class TexturesGenerator : public Thread {
+public:
+ TexturesGenerator() : Thread() { }
+ virtual ~TexturesGenerator() { }
+ virtual status_t readyToRun();
+
+ void schedulePaintForTilesSet(TilesSet* set);
+
+private:
+ virtual bool threadLoop();
+ Vector<TilesSet*> mRequestedPixmaps;
+ android::Mutex mRequestedPixmapsLock;
+ android::Mutex m_newRequestLock;
+ android::Condition m_newRequestCond;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // TexturesGenerator_h
diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp
new file mode 100644
index 0000000..666c00f
--- /dev/null
+++ b/WebCore/platform/graphics/android/TiledPage.cpp
@@ -0,0 +1,257 @@
+/*
+ * 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 "TiledPage.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GLUtils.h"
+#include "TilesManager.h"
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledPage", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+using namespace android;
+
+TiledPage::TiledPage(int id, GLWebViewState* state)
+ : m_id(id)
+ , m_scale(1)
+ , m_glWebViewState(state)
+{
+}
+
+BaseTile* TiledPage::getBaseTile(int x, int y, int quality)
+{
+ TileKey key(x + 1, y + 1);
+ return m_baseTextures.get(key);
+}
+
+void TiledPage::prepareRow(bool goingLeft, int firstTileX, int y, TilesSet* set, int quality)
+{
+ if (y < 0)
+ return;
+ if (!set)
+ return;
+
+ int nbCols = set->nbCols();
+ for (int i = 0; i < nbCols; i++) {
+ int x = firstTileX;
+
+ // If we are goingLeft, we want to schedule the tiles
+ // starting from the left (and to the right if not)
+ if (goingLeft)
+ x += i;
+ else
+ x += (nbCols - 1) - i;
+
+ TileKey key(x + 1, y + 1);
+ BaseTile* tile = 0;
+ if (!m_baseTextures.contains(key)) {
+ tile = new BaseTile(this, x, y);
+ m_baseTextures.set(key, tile);
+ }
+ tile = m_baseTextures.get(key);
+ tile->setUsedLevel(0);
+ tile->setScale(m_scale);
+ set->add(tile);
+ }
+}
+
+void TiledPage::setTileLevel(BaseTile* tile, int firstTileX, int firstTileY)
+{
+ if (!tile)
+ return;
+
+ if (!m_glWebViewState)
+ return;
+
+ int nbTilesWidth = m_glWebViewState->nbTilesWidth();
+ int nbTilesHeight = m_glWebViewState->nbTilesHeight();
+ int dx = 0;
+ int dy = 0;
+
+ if (firstTileX > tile->x())
+ dx = firstTileX - tile->x();
+ else if (firstTileX + (nbTilesWidth - 1) < tile->x())
+ dx = tile->x() - firstTileX - (nbTilesWidth - 1);
+
+ if (firstTileY > tile->y())
+ dy = firstTileY - tile->y();
+ else if (firstTileY + (nbTilesHeight - 1) < tile->y())
+ dy = tile->y() - firstTileY - (nbTilesHeight - 1);
+
+ int d = std::max(dx, dy);
+
+ XLOG("setTileLevel tile: %x, fxy(%d, %d), level: %d", tile, firstTileX, firstTileY, d);
+ tile->setUsedLevel(d);
+}
+
+void TiledPage::prepare(bool goingDown, bool goingLeft, int firstTileX, int firstTileY)
+{
+ if (!m_glWebViewState)
+ return;
+
+ int nbTilesWidth = m_glWebViewState->nbTilesWidth();
+ int nbTilesHeight = m_glWebViewState->nbTilesHeight();
+
+ TilesSet* highResSet = new TilesSet(m_id + 1, scale(), firstTileX, firstTileY,
+ nbTilesHeight, nbTilesWidth);
+
+ // We chose to display tiles depending on the scroll direction:
+ if (goingDown) {
+ for (int i = 0; i < nbTilesHeight; i++)
+ prepareRow(goingLeft, firstTileX, firstTileY + i, highResSet, 1);
+ } else {
+ for (int i = 0; i < nbTilesHeight; i++)
+ prepareRow(goingLeft, firstTileX, firstTileY + (nbTilesHeight - 1) - i, highResSet, 1);
+ }
+
+ TileMap::const_iterator end = m_baseTextures.end();
+ for (TileMap::const_iterator it = m_baseTextures.begin(); it != end; ++it) {
+ BaseTile* tile = it->second;
+ setTileLevel(tile, firstTileX, firstTileY);
+ }
+
+#ifdef DEBUG
+ XLOG("+++ BEFORE RESERVE TEXTURES (%d x %d) at (%d, %d), TiledPage %x",
+ nbTilesWidth, nbTilesHeight, firstTileX, firstTileY, this);
+ TilesManager::instance()->printTextures();
+#endif // DEBUG
+
+ highResSet->reserveTextures();
+
+#ifdef DEBUG
+ TilesManager::instance()->printTextures();
+ XLOG("--- AFTER RESERVE TEXTURES (%d x %d) at (%d, %d), TiledPage %x",
+ nbTilesWidth, nbTilesHeight, firstTileX, firstTileY, this);
+#endif // DEBUG
+
+ // schedulePaintForTilesSet will take ownership of the highResSet here,
+ // so no delete necessary.
+ TilesManager::instance()->schedulePaintForTilesSet(highResSet);
+}
+
+bool TiledPage::ready(int firstTileX, int firstTileY)
+{
+ if (!m_glWebViewState)
+ return false;
+
+ int nbTilesWidth = m_glWebViewState->nbTilesWidth();
+ int nbTilesHeight = m_glWebViewState->nbTilesHeight();
+
+ for (int i = 0; i < nbTilesHeight; i++) {
+ for (int j = 0; j < nbTilesWidth; j++) {
+ int x = j + firstTileX;
+ int y = i + firstTileY;
+ BaseTile* t = getBaseTile(x, y, 1);
+ if (!t || !t->isBitmapReady())
+ return false;
+ }
+ }
+ return true;
+}
+
+void TiledPage::draw(float transparency, SkRect& viewport,
+ int firstTileX, int firstTileY)
+{
+ if (!m_glWebViewState)
+ return;
+
+ float w = TilesManager::instance()->tileWidth() / m_scale;
+ float h = TilesManager::instance()->tileHeight() / m_scale;
+ int nbTilesWidth = m_glWebViewState->nbTilesWidth();
+ int nbTilesHeight = m_glWebViewState->nbTilesHeight();
+
+ XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
+ for (int i = 0; i < nbTilesHeight; i++) {
+ for (int j = 0; j < nbTilesWidth; j++) {
+ int x = j + firstTileX;
+ int y = i + firstTileY;
+
+ BaseTile* tile = getBaseTile(x, y, 1);
+
+ if (!tile) {
+ XLOG("NO TILE AT %d, %d", x, y);
+ continue;
+ }
+
+ SkRect rect;
+ rect.fLeft = x * w;
+ rect.fTop = y * h;
+ rect.fRight = rect.fLeft + w;
+ rect.fBottom = rect.fTop + h;
+
+ TilesManager::instance()->shader()->setViewport(viewport);
+ tile->draw(transparency, rect);
+ }
+ }
+
+ XLOG("FINISHED WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
+ TilesManager::instance()->printTextures();
+}
+
+bool TiledPage::paintBaseLayerContent(SkCanvas* canvas)
+{
+ if (m_glWebViewState)
+ return m_glWebViewState->paintBaseLayerContent(canvas);
+ return false;
+}
+
+unsigned int TiledPage::currentPictureCounter()
+{
+ if (m_glWebViewState)
+ return m_glWebViewState->currentPictureCounter();
+ return 0;
+}
+
+TiledPage* TiledPage::sibling()
+{
+ if (!m_glWebViewState)
+ return 0;
+
+ if (m_glWebViewState->frontPage() == this)
+ return m_glWebViewState->backPage();
+ return m_glWebViewState->frontPage();
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h
new file mode 100644
index 0000000..712566c
--- /dev/null
+++ b/WebCore/platform/graphics/android/TiledPage.h
@@ -0,0 +1,64 @@
+/*
+ * 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 TiledPage_h
+#define TiledPage_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "BaseTile.h"
+#include "GLWebViewState.h"
+#include "SkCanvas.h"
+#include "TilesSet.h"
+
+namespace WebCore {
+
+class TiledPage {
+public:
+ TiledPage(int id, GLWebViewState* state);
+ ~TiledPage() { }
+ BaseTile* getBaseTile(int x, int y, int quality);
+ void prepare(bool goingDown, bool goingLeft, int firstTileX, int firstTileY);
+ void setScale(float scale) { m_scale = scale; }
+ bool ready(int firstTileX, int firstTileY);
+ void draw(float transparency, SkRect& viewport, int firstTileX, int firstTileY);
+ float scale() const { return m_scale; }
+ bool paintBaseLayerContent(SkCanvas*);
+ unsigned int currentPictureCounter();
+ TiledPage* sibling();
+ GLWebViewState* glWebViewState() { return m_glWebViewState; }
+private:
+ void setTileLevel(BaseTile* tile, int firstTileX, int firstTileY);
+ void prepareRow(bool goingLeft, int firstTileX, int y, TilesSet* set, int quality);
+ TileMap m_baseTextures;
+ int m_id;
+ float m_scale;
+ GLWebViewState* m_glWebViewState;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // TiledPage_h
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
new file mode 100644
index 0000000..a600f39
--- /dev/null
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -0,0 +1,254 @@
+/*
+ * 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 "TilesManager.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "BaseTile.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesManager", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+// Important: We need at least twice as much textures as is needed to cover
+// one viewport, otherwise the allocation may stall.
+// We need n textures for one TiledPage, and another n textures for the
+// second page used when scaling.
+// In our case, we use 300x300 textures. On the tablet, this equals to
+// at least 24 (6 * 4) textures, hence 48.
+#define DEFAULT_TEXTURES_ALLOCATION 48
+#define DEFAULT_TEXTURE_SIZE_WIDTH 300
+#define DEFAULT_TEXTURE_SIZE_HEIGHT 300
+
+namespace WebCore {
+
+TilesManager::TilesManager()
+ : m_generatorReady(false)
+{
+ m_textures.reserveCapacity(DEFAULT_TEXTURES_ALLOCATION);
+ for (int i = 0; i < DEFAULT_TEXTURES_ALLOCATION; i++) {
+ BackedDoubleBufferedTexture* texture = new BackedDoubleBufferedTexture(
+ tileWidth(), tileHeight());
+ m_textures.append(texture);
+ }
+
+ m_pixmapsGenerationThread = new TexturesGenerator();
+ m_pixmapsGenerationThread->run("TexturesGenerator");
+}
+
+// Has to be run on the texture generation threads
+void TilesManager::enableTextures()
+{
+ android::Mutex::Autolock lock(m_texturesLock);
+ for (unsigned int i = 0; i < m_textures.size(); i++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ texture->producerAcquireContext();
+ }
+}
+
+void TilesManager::printTextures()
+{
+#ifdef DEBUG
+ XLOG("++++++");
+ for (unsigned int i = 0; i < m_textures.size(); i++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ BaseTile* o = 0;
+ if (texture->owner())
+ o = (BaseTile*) texture->owner();
+ int x = -1;
+ int y = -1;
+ if (o) {
+ x = o->x();
+ y = o->y();
+ }
+ XLOG("[%d] texture %x (picture: %d) usedLevel: %d busy: %d owner: %x (%d, %d) page: %x scale: %.2f",
+ i, texture, texture->pictureUsed(), texture->usedLevel(),
+ texture->busy(), o, x, y, o ? o->page() : 0, o ? o->scale() : 0);
+ }
+ XLOG("------");
+#endif // DEBUG
+}
+
+void TilesManager::paintTexturesDefault()
+{
+ android::Mutex::Autolock lock(m_texturesLock);
+ for (unsigned int i = 0; i < m_textures.size(); i++) {
+ for (int j = 0; j < 2; j++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ TextureInfo* textureInfo = texture->producerLock();
+ SkCanvas* canvas = texture->canvas();
+#ifdef DEBUG
+ if (j)
+ canvas->drawARGB(255, 0, 0, 255);
+ else
+ canvas->drawARGB(255, 255, 0, 255);
+ SkPaint paint;
+ paint.setARGB(128, 255, 0, 0);
+ paint.setStrokeWidth(3);
+ canvas->drawLine(0, 0, tileWidth(), tileHeight(), paint);
+ paint.setARGB(128, 0, 255, 0);
+ canvas->drawLine(0, tileHeight(), tileWidth(), 0, paint);
+ paint.setARGB(128, 0, 0, 255);
+ canvas->drawLine(0, 0, tileWidth(), 0, paint);
+ canvas->drawLine(tileWidth(), 0, tileWidth(), tileHeight(), paint);
+#else
+ canvas->drawARGB(255, 255, 255, 255);
+#endif // DEBUG
+ PaintingInfo info;
+ texture->update(textureInfo, info);
+ texture->producerRelease();
+ }
+ }
+}
+
+void TilesManager::resetTextureUsage(TiledPage* page)
+{
+ android::Mutex::Autolock lock(m_texturesLock);
+ for (unsigned int i = 0; i < m_textures.size(); i++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ if (texture->owner()) {
+ if (texture->owner()->page() == page)
+ texture->setUsedLevel(-1);
+ }
+ }
+}
+
+BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner)
+{
+ android::Mutex::Autolock lock(m_texturesLock);
+ unsigned int max = m_textures.size();
+ // First see if we have something already painted for this tile
+ for (unsigned int i = 0; i < max; i++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ if (texture->painter() == owner) {
+ if (texture->acquire(owner)) {
+ texture->setUsedLevel(0);
+ XLOG("same painter, getAvailableTexture(%x) => texture %x", owner, texture);
+ return texture;
+ }
+ }
+ }
+ // Then, let's return an owned texture if any
+ for (unsigned int i = 0; i < max; i++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ if (texture->owner() == owner) {
+ texture->setUsedLevel(0);
+ XLOG("same owner, getAvailableTexture(%x) => texture %x", owner, texture);
+ return texture;
+ }
+ }
+ // Ok... at this point we need to decide which texture to grab
+ // The texture level indicates their closeness to the current viewport;
+ // let's just grab the texture that is as far as possible, or any
+ // texture that is unused.
+ BackedDoubleBufferedTexture* farthestTexture = 0;
+ int farthestTextureLevel = 0;
+ for (unsigned int i = 0; i < max; i++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ if (texture->usedLevel() == -1) { // found an unused texture, grab it
+ farthestTexture = texture;
+ break;
+ }
+ if (farthestTextureLevel < texture->usedLevel()) {
+ farthestTextureLevel = texture->usedLevel();
+ farthestTexture = texture;
+ }
+ }
+ if (farthestTexture && farthestTexture->acquire(owner)) {
+ farthestTexture->setUsedLevel(0);
+ XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d)",
+ owner, farthestTexture, farthestTexture->usedLevel());
+ return farthestTexture;
+ }
+ // At this point, all textures are used. Let's just grab one
+ // that is not ours...
+ // First, get the two tiled page associated to this, to be sure
+ // we won't starve ourselves
+ TiledPage* currentPage = owner->page();
+ TiledPage* nextPage = currentPage->sibling();
+ for (unsigned int i = 0; i < max; i++) {
+ BackedDoubleBufferedTexture* texture = m_textures[i];
+ if (texture->owner()
+ && texture->owner()->page() != currentPage
+ && texture->owner()->page() != nextPage) {
+ if (texture->acquire(owner)) {
+ XLOG("grab a texture that wasn't ours, (%x != %x) at %d => texture %x",
+ owner->page(), texture->owner()->page(), i, texture);
+ texture->setUsedLevel(0);
+ return texture;
+ }
+ }
+ }
+
+ XLOG("Couldn't find an available texture for BaseTile %x (%d, %d) !!!",
+ owner, owner->x(), owner->y());
+#ifdef DEBUG
+ printTextures();
+#endif // DEBUG
+ return 0;
+}
+
+float TilesManager::tileWidth() const
+{
+ return DEFAULT_TEXTURE_SIZE_WIDTH;
+}
+
+float TilesManager::tileHeight() const
+{
+ return DEFAULT_TEXTURE_SIZE_HEIGHT;
+}
+
+TilesManager* TilesManager::instance()
+{
+ if (!gInstance) {
+ gInstance = new TilesManager();
+ XLOG("Waiting for the generator...");
+ gInstance->waitForGenerator();
+ XLOG("Generator ready!");
+ }
+ return gInstance;
+}
+
+TilesManager* TilesManager::gInstance = 0;
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
new file mode 100644
index 0000000..2ac0ca6
--- /dev/null
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -0,0 +1,97 @@
+/*
+ * 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 TilesManager_h
+#define TilesManager_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "BackedDoubleBufferedTexture.h"
+#include "BaseTile.h"
+#include "ShaderProgram.h"
+#include "TexturesGenerator.h"
+#include "TiledPage.h"
+#include "TilesSet.h"
+#include <utils/threads.h>
+
+namespace WebCore {
+
+class TilesManager {
+public:
+ static TilesManager* instance();
+
+ void schedulePaintForTilesSet(TilesSet* set)
+ {
+ m_pixmapsGenerationThread->schedulePaintForTilesSet(set);
+ }
+
+ ShaderProgram* shader() { return &m_shader; }
+
+ BackedDoubleBufferedTexture* getAvailableTexture(BaseTile* owner);
+
+ void markGeneratorAsReady()
+ {
+ android::Mutex::Autolock lock(m_generatorLock);
+ m_generatorReadyCond.signal();
+ }
+
+ void printTextures();
+ void enableTextures();
+
+ void resetTextureUsage(TiledPage* page);
+ void paintTexturesDefault();
+
+ float tileWidth() const;
+ float tileHeight() const;
+
+private:
+
+ TilesManager();
+
+ void waitForGenerator()
+ {
+ android::Mutex::Autolock lock(m_generatorLock);
+ m_generatorReadyCond.wait(m_generatorLock);
+ }
+
+ Vector<BackedDoubleBufferedTexture*> m_textures;
+
+ bool m_generatorReady;
+
+ sp<TexturesGenerator> m_pixmapsGenerationThread;
+
+ android::Mutex m_texturesLock;
+ android::Mutex m_generatorLock;
+ android::Condition m_generatorReadyCond;
+
+ static TilesManager* gInstance;
+
+ ShaderProgram m_shader;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // TilesManager_h
diff --git a/WebCore/platform/graphics/android/TilesSet.cpp b/WebCore/platform/graphics/android/TilesSet.cpp
new file mode 100644
index 0000000..25f93e5
--- /dev/null
+++ b/WebCore/platform/graphics/android/TilesSet.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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 "TilesSet.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesSet", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+#ifdef DEBUG
+static int gTilesSetCount = 0;
+int TilesSet::count()
+{
+ return gTilesSetCount;
+}
+#endif
+
+TilesSet::TilesSet(int id, float scale, int firstTileX, int firstTileY, int rows, int cols)
+ : m_id(id)
+ , m_scale(scale)
+ , m_firstTileX(firstTileX)
+ , m_firstTileY(firstTileY)
+ , m_nbRows(rows)
+ , m_nbCols(cols)
+ , m_painting(false)
+{
+#ifdef DEBUG
+ gTilesSetCount++;
+#endif
+}
+
+TilesSet::~TilesSet()
+{
+#ifdef DEBUG
+ gTilesSetCount--;
+#endif
+}
+
+bool TilesSet::operator==(const TilesSet& set)
+{
+ return (id() == set.id())
+ && (firstTileX() == set.firstTileX())
+ && (firstTileY() == set.firstTileY())
+ && (nbRows() == set.nbRows())
+ && (nbCols() == set.nbCols());
+}
+
+void TilesSet::reserveTextures()
+{
+ XLOG("reserveTextures (%d tiles)", mTiles.size());
+ for (unsigned int i = 0; i < mTiles.size(); i++)
+ mTiles[i]->reserveTexture();
+}
+
+void TilesSet::paint()
+{
+ XLOG("%x, painting %d tiles", this, mTiles.size());
+ for (unsigned int i = 0; i < mTiles.size(); i++)
+ mTiles[i]->paintBitmap();
+ XLOG("%x, end of painting %d tiles", this, mTiles.size());
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/TilesSet.h b/WebCore/platform/graphics/android/TilesSet.h
new file mode 100644
index 0000000..0e2ebb5
--- /dev/null
+++ b/WebCore/platform/graphics/android/TilesSet.h
@@ -0,0 +1,76 @@
+/*
+ * 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 TilesSet_h
+#define TilesSet_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "BaseTile.h"
+#include "Vector.h"
+
+namespace WebCore {
+
+class TilesSet {
+public:
+#ifdef DEBUG
+ static int count();
+#endif
+ TilesSet(int id, float scale, int firstTileX, int firstTileY, int rows, int cols);
+ ~TilesSet();
+
+ int id() const { return m_id; }
+ float scale() const { return m_scale; }
+ int firstTileX() const { return m_firstTileX; }
+ int firstTileY() const { return m_firstTileY; }
+ int nbRows() const { return m_nbRows; }
+ int nbCols() const { return m_nbCols; }
+ bool operator==(const TilesSet& set);
+ void reserveTextures();
+
+ void paint();
+ void setPainting(bool state) { m_painting = state; }
+
+ void add(BaseTile* texture)
+ {
+ mTiles.append(texture);
+ }
+
+private:
+ Vector<BaseTile*> mTiles;
+
+ int m_id;
+ float m_scale;
+ int m_firstTileX;
+ int m_firstTileY;
+ int m_nbRows;
+ int m_nbCols;
+ bool m_painting;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // TilesSet_h
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 841434f..4093fa5 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -53,6 +53,7 @@
#ifdef ANDROID_INSTRUMENT
#include "TimeCounter.h"
#endif
+#include "TilesManager.h"
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebViewCore.h"
@@ -384,6 +385,56 @@ void drawCursorPostamble()
}
}
+bool drawGL(WebCore::IntRect& viewRect, float scale, int extras)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (!m_baseLayer)
+ return false;
+
+ m_glWebViewState.resetExtra(false);
+ CachedRoot* root = getFrameCache(AllowNewer);
+ if (!root) {
+ DBG_NAV_LOG("!root");
+ if (extras == DrawExtrasCursorRing)
+ resetCursorRing();
+ return false;
+ }
+ DrawExtra* extra = 0;
+ switch (extras) {
+ case DrawExtrasFind:
+ extra = &m_findOnPage;
+ break;
+ case DrawExtrasSelection:
+ extra = &m_selectText;
+ break;
+ case DrawExtrasCursorRing:
+ if (drawCursorPreamble(root) && m_ring.setup()) {
+ if (!m_ring.m_isButton)
+ extra = &m_ring;
+ drawCursorPostamble();
+ }
+ break;
+ default:
+ ;
+ }
+
+ unsigned int pic = m_glWebViewState.currentPictureCounter();
+ if (extra) {
+ LayerAndroid* mainPicture = new LayerAndroid(m_navPictureUI);
+ m_glWebViewState.setExtra(extra, mainPicture);
+ } else {
+ m_glWebViewState.resetExtra(true);
+ }
+
+ SkRect visibleRect;
+ calcOurContentVisibleRect(&visibleRect);
+ bool ret = m_baseLayer->drawGL(viewRect, visibleRect, scale);
+ if (ret || m_glWebViewState.currentPictureCounter() != pic)
+ return true;
+#endif
+ return false;
+}
+
PictureSet* draw(SkCanvas* canvas, SkColor bgColor, int extras, bool split)
{
PictureSet* ret = 0;
@@ -1207,8 +1258,12 @@ static void copyScrollPositionRecursive(const LayerAndroid* from,
}
}
-void setBaseLayer(BaseLayerAndroid* layer)
+void setBaseLayer(BaseLayerAndroid* layer, WebCore::IntRect& rect)
{
+#if USE(ACCELERATED_COMPOSITING)
+ m_glWebViewState.setBaseLayer(layer, rect);
+#endif
+
if (layer) {
copyScrollPositionRecursive(compositeRoot(),
static_cast<LayerAndroid*>(layer->getChild(0)));
@@ -1261,6 +1316,9 @@ private: // local state for WebView
FindOnPage m_findOnPage;
CursorRing m_ring;
BaseLayerAndroid* m_baseLayer;
+#if USE(ACCELERATED_COMPOSITING)
+ GLWebViewState m_glWebViewState;
+#endif
}; // end of WebView class
/*
@@ -1497,6 +1555,13 @@ static jint nativeDraw(JNIEnv *env, jobject obj, jobject canv, jint color,
return reinterpret_cast<jint>(GET_NATIVE_VIEW(env, obj)->draw(canvas, color, extras, split));
}
+static bool nativeDrawGL(JNIEnv *env, jobject obj, jobject jrect,
+ jfloat scale, jint extras)
+{
+ WebCore::IntRect viewRect = jrect_to_webrect(env, jrect);
+ return GET_NATIVE_VIEW(env, obj)->drawGL(viewRect, scale, extras);
+}
+
static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj)
{
#if USE(ACCELERATED_COMPOSITING)
@@ -1507,10 +1572,11 @@ static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj)
return false;
}
-static void nativeSetBaseLayer(JNIEnv *env, jobject obj, jint layer)
+static void nativeSetBaseLayer(JNIEnv *env, jobject obj, jint layer, jobject jrect)
{
BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(layer);
- GET_NATIVE_VIEW(env, obj)->setBaseLayer(layerImpl);
+ WebCore::IntRect rect = jrect_to_webrect(env, jrect);
+ GET_NATIVE_VIEW(env, obj)->setBaseLayer(layerImpl, rect);
}
static void nativeReplaceBaseContent(JNIEnv *env, jobject obj, jint content)
@@ -2165,6 +2231,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeDestroy },
{ "nativeDraw", "(Landroid/graphics/Canvas;IIZ)I",
(void*) nativeDraw },
+ { "nativeDrawGL", "(Landroid/graphics/Rect;FI)Z",
+ (void*) nativeDrawGL },
{ "nativeDumpDisplayTree", "(Ljava/lang/String;)V",
(void*) nativeDumpDisplayTree },
{ "nativeEvaluateLayersAnimations", "()Z",
@@ -2257,7 +2325,7 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetFindIsUp },
{ "nativeSetHeightCanMeasure", "(Z)V",
(void*) nativeSetHeightCanMeasure },
- { "nativeSetBaseLayer", "(I)V",
+ { "nativeSetBaseLayer", "(ILandroid/graphics/Rect;)V",
(void*) nativeSetBaseLayer },
{ "nativeReplaceBaseContent", "(I)V",
(void*) nativeReplaceBaseContent },