summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--WebCore/Android.mk2
-rw-r--r--WebCore/platform/android/RenderThemeAndroid.cpp20
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp10
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h7
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp15
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp73
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h6
-rw-r--r--WebCore/platform/graphics/android/FontAndroid.cpp5
-rw-r--r--WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp16
-rw-r--r--WebCore/platform/graphics/android/GLUtils.cpp23
-rw-r--r--WebCore/platform/graphics/android/GLUtils.h1
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp70
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.h8
-rw-r--r--WebCore/platform/graphics/android/GraphicsContextAndroid.cpp13
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp22
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.h4
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp62
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h3
-rw-r--r--WebCore/platform/graphics/android/PaintTileOperation.cpp (renamed from WebCore/platform/graphics/android/TileSet.cpp)86
-rw-r--r--WebCore/platform/graphics/android/PaintTileOperation.h (renamed from WebCore/platform/graphics/android/PaintTileSetOperation.h)30
-rw-r--r--WebCore/platform/graphics/android/PlatformGraphicsContext.h7
-rw-r--r--WebCore/platform/graphics/android/QueuedOperation.h17
-rw-r--r--WebCore/platform/graphics/android/SharedTexture.cpp5
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.cpp102
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.h6
-rw-r--r--WebCore/platform/graphics/android/TileSet.h77
-rw-r--r--WebCore/platform/graphics/android/TiledPage.cpp135
-rw-r--r--WebCore/platform/graphics/android/TiledPage.h11
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp2
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h11
-rw-r--r--WebCore/platform/graphics/android/android_graphics.h1
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp20
-rw-r--r--WebKit/Android.mk1
-rw-r--r--WebKit/android/RenderSkinAndroid.cpp13
-rw-r--r--WebKit/android/RenderSkinAndroid.h31
-rw-r--r--WebKit/android/RenderSkinButton.cpp73
-rw-r--r--WebKit/android/RenderSkinButton.h12
-rw-r--r--WebKit/android/RenderSkinMediaButton.cpp5
-rw-r--r--WebKit/android/RenderSkinNinePatch.cpp89
-rw-r--r--WebKit/android/RenderSkinNinePatch.h48
-rw-r--r--WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp9
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp19
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp4
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.h4
-rw-r--r--WebKit/android/jni/WebViewCore.cpp6
-rw-r--r--WebKit/android/nav/WebView.cpp40
47 files changed, 740 insertions, 485 deletions
diff --git a/Android.mk b/Android.mk
index 0bddbc1..51640aa 100644
--- a/Android.mk
+++ b/Android.mk
@@ -451,7 +451,6 @@ endif # JAVASCRIPT_ENGINE == jsc
# will strip out any unused code from the entry point.
include $(CLEAR_VARS)
# if you need to make webcore huge (for debugging), enable this line
-#LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libwebcore
LOCAL_LDLIBS := $(WEBKIT_LDLIBS)
LOCAL_SHARED_LIBRARIES := $(WEBKIT_SHARED_LIBRARIES)
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index feeb56b..5bc6d83 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -620,6 +620,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/MediaLayer.cpp \
platform/graphics/android/MediaTexture.cpp \
platform/graphics/android/PaintLayerOperation.cpp \
+ platform/graphics/android/PaintTileOperation.cpp \
platform/graphics/android/PathAndroid.cpp \
platform/graphics/android/PatternAndroid.cpp \
platform/graphics/android/PlatformGraphicsContext.cpp \
@@ -630,7 +631,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/TexturesGenerator.cpp \
platform/graphics/android/TilesManager.cpp \
platform/graphics/android/TiledPage.cpp \
- platform/graphics/android/TileSet.cpp \
platform/graphics/android/VideoLayerAndroid.cpp \
platform/graphics/android/android_graphics.cpp \
diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp
index 944504e..113fa63 100644
--- a/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -44,6 +44,7 @@
#include "RenderSkinRadio.h"
#include "SkCanvas.h"
#include "UserAgentStyleSheets.h"
+#include "WebCoreFrameBridge.h"
namespace WebCore {
@@ -67,6 +68,13 @@ static SkCanvas* getCanvasFromInfo(const PaintInfo& info)
return info.context->platformContext()->mCanvas;
}
+static android::WebFrame* getWebFrame(const Node* node)
+{
+ if (!node)
+ return 0;
+ return android::WebFrame::getWebFrame(node->document()->frame());
+}
+
RenderTheme* theme()
{
DEFINE_STATIC_LOCAL(RenderThemeAndroid, androidTheme, ());
@@ -223,9 +231,15 @@ bool RenderThemeAndroid::paintButton(RenderObject* obj, const PaintInfo& info, c
// If it is a disabled button, simply paint it to the master picture.
Node* node = obj->node();
Element* formControlElement = static_cast<Element*>(node);
- if (formControlElement && !formControlElement->isEnabledFormControl())
- RenderSkinButton::Draw(getCanvasFromInfo(info), rect, RenderSkinAndroid::kDisabled);
- else
+ if (formControlElement && !formControlElement->isEnabledFormControl()) {
+ android::WebFrame* webFrame = getWebFrame(node);
+ if (webFrame) {
+ const RenderSkinAndroid* skins = webFrame->renderSkins();
+ if (skins)
+ skins->renderSkinButton()->draw(getCanvasFromInfo(info), rect,
+ RenderSkinAndroid::kDisabled);
+ }
+ } else
// Store all the important information in the platform context.
info.context->platformContext()->storeButtonInfo(node, rect);
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
index dc0962c..964422a 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
@@ -137,6 +137,7 @@ void BackedDoubleBufferedTexture::setNotBusy()
m_delayedRelease = false;
m_delayedReleaseOwner = 0;
}
+ m_busyCond.signal();
}
bool BackedDoubleBufferedTexture::busy()
@@ -189,7 +190,7 @@ void BackedDoubleBufferedTexture::producerUpdate(TextureInfo* textureInfo)
producerReleaseAndSwap();
}
-bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner)
+bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner, bool force)
{
if (m_owner == owner) {
if (m_delayedRelease) {
@@ -199,7 +200,7 @@ bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner)
return true;
}
- return setOwner(owner);
+ return setOwner(owner, force);
}
bool BackedDoubleBufferedTexture::tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage)
@@ -216,13 +217,16 @@ bool BackedDoubleBufferedTexture::tryAcquire(TextureOwner* owner, TiledPage* cur
return false;
}
-bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner)
+bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner, bool force)
{
// if the writable texture is busy (i.e. currently being written to) then we
// can't change the owner out from underneath that texture
m_busyLock.lock();
+ while (m_busy && force)
+ m_busyCond.wait(m_busyLock);
bool busy = m_busy;
m_busyLock.unlock();
+
if (!busy) {
// if we are not busy we can try to remove the texture from the layer;
// LayerAndroid::removeTexture() is protected by the same lock as
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
index 8bfae59..7c2ea90 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
@@ -88,12 +88,12 @@ public:
// allows consumer thread to assign ownership of the texture to the tile. It
// returns false if ownership cannot be transferred because the tile is busy
- bool acquire(TextureOwner* owner);
+ bool acquire(TextureOwner* owner, bool force = false);
bool release(TextureOwner* owner);
bool tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage);
// set the texture owner if not busy. Return false if busy, true otherwise.
- bool setOwner(TextureOwner* owner);
+ bool setOwner(TextureOwner* owner, bool force = false);
// private member accessor functions
TextureOwner* owner() { return m_owner; } // only used by the consumer thread
@@ -136,6 +136,9 @@ private:
// We mutex protect the reads/writes of m_busy to ensure that we are reading
// the most up-to-date value even across processors in an SMP system.
android::Mutex m_busyLock;
+ // We use this condition variable to signal that the texture
+ // is not busy anymore
+ android::Condition m_busyCond;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index c59a5a5..ebf8c88 100644
--- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -163,13 +163,19 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
zooming = true;
}
+ // Display the current page
+ TiledPage* tiledPage = m_glWebViewState->frontPage();
+ tiledPage->setScale(m_glWebViewState->currentScale());
+
// Let's prepare the page if needed
if (prepareNextTiledPage) {
TiledPage* nextTiledPage = m_glWebViewState->backPage();
nextTiledPage->setScale(scale);
m_glWebViewState->setFutureViewport(viewportTileBounds);
m_glWebViewState->lockBaseLayerUpdate();
- nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds, true);
+ nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds);
+ // Cancel pending paints for the foreground page
+ TilesManager::instance()->removePaintOperationsForPage(tiledPage, false);
}
float transparency = 1;
@@ -205,9 +211,6 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
}
}
- // Display the current page
- TiledPage* tiledPage = m_glWebViewState->frontPage();
- tiledPage->setScale(m_glWebViewState->currentScale());
const SkIRect& preZoomBounds = m_glWebViewState->preZoomBounds();
TiledPage* nextTiledPage = m_glWebViewState->backPage();
@@ -240,7 +243,8 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
if (!zooming)
m_glWebViewState->unlockBaseLayerUpdate();
- tiledPage->prepare(goingDown, goingLeft, preZoomBounds, true);
+ if (!prepareNextTiledPage)
+ tiledPage->prepare(goingDown, goingLeft, preZoomBounds);
tiledPage->draw(transparency, preZoomBounds);
}
@@ -254,6 +258,7 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
m_glWebViewState->unlockBaseLayerUpdate();
}
+ m_glWebViewState->paintExtras();
return needsRedraw;
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index d58c549..c74a278 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -66,11 +66,11 @@ BaseTile::BaseTile()
, m_texture(0)
, m_scale(1)
, m_dirty(true)
+ , m_repaintPending(false)
, m_usable(true)
, m_lastDirtyPicture(0)
, m_fullRepaintA(true)
, m_fullRepaintB(true)
- , m_painting(false)
, m_lastPaintedPicture(0)
{
#ifdef DEBUG_COUNT
@@ -105,8 +105,7 @@ void BaseTile::reserveTexture()
BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this);
android::AutoMutex lock(m_atomicSync);
- if (texture && !m_painting &&
- m_texture != texture) {
+ if (texture && m_texture != texture) {
m_lastPaintedPicture = 0;
fullInval();
m_texture = texture;
@@ -118,8 +117,6 @@ bool BaseTile::removeTexture(BackedDoubleBufferedTexture* texture)
XLOG("%x removeTexture res: %x... page %x", this, m_texture, m_page);
// We update atomically, so paintBitmap() can see the correct value
android::AutoMutex lock(m_atomicSync);
- if (m_painting)
- return false;
if (m_texture == texture)
m_texture = 0;
return true;
@@ -166,12 +163,31 @@ bool BaseTile::isDirty()
return m_dirty;
}
+bool BaseTile::isRepaintPending()
+{
+ android::AutoMutex lock(m_atomicSync);
+ return m_repaintPending;
+}
+
+void BaseTile::setRepaintPending(bool pending)
+{
+ android::AutoMutex lock(m_atomicSync);
+ m_repaintPending = pending;
+}
+
void BaseTile::setUsedLevel(int usedLevel)
{
if (m_texture)
m_texture->setUsedLevel(usedLevel);
}
+int BaseTile::usedLevel()
+{
+ if (m_texture)
+ return m_texture->usedLevel();
+ return -1;
+}
+
void BaseTile::draw(float transparency, SkRect& rect, float scale)
{
if (m_x < 0 || m_y < 0 || m_scale != scale)
@@ -261,14 +277,12 @@ void BaseTile::paintBitmap()
bool dirty = m_dirty;
BackedDoubleBufferedTexture* texture = m_texture;
SkRegion dirtyArea = *m_currentDirtyArea;
- m_painting = true;
float scale = m_scale;
const int x = m_x;
const int y = m_y;
m_atomicSync.unlock();
if (!dirty || !texture) {
- m_painting = false;
return;
}
@@ -281,7 +295,6 @@ void BaseTile::paintBitmap()
// transferred to another BaseTile under us)
if (texture->owner() != this || texture->usedLevel() > 1) {
texture->producerRelease();
- m_painting = false;
return;
}
@@ -359,40 +372,40 @@ void BaseTile::paintBitmap()
texture->setTile(textureInfo, x, y, scale, pictureCount);
texture->producerReleaseAndSwap();
- m_lastPaintedPicture = pictureCount;
-
- // set the fullrepaint flags
+ if (texture == m_texture) {
+ m_lastPaintedPicture = pictureCount;
- if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA)
- m_fullRepaintA = false;
+ // set the fullrepaint flags
- if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)
- m_fullRepaintB = false;
+ if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA)
+ m_fullRepaintA = false;
- // The various checks to see if we are still dirty...
+ if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)
+ m_fullRepaintB = false;
- m_dirty = false;
+ // The various checks to see if we are still dirty...
- if (m_scale != scale)
- m_dirty = true;
+ m_dirty = false;
- if (!fullRepaint)
- m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op);
+ if (m_scale != scale)
+ m_dirty = true;
- if (!m_currentDirtyArea->isEmpty())
- m_dirty = true;
+ if (!fullRepaint)
+ m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op);
- // Now we can swap the dirty areas
+ if (!m_currentDirtyArea->isEmpty())
+ m_dirty = true;
- m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA;
+ // Now we can swap the dirty areas
- if (!m_currentDirtyArea->isEmpty())
- m_dirty = true;
+ m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA;
- if (!m_dirty)
- m_usable = true;
+ if (!m_currentDirtyArea->isEmpty())
+ m_dirty = true;
- m_painting = false;
+ if (!m_dirty)
+ m_usable = true;
+ }
m_atomicSync.unlock();
}
diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h
index b832eee..7b28f76 100644
--- a/WebCore/platform/graphics/android/BaseTile.h
+++ b/WebCore/platform/graphics/android/BaseTile.h
@@ -72,6 +72,7 @@ public:
void reserveTexture();
void setUsedLevel(int);
+ int usedLevel();
bool isTileReady();
void draw(float transparency, SkRect& rect, float scale);
@@ -89,6 +90,8 @@ public:
void markAsDirty(const unsigned int pictureCount,
const SkRegion& dirtyArea);
bool isDirty();
+ bool isRepaintPending();
+ void setRepaintPending(bool pending);
void setUsable(bool usable);
float scale() const { return m_scale; }
void setScale(float scale);
@@ -114,6 +117,8 @@ private:
float m_scale;
// used to signal that the that the tile is out-of-date and needs to be redrawn
bool m_dirty;
+ // used to signal that a repaint is pending
+ bool m_repaintPending;
// used to signal whether or not the draw can use this tile.
bool m_usable;
// stores the id of the latest picture from webkit that caused this tile to
@@ -127,7 +132,6 @@ private:
bool m_fullRepaintA;
bool m_fullRepaintB;
SkRegion* m_currentDirtyArea;
- bool m_painting;
// stores the id of the latest picture painted to the tile. If the id is 0
// then we know that the picture has not yet been painted an there is nothing
diff --git a/WebCore/platform/graphics/android/FontAndroid.cpp b/WebCore/platform/graphics/android/FontAndroid.cpp
index ffaeded..e896a46 100644
--- a/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -83,8 +83,9 @@ static bool setupForText(SkPaint* paint, GraphicsContext* gc,
float shadowBlur;
Color shadowColor;
bool hasShadow = gc->getShadow(shadowOffset, shadowBlur, shadowColor);
-
- if (hasShadow || (mode == (cTextStroke & cTextFill))) {
+ bool hasBothStrokeAndFill =
+ (mode & (cTextStroke | cTextFill)) == (cTextStroke | cTextFill);
+ if (hasShadow || hasBothStrokeAndFill) {
SkLayerDrawLooper* looper = new SkLayerDrawLooper;
paint->setLooper(looper)->unref();
diff --git a/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
index 352516b..337a94d 100644
--- a/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
+++ b/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
@@ -163,11 +163,15 @@ void FontPlatformData::setupPaint(SkPaint* paint) const
if (!(ts > 0))
ts = 12;
+ if (hashTableDeletedFontValue() == mTypeface)
+ paint->setTypeface(0);
+ else
+ paint->setTypeface(mTypeface);
+
paint->setAntiAlias(true);
paint->setSubpixelText(true);
paint->setHinting(SkPaint::kSlight_Hinting);
paint->setTextSize(SkFloatToScalar(ts));
- paint->setTypeface(mTypeface);
paint->setFakeBoldText(mFakeBold);
paint->setTextSkewX(mFakeItalic ? -SK_Scalar1/4 : 0);
#ifndef SUPPORT_COMPLEX_SCRIPTS
@@ -177,7 +181,10 @@ void FontPlatformData::setupPaint(SkPaint* paint) const
uint32_t FontPlatformData::uniqueID() const
{
- return mTypeface->uniqueID();
+ if (hashTableDeletedFontValue() == mTypeface)
+ return SkTypeface::UniqueID(0);
+ else
+ return SkTypeface::UniqueID(mTypeface);
}
bool FontPlatformData::operator==(const FontPlatformData& a) const
@@ -207,7 +214,10 @@ unsigned FontPlatformData::hash() const
bool FontPlatformData::isFixedPitch() const
{
- return mTypeface ? mTypeface->isFixedWidth() : false;
+ if (mTypeface && (mTypeface != hashTableDeletedFontValue()))
+ return mTypeface->isFixedWidth();
+ else
+ return false;
}
HB_FaceRec_* FontPlatformData::harfbuzzFace() const
diff --git a/WebCore/platform/graphics/android/GLUtils.cpp b/WebCore/platform/graphics/android/GLUtils.cpp
index 23bf525..5eabb85 100644
--- a/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/WebCore/platform/graphics/android/GLUtils.cpp
@@ -289,6 +289,25 @@ void GLUtils::deleteTexture(GLuint* texture)
*texture = 0;
}
+GLuint GLUtils::createSampleColorTexture(int r, int g, int b) {
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ GLubyte pixels[4 *3] = {
+ r, g, b,
+ r, g, b,
+ r, g, b,
+ r, g, b
+ };
+ glBindTexture(GL_TEXTURE_2D, texture);
+ GLUtils::checkGlError("glBindTexture");
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+ GLUtils::checkGlError("glTexImage2D");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ return texture;
+}
+
GLuint GLUtils::createSampleTexture()
{
GLuint texture;
@@ -375,8 +394,8 @@ void GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, SkBitmap& bi
bitmap.unlockPixels();
if (GLUtils::checkGlError("glTexSubImage2D")) {
XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
- " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
- bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
+ " x %d, y %d, internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
+ bitmap.width(), bitmap.height(), x, y, internalformat, type, bitmap.getPixels());
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
diff --git a/WebCore/platform/graphics/android/GLUtils.h b/WebCore/platform/graphics/android/GLUtils.h
index 64aedbb..1e8df39 100644
--- a/WebCore/platform/graphics/android/GLUtils.h
+++ b/WebCore/platform/graphics/android/GLUtils.h
@@ -59,6 +59,7 @@ public:
// Texture utilities
static EGLContext createBackgroundContext(EGLContext sharedContext);
static void deleteTexture(GLuint* texture);
+ static GLuint createSampleColorTexture(int r, int g, int b);
static GLuint createSampleTexture();
static void createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
static void updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp
index 6f95836..74f03f5 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -30,6 +30,7 @@
#include "BaseLayerAndroid.h"
#include "ClassTracker.h"
+#include "GLUtils.h"
#include "LayerAndroid.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
@@ -78,6 +79,8 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
, m_baseLayerUpdate(true)
, m_backgroundColor(SK_ColorWHITE)
, m_prevDrawTime(0)
+ , m_displayRings(false)
+ , m_focusRingTexture(-1)
{
m_viewport.setEmpty();
m_previousViewport.setEmpty();
@@ -144,6 +147,7 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval
SkSafeUnref(m_currentBaseLayer);
m_currentBaseLayer = layer;
}
+ m_displayRings = false;
invalRegion(inval);
#ifdef MEASURES_PERF
@@ -155,6 +159,13 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval
TilesManager::instance()->setShowVisualIndicator(showVisualIndicator);
}
+void GLWebViewState::setRings(Vector<IntRect>& rings)
+{
+ android::Mutex::Autolock lock(m_baseLayerLock);
+ m_displayRings = true;
+ m_rings = rings;
+}
+
void GLWebViewState::invalRegion(const SkRegion& region)
{
SkRegion::Iterator iterator(region);
@@ -197,6 +208,7 @@ void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture,
if (!m_lastInval.isEmpty())
inval(m_lastInval);
m_lastInval = rect;
+ m_displayRings = false;
}
void GLWebViewState::inval(const IntRect& rect)
@@ -220,6 +232,64 @@ void GLWebViewState::inval(const IntRect& rect)
}
}
+void GLWebViewState::resetRings()
+{
+ m_displayRings = false;
+}
+
+void GLWebViewState::drawFocusRing(IntRect& srcRect)
+{
+ // TODO: use a 9-patch texture to draw the focus ring
+ // instead of plain colors
+ const int border = 1;
+ const int fuzzyBorder = border * 2;
+ const int padding = 4;
+ const float alpha = 0.3;
+ const float borderAlpha = 0.40;
+
+ const int r = 104;
+ const int g = 153;
+ const int b = 255;
+
+ if (m_focusRingTexture == -1)
+ m_focusRingTexture = GLUtils::createSampleColorTexture(r, g, b);
+
+ SkRect rLeft, rTop, rRight, rBottom, rOverlay;
+
+ IntRect rect(srcRect.x() - padding, srcRect.y() - padding,
+ srcRect.width() + (padding * 2), srcRect.height() + (padding * 2));
+ rLeft.set(rect.x() - border, rect.y(),
+ rect.x(), rect.y() + rect.height());
+ rTop.set(rect.x() - border, rect.y() - border,
+ rect.x() + rect.width() + border, rect.y());
+ rRight.set(rect.x() + rect.width(), rect.y(),
+ rect.x() + rect.width() + border,
+ rect.y() + rect.height());
+ rBottom.set(rect.x() - border, rect.y() + rect.height(),
+ rect.x() + rect.width() + border,
+ rect.y() + rect.height() + border);
+ rOverlay.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder,
+ rect.x() + rect.width() + fuzzyBorder,
+ rect.y() + rect.height() + fuzzyBorder);
+
+ TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, borderAlpha);
+ TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, borderAlpha);
+ TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, borderAlpha);
+ TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, borderAlpha);
+ TilesManager::instance()->shader()->drawQuad(rOverlay, m_focusRingTexture, alpha);
+}
+
+void GLWebViewState::paintExtras()
+{
+ if (m_displayRings) {
+ // TODO: handles correctly the multi-rings case
+ for (int i=0; i<m_rings.size(); i++) {
+ IntRect rect = m_rings.at(i);
+ drawFocusRing(rect);
+ }
+ }
+}
+
unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
{
android::Mutex::Autolock lock(m_baseLayerLock);
diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h
index ac75605..7892337 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/WebCore/platform/graphics/android/GLWebViewState.h
@@ -179,6 +179,11 @@ public:
bool isPictureAfterFirstLayout);
void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&, bool allowSame);
void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale);
+ void paintExtras();
+
+ void setRings(Vector<IntRect>& rings);
+ void resetRings();
+ void drawFocusRing(IntRect& rect);
TiledPage* sibling(TiledPage* page);
TiledPage* frontPage();
@@ -283,6 +288,9 @@ private:
double m_delayTimes[MAX_MEASURES_PERF];
bool m_measurePerfs;
#endif
+ bool m_displayRings;
+ Vector<IntRect> m_rings;
+ int m_focusRingTexture;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
index 1a32ef5..64b6ad3 100644
--- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
@@ -101,10 +101,16 @@ static bool setBitmapDash(SkPaint* paint, int width) {
// Is Color premultiplied or not? If it is, then I can't blindly pass it to paint.setColor()
struct ShadowRec {
- SkScalar blur; // >0 means valid shadow
+ SkScalar blur;
SkScalar dx;
SkScalar dy;
- SkColor color;
+ SkColor color; // alpha>0 means valid shadow
+ ShadowRec(SkScalar b = 0,
+ SkScalar x = 0,
+ SkScalar y = 0,
+ SkColor c = 0) // by default, alpha=0, so no shadow
+ : blur(b), dx(x), dy(y), color(c)
+ {};
};
class GraphicsContextPlatformPrivate {
@@ -141,7 +147,6 @@ public:
, strokeColor(SK_ColorBLACK)
, useAA(true)
{
- shadow.blur = 0;
}
State(const State& other)
@@ -283,7 +288,7 @@ public:
paint->setAntiAlias(m_state->useAA);
paint->setDither(true);
paint->setXfermodeMode(m_state->mode);
- if (m_state->shadow.blur > 0) {
+ if (SkColorGetA(m_state->shadow.color) > 0) {
SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur,
m_state->shadow.dx,
m_state->shadow.dy,
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 96cfd3d..59f8408 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -120,6 +120,8 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_needsNotifyClient(false),
m_haveContents(false),
m_haveImage(false),
+ m_newImage(false),
+ m_imageRef(0),
m_foregroundLayer(0),
m_foregroundClipLayer(0)
{
@@ -623,6 +625,14 @@ bool GraphicsLayerAndroid::repaint()
return true;
}
+ if (m_needsRepaint && m_haveImage && m_newImage) {
+ // We need to tell the GL thread that we will need to repaint the
+ // texture. Only do so if we effectively have a new image!
+ m_contentLayer->needsRepaint();
+ m_newImage = false;
+ m_needsRepaint = false;
+ return true;
+ }
return false;
}
@@ -834,9 +844,15 @@ void GraphicsLayerAndroid::setContentsToImage(Image* image)
if (image) {
m_haveContents = true;
m_haveImage = true;
- m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
- setNeedsDisplay();
- askForSync();
+ // Only pass the new image if it's a different one
+ if (image->nativeImageForCurrentFrame() != m_imageRef) {
+ m_newImage = true;
+ m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
+ // remember the passed image.
+ m_imageRef = image->nativeImageForCurrentFrame();
+ setNeedsDisplay();
+ askForSync();
+ }
}
}
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index da247ca..94b828b 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -25,10 +25,12 @@
#include "GraphicsLayerClient.h"
#include "LayerAndroid.h"
#include "RefPtr.h"
+#include "SkBitmapRef.h"
#include "Vector.h"
class FloatPoint3D;
class Image;
+class SkBitmapRef;
namespace WebCore {
@@ -142,6 +144,8 @@ private:
bool m_haveContents;
bool m_haveImage;
+ bool m_newImage;
+ SkBitmapRef* m_imageRef; // only used to remember previously passed images
Vector<FloatRect> m_invalidatedRects;
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 78e55c1..e616041 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -44,19 +44,12 @@ static int gUniqueId;
class OpacityDrawFilter : public SkDrawFilter {
public:
OpacityDrawFilter(int opacity) : m_opacity(opacity) { }
- virtual bool filter(SkCanvas* canvas, SkPaint* paint, Type)
+ virtual void filter(SkPaint* paint, Type)
{
- m_previousOpacity = paint->getAlpha();
paint->setAlpha(m_opacity);
- return true;
- }
- virtual void restore(SkCanvas* canvas, SkPaint* paint, Type)
- {
- paint->setAlpha(m_previousOpacity);
}
private:
int m_opacity;
- int m_previousOpacity;
};
///////////////////////////////////////////////////////////////////////////////
@@ -92,6 +85,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : SkLayer(),
LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_haveClip(layer.m_haveClip),
m_isIframe(layer.m_isIframe),
+ m_contentsImage(0),
m_extra(0), // deliberately not copied
m_uniqueId(layer.m_uniqueId),
m_drawingTexture(0),
@@ -100,8 +94,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_owningLayer(layer.m_owningLayer)
{
m_isFixed = layer.m_isFixed;
- m_contentsImage = layer.m_contentsImage;
- SkSafeRef(m_contentsImage);
+ copyBitmap(layer.m_contentsImage);
m_renderLayerPos = layer.m_renderLayerPos;
m_transform = layer.m_transform;
m_backgroundColor = layer.m_backgroundColor;
@@ -202,7 +195,7 @@ LayerAndroid::~LayerAndroid()
removeTexture(0);
removeChildren();
delete m_extra;
- SkSafeUnref(m_contentsImage);
+ delete m_contentsImage;
SkSafeUnref(m_recordingPicture);
m_animations.clear();
#ifdef DEBUG_COUNT
@@ -650,9 +643,23 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
this->getChild(i)->updateGLPositions(localMatrix, drawClip(), opacity);
}
+void LayerAndroid::copyBitmap(SkBitmap* bitmap)
+{
+ if (!bitmap)
+ return;
+
+ delete m_contentsImage;
+ m_contentsImage = new SkBitmap();
+ SkBitmap::Config config = bitmap->config();
+ int w = bitmap->width();
+ int h = bitmap->height();
+ m_contentsImage->setConfig(config, w, h);
+ bitmap->copyTo(m_contentsImage, config);
+}
+
void LayerAndroid::setContentsImage(SkBitmapRef* img)
{
- SkRefCnt_SafeAssign(m_contentsImage, img);
+ copyBitmap(&img->bitmap());
}
bool LayerAndroid::needsTexture()
@@ -889,7 +896,7 @@ void LayerAndroid::createGLTextures()
uniqueId(), this, m_dirty, m_reservedTexture,
m_reservedTexture->rect().width(), m_reservedTexture->rect().height());
PaintLayerOperation* operation = new PaintLayerOperation(this);
- TilesManager::instance()->scheduleOperation(operation, !m_drawingTexture);
+ TilesManager::instance()->scheduleOperation(operation);
} else {
XLOG("We don't schedule a paint for layer %d (%x), because we already sent a request",
uniqueId(), this);
@@ -930,9 +937,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
if (m_drawingTexture) {
TextureInfo* textureInfo = m_drawingTexture->consumerLock();
- if (!m_drawingTexture->readyFor(this))
- m_dirty = true;
- if (textureInfo) {
+ bool ready = m_drawingTexture->readyFor(this);
+ if (textureInfo && (!m_contentsImage || (ready && m_contentsImage))) {
SkRect bounds;
bounds.set(m_drawingTexture->rect());
XLOG("LayerAndroid %d %x (%.2f, %.2f) drawGL (texture %x, %d, %d, %d, %d)",
@@ -944,6 +950,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
textureInfo->m_textureId,
m_drawOpacity, true);
}
+ if (!ready)
+ m_dirty = true;
m_drawingTexture->consumerRelease();
} else if (needsTexture()) {
m_dirty = true;
@@ -1034,14 +1042,18 @@ void LayerAndroid::paintBitmapGL()
IntRect textureRect = texture->rect();
canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
- SkPicture picture;
- SkCanvas* nCanvas = picture.beginRecording(textureRect.width(),
- textureRect.height());
- nCanvas->scale(scale, scale);
- nCanvas->translate(-textureRect.x(), -textureRect.y());
- contentDraw(nCanvas);
- picture.endRecording();
- picture.draw(canvas);
+ if (m_contentsImage) {
+ contentDraw(canvas);
+ } else {
+ SkPicture picture;
+ SkCanvas* nCanvas = picture.beginRecording(textureRect.width(),
+ textureRect.height());
+ nCanvas->scale(scale, scale);
+ nCanvas->translate(-textureRect.x(), -textureRect.y());
+ contentDraw(nCanvas);
+ picture.endRecording();
+ picture.draw(canvas);
+ }
extraDraw(canvas);
m_atomicSync.lock();
@@ -1071,7 +1083,7 @@ void LayerAndroid::contentDraw(SkCanvas* canvas)
if (m_contentsImage) {
SkRect dest;
dest.set(0, 0, getSize().width(), getSize().height());
- canvas->drawBitmapRect(m_contentsImage->bitmap(), 0, dest);
+ canvas->drawBitmapRect(*m_contentsImage, 0, dest);
} else {
canvas->drawPicture(*m_recordingPicture);
}
diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h
index 0846930..e01a9a7 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/WebCore/platform/graphics/android/LayerAndroid.h
@@ -234,6 +234,7 @@ public:
*/
void setContentsImage(SkBitmapRef* img);
bool hasContentsImage() { return m_contentsImage; }
+ void copyBitmap(SkBitmap*);
void bounds(SkRect*) const;
@@ -304,7 +305,7 @@ private:
// it is a much faster method than using m_recordingPicture.
SkPicture* m_recordingPicture;
- SkBitmapRef* m_contentsImage;
+ SkBitmap* m_contentsImage;
typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
KeyframesMap m_animations;
diff --git a/WebCore/platform/graphics/android/TileSet.cpp b/WebCore/platform/graphics/android/PaintTileOperation.cpp
index 1214aa2..222b69b 100644
--- a/WebCore/platform/graphics/android/TileSet.cpp
+++ b/WebCore/platform/graphics/android/PaintTileOperation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010, The Android Open Source Project
+ * Copyright 2011, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,64 +24,58 @@
*/
#include "config.h"
-#include "TileSet.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "ClassTracker.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, "TileSet", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
+#include "PaintTileOperation.h"
namespace WebCore {
-TileSet::TileSet(TiledPage* tiledPage, int rows, int cols)
- : m_tiledPage(tiledPage)
- , m_nbRows(rows)
- , m_nbCols(cols)
+PaintTileOperation::PaintTileOperation(BaseTile* tile)
+ : QueuedOperation(QueuedOperation::PaintTile, tile->page())
+ , m_tile(tile)
{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("TileSet");
-#endif
+ if (m_tile)
+ m_tile->setRepaintPending(true);
}
-TileSet::~TileSet()
+PaintTileOperation::~PaintTileOperation()
{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("TileSet");
-#endif
+ if (m_tile) {
+ m_tile->setRepaintPending(false);
+ m_tile = 0;
+ }
}
-bool TileSet::operator==(const TileSet& set)
+bool PaintTileOperation::operator==(const QueuedOperation* operation)
{
- return m_tiledPage == set.m_tiledPage
- && m_nbRows == set.m_nbRows
- && m_nbCols == set.m_nbCols;
+ if (operation->type() != type())
+ return false;
+ const PaintTileOperation* op = static_cast<const PaintTileOperation*>(operation);
+ return op->m_tile == m_tile;
}
-
-void TileSet::paint()
+void PaintTileOperation::run()
{
- XLOG("%x, painting %d tiles", this, m_tiles.size());
- for (unsigned int i = 0; i < m_tiles.size(); i++)
- m_tiles[i]->paintBitmap();
- XLOG("%x, end of painting %d tiles", this, m_tiles.size());
+ if (m_tile) {
+ m_tile->paintBitmap();
+ m_tile->setRepaintPending(false);
+ m_tile = 0;
+ }
}
-} // namespace WebCore
+int PaintTileOperation::priority()
+{
+ if (!m_tile || m_tile->usedLevel() < 0)
+ return -1;
+ bool goingDown = m_tile->page()->scrollingDown();
+ SkIRect *rect = m_tile->page()->expandedTileBounds();
+ int firstTileX = rect->fLeft;
+ int nbTilesWidth = rect->width();
+ int priority = m_tile->x() - firstTileX;
+ if (goingDown)
+ priority += (rect->fBottom - m_tile->y()) * nbTilesWidth;
+ else
+ priority += (m_tile->y() - rect->fTop) * nbTilesWidth;
+ priority += m_tile->usedLevel() * 100000;
+ return priority;
+}
-#endif // USE(ACCELERATED_COMPOSITING)
+}
diff --git a/WebCore/platform/graphics/android/PaintTileSetOperation.h b/WebCore/platform/graphics/android/PaintTileOperation.h
index fba7220..0920f32 100644
--- a/WebCore/platform/graphics/android/PaintTileSetOperation.h
+++ b/WebCore/platform/graphics/android/PaintTileOperation.h
@@ -27,33 +27,19 @@
#define PaintTileSetOperation_h
#include "QueuedOperation.h"
-#include "TileSet.h"
namespace WebCore {
-class PaintTileSetOperation : public QueuedOperation {
+class PaintTileOperation : public QueuedOperation {
public:
- PaintTileSetOperation(TileSet* set)
- : QueuedOperation(QueuedOperation::PaintTileSet, set->page())
- , m_set(set) {}
- virtual ~PaintTileSetOperation()
- {
- delete m_set;
- }
- virtual bool operator==(const QueuedOperation* operation)
- {
- if (operation->type() != type())
- return false;
- const PaintTileSetOperation* op = static_cast<const PaintTileSetOperation*>(operation);
- return op->m_set == m_set;
- }
- virtual void run()
- {
- if (m_set)
- m_set->paint();
- }
+ PaintTileOperation(BaseTile* tile);
+ virtual ~PaintTileOperation();
+ virtual bool operator==(const QueuedOperation* operation);
+ virtual void run();
+ virtual int priority();
+
private:
- TileSet* m_set;
+ BaseTile* m_tile;
};
}
diff --git a/WebCore/platform/graphics/android/PlatformGraphicsContext.h b/WebCore/platform/graphics/android/PlatformGraphicsContext.h
index 8d0df36..0ce86d2 100644
--- a/WebCore/platform/graphics/android/PlatformGraphicsContext.h
+++ b/WebCore/platform/graphics/android/PlatformGraphicsContext.h
@@ -106,7 +106,8 @@ public:
// corresponds to the focused node passed in. If its state has changed,
// re-record to the subpicture, so the master picture will reflect the
// change.
- void updateFocusState(WebCore::RenderSkinAndroid::State state)
+ void updateFocusState(WebCore::RenderSkinAndroid::State state,
+ const WebCore::RenderSkinButton* buttonSkin)
{
if (state == m_state)
return;
@@ -117,8 +118,8 @@ public:
state == WebCore::RenderSkinAndroid::kFocused)
return;
m_state = state;
- SkCanvas* canvas = m_picture->beginRecording(m_rect.width(), m_rect.height());
- WebCore::RenderSkinButton::Draw(canvas, m_rect, state);
+ SkCanvas* canvas = m_picture->beginRecording(m_rect.right(), m_rect.bottom());
+ buttonSkin->draw(canvas, m_rect, state);
m_picture->endRecording();
}
private:
diff --git a/WebCore/platform/graphics/android/QueuedOperation.h b/WebCore/platform/graphics/android/QueuedOperation.h
index 089483d..98f3e2f 100644
--- a/WebCore/platform/graphics/android/QueuedOperation.h
+++ b/WebCore/platform/graphics/android/QueuedOperation.h
@@ -32,13 +32,14 @@ namespace WebCore {
class QueuedOperation {
public:
- enum OperationType { Undefined, PaintTileSet, PaintLayer, DeleteTexture };
+ enum OperationType { Undefined, PaintTile, PaintLayer, DeleteTexture };
QueuedOperation(OperationType type, TiledPage* page)
: m_type(type)
, m_page(page) {}
virtual ~QueuedOperation() {}
virtual void run() = 0;
virtual bool operator==(const QueuedOperation* operation) = 0;
+ virtual int priority() { return -1; }
OperationType type() const { return m_type; }
TiledPage* page() const { return m_page; }
private:
@@ -65,6 +66,20 @@ class PageFilter : public OperationFilter {
TiledPage* m_page;
};
+class PagePaintFilter : public OperationFilter {
+ public:
+ PagePaintFilter(TiledPage* page) : m_page(page) {}
+ virtual bool check(QueuedOperation* operation)
+ {
+ if (operation->type() == QueuedOperation::PaintTile
+ && operation->page() == m_page)
+ return true;
+ return false;
+ }
+ private:
+ TiledPage* m_page;
+};
+
}
#endif // QueuedOperation_h
diff --git a/WebCore/platform/graphics/android/SharedTexture.cpp b/WebCore/platform/graphics/android/SharedTexture.cpp
index 495fdd0..040a28a 100644
--- a/WebCore/platform/graphics/android/SharedTexture.cpp
+++ b/WebCore/platform/graphics/android/SharedTexture.cpp
@@ -156,8 +156,9 @@ void SharedTexture::releaseSource()
m_targetTexture.copyAttributes(&m_sourceTexture);
}
- // create an image from the texture
- if (m_eglImage == EGL_NO_IMAGE_KHR) {
+ // create an image from the texture, only when the texture is valid
+ if (m_eglImage == EGL_NO_IMAGE_KHR && m_sourceTexture.m_width
+ && m_sourceTexture.m_height) {
GLUtils::createEGLImageFromTexture(m_sourceTexture.m_textureId, &m_eglImage);
LOGV("Generating Image (%d) 0x%x", m_sourceTexture.m_textureId, m_eglImage);
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp
index ad5de1f..e6bef6a 100644
--- a/WebCore/platform/graphics/android/TexturesGenerator.cpp
+++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp
@@ -51,27 +51,11 @@
namespace WebCore {
-void TexturesGenerator::scheduleOperation(QueuedOperation* operation, bool scheduleFirst)
+void TexturesGenerator::scheduleOperation(QueuedOperation* operation)
{
{
android::Mutex::Autolock lock(mRequestedOperationsLock);
- for (unsigned int i = 0; i < mRequestedOperations.size(); i++) {
- QueuedOperation** s = &mRequestedOperations[i];
- // A similar operation is already in the queue. The newer operation may
- // have additional dirty tiles so delete the existing operation and
- // replace it with the new one.
- if (*s && *s == operation) {
- QueuedOperation* oldOperation = *s;
- *s = operation;
- delete oldOperation;
- return;
- }
- }
-
- if (scheduleFirst)
- mRequestedOperations.prepend(operation);
- else
- mRequestedOperations.append(operation);
+ mRequestedOperations.append(operation);
}
mRequestedOperationsCond.signal();
}
@@ -81,6 +65,11 @@ void TexturesGenerator::removeOperationsForPage(TiledPage* page)
removeOperationsForFilter(new PageFilter(page));
}
+void TexturesGenerator::removePaintOperationsForPage(TiledPage* page, bool waitForRunning)
+{
+ removeOperationsForFilter(new PagePaintFilter(page), waitForRunning);
+}
+
void TexturesGenerator::removeOperationsForBaseLayer(BaseLayerAndroid* layer)
{
removeOperationsForFilter(new PaintLayerBaseFilter(layer));
@@ -93,6 +82,11 @@ void TexturesGenerator::removeOperationsForTexture(LayerTexture* texture)
void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
{
+ removeOperationsForFilter(filter, true);
+}
+
+void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning)
+{
android::Mutex::Autolock lock(mRequestedOperationsLock);
for (unsigned int i = 0; i < mRequestedOperations.size();) {
QueuedOperation* operation = mRequestedOperations[i];
@@ -104,18 +98,22 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
}
}
- QueuedOperation* operation = m_currentOperation;
- if (operation && filter->check(operation))
- m_waitForCompletion = true;
-
- delete filter;
-
- // At this point, it means that we are currently executing an operation that
- // we want to be removed -- we should wait until it is done, so that
- // when we return our caller can be sure that there is no more operations
- // in the queue matching the given filter.
- while (m_waitForCompletion)
- mRequestedOperationsCond.wait(mRequestedOperationsLock);
+ if (waitForRunning) {
+ QueuedOperation* operation = m_currentOperation;
+ if (operation && filter->check(operation))
+ m_waitForCompletion = true;
+
+ delete filter;
+
+ // At this point, it means that we are currently executing an operation that
+ // we want to be removed -- we should wait until it is done, so that
+ // when we return our caller can be sure that there is no more operations
+ // in the queue matching the given filter.
+ while (m_waitForCompletion)
+ mRequestedOperationsCond.wait(mRequestedOperationsLock);
+ } else {
+ delete filter;
+ }
}
status_t TexturesGenerator::readyToRun()
@@ -125,6 +123,37 @@ status_t TexturesGenerator::readyToRun()
return NO_ERROR;
}
+// Must be called from within a lock!
+QueuedOperation* TexturesGenerator::popNext()
+{
+ // Priority can change between when it was added and now
+ // Hence why the entire queue is rescanned
+ QueuedOperation* current = mRequestedOperations.last();
+ int currentPriority = current->priority();
+ if (currentPriority < 0) {
+ mRequestedOperations.removeLast();
+ return current;
+ }
+ int currentIndex = mRequestedOperations.size() - 1;
+ // Scan from the back to make removing faster (less items to copy)
+ for (int i = mRequestedOperations.size() - 2; i >= 0; i--) {
+ QueuedOperation *next = mRequestedOperations[i];
+ int nextPriority = next->priority();
+ if (nextPriority < 0) {
+ // Found a very high priority item, go ahead and just handle it now
+ mRequestedOperations.remove(i);
+ return next;
+ }
+ if (nextPriority < currentPriority) {
+ current = next;
+ currentPriority = nextPriority;
+ currentIndex = i;
+ }
+ }
+ mRequestedOperations.remove(currentIndex);
+ return current;
+}
+
bool TexturesGenerator::threadLoop()
{
// Check if we have any pending operations.
@@ -138,20 +167,14 @@ bool TexturesGenerator::threadLoop()
m_currentOperation = 0;
bool stop = false;
while (!stop) {
- XLOG("threadLoop evaluating the requests");
mRequestedOperationsLock.lock();
- if (mRequestedOperations.size()) {
- m_currentOperation = mRequestedOperations.first();
- mRequestedOperations.remove(0);
- XLOG("threadLoop, popping the first request (%d requests left)",
- mRequestedOperations.size());
- }
+ if (mRequestedOperations.size())
+ m_currentOperation = popNext();
mRequestedOperationsLock.unlock();
if (m_currentOperation) {
- XLOG("threadLoop, painting the request");
+ XLOG("threadLoop, painting the request with priority %d", m_currentOperation->priority());
m_currentOperation->run();
- XLOG("threadLoop, painting the request - DONE");
}
mRequestedOperationsLock.lock();
@@ -168,6 +191,7 @@ bool TexturesGenerator::threadLoop()
mRequestedOperationsLock.unlock();
}
+ XLOG("threadLoop empty");
return true;
}
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.h b/WebCore/platform/graphics/android/TexturesGenerator.h
index 169471c..b03f52d 100644
--- a/WebCore/platform/graphics/android/TexturesGenerator.h
+++ b/WebCore/platform/graphics/android/TexturesGenerator.h
@@ -30,7 +30,6 @@
#include "LayerTexture.h"
#include "QueuedOperation.h"
-#include "TileSet.h"
#include "TiledPage.h"
#include <utils/threads.h>
@@ -52,11 +51,14 @@ public:
void removeOperationsForPage(TiledPage* page);
void removeOperationsForBaseLayer(BaseLayerAndroid* layer);
void removeOperationsForTexture(LayerTexture* texture);
+ void removePaintOperationsForPage(TiledPage* page, bool waitForRunning);
void removeOperationsForFilter(OperationFilter* filter);
+ void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning);
- void scheduleOperation(QueuedOperation* operation, bool scheduleFirst);
+ void scheduleOperation(QueuedOperation* operation);
private:
+ QueuedOperation* popNext();
virtual bool threadLoop();
Vector<QueuedOperation*> mRequestedOperations;
android::Mutex mRequestedOperationsLock;
diff --git a/WebCore/platform/graphics/android/TileSet.h b/WebCore/platform/graphics/android/TileSet.h
deleted file mode 100644
index aa0f2ed..0000000
--- a/WebCore/platform/graphics/android/TileSet.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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 TileSet_h
-#define TileSet_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "BaseTile.h"
-#include "Vector.h"
-
-namespace WebCore {
-
-/**
- * This purpose of this class is to act as a container for BaseTiles that need
- * to upload their contents to the GPU. A TiledPage creates a new TileSet and
- * provides the set with identifying characteristics of the TiledPage's current
- * state (see constructor). This information allows the consumer of the TileSet
- * to determine if an equivalent TileSet already exists in the upload pipeline.
- */
-class TileSet {
-public:
- TileSet(TiledPage* tiledPage, int nbRows, int nbCols);
- ~TileSet();
-
- bool operator==(const TileSet& set);
- void paint();
-
- void add(BaseTile* texture)
- {
- m_tiles.append(texture);
- }
-
- TiledPage* page()
- {
- return m_tiledPage;
- }
-
- unsigned int size()
- {
- return m_tiles.size();
- }
-
-private:
- Vector<BaseTile*> m_tiles;
-
- TiledPage* m_tiledPage;
- int m_nbRows;
- int m_nbCols;
-};
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
-#endif // TileSet_h
diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp
index 6f910a3..5212871 100644
--- a/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/WebCore/platform/graphics/android/TiledPage.cpp
@@ -30,7 +30,7 @@
#include "GLUtils.h"
#include "IntRect.h"
-#include "PaintTileSetOperation.h"
+#include "PaintTileOperation.h"
#include "TilesManager.h"
#ifdef DEBUG
@@ -82,7 +82,6 @@ void TiledPage::updateBaseTileSize()
int baseTileSize = TilesManager::instance()->maxTextureCount() + 1;
if (baseTileSize > m_baseTileSize)
m_baseTileSize = baseTileSize;
- XLOG("Allocate %d tiles", m_baseTileSize);
}
TiledPage::~TiledPage()
@@ -126,6 +125,7 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC
const int lastDirtyTileX = static_cast<int>(ceilf(inval.right() * invTileContentWidth));
const int lastDirtyTileY = static_cast<int>(ceilf(inval.bottom() * invTileContentHeight));
+ XLOG("Marking X %d-%d and Y %d-%d dirty", firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY);
// We defer marking the tile as dirty until the next time we need to prepare
// to draw.
m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op);
@@ -133,12 +133,10 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC
m_latestPictureInval = pictureCount;
}
-void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set)
+void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds)
{
if (y < 0)
return;
- if (!set)
- return;
for (int i = 0; i < tilesInRow; i++) {
int x = firstTileX;
@@ -177,12 +175,41 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
// ensure there is a texture associated with the tile and then check to
// see if the texture is dirty and in need of repainting
currentTile->reserveTexture();
- if (currentTile->isDirty())
- set->add(currentTile);
+ updateTileUsedLevel(tileBounds, *currentTile);
+ if (currentTile->isDirty() && !currentTile->isRepaintPending()) {
+ PaintTileOperation *operation = new PaintTileOperation(currentTile);
+ TilesManager::instance()->scheduleOperation(operation);
+ } else if (currentTile->isDirty()) {
+ XLOG("Tile %dx%d is dirty, but awaiting repaint", currentTile->x(), currentTile->y());
+ }
}
}
}
+void TiledPage::updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile)
+{
+ const int lastTileX = tileBounds.fRight - 1;
+ const int lastTileY = tileBounds.fBottom - 1;
+
+ // set the used level of the tile (e.g. distance from the viewport)
+ int dx = 0;
+ int dy = 0;
+
+ if (tileBounds.fLeft > tile.x())
+ dx = tileBounds.fLeft - tile.x();
+ else if (lastTileX < tile.x())
+ dx = tile.x() - lastTileX;
+
+ if (tileBounds.fTop > tile.y())
+ dy = tileBounds.fTop - tile.y();
+ else if (lastTileY < tile.y())
+ dy = tile.y() - lastTileY;
+
+ int d = std::max(dx, dy);
+
+ tile.setUsedLevel(d);
+}
+
void TiledPage::updateTileState(const SkIRect& tileBounds)
{
if (!m_glWebViewState || tileBounds.isEmpty()) {
@@ -191,41 +218,19 @@ void TiledPage::updateTileState(const SkIRect& tileBounds)
return;
}
- const int nbTilesWidth = tileBounds.width() - 1;
- const int nbTilesHeight = tileBounds.height() - 1;
-
- const int lastTileX = tileBounds.fRight - 1;
- const int lastTileY = tileBounds.fBottom - 1;
-
for (int x = 0; x < m_baseTileSize; x++) {
BaseTile& tile = m_baseTiles[x];
- // if the tile is in the dirty region then we must invalidate it
- if (m_invalRegion.contains(tile.x(), tile.y()))
- tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion);
-
// if the tile no longer has a texture then proceed to the next tile
if (tile.isAvailable())
continue;
- // set the used level of the tile (e.g. distance from the viewport)
- int dx = 0;
- int dy = 0;
-
- if (tileBounds.fLeft > tile.x())
- dx = tileBounds.fLeft - tile.x();
- else if (lastTileX < tile.x())
- dx = tile.x() - lastTileX;
-
- if (tileBounds.fTop > tile.y())
- dy = tileBounds.fTop - tile.y();
- else if (lastTileY < tile.y())
- dy = tile.y() - lastTileY;
-
- int d = std::max(dx, dy);
+ // if the tile is in the dirty region then we must invalidate it
+ if (m_invalRegion.contains(tile.x(), tile.y()))
+ tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion);
- tile.setUsedLevel(d);
+ updateTileUsedLevel(tileBounds, tile);
}
// clear the invalidated region as all tiles within that region have now
@@ -234,8 +239,7 @@ void TiledPage::updateTileState(const SkIRect& tileBounds)
m_invalTilesRegion.setEmpty();
}
-void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds,
- bool scheduleFirst)
+void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds)
{
if (!m_glWebViewState)
return;
@@ -243,6 +247,7 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
// update the tiles distance from the viewport
updateTileState(tileBounds);
m_prepare = true;
+ m_scrollingDown = goingDown;
int firstTileX = tileBounds.fLeft;
int firstTileY = tileBounds.fTop;
@@ -255,43 +260,29 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
const int baseContentHeight = m_glWebViewState->baseContentHeight();
const int baseContentWidth = m_glWebViewState->baseContentWidth();
- TileSet* set = new TileSet(this, nbTilesHeight, nbTilesWidth);
-
- if (!scheduleFirst) {
- // Expand number of tiles to allow tiles outside of viewport to be prepared for
- // smoother scrolling.
- int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
- int nMaxTilesPerPage = m_baseTileSize / 2;
- int expandX = TilesManager::instance()->expandedTileBoundsX();
- int expandY = TilesManager::instance()->expandedTileBoundsY();
- if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) {
- firstTileX -= expandX;
- lastTileX += expandX;
- nbTilesWidth += expandX * 2;
- }
- if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) {
- firstTileY -= expandY;
- lastTileY += expandY;
- nbTilesHeight += expandY * 2;
- }
+ // Expand number of tiles to allow tiles outside of viewport to be prepared for
+ // smoother scrolling.
+ int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
+ int nMaxTilesPerPage = m_baseTileSize / 2;
+ int expandX = TilesManager::instance()->expandedTileBoundsX();
+ int expandY = TilesManager::instance()->expandedTileBoundsY();
+ if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) {
+ firstTileX -= expandX;
+ lastTileX += expandX;
+ nbTilesWidth += expandX * 2;
}
-
- // We chose to prepare tiles depending on the scroll direction. Tiles are
- // appended to the list and the texture uploader goes through the list front
- // to back. So we append tiles in reverse order because the last additions
- // to the are processed first.
- if (goingDown) {
- for (int i = 0; i < nbTilesHeight; i++)
- prepareRow(goingLeft, nbTilesWidth, firstTileX, lastTileY - i, set);
- } else {
- for (int i = 0; i < nbTilesHeight; i++)
- prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, set);
+ if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) {
+ firstTileY -= expandY;
+ lastTileY += expandY;
+ nbTilesHeight += expandY * 2;
}
+ m_expandedTileBounds.fLeft = firstTileX;
+ m_expandedTileBounds.fTop = firstTileY;
+ m_expandedTileBounds.fRight = lastTileX;
+ m_expandedTileBounds.fBottom = lastTileY;
- // The paint operation will take ownership of the tileSet here, so no delete
- // is necessary.
- PaintTileSetOperation* operation = new PaintTileSetOperation(set);
- TilesManager::instance()->scheduleOperation(operation, scheduleFirst);
+ for (int i = 0; i < nbTilesHeight; i++)
+ prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, tileBounds);
}
bool TiledPage::ready(const SkIRect& tileBounds, float scale)
@@ -330,7 +321,6 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds)
actualTileBounds.fLeft -= TilesManager::instance()->expandedTileBoundsX();
actualTileBounds.fRight += TilesManager::instance()->expandedTileBoundsX();
- XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
for (int j = 0; j < m_baseTileSize; j++) {
BaseTile& tile = m_baseTiles[j];
if (actualTileBounds.contains(tile.x(), tile.y())) {
@@ -344,11 +334,6 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds)
tile.draw(transparency, rect, m_scale);
}
}
-
-#ifdef DEBUG
- XLOG("FINISHED WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
- TilesManager::instance()->printTextures();
-#endif // DEBUG
}
unsigned int TiledPage::paintBaseLayerContent(SkCanvas* canvas)
diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h
index 7e0bb2e..1aa3e61 100644
--- a/WebCore/platform/graphics/android/TiledPage.h
+++ b/WebCore/platform/graphics/android/TiledPage.h
@@ -31,7 +31,6 @@
#include "BaseTile.h"
#include "SkCanvas.h"
#include "SkRegion.h"
-#include "TileSet.h"
namespace WebCore {
@@ -57,8 +56,7 @@ public:
TiledPage* sibling();
// prepare the page for display on the screen
- void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds,
- bool scheduleFirst = false);
+ void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds);
// check to see if the page is ready for display
bool ready(const SkIRect& tileBounds, float scale);
// draw the page on the screen
@@ -75,10 +73,13 @@ public:
void invalidateRect(const IntRect& invalRect, const unsigned int pictureCount);
void setUsable(bool usable);
void updateBaseTileSize();
+ bool scrollingDown() { return m_scrollingDown; }
+ SkIRect* expandedTileBounds() { return &m_expandedTileBounds; }
private:
void updateTileState(const SkIRect& tileBounds);
- void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set);
+ void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds);
+ void updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile);
BaseTile* getBaseTile(int x, int y) const;
@@ -103,6 +104,8 @@ private:
SkRegion m_invalTilesRegion;
unsigned int m_latestPictureInval;
bool m_prepare;
+ bool m_scrollingDown;
+ SkIRect m_expandedTileBounds;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index afc53eb..5a9a164 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -249,7 +249,7 @@ LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer,
layer->uniqueId(), layer);
}
- if (best && best->acquire(layer))
+ if (best && best->acquire(layer, any))
return best;
return 0;
}
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
index 5a4e28a..6d49cca 100644
--- a/WebCore/platform/graphics/android/TilesManager.h
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -39,8 +39,6 @@
namespace WebCore {
-class TileSet;
-
class TilesManager {
public:
static TilesManager* instance();
@@ -57,6 +55,11 @@ public:
m_pixmapsGenerationThread->removeOperationsForPage(page);
}
+ void removePaintOperationsForPage(TiledPage* page, bool waitForCompletion)
+ {
+ m_pixmapsGenerationThread->removePaintOperationsForPage(page, waitForCompletion);
+ }
+
void removeOperationsForBaseLayer(BaseLayerAndroid* layer)
{
m_pixmapsGenerationThread->removeOperationsForBaseLayer(layer);
@@ -67,9 +70,9 @@ public:
m_pixmapsGenerationThread->removeOperationsForTexture(texture);
}
- void scheduleOperation(QueuedOperation* operation, bool scheduleFirst = false)
+ void scheduleOperation(QueuedOperation* operation)
{
- m_pixmapsGenerationThread->scheduleOperation(operation, scheduleFirst);
+ m_pixmapsGenerationThread->scheduleOperation(operation);
}
ShaderProgram* shader() { return &m_shader; }
diff --git a/WebCore/platform/graphics/android/android_graphics.h b/WebCore/platform/graphics/android/android_graphics.h
index be309a6..89312b5 100644
--- a/WebCore/platform/graphics/android/android_graphics.h
+++ b/WebCore/platform/graphics/android/android_graphics.h
@@ -56,6 +56,7 @@ public:
virtual void draw(SkCanvas* , LayerAndroid* , IntRect* );
void setIsButton(const CachedNode* );
bool setup();
+ WTF::Vector<IntRect>& rings() { return m_rings; }
private:
friend class WebView;
WebViewCore* m_viewImpl; // copy for convenience
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 6578d1d..c0dba6f 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -535,8 +535,17 @@ bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, con
RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
const IntRect& bounds = it->second;
- if (layerBounds.intersects(bounds))
+ if (layerBounds.intersects(bounds)) {
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ RenderLayer* intersectedLayer = it->first;
+ if (intersectedLayer && intersectedLayer->isFixed()) {
+ if (bounds.contains(layerBounds)) {
+ continue;
+ }
+ }
+#endif
return true;
+ }
}
return false;
@@ -1170,15 +1179,6 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
if (!canBeComposited(layer))
return false;
-#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- // if an ancestor is fixed positioned, we need to be composited...
- const RenderLayer* currLayer = layer;
- while ((currLayer = currLayer->parent())) {
- if (currLayer->isComposited() && currLayer->isFixed())
- return true;
- }
-#endif
-
// The root layer always has a compositing layer, but it may not have backing.
return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
}
diff --git a/WebKit/Android.mk b/WebKit/Android.mk
index 88defda..5998227 100644
--- a/WebKit/Android.mk
+++ b/WebKit/Android.mk
@@ -53,6 +53,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
android/RenderSkinButton.cpp \
android/RenderSkinCombo.cpp \
android/RenderSkinMediaButton.cpp \
+ android/RenderSkinNinePatch.cpp \
android/RenderSkinRadio.cpp \
android/TimeCounter.cpp \
\
diff --git a/WebKit/android/RenderSkinAndroid.cpp b/WebKit/android/RenderSkinAndroid.cpp
index 00f2b96..9383a9c 100644
--- a/WebKit/android/RenderSkinAndroid.cpp
+++ b/WebKit/android/RenderSkinAndroid.cpp
@@ -37,15 +37,14 @@
#include "utils/Asset.h"
namespace WebCore {
-
-RenderSkinAndroid::RenderSkinAndroid()
- : m_height(0)
- , m_width(0)
-{}
-void RenderSkinAndroid::Init(android::AssetManager* am, String drawableDirectory)
+RenderSkinAndroid::~RenderSkinAndroid()
{
- RenderSkinButton::Init(am, drawableDirectory);
+ delete m_button;
+}
+RenderSkinAndroid::RenderSkinAndroid(android::AssetManager* am, String drawableDirectory)
+{
+ m_button = new RenderSkinButton(am, drawableDirectory);
RenderSkinCombo::Init(am, drawableDirectory);
RenderSkinMediaButton::Init(am, drawableDirectory);
RenderSkinRadio::Init(am, drawableDirectory);
diff --git a/WebKit/android/RenderSkinAndroid.h b/WebKit/android/RenderSkinAndroid.h
index b877ff2..73773ea 100644
--- a/WebKit/android/RenderSkinAndroid.h
+++ b/WebKit/android/RenderSkinAndroid.h
@@ -36,17 +36,11 @@ class SkBitmap;
namespace WebCore {
class Node;
-class PlatformGraphicsContext;
+class RenderSkinButton;
-/* RenderSkinAndroid is the base class for all RenderSkins. Form elements each have a
- * subclass for drawing themselves.
- */
class RenderSkinAndroid
{
public:
- RenderSkinAndroid();
- virtual ~RenderSkinAndroid() {}
-
enum State {
kDisabled,
kNormal,
@@ -60,7 +54,8 @@ public:
* Initialize the Android skinning system. The AssetManager may be used to find resources used
* in rendering.
*/
- static void Init(android::AssetManager*, String drawableDirectory);
+ RenderSkinAndroid(android::AssetManager*, String drawableDirectory);
+ ~RenderSkinAndroid();
/* DecodeBitmap determines which file to use, with the given fileName of the form
* "images/bitmap.png", and uses the asset manager to select the exact one. It
@@ -68,24 +63,10 @@ public:
*/
static bool DecodeBitmap(android::AssetManager* am, const char* fileName, SkBitmap* bitmap);
- /* draw() tells the skin to draw itself, and returns true if the skin needs
- * a redraw to animations, false otherwise
- */
- virtual bool draw(PlatformGraphicsContext*) { return false; }
-
- /* notifyState() checks to see if the element is checked, focused, and enabled
- * it must be implemented in the subclass
- */
- virtual void notifyState(Node* element) { }
-
- /* setDim() tells the skin its width and height
- */
- virtual void setDim(int width, int height) { m_width = width; m_height = height; }
-
-protected:
- int m_height;
- int m_width;
+ const RenderSkinButton* renderSkinButton() const { return m_button; }
+private:
+ RenderSkinButton* m_button;
};
} // WebCore
diff --git a/WebKit/android/RenderSkinButton.cpp b/WebKit/android/RenderSkinButton.cpp
index 1dc6560..6a0ae54 100644
--- a/WebKit/android/RenderSkinButton.cpp
+++ b/WebKit/android/RenderSkinButton.cpp
@@ -31,47 +31,36 @@
#include "IntRect.h"
#include "Node.h"
#include "RenderSkinButton.h"
+#include "RenderSkinNinePatch.h"
#include "SkCanvas.h"
#include "SkNinePatch.h"
#include "SkRect.h"
+#include <utils/Asset.h>
+#include <utils/AssetManager.h>
#include <utils/Debug.h>
#include <utils/Log.h>
+#include <utils/ResourceTypes.h>
#include <wtf/text/CString.h>
-struct PatchData {
- const char* name;
- int8_t outset, margin;
-};
-
-static const PatchData gFiles[] =
- {
- { "btn_default_disabled_holo.9.png", 2, 7 },
- { "btn_default_normal_holo.9.png", 2, 7 },
- { "btn_default_focused_holo.9.png", 2, 7 },
- { "btn_default_pressed_holo.9.png", 2, 7 }
+static const char* gFiles[] = {
+ "btn_default_disabled_holo.9.png",
+ "btn_default_normal_holo.9.png",
+ "btn_default_focused_holo.9.png",
+ "btn_default_pressed_holo.9.png"
};
-static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])];
-static bool gDecoded;
-static bool gHighRes;
-
namespace WebCore {
-void RenderSkinButton::Init(android::AssetManager* am, String drawableDirectory)
+RenderSkinButton::RenderSkinButton(android::AssetManager* am, String drawableDirectory)
{
- static bool gInited;
- if (gInited)
- return;
-
- gInited = true;
- gDecoded = true;
- gHighRes = drawableDirectory[drawableDirectory.length() - 5] == 'h';
- for (size_t i = 0; i < sizeof(gFiles)/sizeof(gFiles[0]); i++) {
- String path = drawableDirectory + gFiles[i].name;
- if (!RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &gButton[i])) {
- gDecoded = false;
- LOGD("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw");
- break;
+ m_decoded = true;
+ for (size_t i = 0; i < 4; i++) {
+ String path = String(drawableDirectory.impl());
+ path.append(String(gFiles[i]));
+ if (!RenderSkinNinePatch::decodeAsset(am, path.utf8().data(), &m_buttons[i])) {
+ m_decoded = false;
+ LOGE("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw");
+ return;
}
}
@@ -82,11 +71,12 @@ void RenderSkinButton::Init(android::AssetManager* am, String drawableDirectory)
android::CompileTimeAssert<(RenderSkinAndroid::kPressed == 3)> a4;
}
-void RenderSkinButton::Draw(SkCanvas* canvas, const IntRect& r, RenderSkinAndroid::State newState)
+void RenderSkinButton::draw(SkCanvas* canvas, const IntRect& r,
+ RenderSkinAndroid::State newState) const
{
// If we failed to decode, do nothing. This way the browser still works,
// and webkit will still draw the label and layout space for us.
- if (!gDecoded) {
+ if (!m_decoded) {
return;
}
@@ -94,26 +84,7 @@ void RenderSkinButton::Draw(SkCanvas* canvas, const IntRect& r, RenderSkinAndroi
SkASSERT(static_cast<unsigned>(newState) <
static_cast<unsigned>(RenderSkinAndroid::kNumStates));
- // Set up the ninepatch information for drawing.
- SkRect bounds(r);
- const PatchData& pd = gFiles[newState];
- int marginValue = pd.margin + pd.outset;
-
- SkIRect margin;
-
- margin.set(marginValue, marginValue, marginValue, marginValue);
- if (gHighRes) {
- /* FIXME: it shoudn't be necessary to offset the button here,
- but gives the right results. */
- bounds.offset(0, SK_Scalar1 * 2);
- /* FIXME: This temporarily gets around the fact that the margin values and
- positioning were created for a low res asset, which was used on
- g1-like devices. A better fix would be to read the offset information
- out of the png. */
- margin.set(10, 9, 10, 14);
- }
- // Draw to the canvas.
- SkNinePatch::DrawNine(canvas, bounds, gButton[newState], margin);
+ RenderSkinNinePatch::DrawNinePatch(canvas, SkRect(r), m_buttons[newState]);
}
} //WebCore
diff --git a/WebKit/android/RenderSkinButton.h b/WebKit/android/RenderSkinButton.h
index e9cf0ec..e9db74c 100644
--- a/WebKit/android/RenderSkinButton.h
+++ b/WebKit/android/RenderSkinButton.h
@@ -27,24 +27,28 @@
#define RenderSkinButton_h
#include "RenderSkinAndroid.h"
+#include "RenderSkinNinePatch.h"
class SkCanvas;
namespace WebCore {
class IntRect;
-class RenderSkinButton
-{
+
+class RenderSkinButton {
public:
/**
* Initialize the class before use. Uses the AssetManager to initialize any
* bitmaps the class may use.
*/
- static void Init(android::AssetManager*, String drawableDirectory);
+ RenderSkinButton(android::AssetManager*, String drawableDirectory);
/**
* Draw the skin to the canvas, using the rectangle for its bounds and the
* State to determine which skin to use, i.e. focused or not focused.
*/
- static void Draw(SkCanvas* , const IntRect& , RenderSkinAndroid::State);
+ void draw(SkCanvas* , const IntRect& , RenderSkinAndroid::State) const;
+private:
+ bool m_decoded;
+ NinePatch m_buttons[4];
};
} // WebCore
diff --git a/WebKit/android/RenderSkinMediaButton.cpp b/WebKit/android/RenderSkinMediaButton.cpp
index 745fa88..090d55e 100644
--- a/WebKit/android/RenderSkinMediaButton.cpp
+++ b/WebKit/android/RenderSkinMediaButton.cpp
@@ -58,8 +58,8 @@ static const PatchData gFiles[] =
{ "spinner_76_inner_holo.png", 0, 0 }, // SPINNER_INNER
{ "ic_media_video_poster.png", 0, 0 }, // VIDEO
{ "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER
- { "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK
- { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB
+ { "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK
+ { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB
};
static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])];
@@ -112,6 +112,7 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT
alpha = 190;
SkColor backgroundColor = SkColorSetARGB(alpha, 34, 34, 34);
+ SkColor trackBackgroundColor = SkColorSetARGB(255, 100, 100, 100);
paint.setColor(backgroundColor);
paint.setFlags(SkPaint::kFilterBitmap_Flag);
diff --git a/WebKit/android/RenderSkinNinePatch.cpp b/WebKit/android/RenderSkinNinePatch.cpp
new file mode 100644
index 0000000..0c915c0
--- /dev/null
+++ b/WebKit/android/RenderSkinNinePatch.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "config.h"
+
+#include "RenderSkinNinePatch.h"
+#include "NinePatchPeeker.h"
+#include "SkCanvas.h"
+#include "SkImageDecoder.h"
+#include "SkRect.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+#include <utils/Asset.h>
+#include <utils/AssetManager.h>
+#include <utils/Log.h>
+#include <utils/ResourceTypes.h>
+
+class SkPaint;
+class SkRegion;
+
+using namespace android;
+
+extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds,
+ const SkBitmap& bitmap, const Res_png_9patch& chunk,
+ const SkPaint* paint, SkRegion** outRegion);
+
+bool RenderSkinNinePatch::decodeAsset(AssetManager* am, const char* filename, NinePatch* ninepatch) {
+ Asset* asset = am->open(filename, android::Asset::ACCESS_BUFFER);
+ if (!asset) {
+ asset = am->openNonAsset(filename, android::Asset::ACCESS_BUFFER);
+ if (!asset) {
+ return false;
+ }
+ }
+
+ SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode;
+ SkBitmap::Config prefConfig = SkBitmap::kNo_Config;
+ SkStream* stream = new SkMemoryStream(asset->getBuffer(false), asset->getLength());
+ SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
+ if (!decoder) {
+ asset->close();
+ LOGE("RenderSkinNinePatch::Failed to create an image decoder");
+ return false;
+ }
+
+ decoder->setSampleSize(1);
+ decoder->setDitherImage(true);
+ decoder->setPreferQualityOverSpeed(false);
+
+ NinePatchPeeker peeker(decoder);
+
+ SkAutoTDelete<SkImageDecoder> add(decoder);
+
+ decoder->setPeeker(&peeker);
+ if (!decoder->decode(stream, &ninepatch->m_bitmap, prefConfig, mode, true)) {
+ asset->close();
+ LOGE("RenderSkinNinePatch::Failed to decode nine patch asset");
+ return false;
+ }
+
+ asset->close();
+ if (!peeker.fPatchIsValid) {
+ LOGE("RenderSkinNinePatch::Patch data not valid");
+ return false;
+ }
+ void** data = &ninepatch->m_serializedPatchData;
+ *data = malloc(peeker.fPatch->serializedSize());
+ peeker.fPatch->serialize(*data);
+ return true;
+}
+
+void RenderSkinNinePatch::DrawNinePatch(SkCanvas* canvas, const SkRect& bounds,
+ const NinePatch& patch) {
+ Res_png_9patch* data = Res_png_9patch::deserialize(patch.m_serializedPatchData);
+ NinePatch_Draw(canvas, bounds, patch.m_bitmap, *data, 0, 0);
+}
diff --git a/WebKit/android/RenderSkinNinePatch.h b/WebKit/android/RenderSkinNinePatch.h
new file mode 100644
index 0000000..e4db260
--- /dev/null
+++ b/WebKit/android/RenderSkinNinePatch.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RenderSkinNinePatch_h
+#define RenderSkinNinePatch_h
+
+#include "SkBitmap.h"
+#include "utils/Asset.h"
+
+namespace android {
+ class AssetManager;
+}
+
+class SkCanvas;
+class SkRect;
+
+struct NinePatch {
+ SkBitmap m_bitmap;
+ void* m_serializedPatchData;
+ NinePatch() {
+ m_serializedPatchData = 0;
+ }
+ ~NinePatch() {
+ if (m_serializedPatchData)
+ free(m_serializedPatchData);
+ }
+};
+
+class RenderSkinNinePatch {
+public:
+ static bool decodeAsset(android::AssetManager*, const char* fileName, NinePatch*);
+ static void DrawNinePatch(SkCanvas*, const SkRect&, const NinePatch&);
+};
+
+#endif // RenderSkinNinePatch_h
diff --git a/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp b/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
index 875b222..3779ba8 100644
--- a/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
+++ b/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
@@ -40,11 +40,11 @@ public:
: m_inputStream(env->NewGlobalRef(inputStream))
, m_buffer(0) {
LOG_ALWAYS_FATAL_IF(!inputStream);
- m_inputStreamClass = env->FindClass("java/io/InputStream");
- LOG_ALWAYS_FATAL_IF(!m_inputStreamClass);
- m_read = env->GetMethodID(m_inputStreamClass, "read", "([B)I");
+ jclass inputStreamClass = env->FindClass("java/io/InputStream");
+ LOG_ALWAYS_FATAL_IF(!inputStreamClass);
+ m_read = env->GetMethodID(inputStreamClass, "read", "([B)I");
LOG_ALWAYS_FATAL_IF(!m_read);
- m_close = env->GetMethodID(m_inputStreamClass, "close", "()V");
+ m_close = env->GetMethodID(inputStreamClass, "close", "()V");
LOG_ALWAYS_FATAL_IF(!m_close);
}
@@ -76,7 +76,6 @@ public:
private:
jobject m_inputStream;
jbyteArray m_buffer;
- jclass m_inputStreamClass;
jmethodID m_read;
jmethodID m_close;
};
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index fcfb4ca..cf218e7 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -180,14 +180,29 @@ bool WebUrlLoaderClient::start(bool isMainResource, bool isMainFrame, bool sync,
thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start));
// Run callbacks until the queue is exhausted and m_finished is true.
+ // Sometimes, a sync load can wait forever and lock up the WebCore thread,
+ // here we use TimedWait() with multiple tries to avoid locking.
+ const int kMaxNumTimeout = 3;
+ const int kCallbackWaitingTime = 10;
+ int num_timeout = 0;
while(!m_finished) {
while (!m_queue.empty()) {
OwnPtr<Task> task(m_queue.front());
m_queue.pop_front();
task->Run();
}
- if (m_queue.empty() && !m_finished) {
- syncCondition()->Wait();
+ if (m_finished) break;
+
+ syncCondition()->TimedWait(base::TimeDelta::FromSeconds(kCallbackWaitingTime));
+ if (m_queue.empty()) {
+ LOGE("Synchronous request timed out after %d seconds for the %dth try, URL: %s",
+ kCallbackWaitingTime, num_timeout, m_request->getUrl().c_str());
+ num_timeout++;
+ if (num_timeout >= kMaxNumTimeout) {
+ cancel();
+ m_resourceHandle = 0;
+ return false;
+ }
}
}
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index 7d1adb0..d59a53b 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -334,6 +334,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
mUserAgent = WTF::String();
mUserInitiatedAction = false;
mBlockNetworkLoads = false;
+ m_renderSkins = 0;
}
WebFrame::~WebFrame()
@@ -345,6 +346,7 @@ WebFrame::~WebFrame()
mJavaFrame->mObj = 0;
}
delete mJavaFrame;
+ delete m_renderSkins;
}
WebFrame* WebFrame::getWebFrame(const WebCore::Frame* frame)
@@ -1261,7 +1263,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
// Setup the asset manager.
AssetManager* am = assetManagerForJavaObject(env, jAssetManager);
// Initialize our skinning classes
- WebCore::RenderSkinAndroid::Init(am, directory);
+ webFrame->setRenderSkins(new WebCore::RenderSkinAndroid(am, directory));
}
for (int i = WebCore::PlatformBridge::FileUploadLabel;
i <= WebCore::PlatformBridge::FileUploadNoFileChosenLabel; i++)
diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h
index 25232e4..6522a5f 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.h
+++ b/WebKit/android/jni/WebCoreFrameBridge.h
@@ -43,6 +43,7 @@ namespace WebCore {
class Image;
class Page;
class RenderPart;
+ class RenderSkinAndroid;
class ResourceHandle;
class ResourceLoaderAndroid;
class ResourceRequest;
@@ -155,6 +156,8 @@ class WebFrame : public WebCoreRefObject {
bool shouldSaveFormData();
void saveFormData(WebCore::HTMLFormElement*);
+ const WebCore::RenderSkinAndroid* renderSkins() const { return m_renderSkins; }
+ void setRenderSkins(const WebCore::RenderSkinAndroid* skins) { m_renderSkins = skins; }
private:
struct JavaBrowserFrame;
JavaBrowserFrame* mJavaFrame;
@@ -162,6 +165,7 @@ private:
WTF::String mUserAgent;
bool mBlockNetworkLoads;
bool mUserInitiatedAction;
+ const WebCore::RenderSkinAndroid* m_renderSkins;
};
} // namespace android
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index c038ccd..4bba71a 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -3079,7 +3079,7 @@ bool WebViewCore::handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint
return 0;
}
- for (unsigned c = 0; c < points.size(); c++) {
+ for (int c = 0; c < static_cast<int>(points.size()); c++) {
points[c].setX(points[c].x() - m_scrollOffsetX);
points[c].setY(points[c].y() - m_scrollOffsetY);
@@ -3993,10 +3993,8 @@ static jstring FindAddress(JNIEnv *env, jobject obj, jstring addr,
bool success = CacheBuilder::FindAddress(addrChars, length,
&start, &end, caseInsensitive) == CacheBuilder::FOUND_COMPLETE;
jstring ret = 0;
- if (success) {
+ if (success)
ret = env->NewString(addrChars + start, end - start);
- env->DeleteLocalRef(ret);
- }
env->ReleaseStringChars(addr, addrChars);
return ret;
}
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 09fcd67..fe69eae 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -71,7 +71,9 @@
#include <JNIUtility.h>
#include <JNIHelp.h>
#include <jni.h>
+#include <android_runtime/android_util_AssetManager.h>
#include <ui/KeycodeLabels.h>
+#include <utils/AssetManager.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>
@@ -138,7 +140,7 @@ struct JavaGlue {
}
} m_javaGlue;
-WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
+WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, AssetManager* am) :
m_ring((WebViewCore*) viewImpl)
{
jclass clazz = env->FindClass("android/webkit/WebView");
@@ -190,6 +192,10 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
m_ringAnimationEnd = 0;
m_baseLayer = 0;
m_glDrawFunctor = 0;
+ if (drawableDir.isEmpty())
+ m_buttonSkin = 0;
+ else
+ m_buttonSkin = new RenderSkinButton(am, drawableDir);
#if USE(ACCELERATED_COMPOSITING)
m_glWebViewState = 0;
#endif
@@ -213,6 +219,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
delete m_navPictureUI;
SkSafeUnref(m_baseLayer);
delete m_glDrawFunctor;
+ delete m_buttonSkin;
}
void stopGL()
@@ -279,7 +286,7 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate)
const CachedNode* cachedCursor = 0;
// Lock the mutex, since we now share with the WebCore thread.
m_viewImpl->gButtonMutex.lock();
- if (m_viewImpl->m_buttons.size()) {
+ if (m_viewImpl->m_buttons.size() && m_buttonSkin) {
// FIXME: In a future change, we should keep track of whether the selection
// has changed to short circuit (note that we would still need to update
// if we received new buttons from the WebCore thread).
@@ -308,7 +315,7 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate)
state = RenderSkinAndroid::kFocused;
}
}
- ptr->updateFocusState(state);
+ ptr->updateFocusState(state, m_buttonSkin);
}
}
m_viewImpl->gButtonMutex.unlock();
@@ -478,13 +485,18 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
SkPicture picture;
IntRect rect(0, 0, 0, 0);
bool allowSame = false;
+ m_glWebViewState->resetRings();
if (extra) {
- LayerAndroid mainPicture(m_navPictureUI);
- PictureSet* content = m_baseLayer->content();
- SkCanvas* canvas = picture.beginRecording(content->width(),
- content->height());
- extra->draw(canvas, &mainPicture, &rect);
- picture.endRecording();
+ if (extra == &m_ring) {
+ m_glWebViewState->setRings(m_ring.rings());
+ } else {
+ LayerAndroid mainPicture(m_navPictureUI);
+ PictureSet* content = m_baseLayer->content();
+ SkCanvas* canvas = picture.beginRecording(content->width(),
+ content->height());
+ extra->draw(canvas, &mainPicture, &rect);
+ picture.endRecording();
+ }
} else if (extras == DrawExtrasCursorRing && m_ring.m_isButton) {
const CachedFrame* cachedFrame;
const CachedNode* cachedCursor = root->currentCursor(&cachedFrame);
@@ -1465,6 +1477,7 @@ private: // local state for WebView
#if USE(ACCELERATED_COMPOSITING)
GLWebViewState* m_glWebViewState;
#endif
+ const RenderSkinButton* m_buttonSkin;
}; // end of WebView class
@@ -1576,9 +1589,12 @@ static void nativeClearCursor(JNIEnv *env, jobject obj)
view->clearCursor();
}
-static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl)
+static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl, jstring drawableDir,
+ jobject jAssetManager)
{
- WebView* webview = new WebView(env, obj, viewImpl);
+ AssetManager* am = assetManagerForJavaObject(env, jAssetManager);
+ WTF::String dir = jstringToWtfString(env, drawableDir);
+ WebView* webview = new WebView(env, obj, viewImpl, dir, am);
// NEED THIS OR SOMETHING LIKE IT!
//Release(obj);
}
@@ -2484,7 +2500,7 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeCacheHitNodePointer },
{ "nativeClearCursor", "()V",
(void*) nativeClearCursor },
- { "nativeCreate", "(I)V",
+ { "nativeCreate", "(ILjava/lang/String;Landroid/content/res/AssetManager;)V",
(void*) nativeCreate },
{ "nativeCursorFramePointer", "()I",
(void*) nativeCursorFramePointer },