summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/page/Settings.cpp6
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp38
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h55
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp103
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h24
-rw-r--r--WebCore/platform/graphics/android/DoubleBufferedTexture.h5
-rw-r--r--WebCore/platform/graphics/android/FontCacheAndroid.cpp7
-rw-r--r--WebCore/platform/graphics/android/GLUtils.cpp5
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp11
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.h27
-rw-r--r--WebCore/platform/graphics/android/GraphicsContextAndroid.cpp11
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp25
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.cpp29
-rw-r--r--WebCore/platform/graphics/android/TileSet.cpp32
-rw-r--r--WebCore/platform/graphics/android/TileSet.h11
-rw-r--r--WebCore/platform/graphics/android/TiledPage.cpp67
-rw-r--r--WebCore/platform/graphics/android/TiledPage.h15
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp5
-rw-r--r--WebCore/rendering/RenderView.cpp2
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.cpp2
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.h2
-rw-r--r--WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp50
-rw-r--r--WebKit/android/WebCoreSupport/autofill/WebAutoFill.h4
-rw-r--r--WebKit/android/jni/DeviceMotionAndOrientationManager.cpp3
-rw-r--r--WebKit/android/jni/WebCoreJniOnLoad.cpp4
-rw-r--r--WebKit/android/jni/WebViewCore.cpp8
-rw-r--r--WebKit/android/jni/WebViewCore.h2
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp2
-rw-r--r--WebKit/android/nav/CachedFrame.cpp53
-rw-r--r--WebKit/android/nav/CachedInput.cpp7
-rw-r--r--WebKit/android/nav/CachedLayer.cpp96
-rw-r--r--WebKit/android/nav/CachedLayer.h2
-rw-r--r--WebKit/android/nav/CachedRoot.cpp11
-rw-r--r--WebKit/android/nav/FindCanvas.h5
-rw-r--r--WebKit/android/nav/SelectText.cpp2
-rw-r--r--WebKit/android/nav/WebView.cpp32
36 files changed, 441 insertions, 322 deletions
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 8e8d43b..aa758c4 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -160,12 +160,12 @@ Settings::Settings(Page* page)
, m_interactiveFormValidation(false)
, m_usePreHTML5ParserQuirks(false)
, m_hyperlinkAuditingEnabled(false)
-#if ENABLE(WEB_AUTOFILL)
- , m_autoFillEnabled(false)
-#endif
#ifdef ANDROID_PLUGINS
, m_pluginsOnDemand(false)
#endif
+#if ENABLE(WEB_AUTOFILL)
+ , m_autoFillEnabled(false)
+#endif
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
index 7cecddd..1a8e686 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
@@ -56,28 +56,27 @@ BackedDoubleBufferedTexture::~BackedDoubleBufferedTexture()
TextureInfo* BackedDoubleBufferedTexture::producerLock()
{
- m_varLock.lock();
+ m_busyLock.lock();
m_busy = true;
- m_varLock.unlock();
+ m_busyLock.unlock();
return DoubleBufferedTexture::producerLock();
}
void BackedDoubleBufferedTexture::producerRelease()
{
DoubleBufferedTexture::producerRelease();
- android::Mutex::Autolock lock(m_varLock);
+ android::Mutex::Autolock lock(m_busyLock);
m_busy = false;
}
void BackedDoubleBufferedTexture::producerReleaseAndSwap()
{
DoubleBufferedTexture::producerReleaseAndSwap();
- android::Mutex::Autolock lock(m_varLock);
+ android::Mutex::Autolock lock(m_busyLock);
m_busy = false;
}
-void BackedDoubleBufferedTexture::producerUpdate(BaseTile* painter,
- TextureInfo* textureInfo, PaintingInfo& info)
+void BackedDoubleBufferedTexture::producerUpdate(TextureInfo* textureInfo)
{
// no need to upload a texture since the bitmap is empty
if (!m_bitmap.width() && !m_bitmap.height()) {
@@ -93,34 +92,9 @@ void BackedDoubleBufferedTexture::producerUpdate(BaseTile* painter,
textureInfo->m_height = m_bitmap.height();
}
- m_varLock.lock();
- // set the painting information for this texture
- if (equalsIdTextureA(textureInfo->m_textureId))
- m_paintingInfoA = info;
- else if (equalsIdTextureB(textureInfo->m_textureId))
- m_paintingInfoB = info;
- m_varLock.unlock();
-
producerReleaseAndSwap();
}
-// Compare the current texture displayed with some PaintingInfo.
-bool BackedDoubleBufferedTexture::consumerTextureUpToDate(PaintingInfo& info)
-{
- android::Mutex::Autolock lock(m_varLock);
- if (isTextureAReadable())
- return info == m_paintingInfoA;
- return info == m_paintingInfoB;
-}
-
-bool BackedDoubleBufferedTexture::consumerTextureSimilar(PaintingInfo& info)
-{
- android::Mutex::Autolock lock(m_varLock);
- if (isTextureAReadable())
- return info.similar(m_paintingInfoA);
- return info.similar(m_paintingInfoB);
-}
-
bool BackedDoubleBufferedTexture::acquire(BaseTile* owner)
{
if (m_owner == owner)
@@ -128,7 +102,7 @@ bool BackedDoubleBufferedTexture::acquire(BaseTile* owner)
// if the writable texture is busy (i.e. currently being written to) then we
// can't change the owner out from underneath that texture
- android::Mutex::Autolock lock(m_varLock);
+ android::Mutex::Autolock lock(m_busyLock);
if (!m_busy) {
if (m_owner)
m_owner->removeTexture();
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
index 1faa110..6bbb97a 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
@@ -36,42 +36,6 @@ namespace WebCore {
class BaseTile;
-class PaintingInfo {
-public:
- PaintingInfo() : m_x(-1), m_y(-1), m_webview(0), m_picture(0) { }
- PaintingInfo(int x, int y, GLWebViewState* webview)
- : m_x(x)
- , m_y(y)
- , m_webview(webview)
- , m_picture(0)
- {
- if(webview)
- m_picture = webview->currentPictureCounter();
- }
- 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:
@@ -88,7 +52,7 @@ public:
// updates the texture with current bitmap and releases (and if needed also
// swaps) the texture.
- void producerUpdate(BaseTile* painter, TextureInfo* textureInfo, PaintingInfo& info);
+ void producerUpdate(TextureInfo* textureInfo);
// The level can be one of the following values:
// * -1 for an unused texture.
@@ -107,11 +71,7 @@ public:
BaseTile* owner() { return m_owner; } // only used by the consumer thread
SkCanvas* canvas() { return m_canvas; } // only used by the producer thread
- // checks to see if the current readable texture equals the provided PaintingInfo
- bool consumerTextureUpToDate(PaintingInfo& info);
- // checks to see if the current readable texture is similar to the provided PaintingInfo
- bool consumerTextureSimilar(PaintingInfo& info);
-
+ // This is to be only used for debugging on the producer thread
bool busy() { return m_busy; }
private:
@@ -120,12 +80,13 @@ private:
int m_usedLevel;
BaseTile* m_owner;
- //The following values are shared among threads and use m_varLock to stay synced
- PaintingInfo m_paintingInfoA;
- PaintingInfo m_paintingInfoB;
+ // This values signals that the texture is currently in use by the consumer.
+ // This allows us to prevent the owner of the texture from changing while the
+ // consumer is holding a lock on the texture.
bool m_busy;
-
- android::Mutex m_varLock;
+ // 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;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index 5ab801e..ff5d9ca 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -72,6 +72,9 @@ BaseTile::BaseTile(TiledPage* page, int x, int y)
, m_y(y)
, m_texture(0)
, m_scale(1)
+ , m_dirty(true)
+ , m_lastDirtyPicture(0)
+ , m_lastPaintedPicture(0)
{
#ifdef DEBUG_COUNT
gBaseTileCount++;
@@ -80,6 +83,7 @@ BaseTile::BaseTile(TiledPage* page, int x, int y)
BaseTile::~BaseTile()
{
+ setUsedLevel(-1);
#ifdef DEBUG_COUNT
gBaseTileCount--;
#endif
@@ -90,26 +94,43 @@ BaseTile::~BaseTile()
void BaseTile::reserveTexture()
{
BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this);
- // We update atomically, so paintBitmap() can see the correct value
- android_atomic_acquire_store((int32_t)texture, (int32_t*)&m_texture);
- XLOG("%x (%d, %d) reserveTexture res: %x...", this, x(), y(), m_texture);
+
+ android::AutoMutex lock(m_atomicSync);
+ if (m_texture != texture) {
+ m_lastPaintedPicture = 0;
+ m_dirty = true;
+ }
+ m_texture = texture;
}
void BaseTile::removeTexture()
{
XLOG("%x removeTexture res: %x...", this, m_texture);
// We update atomically, so paintBitmap() can see the correct value
- android_atomic_acquire_store(0, (int32_t*)&m_texture);
+ android::AutoMutex lock(m_atomicSync);
+ m_texture = 0;
}
void BaseTile::setScale(float scale)
{
+ android::AutoMutex lock(m_atomicSync);
+ if (m_scale != scale)
+ m_dirty = true;
m_scale = scale;
- // FIXME: the following two lines force a memory barrier which causes
- // m_scale to be observable on other cores. We should replace this
- // with a dedicated system function if/when available.
- int32_t tempValue = 0;
- android_atomic_acquire_load(&tempValue);
+}
+
+void BaseTile::markAsDirty(int unsigned pictureCount)
+{
+ android::AutoMutex lock(m_atomicSync);
+ m_lastDirtyPicture = pictureCount;
+ if (m_lastPaintedPicture < m_lastDirtyPicture)
+ m_dirty = true;
+}
+
+bool BaseTile::isDirty()
+{
+ android::AutoMutex lock(m_atomicSync);
+ return m_dirty;
}
void BaseTile::setUsedLevel(int usedLevel)
@@ -120,13 +141,13 @@ void BaseTile::setUsedLevel(int usedLevel)
void BaseTile::draw(float transparency, SkRect& rect)
{
+ // No need to mutex protect reads of m_texture as it is only written to by
+ // the consumer thread.
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());
-
TextureInfo* textureInfo = m_texture->consumerLock();
if (!textureInfo) {
XLOG("%x (%d, %d) trying to draw, but no textureInfo!", this, x(), y());
@@ -134,61 +155,57 @@ void BaseTile::draw(float transparency, SkRect& rect)
return;
}
- if (m_texture->consumerTextureSimilar(info)) {
+ m_atomicSync.lock();
+ bool isTexturePainted = m_lastPaintedPicture;
+ m_atomicSync.unlock();
+
+ if (isTexturePainted)
TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId,
transparency);
- }
m_texture->consumerRelease();
}
-bool BaseTile::isBitmapReady()
+bool BaseTile::isTileReady()
{
if (!m_texture)
return false;
if (m_texture->owner() != this)
return false;
- PaintingInfo info(m_x, m_y, m_page->glWebViewState());
- return m_texture->consumerTextureUpToDate(info);
+
+ android::AutoMutex lock(m_atomicSync);
+ return !m_dirty;
}
// This is called from the texture generation thread
void BaseTile::paintBitmap()
{
- const int x = m_x;
- const int y = m_y;
- TiledPage* tiledPage = m_page;
-
- // We acquire the texture atomically. Once we have it, we
- // can continue with it, and m_texture can be updated without
- // consequences.
- BackedDoubleBufferedTexture* texture = reinterpret_cast<BackedDoubleBufferedTexture*>(
- android_atomic_release_load((int32_t*)&m_texture));
- // The loading of m_texture forces the execution of a memory barrier,
- // which ensures that we are observing the most recent value of m_scale
- // written by another core.
+ // We acquire the values below atomically. This ensures that we are reading
+ // values correctly across cores. Further, once we have these values they
+ // can be updated by other threads without consequence.
+ m_atomicSync.lock();
+ bool dirty = m_dirty;
+ BackedDoubleBufferedTexture* texture = m_texture;
float scale = m_scale;
+ m_atomicSync.unlock();
- if (!texture)
+ if(!dirty || !texture)
return;
+ const int x = m_x;
+ const int y = m_y;
+ TiledPage* tiledPage = m_page;
+
TextureInfo* textureInfo = texture->producerLock();
- // at this point we can safely check the ownership
- // (if the texture got transferred to another BaseTile
- // under us)
+ // 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->producerRelease();
return;
}
- PaintingInfo info(x, y, tiledPage->glWebViewState());
- if (texture->consumerTextureUpToDate(info)) {
- texture->producerRelease();
- return;
- }
-
float tileWidth = textureInfo->m_width;
float tileHeight = textureInfo->m_height;
@@ -203,7 +220,7 @@ void BaseTile::paintBitmap()
canvas->scale(scale, scale);
canvas->translate(-x * w, -y * h);
- tiledPage->paintBaseLayerContent(canvas);
+ unsigned int pictureCount = tiledPage->paintBaseLayerContent(canvas);
canvas->restore();
@@ -219,7 +236,13 @@ void BaseTile::paintBitmap()
canvas->drawLine(tileWidth, 0, tileWidth, tileHeight, paint);
#endif
- texture->producerUpdate(this, textureInfo, info);
+ texture->producerUpdate(textureInfo);
+
+ m_atomicSync.lock();
+ m_lastPaintedPicture = pictureCount;
+ if (m_lastPaintedPicture >= m_lastDirtyPicture)
+ m_dirty = false;
+ m_atomicSync.unlock();
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h
index 429d950..8870cbf 100644
--- a/WebCore/platform/graphics/android/BaseTile.h
+++ b/WebCore/platform/graphics/android/BaseTile.h
@@ -36,6 +36,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
+#include <utils/threads.h>
namespace WebCore {
@@ -69,12 +70,15 @@ public:
void reserveTexture();
void removeTexture();
void setUsedLevel(int);
- bool isBitmapReady();
+ bool isTileReady();
void draw(float transparency, SkRect& rect);
// the only thread-safe function called by the background thread
void paintBitmap();
+ void markAsDirty(const unsigned int pictureCount);
+ bool isDirty();
+
float scale() const { return m_scale; }
void setScale(float scale);
@@ -89,9 +93,25 @@ private:
int m_x;
int m_y;
- // these variables can be updated throughout the lifetime of the object
+ // The remaining variables can be updated throughout the lifetime of the object
BackedDoubleBufferedTexture* m_texture;
float m_scale;
+ // used to signal that the that the tile is out-of-date and needs to be redrawn
+ bool m_dirty;
+ // stores the id of the latest picture from webkit that caused this tile to
+ // become dirty. A tile is no longer dirty when it has been painted with a
+ // picture that is newer than this value.
+ unsigned int m_lastDirtyPicture;
+ // 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
+ // to display (dirty or otherwise).
+ unsigned int m_lastPaintedPicture;
+
+ // This mutex serves two purposes. (1) It ensures that certain operations
+ // happen atomically and (2) it makes sure those operations are synchronized
+ // across all threads and cores.
+ android::Mutex m_atomicSync;
+
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.h b/WebCore/platform/graphics/android/DoubleBufferedTexture.h
index d16d5f3..2b2fd03 100644
--- a/WebCore/platform/graphics/android/DoubleBufferedTexture.h
+++ b/WebCore/platform/graphics/android/DoubleBufferedTexture.h
@@ -50,11 +50,6 @@ public:
TextureInfo* consumerLock();
void consumerRelease();
-protected:
- bool equalsIdTextureA(GLuint id) { return id == m_textureA.getSourceTextureId(); }
- bool equalsIdTextureB(GLuint id) { return id == m_textureB.getSourceTextureId(); }
- bool isTextureAReadable() { return getReadableTexture() == &m_textureA; }
-
private:
SharedTexture* getReadableTexture();
SharedTexture* getWriteableTexture();
diff --git a/WebCore/platform/graphics/android/FontCacheAndroid.cpp b/WebCore/platform/graphics/android/FontCacheAndroid.cpp
index dac005f..2f41c3c 100644
--- a/WebCore/platform/graphics/android/FontCacheAndroid.cpp
+++ b/WebCore/platform/graphics/android/FontCacheAndroid.cpp
@@ -26,8 +26,9 @@
#include "config.h"
#include "FontCache.h"
-#include "FontPlatformData.h"
+
#include "Font.h"
+#include "FontPlatformData.h"
#include "NotImplemented.h"
#include "SimpleFontData.h"
#include "SkPaint.h"
@@ -73,8 +74,8 @@ static char* AtomicStringToUTF8String(const AtomicString& utf16)
SkASSERT(sizeof(uint16_t) == sizeof(utf16.characters()[0]));
const uint16_t* uni = (uint16_t*)utf16.characters();
- size_t bytes = SkUTF16_ToUTF8(uni, utf16.length(), NULL);
- char* utf8 = (char*)sk_malloc_throw(bytes + 1);
+ size_t bytes = SkUTF16_ToUTF8(uni, utf16.length(), 0);
+ char* utf8 = (char*)sk_malloc_throw(bytes + 1);
(void)SkUTF16_ToUTF8(uni, utf16.length(), utf8);
utf8[bytes] = 0;
diff --git a/WebCore/platform/graphics/android/GLUtils.cpp b/WebCore/platform/graphics/android/GLUtils.cpp
index e9c0796..1c84fe2 100644
--- a/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/WebCore/platform/graphics/android/GLUtils.cpp
@@ -121,14 +121,15 @@ bool GLUtils::isEGLImageSupported() {
const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
- return strstr(eglExtensions, "EGL_KHR_image_base") &&
+ return eglExtensions && glExtensions &&
+ strstr(eglExtensions, "EGL_KHR_image_base") &&
strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") &&
strstr(glExtensions, "GL_OES_EGL_image");
}
bool GLUtils::isEGLFenceSyncSupported() {
const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
- return strstr(eglExtensions, "EGL_KHR_fence_sync");
+ return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync");
}
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp
index e1e517c..4ad22d8 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -81,7 +81,6 @@ GLWebViewState::GLWebViewState()
, 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);
#ifdef DEBUG_COUNT
@@ -108,8 +107,13 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, IntRect& rect)
m_navLayer = 0;
if (m_baseLayer) {
m_baseLayer->setGLWebViewState(this);
- m_invalidatedRect.set(rect);
m_currentPictureCounter++;
+
+ if (!rect.isEmpty()) {
+ // find which tiles fall within the invalRect and mark them as dirty
+ m_tiledPageA->invalidateRect(rect, m_currentPictureCounter);
+ m_tiledPageB->invalidateRect(rect, m_currentPictureCounter);
+ }
}
}
@@ -132,7 +136,7 @@ void GLWebViewState::resetExtra(bool repaint)
m_navLayer = 0;
}
-void GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
+unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
{
android::Mutex::Autolock lock(m_baseLayerLock);
if (m_baseLayer) {
@@ -140,6 +144,7 @@ void GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
if (m_extra && m_navLayer)
m_extra->draw(canvas, m_navLayer);
}
+ return m_currentPictureCounter;
}
void GLWebViewState::scheduleUpdate(const double& currentTime, float scale)
diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h
index 95bc07d..3eaabb3 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/WebCore/platform/graphics/android/GLWebViewState.h
@@ -95,8 +95,9 @@ class LayerAndroid;
// 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).
+// tiles we need (i.e. in the viewport and dirty) into a TilesSet and call
+// BaseTile::reserveTexture() for each tile (which ensures there is a specific
+// GL textures backing the BaseTiles).
//
// reserveTexture() will ask the TilesManager for a texture. The allocation
// mechanism goal is to (in order):
@@ -104,8 +105,22 @@ class LayerAndroid;
// - 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.
+// Note that to compute the distance of each tile from the viewport, each time
+// we prepare() a TiledPage. Also during each prepare() we compute which tiles
+// are dirty based on the info we have received from webkit.
+//
+// BaseTile Invalidation
+// ------------------
+//
+// We do not want to redraw a tile if the tile is up-to-date. A tile is
+// considered to be dirty an in need of redrawing in the following cases
+// - the tile has acquires a new texture
+// - webkit invalidates all or part of the tiles contents
+//
+// To handle the case of webkit invalidation we store two ids (counters) of the
+// pictureSets in the tile. The first id (A) represents the pictureSet used to
+// paint the tile and the second id (B) represents the pictureSet in which the
+// tile was invalidated by webkit. Thus, if A < B then tile is dirty.
//
// Painting scheduling
// -------------------
@@ -155,7 +170,7 @@ public:
int originalTilesPosY() const { return m_originalTilesPosY; }
void setOriginalTilesPosY(int pos) { m_originalTilesPosY = pos; }
- void paintBaseLayerContent(SkCanvas* canvas);
+ unsigned int paintBaseLayerContent(SkCanvas* canvas);
void setBaseLayer(BaseLayerAndroid* layer, IntRect& rect);
void setExtra(android::DrawExtra* extra, LayerAndroid* navLayer);
void resetExtra(bool repaint);
@@ -176,7 +191,6 @@ public:
int firstTileY() const { return m_firstTileY; }
unsigned int currentPictureCounter() const { return m_currentPictureCounter; }
- SkRect& invalidatedRect() { return m_invalidatedRect; }
private:
@@ -207,7 +221,6 @@ private:
android::Mutex m_baseLayerLock;
BaseLayerAndroid* m_baseLayer;
unsigned int m_currentPictureCounter;
- SkRect m_invalidatedRect;
bool m_usePageA;
TiledPage* m_tiledPageA;
TiledPage* m_tiledPageB;
diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
index b76f5d5..5d38295 100644
--- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
@@ -70,7 +70,7 @@ template <typename T> T* deepCopyPtr(const T* src)
// 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; // >=0 means valid shadow
SkScalar dx;
SkScalar dy;
SkColor color;
@@ -149,13 +149,13 @@ public:
bool setupShadowPaint(SkPaint* paint, SkPoint* offset)
{
- if (shadow.blur > 0) {
+ if (shadow.blur >= 0) {
paint->setAntiAlias(true);
paint->setDither(true);
paint->setXfermodeMode(mode);
paint->setColor(shadow.color);
paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur,
- SkBlurMaskFilter::kNormal_BlurStyle))->unref();
+ SkBlurMaskFilter::kNormal_BlurStyle))->safeUnref();
offset->set(shadow.dx, shadow.dy);
return true;
}
@@ -253,7 +253,7 @@ public:
paint->setAntiAlias(m_state->useAA);
paint->setDither(true);
paint->setXfermodeMode(m_state->mode);
- if (m_state->shadow.blur > 0) {
+ if (m_state->shadow.blur >= 0) {
SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur,
m_state->shadow.dx,
m_state->shadow.dy,
@@ -944,9 +944,6 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const
if (paintingDisabled())
return;
- if (blur <= 0)
- this->clearPlatformShadow();
-
SkColor c;
if (color.isValid())
c = color.rgb();
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 5210171..f88401c 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -342,10 +342,12 @@ void LayerAndroid::findInner(LayerAndroidFindState& state) const
bounds(&localBounds);
if (!localBounds.contains(x, y))
return;
- if (!m_recordingPicture)
- return;
- if (!state.drew(m_recordingPicture, localBounds))
- return;
+ if (!m_foregroundPicture) {
+ if (!m_recordingPicture)
+ return;
+ if (!state.drew(m_recordingPicture, localBounds))
+ return;
+ }
state.setBest(this); // set last match (presumably on top)
}
@@ -688,8 +690,19 @@ void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const
}
if (m_recordingPicture) {
- writeIntVal(file, indentLevel + 1, "picture width", m_recordingPicture->width());
- writeIntVal(file, indentLevel + 1, "picture height", m_recordingPicture->height());
+ writeIntVal(file, indentLevel + 1, "m_recordingPicture.width", m_recordingPicture->width());
+ writeIntVal(file, indentLevel + 1, "m_recordingPicture.height", m_recordingPicture->height());
+ }
+
+ if (m_foregroundPicture) {
+ writeIntVal(file, indentLevel + 1, "m_foregroundPicture.width", m_foregroundPicture->width());
+ writeIntVal(file, indentLevel + 1, "m_foregroundPicture.height", m_foregroundPicture->height());
+ writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fLeft", m_foregroundClip.fLeft);
+ writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fTop", m_foregroundClip.fTop);
+ writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fRight", m_foregroundClip.fRight);
+ writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fBottom", m_foregroundClip.fBottom);
+ writeFloatVal(file, indentLevel + 1, "m_foregroundLocation.fX", m_foregroundLocation.fX);
+ writeFloatVal(file, indentLevel + 1, "m_foregroundLocation.fY", m_foregroundLocation.fY);
}
if (countChildren()) {
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp
index f81a297..0c385b8 100644
--- a/WebCore/platform/graphics/android/TexturesGenerator.cpp
+++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp
@@ -53,10 +53,13 @@ void TexturesGenerator::schedulePaintForTileSet(TileSet* set)
{
android::Mutex::Autolock lock(mRequestedPixmapsLock);
for (unsigned int i = 0; i < mRequestedPixmaps.size(); i++) {
- TileSet* s = mRequestedPixmaps[i];
- if (s && *s == *set) {
- // Similar set already in the queue
- delete set;
+ TileSet** s = &mRequestedPixmaps[i];
+ // A similar set is already in the queue. The newer set may have additional
+ // dirty tiles so delete the existing set and replace it with the new one.
+ if (*s && **s == *set) {
+ TileSet* oldSet = *s;
+ *s = set;
+ delete oldSet;
return;
}
}
@@ -112,11 +115,19 @@ status_t TexturesGenerator::readyToRun()
bool TexturesGenerator::threadLoop()
{
- XLOG("threadLoop, waiting for signal");
- m_newRequestLock.lock();
- m_newRequestCond.wait(m_newRequestLock);
- m_newRequestLock.unlock();
- XLOG("threadLoop, got signal");
+ mRequestedPixmapsLock.lock();
+
+ if (!mRequestedPixmaps.size()) {
+ XLOG("threadLoop, waiting for signal");
+ m_newRequestLock.lock();
+ mRequestedPixmapsLock.unlock();
+ m_newRequestCond.wait(m_newRequestLock);
+ m_newRequestLock.unlock();
+ XLOG("threadLoop, got signal");
+ } else {
+ XLOG("threadLoop going as we already have something in the queue");
+ mRequestedPixmapsLock.unlock();
+ }
m_currentSet = 0;
bool stop = false;
diff --git a/WebCore/platform/graphics/android/TileSet.cpp b/WebCore/platform/graphics/android/TileSet.cpp
index fe13ef3..4530640 100644
--- a/WebCore/platform/graphics/android/TileSet.cpp
+++ b/WebCore/platform/graphics/android/TileSet.cpp
@@ -56,10 +56,8 @@ int TileSet::count()
}
#endif
-TileSet::TileSet(int id, int firstTileX, int firstTileY, int rows, int cols)
- : m_id(id)
- , m_firstTileX(firstTileX)
- , m_firstTileY(firstTileY)
+TileSet::TileSet(TiledPage* tiledPage, int rows, int cols)
+ : m_tiledPage(tiledPage)
, m_nbRows(rows)
, m_nbCols(cols)
{
@@ -77,36 +75,12 @@ TileSet::~TileSet()
bool TileSet::operator==(const TileSet& set)
{
- return m_id == set.m_id
- && m_firstTileX == set.m_firstTileX
- && m_firstTileY == set.m_firstTileY
+ return m_tiledPage == set.m_tiledPage
&& m_nbRows == set.m_nbRows
&& m_nbCols == set.m_nbCols;
}
-void TileSet::reserveTextures()
-{
-#ifdef DEBUG
- if (m_tiles.size()) {
- TiledPage* page = m_tiles[0]->page();
- XLOG("reserveTextures (%d tiles) for page %x (sibling: %x)", m_tiles.size(), page, page->sibling());
- TilesManager::instance()->printTextures();
- }
-#endif // DEBUG
-
- for (unsigned int i = 0; i < m_tiles.size(); i++)
- m_tiles[i]->reserveTexture();
-
-#ifdef DEBUG
- if (m_tiles.size()) {
- TiledPage* page = m_tiles[0]->page();
- XLOG(" DONE reserveTextures (%d tiles) for page %x (sibling: %x)", m_tiles.size(), page, page->sibling());
- TilesManager::instance()->printTextures();
- }
-#endif // DEBUG
-}
-
void TileSet::paint()
{
XLOG("%x, painting %d tiles", this, m_tiles.size());
diff --git a/WebCore/platform/graphics/android/TileSet.h b/WebCore/platform/graphics/android/TileSet.h
index adf6d13..fd65ad7 100644
--- a/WebCore/platform/graphics/android/TileSet.h
+++ b/WebCore/platform/graphics/android/TileSet.h
@@ -45,11 +45,10 @@ public:
#ifdef DEBUG_COUNT
static int count();
#endif
- TileSet(int id, int firstTileX, int firstTileY, int rows, int cols);
+ TileSet(TiledPage* tiledPage, int nbRows, int nbCols);
~TileSet();
bool operator==(const TileSet& set);
- void reserveTextures();
void paint();
void add(BaseTile* texture)
@@ -59,17 +58,13 @@ public:
TiledPage* page()
{
- if (m_tiles.size())
- return m_tiles[0]->page();
- return 0;
+ return m_tiledPage;
}
private:
Vector<BaseTile*> m_tiles;
- int m_id;
- int m_firstTileX;
- int m_firstTileY;
+ TiledPage* m_tiledPage;
int m_nbRows;
int m_nbCols;
};
diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp
index 6430b02..358c1a8 100644
--- a/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/WebCore/platform/graphics/android/TiledPage.cpp
@@ -29,6 +29,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "GLUtils.h"
+#include "IntRect.h"
#include "TilesManager.h"
#ifdef DEBUG
@@ -64,6 +65,7 @@ TiledPage::TiledPage(int id, GLWebViewState* state)
, m_scale(1)
, m_invScale(1)
, m_glWebViewState(state)
+ , m_latestPictureInval(0)
{
#ifdef DEBUG_COUNT
gTilePageCount++;
@@ -94,6 +96,24 @@ BaseTile* TiledPage::getBaseTile(int x, int y)
return m_baseTiles.get(key);
}
+void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureCount)
+{
+ // Given the current scale level we need to mark the appropriate tiles as dirty
+ TilesManager* manager = TilesManager::instance();
+ const float invTileContentWidth = m_scale / manager->tileWidth();
+ const float invTileContentHeight = m_scale / manager->tileHeight();
+
+ const int firstDirtyTileX = static_cast<int>(floorf(inval.x() * invTileContentWidth));
+ const int firstDirtyTileY = static_cast<int>(floorf(inval.y() * invTileContentHeight));
+ const int lastDirtyTileX = static_cast<int>(ceilf(inval.right() * invTileContentWidth));
+ const int lastDirtyTileY = static_cast<int>(ceilf(inval.bottom() * invTileContentHeight));
+
+ // 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);
+ m_latestPictureInval = pictureCount;
+}
+
void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set)
{
if (y < 0)
@@ -119,11 +139,16 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
}
tile = m_baseTiles.get(key);
tile->setScale(m_scale);
- set->add(tile);
+
+ // ensure there is a texture associated with the tile and then check to
+ // see if the texture is dirty and in need of repainting
+ tile->reserveTexture();
+ if(tile->isDirty())
+ set->add(tile);
}
}
-void TiledPage::setTileLevels(int firstTileX, int firstTileY)
+void TiledPage::updateTileState(int firstTileX, int firstTileY)
{
if (!m_glWebViewState)
return;
@@ -138,6 +163,11 @@ void TiledPage::setTileLevels(int firstTileX, int firstTileY)
if(!tile)
continue;
+ // 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);
+
+ // set the used level of the tile (e.g. distance from the viewport)
int dx = 0;
int dy = 0;
@@ -156,6 +186,10 @@ void TiledPage::setTileLevels(int firstTileX, int firstTileY)
XLOG("setTileLevel tile: %x, fxy(%d, %d), level: %d", tile, firstTileX, firstTileY, d);
tile->setUsedLevel(d);
}
+
+ // clear the invalidated region as all tiles within that region have now
+ // been marked as dirty.
+ m_invalRegion.setEmpty();
}
void TiledPage::prepare(bool goingDown, bool goingLeft, int firstTileX, int firstTileY)
@@ -163,10 +197,13 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, int firstTileX, int firs
if (!m_glWebViewState)
return;
+ // update the tiles distance from the viewport
+ updateTileState(firstTileX, firstTileY);
+
int nbTilesWidth = m_glWebViewState->nbTilesWidth();
int nbTilesHeight = m_glWebViewState->nbTilesHeight();
- TileSet* highResSet = new TileSet(m_id, firstTileX, firstTileY, nbTilesHeight, nbTilesWidth);
+ TileSet* highResSet = new TileSet(this, nbTilesHeight, nbTilesWidth);
// We chose to display tiles depending on the scroll direction:
if (goingDown) {
@@ -178,23 +215,6 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, int firstTileX, int firs
prepareRow(goingLeft, nbTilesWidth, firstTileX, startingTileY - i, highResSet);
}
- // update the tiles distance from the viewport
- setTileLevels(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
-
// schedulePaintForTileSet will take ownership of the highResSet here,
// so no delete necessary.
TilesManager::instance()->schedulePaintForTileSet(highResSet);
@@ -213,7 +233,7 @@ bool TiledPage::ready(int firstTileX, int firstTileY)
int x = j + firstTileX;
int y = i + firstTileY;
BaseTile* t = getBaseTile(x, y);
- if (!t || !t->isBitmapReady())
+ if (!t || !t->isTileReady())
return false;
}
}
@@ -260,10 +280,11 @@ void TiledPage::draw(float transparency, SkRect& viewport, int firstTileX, int f
#endif // DEBUG
}
-void TiledPage::paintBaseLayerContent(SkCanvas* canvas)
+unsigned int TiledPage::paintBaseLayerContent(SkCanvas* canvas)
{
if (m_glWebViewState)
- m_glWebViewState->paintBaseLayerContent(canvas);
+ return m_glWebViewState->paintBaseLayerContent(canvas);
+ return 0;
}
TiledPage* TiledPage::sibling()
diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h
index 8be2361..b532033 100644
--- a/WebCore/platform/graphics/android/TiledPage.h
+++ b/WebCore/platform/graphics/android/TiledPage.h
@@ -30,11 +30,13 @@
#include "BaseTile.h"
#include "SkCanvas.h"
+#include "SkRegion.h"
#include "TileSet.h"
namespace WebCore {
class GLWebViewState;
+class IntRect;
typedef std::pair<int, int> TileKey;
typedef HashMap<TileKey, BaseTile*> TileMap;
@@ -68,15 +70,17 @@ public:
void draw(float transparency, SkRect& viewport, int firstTileX, int firstTileY);
// used by individual tiles to generate the bitmap for their tile
- void paintBaseLayerContent(SkCanvas*);
+ unsigned int paintBaseLayerContent(SkCanvas*);
// used by individual tiles to get the information about the current picture
GLWebViewState* glWebViewState() { return m_glWebViewState; }
float scale() const { return m_scale; }
void setScale(float scale) { m_scale = scale; m_invScale = 1 / scale; }
+ void invalidateRect(const IntRect& invalRect, const unsigned int pictureCount);
+
private:
- void setTileLevels(int firstTileX, int firstTileY);
+ void updateTileState(int firstTileX, int firstTileY);
void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set);
BaseTile* getBaseTile(int x, int y);
@@ -86,6 +90,13 @@ private:
float m_scale;
float m_invScale;
GLWebViewState* m_glWebViewState;
+
+ // used to identify the tiles that have been invalidated (marked dirty) since
+ // the last time updateTileState() has been called. The region is stored in
+ // terms of the (x,y) coordinates used to determine the location of the tile
+ // within the page, not in content/view pixel coordinates.
+ SkRegion m_invalRegion;
+ unsigned int m_latestPictureInval;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index 54ca9ad..9ebfe02 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -136,8 +136,7 @@ void TilesManager::paintTexturesDefault()
#else
canvas->drawARGB(255, 255, 255, 255);
#endif // DEBUG
- PaintingInfo info;
- texture->producerUpdate(0, textureInfo, info);
+ texture->producerUpdate(textureInfo);
}
}
}
@@ -186,9 +185,9 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner)
}
}
if (farthestTexture && farthestTexture->acquire(owner)) {
- farthestTexture->setUsedLevel(0);
XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d)",
owner, farthestTexture, farthestTexture->usedLevel());
+ farthestTexture->setUsedLevel(0);
return farthestTexture;
}
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 260a081..0538d99 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -39,7 +39,7 @@
#include "RenderLayerCompositor.h"
#endif
-#ifdef ANDROID_LAYOUT
+#if defined(ANDROID_LAYOUT) || defined(ANDROID_FIXED_ELEMENTS)
#include "Settings.h"
#endif
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp
index f21c1a2..e939be4 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -130,7 +130,7 @@ void WebRequest::finish(bool success)
m_urlLoader = 0;
}
-void WebRequest::appendFileToUpload(std::string filename)
+void WebRequest::appendFileToUpload(const std::string& filename)
{
// AppendFileToUpload is only valid before calling start
ASSERT(m_loadState == Created, "appendFileToUpload called on a WebRequest not in CREATED state: (%s)", m_url.c_str());
diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h
index c82096e..c7026a5 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.h
+++ b/WebKit/android/WebCoreSupport/WebRequest.h
@@ -61,7 +61,7 @@ public:
// Optional, but if used has to be called before start
void appendBytesToUpload(Vector<char>* data);
- void appendFileToUpload(std::string filename);
+ void appendFileToUpload(const std::string& filename);
void start(bool isPrivateBrowsing);
void cancel();
diff --git a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp
index 1aecef1..217bbc0 100644
--- a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp
+++ b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp
@@ -57,7 +57,6 @@ static URLRequestContext* webAutoFillContextGetter()
WebAutoFill::WebAutoFill()
: mWebViewCore(0)
- , mUniqueProfileId(NO_PROFILE_SET)
{
mFormManager = new FormManager();
mQueryId = 1;
@@ -107,7 +106,7 @@ void WebAutoFill::formFieldFocused(WebCore::HTMLFormControlElement* formFieldEle
// In case that we've just been disabled and the last time we got autofill
// suggestions and told Java about them, clear that bit Java side now
// we're disabled.
- mWebViewCore->setWebTextViewAutoFillable(FORM_NOT_AUTOFILLABLE);
+ mWebViewCore->setWebTextViewAutoFillable(FORM_NOT_AUTOFILLABLE, string16());
return;
}
@@ -125,7 +124,7 @@ void WebAutoFill::formFieldFocused(WebCore::HTMLFormControlElement* formFieldEle
if (!suggestions) {
ASSERT(mWebViewCore);
// Tell Java no autofill suggestions for this form.
- mWebViewCore->setWebTextViewAutoFillable(FORM_NOT_AUTOFILLABLE);
+ mWebViewCore->setWebTextViewAutoFillable(FORM_NOT_AUTOFILLABLE, string16());
return;
}
}
@@ -140,7 +139,7 @@ void WebAutoFill::querySuccessful(int queryId, const string16& value, const stri
mUniqueIdMap[queryId] = uniqueId;
ASSERT(mWebViewCore);
- mWebViewCore->setWebTextViewAutoFillable(queryId);
+ mWebViewCore->setWebTextViewAutoFillable(queryId, mAutoFillProfile->PreviewSummary());
}
void WebAutoFill::fillFormFields(int queryId)
@@ -173,36 +172,37 @@ void WebAutoFill::setProfile(int id, const string16& fullName, const string16& e
const string16& addressLine1, const string16& addressLine2, const string16& city,
const string16& state, const string16& zipCode, const string16& country, const string16& phoneNumber)
{
- AutoFillProfile autoFillProfile;
- mUniqueProfileId = id;
- autoFillProfile.set_unique_id(id);
+ mAutoFillProfile.set(new AutoFillProfile());
+ mAutoFillProfile->set_unique_id(id);
// Constants for AutoFill field types are found in external/chromium/chrome/browser/autofill/field_types.h.
- autoFillProfile.SetInfo(AutoFillType(NAME_FULL), fullName);
- autoFillProfile.SetInfo(AutoFillType(EMAIL_ADDRESS), emailAddress);
- autoFillProfile.SetInfo(AutoFillType(COMPANY_NAME), companyName);
- autoFillProfile.SetInfo(AutoFillType(ADDRESS_HOME_LINE1), addressLine1);
- autoFillProfile.SetInfo(AutoFillType(ADDRESS_HOME_LINE2), addressLine2);
- autoFillProfile.SetInfo(AutoFillType(ADDRESS_HOME_CITY), city);
- autoFillProfile.SetInfo(AutoFillType(ADDRESS_HOME_STATE), state);
- autoFillProfile.SetInfo(AutoFillType(ADDRESS_HOME_ZIP), zipCode);
- autoFillProfile.SetInfo(AutoFillType(ADDRESS_HOME_COUNTRY), country);
- autoFillProfile.SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), phoneNumber);
+ mAutoFillProfile->SetInfo(AutoFillType(NAME_FULL), fullName);
+ mAutoFillProfile->SetInfo(AutoFillType(EMAIL_ADDRESS), emailAddress);
+ mAutoFillProfile->SetInfo(AutoFillType(COMPANY_NAME), companyName);
+ mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), addressLine1);
+ mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), addressLine2);
+ mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), city);
+ mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), state);
+ mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), zipCode);
+ mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_COUNTRY), country);
+ mAutoFillProfile->SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), phoneNumber);
std::vector<AutoFillProfile> profiles;
- profiles.push_back(autoFillProfile);
+ profiles.push_back(*mAutoFillProfile);
mTabContents->profile()->GetPersonalDataManager()->SetProfiles(&profiles);
}
void WebAutoFill::clearProfiles()
{
- // For now Chromium only ever knows about one profile, so we can just
- // remove it by unique id. If we support multiple profiles in the future
- // we need to remove them all here.
- if (mUniqueProfileId != NO_PROFILE_SET) {
- mTabContents->profile()->GetPersonalDataManager()->RemoveProfile(mUniqueProfileId);
- mUniqueProfileId = NO_PROFILE_SET;
- }
+ if (!mAutoFillProfile)
+ return;
+ // For now Chromium only ever knows about one profile, so we can just
+ // remove it by unique id. If we support multiple profiles in the future
+ // we need to remove them all here.
+ int uniqueProfileId = mAutoFillProfile->unique_id();
+ if (uniqueProfileId != NO_PROFILE_SET)
+ mTabContents->profile()->GetPersonalDataManager()->RemoveProfile(uniqueProfileId);
+ mAutoFillProfile.set(0);
}
}
diff --git a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h
index d74c838..c4b63b0 100644
--- a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h
+++ b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h
@@ -73,6 +73,7 @@ private:
OwnPtr<AutoFillManager> mAutoFillManager;
OwnPtr<AutoFillHost> mAutoFillHost;
OwnPtr<TabContents> mTabContents;
+ OwnPtr<AutoFillProfile> mAutoFillProfile;
typedef std::vector<webkit_glue::FormData, std::allocator<webkit_glue::FormData> > FormList;
FormList mForms;
@@ -84,9 +85,6 @@ private:
AutoFillQueryToUniqueIdMap mUniqueIdMap;
int mQueryId;
- // This is set by Java when a profile is synced.
- int mUniqueProfileId;
-
WebViewCore* mWebViewCore;
};
diff --git a/WebKit/android/jni/DeviceMotionAndOrientationManager.cpp b/WebKit/android/jni/DeviceMotionAndOrientationManager.cpp
index 9db83a3..8beb372 100644
--- a/WebKit/android/jni/DeviceMotionAndOrientationManager.cpp
+++ b/WebKit/android/jni/DeviceMotionAndOrientationManager.cpp
@@ -53,8 +53,7 @@ void DeviceMotionAndOrientationManager::useMock()
void DeviceMotionAndOrientationManager::setMockMotion(PassRefPtr<DeviceMotionData> motion)
{
- if (m_useMock)
- ; // TODO: There is not yet a DeviceMotion mock.
+ // TODO: There is not yet a DeviceMotion mock.
}
void DeviceMotionAndOrientationManager::onMotionChange(PassRefPtr<DeviceMotionData> motion)
diff --git a/WebKit/android/jni/WebCoreJniOnLoad.cpp b/WebKit/android/jni/WebCoreJniOnLoad.cpp
index aaf4003..6790e42 100644
--- a/WebKit/android/jni/WebCoreJniOnLoad.cpp
+++ b/WebKit/android/jni/WebCoreJniOnLoad.cpp
@@ -243,7 +243,9 @@ EXPORT void benchmark(const char* url, int reloadCount, int width, int height) {
// Set all the default settings the Browser normally uses.
Settings* s = frame->settings();
+#ifdef ANDROID_LAYOUT
s->setLayoutAlgorithm(Settings::kLayoutNormal); // Normal layout for now
+#endif
s->setStandardFontFamily("sans-serif");
s->setFixedFontFamily("monospace");
s->setSansSerifFontFamily("sans-serif");
@@ -259,7 +261,9 @@ EXPORT void benchmark(const char* url, int reloadCount, int width, int height) {
s->setDefaultTextEncodingName("latin1");
s->setPluginsEnabled(false);
s->setShrinksStandaloneImagesToFit(false);
+#ifdef ANDROID_LAYOUT
s->setUseWideViewport(false);
+#endif
// Finally, load the actual data
ResourceRequest req(url);
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index c301421..deae37f 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -381,7 +381,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_centerFitRect = GetJMethod(env, clazz, "centerFitRect", "(IIII)V");
m_javaGlue->m_setScrollbarModes = GetJMethod(env, clazz, "setScrollbarModes", "(II)V");
m_javaGlue->m_setInstallableWebApp = GetJMethod(env, clazz, "setInstallableWebApp", "()V");
- m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(I)V");
+ m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V");
env->DeleteLocalRef(clazz);
env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
@@ -3304,10 +3304,12 @@ void WebViewCore::notifyWebAppCanBeInstalled()
checkException(env);
}
-void WebViewCore::setWebTextViewAutoFillable(int queryId)
+void WebViewCore::setWebTextViewAutoFillable(int queryId, const string16& previewSummary)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_setWebTextViewAutoFillable, queryId);
+ jstring preview = env->NewString(previewSummary.data(), previewSummary.length());
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_setWebTextViewAutoFillable, queryId, preview);
+ env->DeleteLocalRef(preview);
}
bool WebViewCore::drawIsPaused() const
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 853c17b..1e2f130 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -508,7 +508,7 @@ namespace android {
void splitContent(PictureSet*);
void notifyWebAppCanBeInstalled();
- void setWebTextViewAutoFillable(int queryId);
+ void setWebTextViewAutoFillable(int queryId, const string16& previewSummary);
DeviceMotionAndOrientationManager* deviceMotionAndOrientationManager() { return &m_deviceMotionAndOrientationManager; }
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index 42a4b53..a7015e7 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -1265,7 +1265,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
cachedInput.init();
cachedInput.setFormPointer(input->form());
cachedInput.setIsTextField(true);
- cachedInput.setIsTextArea(false);
exported = input->value().threadsafeCopy();
cachedInput.setMaxLength(input->maxLength());
cachedInput.setTypeFromElement(input);
@@ -1282,7 +1281,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
HTMLTextAreaElement* area = static_cast<HTMLTextAreaElement*>(node);
cachedInput.setFormPointer(area->form());
cachedInput.setIsTextArea(true);
- cachedInput.setIsTextField(false);
exported = area->value().threadsafeCopy();
} else if (node->hasTagName(HTMLNames::aTag)) {
const HTMLAnchorElement* anchorNode =
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp
index ced87e0..e331464 100644
--- a/WebKit/android/nav/CachedFrame.cpp
+++ b/WebKit/android/nav/CachedFrame.cpp
@@ -27,6 +27,7 @@
#include "CachedHistory.h"
#include "CachedNode.h"
#include "CachedRoot.h"
+#include "LayerAndroid.h"
#include "CachedFrame.h"
@@ -39,10 +40,22 @@ namespace android {
WebCore::IntRect CachedFrame::adjustBounds(const CachedNode* node,
const WebCore::IntRect& rect) const
{
- DBG_NAV_LOGD("node=%p [%d] rect=(%d,%d,w=%d,h=%d)",
- node, node->index(), rect.x(), rect.y(), rect.width(), rect.height());
+ DBG_NAV_LOGV("node=%p [%d] rect=(%d,%d,w=%d,h=%d) view=(%d,%d,w=%d,h=%d)"
+ " local=(%d,%d,w=%d,h=%d) root=(%d,%d,w=%d,h=%d)",
+ node, node->index(), rect.x(), rect.y(), rect.width(), rect.height(),
+ mViewBounds.x(), mViewBounds.y(),
+ mViewBounds.width(), mViewBounds.height(),
+ mLocalViewBounds.x(), mLocalViewBounds.y(),
+ mLocalViewBounds.width(), mLocalViewBounds.height(),
+ mRoot->mViewBounds.x(), mRoot->mViewBounds.y(),
+ mRoot->mViewBounds.width(), mRoot->mViewBounds.height());
#if USE(ACCELERATED_COMPOSITING)
- return layer(node)->adjustBounds(mRoot->rootLayer(), rect);
+ const CachedLayer* cachedLayer = layer(node);
+ const WebCore::LayerAndroid* rootLayer = mRoot->rootLayer();
+ IntRect rrect = cachedLayer->adjustBounds(rootLayer, rect);
+ if (!cachedLayer->layer(rootLayer)->contentIsScrollable())
+ rrect.move(-mViewBounds.x(), -mViewBounds.y());
+ return rrect;
#else
return rect;
#endif
@@ -55,8 +68,14 @@ WebCore::IntRect CachedFrame::unadjustBounds(const CachedNode* node,
const WebCore::IntRect& rect) const
{
#if USE(ACCELERATED_COMPOSITING)
- if (node->isInLayer())
- return layer(node)->unadjustBounds(mRoot->rootLayer(), rect);
+ if (node->isInLayer()) {
+ const CachedLayer* cachedLayer = layer(node);
+ const WebCore::LayerAndroid* rootLayer = mRoot->rootLayer();
+ IntRect rrect = cachedLayer->unadjustBounds(rootLayer, rect);
+ if (!cachedLayer->layer(rootLayer)->contentIsScrollable())
+ rrect.move(mViewBounds.x(), mViewBounds.y());
+ return rrect;
+ }
#endif
return rect;
}
@@ -391,21 +410,27 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect,
bool checkForHidden = checkForHiddenStart;
for (size_t part = 0; part < parts; part++) {
WebCore::IntRect testRect = test->ring(this, part);
- if (test->isInLayer()) {
- DBG_NAV_LOGD("[%d] intersects=%ss testRect=(%d,%d,w=%d,h=%d)"
- " rect=(%d,%d,w=%d,h=%d)", test->index(),
- testRect.intersects(rect) ? "true" : "false",
- testRect.x(), testRect.y(), testRect.width(), testRect.height(),
- rect.x(), rect.y(), rect.width(), rect.height());
- }
if (testRect.intersects(rect)) {
- if (checkForHidden && mRoot->maskIfHidden(&testData) == true)
+#if DEBUG_NAV_UI
+ if (test->isInLayer()) {
+ DBG_NAV_LOGD("[%d] intersects=%s testRect=(%d,%d,w=%d,h=%d)"
+ " rect=(%d,%d,w=%d,h=%d)", test->index(),
+ testRect.intersects(rect) ? "true" : "false",
+ testRect.x(), testRect.y(),
+ testRect.width(), testRect.height(),
+ rect.x(), rect.y(), rect.width(), rect.height());
+ }
+#endif
+ if (checkForHidden && mRoot->maskIfHidden(&testData) == true) {
+ DBG_NAV_LOGD("hidden [%d]", test->index());
break;
+ }
checkForHidden = false;
testRect.intersect(testData.mouseBounds());
if (testRect.contains(center)) {
// We have a direct hit.
if (*directHit == NULL) {
+ DBG_NAV_LOGD("direct hit 1 [%d]", test->index());
*directHit = test;
*directHitFramePtr = this;
IntRect r(center, IntSize(0, 0));
@@ -413,6 +438,7 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect,
*x = r.x();
*y = r.y();
} else {
+ DBG_NAV_LOGD("direct hit 2 [%d]", test->index());
// We have hit another one before
const CachedNode* d = *directHit;
if (d->bounds(this).contains(testRect)) {
@@ -428,6 +454,7 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect,
// calculate the distances, or check the other parts
break;
}
+ DBG_NAV_LOGD("indirect hit [%d]", test->index());
WebCore::IntRect both = rect;
int smaller = testRect.width() < testRect.height() ?
testRect.width() : testRect.height();
diff --git a/WebKit/android/nav/CachedInput.cpp b/WebKit/android/nav/CachedInput.cpp
index 45172fb..6ba3f2e 100644
--- a/WebKit/android/nav/CachedInput.cpp
+++ b/WebKit/android/nav/CachedInput.cpp
@@ -79,17 +79,18 @@ static void printWebCoreString(const char* label,
void CachedInput::Debug::print() const
{
CachedInput* b = base();
- printWebCoreString("// char* mName=\"", b->mName);
DUMP_NAV_LOGD("// void* mForm=%p;\n", b->mForm);
+ printWebCoreString("// char* mName=\"", b->mName);
DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength);
- DUMP_NAV_LOGD("// int mTextSize=%d;\n", b->mTextSize);
- DUMP_NAV_LOGD("// int mInputType=%d;\n", b->mInputType);
DUMP_NAV_LOGD("// int mPaddingLeft=%d;\n", b->mPaddingLeft);
DUMP_NAV_LOGD("// int mPaddingTop=%d;\n", b->mPaddingTop);
DUMP_NAV_LOGD("// int mPaddingRight=%d;\n", b->mPaddingRight);
DUMP_NAV_LOGD("// int mPaddingBottom=%d;\n", b->mPaddingBottom);
+ DUMP_NAV_LOGD("// int mTextSize=%d;\n", b->mTextSize);
+ DUMP_NAV_LOGD("// Type mType=%d;\n", b->mType);
DEBUG_PRINT_BOOL(mIsRtlText);
DEBUG_PRINT_BOOL(mIsTextField);
+ DEBUG_PRINT_BOOL(mIsTextArea);
}
#endif
diff --git a/WebKit/android/nav/CachedLayer.cpp b/WebKit/android/nav/CachedLayer.cpp
index f6b1859..5ad5c8b 100644
--- a/WebKit/android/nav/CachedLayer.cpp
+++ b/WebKit/android/nav/CachedLayer.cpp
@@ -55,7 +55,7 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
// Next, add in the new position of the layer (could be different due to a
// fixed position layer).
- const FloatPoint& position = aLayer->getPosition();
+ FloatPoint position = getGlobalPosition(aLayer);
temp.move(position.x(), position.y());
// Add in any layer translation.
@@ -71,12 +71,13 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
// Finally, clip the result to the foreground (this includes the object's
// border which does not scroll).
IntRect clip(aLayer->foregroundClip());
- clip.move(position.x(), position.y());
- result.intersect(clip);
+ if (!clip.isEmpty()) {
+ clip.move(position.x(), position.y());
+ result.intersect(clip);
+ }
- DBG_NAV_LOGD("root=%p aLayer=%p [%d]"
- " bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g)"
- " pos=(%f,%f)"
+ DBG_NAV_LOGV("root=%p aLayer=%p [%d]"
+ " bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g) pos=(%f,%f)"
" offset=(%d,%d) clip=(%d,%d,w=%d,h=%d)"
" scroll=(%d,%d) origScroll=(%d,%d)"
" result=(%d,%d,w=%d,h=%d)",
@@ -100,7 +101,8 @@ IntRect CachedLayer::unadjustBounds(const LayerAndroid* root,
IntRect temp = bounds;
// Remove the new position (i.e. fixed position elements).
- const FloatPoint& position = aLayer->getPosition();
+ FloatPoint position = getGlobalPosition(aLayer);
+
temp.move(-position.x(), -position.y());
// Remove any layer translation.
@@ -116,9 +118,34 @@ IntRect CachedLayer::unadjustBounds(const LayerAndroid* root,
// Move the bounds by the original scroll.
temp.move(-mScrollOffset.x(), -mScrollOffset.y());
+ DBG_NAV_LOGD("root=%p aLayer=%p [%d]"
+ " bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g) pos=(%f,%f)"
+ " offset=(%d,%d)"
+ " scroll=(%d,%d) origScroll=(%d,%d)"
+ " result=(%d,%d,w=%d,h=%d)",
+ root, aLayer, aLayer->uniqueId(),
+ bounds.x(), bounds.y(), bounds.width(), bounds.height(),
+ translation.x(), translation.y(), position.x(), position.y(),
+ mOffset.x(), mOffset.y(),
+ SkScalarRound(scroll.fX), SkScalarRound(scroll.fY),
+ mScrollOffset.x(), mScrollOffset.y(),
+ temp.x(), temp.y(), temp.width(), temp.height());
return temp;
}
+FloatPoint CachedLayer::getGlobalPosition(const LayerAndroid* aLayer) const
+{
+ SkPoint result = aLayer->getPosition();
+ const SkLayer* parent = aLayer->getParent();
+ while (parent) {
+ result += parent->getPosition();
+ DBG_NAV_LOGV("result=(%g,%g) parent=%p [%d]", result.fX, result.fY,
+ parent, ((LayerAndroid*) parent)->uniqueId());
+ parent = parent->getParent();
+ }
+ return result;
+}
+
const LayerAndroid* CachedLayer::layer(const LayerAndroid* root) const
{
if (!root || mLayer)
@@ -139,7 +166,14 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
temp.move(mScrollOffset.x(), mScrollOffset.y());
const LayerAndroid* aLayer = layer(root);
+ FloatPoint position;
if (aLayer) {
+ const LayerAndroid* parent = static_cast<const LayerAndroid*>
+ (aLayer->getParent());
+ if (parent) {
+ position = getGlobalPosition(parent);
+ temp.move(-position.x(), -position.y());
+ }
// Move the bounds by the scroll position of the layer.
const SkPoint& scroll = aLayer->scrollPosition();
temp.move(SkScalarToFloat(-scroll.fX), SkScalarToFloat(-scroll.fY));
@@ -147,13 +181,26 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
// Clip by the layer's foreground bounds. Since the bounds have
// already be moved local to the layer, no need to move the foreground
// clip.
- temp.intersect(IntRect(aLayer->foregroundClip()));
+ IntRect foregroundClip(aLayer->foregroundClip());
+ if (!foregroundClip.isEmpty())
+ temp.intersect(foregroundClip);
}
- DBG_NAV_LOGD("bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)"
- " result=(%d,%d,w=%d,h=%d)", bounds.x(), bounds.y(),
- bounds.width(), bounds.height(), mOffset.x(), mOffset.y(),
- temp.x(), temp.y(), temp.width(), temp.height());
+#if DEBUG_NAV_UI
+ const FloatPoint& translation = aLayer->translation();
+ SkPoint scroll = SkPoint::Make(0,0);
+ if (aLayer) scroll = aLayer->scrollPosition();
+ DBG_NAV_LOGD("aLayer=%p [%d] bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)"
+ " scrollOffset=(%d,%d) position=(%g,%g) result=(%d,%d,w=%d,h=%d)"
+ " scroll=(%d,%d) trans=(%g,%g)",
+ aLayer, aLayer ? aLayer->uniqueId() : 0,
+ bounds.x(), bounds.y(), bounds.width(), bounds.height(),
+ mOffset.x(), mOffset.y(),
+ mScrollOffset.x(), mScrollOffset.y(), position.x(), position.y(),
+ temp.x(), temp.y(), temp.width(), temp.height(),
+ scroll.fX, scroll.fY,
+ translation.x(), translation.y());
+#endif
return temp;
}
@@ -189,10 +236,14 @@ CachedLayer* CachedLayer::Debug::base() const {
void CachedLayer::Debug::print() const
{
CachedLayer* b = base();
- DUMP_NAV_LOGD(" // int mCachedNodeIndex=%d;", b->mCachedNodeIndex);
- DUMP_NAV_LOGD(" LayerAndroid* mLayer=%p;", b->mLayer);
- DUMP_NAV_LOGD(" int mOffset=(%d, %d);", b->mOffset.x(), b->mOffset.y());
- DUMP_NAV_LOGD(" int mUniqueId=%p;\n", b->mUniqueId);
+ DUMP_NAV_LOGD(" // int mCachedNodeIndex=%d;\n", b->mCachedNodeIndex);
+ DUMP_NAV_LOGD(" // LayerAndroid* mLayer=%p;\n", b->mLayer);
+ DUMP_NAV_LOGD(" // int mOffset=(%d, %d);\n",
+ b->mOffset.x(), b->mOffset.y());
+ DUMP_NAV_LOGD(" // int mScrollOffset=(%d, %d);\n",
+ b->mScrollOffset.x(), b->mScrollOffset.y());
+ DUMP_NAV_LOGD(" // int mUniqueId=%p;\n", b->mUniqueId);
+ DUMP_NAV_LOGD("%s\n", "");
}
#endif
@@ -206,9 +257,20 @@ void CachedLayer::Debug::printLayerAndroid(const LayerAndroid* layer)
++spaces;
SkRect bounds;
layer->bounds(&bounds);
- DUMP_NAV_LOGX("%.*s layer=%p [%d] (%g,%g,%g,%g) picture=%p clipped=%s",
+ DUMP_NAV_LOGD("%.*s layer=%p [%d] (%g,%g,%g,%g)"
+ " position=(%g,%g) translation=(%g,%g) anchor=(%g,%g)"
+ " matrix=(%g,%g) childMatrix=(%g,%g)"
+ " foregroundLocation=(%g,%g)"
+ " picture=%p clipped=%s\n",
spaces, " ", layer, layer->uniqueId(),
bounds.fLeft, bounds.fTop, bounds.width(), bounds.height(),
+ layer->getPosition().fX, layer->getPosition().fY,
+ layer->translation().fX, layer->translation().fY,
+ layer->getAnchorPoint().fX, layer->getAnchorPoint().fY,
+ layer->getMatrix().getTranslateX(), layer->getMatrix().getTranslateY(),
+ layer->getChildrenMatrix().getTranslateX(),
+ layer->getChildrenMatrix().getTranslateY(),
+ layer->scrollPosition().fX, layer->scrollPosition().fY,
layer->picture(), layer->m_haveClip ? "true" : "false");
for (int i = 0; i < layer->countChildren(); i++)
printLayerAndroid(layer->getChild(i));
diff --git a/WebKit/android/nav/CachedLayer.h b/WebKit/android/nav/CachedLayer.h
index a6e4e89..fd5f4a0 100644
--- a/WebKit/android/nav/CachedLayer.h
+++ b/WebKit/android/nav/CachedLayer.h
@@ -32,6 +32,7 @@
class SkPicture;
namespace WebCore {
+ class FloatPoint;
class LayerAndroid;
}
@@ -52,6 +53,7 @@ public:
IntRect unadjustBounds(const LayerAndroid* root,
const IntRect& bounds) const;
int cachedNodeIndex() const { return mCachedNodeIndex; }
+ FloatPoint getGlobalPosition(const LayerAndroid* ) const;
const LayerAndroid* layer(const LayerAndroid* root) const;
IntRect localBounds(const LayerAndroid* root, const IntRect& bounds) const;
SkPicture* picture(const LayerAndroid* root) const;
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index 1897cc0..813357c 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -27,6 +27,7 @@
#include "android_graphics.h"
#include "CachedHistory.h"
#include "CachedInput.h"
+#include "CachedLayer.h"
#include "CachedNode.h"
#include "FindCanvas.h"
#include "FloatRect.h"
@@ -1205,6 +1206,11 @@ void CachedRoot::draw(FindCanvas& canvas) const
const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect,
const CachedFrame** framePtr, int* x, int* y, bool checkForHidden) const
{
+#if DEBUG_NAV_UI
+ DBG_NAV_LOGD("rect=(%d,%d,w=%d,h=%d) xy=(%d,%d)", rect.x(), rect.y(),
+ rect.width(), rect.height(), *x, *y);
+ if (mRootLayer) CachedLayer::Debug::printRootLayerAndroid(mRootLayer);
+#endif
int best = INT_MAX;
bool inside = false;
(const_cast<CachedRoot*>(this))->resetClippedOut();
@@ -1212,8 +1218,8 @@ const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect,
const CachedNode* directHit = NULL;
const CachedNode* node = findBestAt(rect, &best, &inside, &directHit,
&directHitFramePtr, framePtr, x, y, checkForHidden);
- DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(),
- node == NULL ? NULL : node->nodePointer());
+ DBG_NAV_LOGD("node=%d (%p) xy=(%d,%d)", node == NULL ? 0 : node->index(),
+ node == NULL ? NULL : node->nodePointer(), *x, *y);
if (node == NULL) {
node = findBestHitAt(rect, framePtr, x, y);
DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(),
@@ -1840,6 +1846,7 @@ void CachedRoot::Debug::print() const
b->mHistory->mDebug.print(b);
DUMP_NAV_LOGD("// int mMaxXScroll=%d, mMaxYScroll=%d;\n",
b->mMaxXScroll, b->mMaxYScroll);
+ CachedLayer::Debug::printRootLayerAndroid(b->mRootLayer);
#ifdef DUMP_NAV_CACHE_USING_PRINTF
if (gNavCacheLogFile)
fclose(gNavCacheLogFile);
diff --git a/WebKit/android/nav/FindCanvas.h b/WebKit/android/nav/FindCanvas.h
index 903279c..2aba8e0 100644
--- a/WebKit/android/nav/FindCanvas.h
+++ b/WebKit/android/nav/FindCanvas.h
@@ -33,8 +33,9 @@
#include "SkPicture.h"
#include "SkRegion.h"
#include "SkTDArray.h"
-#include "icu/unicode/umachine.h"
-#include "wtf/Vector.h"
+
+#include <unicode/umachine.h>
+#include <wtf/Vector.h>
namespace android {
diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp
index d1f8274..4af9521 100644
--- a/WebKit/android/nav/SelectText.cpp
+++ b/WebKit/android/nav/SelectText.cpp
@@ -1305,11 +1305,11 @@ void SelectText::drawSelectionPointer(SkCanvas* canvas)
getSelectionCaret(&path);
else
getSelectionArrow(&path);
+ SkPixelXorXfermode xorMode(SK_ColorWHITE);
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(SK_ColorBLACK);
- SkPixelXorXfermode xorMode(SK_ColorWHITE);
if (m_extendSelection)
paint.setXfermode(&xorMode);
else
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 3d374d9..d754af5 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -184,6 +184,9 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
m_lastDxTime = 0;
m_ringAnimationEnd = 0;
m_baseLayer = 0;
+#if USE(ACCELERATED_COMPOSITING)
+ m_glWebViewState = 0;
+#endif
}
~WebView()
@@ -195,13 +198,10 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
m_javaGlue.m_obj = 0;
}
#if USE(ACCELERATED_COMPOSITING)
- // We remove the base layer from glWebViewState
- // as we are about to destroy it, while the
- // glWebViewState destructor will be called just after.
- // If we do not remove it here, we risk having BaseTiles
- // trying to paint using a deallocated base layer.
- IntRect rect;
- m_glWebViewState.setBaseLayer(0, rect);
+ // We must remove the m_glWebViewState prior to deleting m_baseLayer. If we
+ // do not remove it here, we risk having BaseTiles trying to paint using a
+ // deallocated base layer.
+ delete m_glWebViewState;
#endif
delete m_frameCacheUI;
delete m_navPictureUI;
@@ -416,6 +416,9 @@ bool drawGL(WebCore::IntRect& viewRect, float scale, int extras)
if (!m_baseLayer)
return false;
+ if (!m_glWebViewState)
+ m_glWebViewState = new GLWebViewState();
+
#if 0
m_glWebViewState.resetExtra(false);
#endif
@@ -445,20 +448,20 @@ bool drawGL(WebCore::IntRect& viewRect, float scale, int extras)
;
}
- unsigned int pic = m_glWebViewState.currentPictureCounter();
+ unsigned int pic = m_glWebViewState->currentPictureCounter();
+
#if 0
if (extra) {
LayerAndroid* mainPicture = new LayerAndroid(m_navPictureUI);
- m_glWebViewState.setExtra(extra, mainPicture);
+ m_glWebViewState->setExtra(extra, mainPicture);
} else {
- m_glWebViewState.resetExtra(true);
+ m_glWebViewState->resetExtra(true);
}
#endif
-
SkRect visibleRect;
calcOurContentVisibleRect(&visibleRect);
bool ret = m_baseLayer->drawGL(viewRect, visibleRect, scale);
- if (ret || m_glWebViewState.currentPictureCounter() != pic)
+ if (ret || m_glWebViewState->currentPictureCounter() != pic)
return true;
#endif
return false;
@@ -1289,7 +1292,8 @@ static void copyScrollPositionRecursive(const LayerAndroid* from,
void setBaseLayer(BaseLayerAndroid* layer, WebCore::IntRect& rect)
{
#if USE(ACCELERATED_COMPOSITING)
- m_glWebViewState.setBaseLayer(layer, rect);
+ if (m_glWebViewState)
+ m_glWebViewState->setBaseLayer(layer, rect);
#endif
if (layer) {
@@ -1345,7 +1349,7 @@ private: // local state for WebView
CursorRing m_ring;
BaseLayerAndroid* m_baseLayer;
#if USE(ACCELERATED_COMPOSITING)
- GLWebViewState m_glWebViewState;
+ GLWebViewState* m_glWebViewState;
#endif
}; // end of WebView class