diff options
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 |