diff options
25 files changed, 317 insertions, 79 deletions
@@ -153,7 +153,8 @@ LOCAL_C_INCLUDES := \ external/skia/include/utils \ external/skia/src/ports \ external/sqlite/dist \ - frameworks/base/core/jni/android/graphics + frameworks/base/core/jni/android/graphics \ + frameworks/base/include LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \ $(LOCAL_PATH)/WebCore \ diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop index 87b7885..4efb8e4 100644 --- a/ThirdPartyProject.prop +++ b/ThirdPartyProject.prop @@ -11,4 +11,4 @@ homepage=http\://webkit.org/ # Currently we track the Chromium 9.0.597 release branch: # http://trac.webkit.org/browser/branches/chromium/597 # which is WebKit r72805 + stability cherry picks. -webkit.chromiumRelease=http\://src.chromium.org/svn/releases/9.0.597.76/DEPS +webkit.chromiumRelease=http\://src.chromium.org/svn/releases/9.0.597.83/DEPS diff --git a/WebCore/Android.mk b/WebCore/Android.mk index 8aa16d9..4428a84 100644 --- a/WebCore/Android.mk +++ b/WebCore/Android.mk @@ -625,6 +625,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/SharedBufferStream.cpp \ platform/graphics/android/ShaderProgram.cpp \ platform/graphics/android/SharedTexture.cpp \ + platform/graphics/android/TextureOwner.cpp \ platform/graphics/android/TexturesGenerator.cpp \ platform/graphics/android/TilesManager.cpp \ platform/graphics/android/TiledPage.cpp \ diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog index b56a885..ae5f73f 100644 --- a/WebCore/ChangeLog +++ b/WebCore/ChangeLog @@ -1,3 +1,18 @@ +2011-01-20 Xiaomei Ji <xji@chromium.org> + + Reviewed by Dan Bernstein. + + Fix regression(r71566): PDF in RTL block might messes up text directionality. + https://bugs.webkit.org/show_bug.cgi?id=52776 + + Test: fast/dom/52776.html + + * platform/text/BidiResolver.h: + (WebCore::::checkDirectionInLowerRaiseEmbeddingLevel): + (WebCore::::lowerExplicitEmbeddingLevel): + (WebCore::::raiseExplicitEmbeddingLevel): + (WebCore::::createBidiRunsForLine): + 2011-01-12 Kenichi Ishibashi <bashi@google.com> Reviewed by Kent Tamura. diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp index 3eeacec..9107b51 100644 --- a/WebCore/bindings/v8/V8GCController.cpp +++ b/WebCore/bindings/v8/V8GCController.cpp @@ -453,8 +453,7 @@ void V8GCController::checkMemoryUsage() // Query the PlatformBridge for memory thresholds as these vary device to device. static const int lowUsageMB = PlatformBridge::lowMemoryUsageMB(); static const int highUsageMB = PlatformBridge::highMemoryUsageMB(); - // We use a delta of -1 to ensure that when we are in a low memory situation we always trigger a GC. - static const int highUsageDeltaMB = -1; + static const int highUsageDeltaMB = PlatformBridge::highUsageDeltaMB(); #else return; #endif diff --git a/WebCore/platform/android/PlatformBridge.h b/WebCore/platform/android/PlatformBridge.h index c67c865..7d54ae5 100644 --- a/WebCore/platform/android/PlatformBridge.h +++ b/WebCore/platform/android/PlatformBridge.h @@ -145,6 +145,7 @@ public: // Memory details for V8 GC static int lowMemoryUsageMB(); static int highMemoryUsageMB(); + static int highUsageDeltaMB(); static int memoryUsageMB(); static int actualMemoryUsageMB(); }; diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp index 6d9fe04..dd69c4c 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp @@ -140,6 +140,7 @@ bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner) if (m_owner && m_owner != owner) m_owner->removeTexture(this); m_owner = owner; + owner->addOwned(this); return true; } return false; @@ -147,8 +148,11 @@ bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner) void BackedDoubleBufferedTexture::release(TextureOwner* owner) { - if (m_owner == owner) + if (m_owner == owner) { + m_owner->removeOwned(this); m_owner = 0; + } + } } // namespace WebCore diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 57a53ab..52ef8ca 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -166,25 +166,28 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale) && (m_glWebViewState->futureViewport() != viewportTileBounds)) prepareNextTiledPage = true; + bool zooming = false; + if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest) { + m_glWebViewState->unlockBaseLayerUpdate(); + zooming = true; + } + // Let's prepare the page if needed if (prepareNextTiledPage) { TiledPage* nextTiledPage = m_glWebViewState->backPage(); nextTiledPage->setScale(scale); m_glWebViewState->setFutureViewport(viewportTileBounds); + m_glWebViewState->unlockBaseLayerUpdate(); nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds); } - bool zooming = false; - if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest) - zooming = true; - float transparency = 1; bool doSwap = false; // If we fired a request, let's check if it's ready to use if (m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale) { TiledPage* nextTiledPage = m_glWebViewState->backPage(); - if (nextTiledPage->ready(viewportTileBounds)) + if (nextTiledPage->ready(viewportTileBounds, m_glWebViewState->futureScale())) m_glWebViewState->setScaleRequestState(GLWebViewState::kReceivedNewScale); } @@ -221,26 +224,29 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale) // out of date. When standing still on the other hand, we wait until // the back page is ready before swapping the pages, ensuring that the // displayed content is in sync. - if (!zooming && !m_glWebViewState->moving()) { - if (!tiledPage->ready(preZoomBounds)) { + if (!doSwap && !zooming && !m_glWebViewState->moving()) { + if (!tiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) { + m_glWebViewState->lockBaseLayerUpdate(); nextTiledPage->setScale(m_glWebViewState->currentScale()); nextTiledPage->prepare(goingDown, goingLeft, preZoomBounds); } - if (nextTiledPage->ready(preZoomBounds)) { + if (nextTiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) { nextTiledPage->draw(transparency, preZoomBounds); + m_glWebViewState->unlockBaseLayerUpdate(); doSwap = true; } else { tiledPage->draw(transparency, preZoomBounds); } } else { // Ask for the tiles and draw -- tiles may be out of date. + m_glWebViewState->unlockBaseLayerUpdate(); tiledPage->prepare(goingDown, goingLeft, preZoomBounds); tiledPage->draw(transparency, preZoomBounds); } bool ret = false; if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest - || !tiledPage->ready(preZoomBounds)) + || !tiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) ret = true; if (doSwap) { diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp index 326f360..252eeab 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -139,6 +139,8 @@ void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture, const IntRect& rect) { android::Mutex::Autolock lock(m_baseLayerLock); + if (!m_baseLayerUpdate) + return; layer->setExtra(picture); if (!rect.isEmpty()) inval(rect); diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index 95d4ff4..6426716 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -77,7 +77,8 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), m_uniqueId(++gUniqueId), m_drawingTexture(0), m_reservedTexture(0), - m_pictureUsed(0), + m_pictureUsed(-1), + m_requestSent(false), m_scale(1) { m_backgroundColor = 0; @@ -94,7 +95,8 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), m_extra(0), // deliberately not copied m_uniqueId(layer.m_uniqueId), m_drawingTexture(0), - m_reservedTexture(0) + m_reservedTexture(0), + m_requestSent(false) { m_isFixed = layer.m_isFixed; m_contentsImage = layer.m_contentsImage; @@ -144,6 +146,7 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), m_uniqueId(-1), m_drawingTexture(0), m_reservedTexture(0), + m_requestSent(false), m_scale(1) { m_backgroundColor = 0; @@ -222,8 +225,9 @@ bool LayerAndroid::evaluateAnimations(double time) const return hasRunningAnimations; } -void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> anim) +void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim) { + RefPtr<AndroidAnimation> anim = prpAnim; if (m_animations.get(anim->name())) removeAnimation(anim->name()); m_animations.add(anim->name(), anim); @@ -641,10 +645,20 @@ void LayerAndroid::createGLTextures() if (!needsScheduleRepaint(reservedTexture)) return; - XLOG("We schedule a paint for layer %d, because isReady %d or m_dirty %d, using texture %x", - uniqueId(), m_reservedTexture->isReady(), m_dirty, m_reservedTexture); - PaintLayerOperation* operation = new PaintLayerOperation(this); - TilesManager::instance()->scheduleOperation(operation); + m_atomicSync.lock(); + if (!m_requestSent) { + m_requestSent = true; + m_atomicSync.unlock(); + XLOG("We schedule a paint for layer %d (%x), because isReady %d or m_dirty %d, using texture %x (%d, %d)", + uniqueId(), this, m_reservedTexture->isReady(), m_dirty, m_reservedTexture, + m_reservedTexture->rect().width(), m_reservedTexture->rect().height()); + PaintLayerOperation* operation = new PaintLayerOperation(this); + TilesManager::instance()->scheduleOperation(operation); + } else { + XLOG("We don't schedule a paint for layer %d (%x), because we already sent a request", + uniqueId(), this); + m_atomicSync.unlock(); + } } bool LayerAndroid::needsScheduleRepaint(LayerTexture* texture) @@ -652,9 +666,11 @@ bool LayerAndroid::needsScheduleRepaint(LayerTexture* texture) if (!texture) return false; - if (!m_pictureUsed || texture->pictureUsed() != m_pictureUsed) { - XLOG("We mark layer %d as dirty because: m_pictureUsed(%d == 0?), texture picture used %x", - uniqueId(), m_pictureUsed, texture->pictureUsed()); + if (!m_pictureUsed == -1 || texture->pictureUsed() != m_pictureUsed) { + XLOG("We mark layer %d (%x) as dirty because: m_pictureUsed(%d == 0?), texture picture used %x", + uniqueId(), this, m_pictureUsed, texture->pictureUsed()); + if (m_pictureUsed == -1) + m_pictureUsed = 0; texture->setPictureUsed(m_pictureUsed); m_dirty = true; } @@ -689,6 +705,8 @@ bool LayerAndroid::drawGL(SkMatrix& matrix) // move the drawing depending on where the texture is on the layer TransformationMatrix m = drawTransform(); m.translate(textureRect.x(), textureRect.y()); + XLOG("LayerAndroid %d %x (%.2f, %.2f) drawGL (texture %x, %d, %d, %d, %d)", uniqueId(), this, getWidth(), getHeight(), + m_drawingTexture, textureRect.x(), textureRect.y(), textureRect.width(), textureRect.height()); TilesManager::instance()->shader()->drawLayerQuad(m, bounds, textureInfo->m_textureId, m_drawOpacity); @@ -750,7 +768,8 @@ void LayerAndroid::paintBitmapGL() return; } - XLOG("LayerAndroid paintBitmapGL (layer %d), texture used %x", uniqueId(), texture); + XLOG("LayerAndroid paintBitmapGL (layer %d), texture used %x (%d, %d)", uniqueId(), texture, + texture->rect().width(), texture->rect().height()); // We need to mark the texture as busy before relinquishing the lock // -- so that TilesManager::cleanupLayersTextures() can check if the texture @@ -770,7 +789,7 @@ void LayerAndroid::paintBitmapGL() return; } - XLOG("LayerAndroid %d paintBitmapGL WE ARE PAINTING", uniqueId()); + XLOG("LayerAndroid %d %x (%.2f, %.2f) paintBitmapGL WE ARE PAINTING", uniqueId(), this, getWidth(), getHeight()); SkCanvas* canvas = texture->canvas(); float scale = texture->scale(); @@ -784,10 +803,17 @@ void LayerAndroid::paintBitmapGL() canvas->restore(); XLOG("LayerAndroid %d paintBitmapGL PAINTING DONE, updating the texture", uniqueId()); + texture->producerUpdate(textureInfo); + + while (!texture->isReady()) { + TextureInfo* textureInfo = texture->producerLock(); + texture->producerUpdate(textureInfo); + } + m_atomicSync.lock(); m_dirty = false; + m_requestSent = false; m_atomicSync.unlock(); - texture->producerUpdate(textureInfo); XLOG("LayerAndroid %d paintBitmapGL UPDATING DONE", uniqueId()); } diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 95f8547..72eba0f 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -301,6 +301,9 @@ private: bool m_dirty; unsigned int m_pictureUsed; + // painting request sent + bool m_requestSent; + float m_scale; // This mutex serves two purposes. (1) It ensures that certain operations diff --git a/WebCore/platform/graphics/android/PaintLayerOperation.cpp b/WebCore/platform/graphics/android/PaintLayerOperation.cpp index dd81d9a..35867c7 100644 --- a/WebCore/platform/graphics/android/PaintLayerOperation.cpp +++ b/WebCore/platform/graphics/android/PaintLayerOperation.cpp @@ -33,7 +33,7 @@ bool PaintLayerOperation::operator==(const QueuedOperation* operation) if (operation->type() != type()) return false; const PaintLayerOperation* op = static_cast<const PaintLayerOperation*>(operation); - return op->m_layer == m_layer; + return op->m_layer->uniqueId() == m_layer->uniqueId(); } void PaintLayerOperation::run() diff --git a/WebCore/platform/graphics/android/TextureOwner.cpp b/WebCore/platform/graphics/android/TextureOwner.cpp new file mode 100644 index 0000000..6a6845a --- /dev/null +++ b/WebCore/platform/graphics/android/TextureOwner.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TextureOwner.h" + +#include "BackedDoubleBufferedTexture.h" + +namespace WebCore { + +TextureOwner::~TextureOwner() +{ + if (m_ownedTextures.size()) { + // This TextureOwner owns textures still! + HashSet<BackedDoubleBufferedTexture*>::iterator it = m_ownedTextures.begin(); + for (; it != m_ownedTextures.end(); ++it) + (*it)->release(this); + } +} + +void TextureOwner::addOwned(BackedDoubleBufferedTexture* t) +{ + // This TextureOwner now owns texture t + m_ownedTextures.add(t); +} + +void TextureOwner::removeOwned(BackedDoubleBufferedTexture* t) +{ + // This textureowner no longer owns texture t. + m_ownedTextures.remove(t); +} +} diff --git a/WebCore/platform/graphics/android/TextureOwner.h b/WebCore/platform/graphics/android/TextureOwner.h index 7b0673d..c421e8a 100644 --- a/WebCore/platform/graphics/android/TextureOwner.h +++ b/WebCore/platform/graphics/android/TextureOwner.h @@ -26,6 +26,8 @@ #ifndef TextureOwner_h #define TextureOwner_h +#include <wtf/HashSet.h> + namespace WebCore { class TiledPage; @@ -33,9 +35,15 @@ class BackedDoubleBufferedTexture; class TextureOwner { public: - virtual ~TextureOwner() {} + virtual ~TextureOwner(); virtual void removeTexture(BackedDoubleBufferedTexture* texture) = 0; virtual TiledPage* page() = 0; + + void addOwned(BackedDoubleBufferedTexture*); + void removeOwned(BackedDoubleBufferedTexture*); + +private: + WTF::HashSet<BackedDoubleBufferedTexture*> m_ownedTextures; }; } diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp index 79509dd..ca6a6c4 100644 --- a/WebCore/platform/graphics/android/TiledPage.cpp +++ b/WebCore/platform/graphics/android/TiledPage.cpp @@ -179,8 +179,10 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y void TiledPage::updateTileState(const SkIRect& tileBounds) { - if (!m_glWebViewState || tileBounds.isEmpty()) + if (!m_glWebViewState || tileBounds.isEmpty()) { + m_invalRegion.setEmpty(); return; + } const int nbTilesWidth = tileBounds.width(); const int nbTilesHeight = tileBounds.height(); @@ -216,7 +218,7 @@ void TiledPage::updateTileState(const SkIRect& tileBounds) int d = std::max(dx, dy); - XLOG("setTileLevel tile: %x, fxy(%d, %d), level: %d", tile, firstTileX, firstTileY, d); + XLOG("setTileLevel tile: %x, fxy(%d, %d), level: %d", tile, tileBounds.fLeft, tileBounds.fTop, d); tile.setUsedLevel(d); } @@ -233,7 +235,6 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound // update the tiles distance from the viewport updateTileState(tileBounds); m_prepare = true; - m_glWebViewState->lockBaseLayerUpdate(); int firstTileX = tileBounds.fLeft; int firstTileY = tileBounds.fTop; @@ -289,7 +290,7 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound TilesManager::instance()->scheduleOperation(operation); } -bool TiledPage::ready(const SkIRect& tileBounds) +bool TiledPage::ready(const SkIRect& tileBounds, float scale) { if (!m_glWebViewState) return false; @@ -297,6 +298,9 @@ bool TiledPage::ready(const SkIRect& tileBounds) if (!m_invalRegion.isEmpty() && !m_prepare) return false; + if (m_scale != scale) + return false; + for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) { for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) { BaseTile* t = getBaseTile(x, y); @@ -305,7 +309,6 @@ bool TiledPage::ready(const SkIRect& tileBounds) } } m_prepare = false; - m_glWebViewState->unlockBaseLayerUpdate(); return true; } diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h index a194ba5..a7402b9 100644 --- a/WebCore/platform/graphics/android/TiledPage.h +++ b/WebCore/platform/graphics/android/TiledPage.h @@ -62,7 +62,7 @@ public: // prepare the page for display on the screen void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds); // check to see if the page is ready for display - bool ready(const SkIRect& tileBounds); + bool ready(const SkIRect& tileBounds, float scale); // draw the page on the screen void draw(float transparency, const SkIRect& tileBounds); diff --git a/WebCore/platform/text/BidiResolver.h b/WebCore/platform/text/BidiResolver.h index 1f87115..6018c3f 100644 --- a/WebCore/platform/text/BidiResolver.h +++ b/WebCore/platform/text/BidiResolver.h @@ -314,23 +314,13 @@ void BidiResolver<Iterator, Run>::checkDirectionInLowerRaiseEmbeddingLevel() using namespace WTF::Unicode; ASSERT(m_status.eor != OtherNeutral || eor.atEnd()); - // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last - // Bidi control characters are included into BidiRun, so last direction - // could be one of the bidi embeddings when there are nested embeddings. - // For example: "‪‫....." - ASSERT(m_status.last == EuropeanNumberSeparator - || m_status.last == EuropeanNumberTerminator - || m_status.last == CommonNumberSeparator - || m_status.last == BoundaryNeutral - || m_status.last == BlockSeparator - || m_status.last == SegmentSeparator - || m_status.last == WhiteSpaceNeutral - || m_status.last == OtherNeutral - || m_status.last == RightToLeftEmbedding - || m_status.last == LeftToRightEmbedding - || m_status.last == RightToLeftOverride - || m_status.last == LeftToRightOverride - || m_status.last == PopDirectionalFormat); + ASSERT(m_status.last != NonSpacingMark + && m_status.last != BoundaryNeutral + && m_status.last != RightToLeftEmbedding + && m_status.last != LeftToRightEmbedding + && m_status.last != RightToLeftOverride + && m_status.last != LeftToRightOverride + && m_status.last != PopDirectionalFormat); if (m_direction == OtherNeutral) m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft; } @@ -342,6 +332,7 @@ void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Dire if (!emptyRun && eor != last) { checkDirectionInLowerRaiseEmbeddingLevel(); + // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last if (from == LeftToRight) { // bidi.sor ... bidi.eor ... bidi.last L if (m_status.eor == EuropeanNumber) { @@ -377,6 +368,7 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire if (!emptyRun && eor != last) { checkDirectionInLowerRaiseEmbeddingLevel(); + // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last if (to == LeftToRight) { // bidi.sor ... bidi.eor ... bidi.last L if (m_status.eor == EuropeanNumber) { @@ -866,6 +858,11 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, boo break; case NonSpacingMark: case BoundaryNeutral: + case RightToLeftEmbedding: + case LeftToRightEmbedding: + case RightToLeftOverride: + case LeftToRightOverride: + case PopDirectionalFormat: // ignore these break; case EuropeanNumber: diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index 20ad5b9..cb1efe1 100644 --- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -145,7 +145,11 @@ void ChromeClientAndroid::unfocus() { notImplemented(); } bool ChromeClientAndroid::canTakeFocus(FocusDirection) { notImplemented(); return false; } void ChromeClientAndroid::takeFocus(FocusDirection) { notImplemented(); } -void ChromeClientAndroid::focusedNodeChanged(Node*) { notImplemented(); } +void ChromeClientAndroid::focusedNodeChanged(Node* node) +{ + android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->focusNodeChanged(node); +} + void ChromeClientAndroid::focusedFrameChanged(Frame*) { notImplemented(); } Page* ChromeClientAndroid::createWindow(Frame* frame, const FrameLoadRequest&, diff --git a/WebKit/android/WebCoreSupport/MemoryUsage.cpp b/WebKit/android/WebCoreSupport/MemoryUsage.cpp index f799a18..32cdebf 100644 --- a/WebKit/android/WebCoreSupport/MemoryUsage.cpp +++ b/WebKit/android/WebCoreSupport/MemoryUsage.cpp @@ -78,4 +78,4 @@ int MemoryUsage::memoryUsageMb(bool forceFresh) int MemoryUsage::m_lowMemoryUsageMb = 0; int MemoryUsage::m_highMemoryUsageMb = 0; - +int MemoryUsage::m_highUsageDeltaMb = 0; diff --git a/WebKit/android/WebCoreSupport/MemoryUsage.h b/WebKit/android/WebCoreSupport/MemoryUsage.h index 899fd08..2a3d7ed 100644 --- a/WebKit/android/WebCoreSupport/MemoryUsage.h +++ b/WebKit/android/WebCoreSupport/MemoryUsage.h @@ -31,12 +31,15 @@ public: static int memoryUsageMb(bool forceFresh); static int lowMemoryUsageMb() { return m_lowMemoryUsageMb; } static int highMemoryUsageMb() { return m_highMemoryUsageMb; } + static int highUsageDeltaMb() { return m_highUsageDeltaMb; } static void setHighMemoryUsageMb(int highMemoryUsageMb) { m_highMemoryUsageMb = highMemoryUsageMb; } static void setLowMemoryUsageMb(int lowMemoryUsageMb) { m_lowMemoryUsageMb = lowMemoryUsageMb; } + static void setHighUsageDeltaMb(int highUsageDeltaMb) { m_highUsageDeltaMb = highUsageDeltaMb; } private: static int m_lowMemoryUsageMb; static int m_highMemoryUsageMb; + static int m_highUsageDeltaMb; }; #endif diff --git a/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/WebKit/android/WebCoreSupport/PlatformBridge.cpp index baeddb2..0bc2e3c 100644 --- a/WebKit/android/WebCoreSupport/PlatformBridge.cpp +++ b/WebKit/android/WebCoreSupport/PlatformBridge.cpp @@ -201,6 +201,11 @@ int PlatformBridge::highMemoryUsageMB() return MemoryUsage::highMemoryUsageMb(); } +int PlatformBridge::highUsageDeltaMB() +{ + return MemoryUsage::highUsageDeltaMb(); +} + int PlatformBridge::memoryUsageMB() { return MemoryUsage::memoryUsageMb(false); diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp index 3712135..4dd183b 100644 --- a/WebKit/android/jni/WebSettings.cpp +++ b/WebKit/android/jni/WebSettings.cpp @@ -509,6 +509,11 @@ public: if (str) { WTF::String localStorageDatabasePath = jstringToWtfString(env,str); if (localStorageDatabasePath.length()) { + localStorageDatabasePath = WebCore::pathByAppendingComponent( + localStorageDatabasePath, "localstorage"); + // We need 770 for folders + mkdir(localStorageDatabasePath.utf8().data(), + permissionFlags660 | S_IXUSR | S_IXGRP); s->setLocalStorageDatabasePath(localStorageDatabasePath); } } diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 6fd7b9c..39f6f2d 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -240,6 +240,7 @@ struct WebViewCoreFields { jfieldID m_drawIsPaused; jfieldID m_lowMemoryUsageMb; jfieldID m_highMemoryUsageMb; + jfieldID m_highUsageDeltaMb; } gWebViewCoreFields; // ---------------------------------------------------------------------------- @@ -400,6 +401,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m MemoryUsage::setLowMemoryUsageMb(env->GetIntField(javaWebViewCore, gWebViewCoreFields.m_lowMemoryUsageMb)); MemoryUsage::setHighMemoryUsageMb(env->GetIntField(javaWebViewCore, gWebViewCoreFields.m_highMemoryUsageMb)); + MemoryUsage::setHighUsageDeltaMb(env->GetIntField(javaWebViewCore, gWebViewCoreFields.m_highUsageDeltaMb)); WebViewCore::addInstance(this); @@ -457,6 +459,7 @@ void WebViewCore::reset(bool fromConstructor) } m_lastFocused = 0; + m_blurringNodePointer = 0; m_lastFocusedBounds = WebCore::IntRect(0,0,0,0); m_focusBoundsChanged = false; m_lastFocusedSelStart = 0; @@ -1192,6 +1195,7 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, int osw = m_screenWidth; int osh = m_screenHeight; int otw = m_textWrapWidth; + float oldScale = m_scale; DBG_NAV_LOGD("old:(w=%d,h=%d,sw=%d,scale=%g) new:(w=%d,h=%d,sw=%d,scale=%g)", ow, oh, osw, m_scale, width, height, screenWidth, scale); m_screenWidth = screenWidth; @@ -1296,7 +1300,9 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, // If this was in response to touching a textfield and showing the IME, // the IME may now cover textfield. Bring it back into view. - revealSelection(); + // If the scale changed, however, this was the result of a zoom. + if (oldScale == m_scale) + revealSelection(); // update the currently visible screen as perceived by the plugin sendPluginVisibleScreen(); } @@ -1429,20 +1435,29 @@ WTF::String WebViewCore::requestLabel(WebCore::Frame* frame, return WTF::String(); } -static bool isContentEditable(WebCore::Node* node) +static bool isContentEditable(const WebCore::Node* node) { if (!node) return false; return node->document()->frame()->selection()->isContentEditable(); } +// Returns true if the node is a textfield, textarea, or contentEditable +static bool isTextInput(const WebCore::Node* node) +{ + if (isContentEditable(node)) + return true; + if (!node) + return false; + WebCore::RenderObject* renderer = node->renderer(); + return renderer && (renderer->isTextField() || renderer->isTextArea()); +} + void WebViewCore::revealSelection() { WebCore::Node* focus = currentFocus(); if (!focus) return; - WebCore::RenderObject* renderer = focus->renderer(); - if ((!renderer || (!renderer->isTextField() && !renderer->isTextArea())) - && !isContentEditable(focus)) + if (!isTextInput(focus)) return; WebCore::Frame* focusedFrame = focus->document()->frame(); if (!focusedFrame->page()->focusController()->isActive()) @@ -2970,7 +2985,6 @@ static void scrollLayer(WebCore::RenderObject* renderer, WebCore::IntPoint* pos) // in which case, 'fake' is set to true bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr, bool fake, int scrollY) { - m_lastClickWasOnTextInput = false; bool valid = framePtr == NULL || CacheBuilder::validNode(m_mainFrame, framePtr, nodePtr); WebFrame* webFrame = WebFrame::getWebFrame(m_mainFrame); @@ -3028,12 +3042,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node static_cast<RenderTextControl*>(renderer)->setScrollTop(scrollY); else scrollLayer(renderer, &m_mousePos); - if (isContentEditable(nodePtr) || (renderer - && (renderer->isTextArea() || renderer->isTextField()))) { - // The user clicked on a text input field. If this causes a blur event - // on a different text input, do not hide the keyboard in formDidBlur - m_lastClickWasOnTextInput = true; - } } if (!valid || !framePtr) framePtr = m_mainFrame; @@ -3049,8 +3057,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp); webFrame->setUserInitiatedAction(false); - m_lastClickWasOnTextInput = false; - // If the user clicked on a textfield, make the focusController active // so we show the blinking cursor. WebCore::Node* focusNode = currentFocus(); @@ -3115,14 +3121,24 @@ void WebViewCore::popupReply(const int* array, int count) void WebViewCore::formDidBlur(const WebCore::Node* node) { - // This blur is the result of clicking on a different input. Do not hide - // the keyboard, since it will just be opened again. - if (m_lastClickWasOnTextInput) return; + // If the blur is on a text input, keep track of the node so we can + // hide the soft keyboard when the new focus is set, if it is not a + // text input. + if (isTextInput(node)) + m_blurringNodePointer = reinterpret_cast<int>(node); +} - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->CallVoidMethod(m_javaGlue->object(env).get(), - m_javaGlue->m_formDidBlur, reinterpret_cast<int>(node)); - checkException(env); +void WebViewCore::focusNodeChanged(const WebCore::Node* newFocus) +{ + if (!m_blurringNodePointer) + return; + if (!isTextInput(newFocus)) { + JNIEnv* env = JSC::Bindings::getJNIEnv(); + env->CallVoidMethod(m_javaGlue->object(env).get(), + m_javaGlue->m_formDidBlur, m_blurringNodePointer); + checkException(env); + } + m_blurringNodePointer = 0; } void WebViewCore::addMessageToConsole(const WTF::String& message, unsigned int lineNumber, const WTF::String& sourceID, int msgLevel) { @@ -3493,12 +3509,19 @@ bool WebViewCore::drawIsPaused() const #if USE(CHROME_NETWORK_STACK) void WebViewCore::setWebRequestContextUserAgent() { - webRequestContext()->setUserAgent(WebFrame::getWebFrame(m_mainFrame)->userAgentForURL(0)); // URL not used + // We cannot create a WebRequestContext, because we might not know it this is a private tab or not yet + if (m_webRequestContext) + m_webRequestContext->setUserAgent(WebFrame::getWebFrame(m_mainFrame)->userAgentForURL(0)); // URL not used } -void WebViewCore::setWebRequestContextCacheMode(int mode) +void WebViewCore::setWebRequestContextCacheMode(int cacheMode) { - webRequestContext()->setCacheMode(mode); + m_cacheMode = cacheMode; + // We cannot create a WebRequestContext, because we might not know it this is a private tab or not yet + if (!m_webRequestContext) + return; + + m_webRequestContext->setCacheMode(cacheMode); } WebRequestContext* WebViewCore::webRequestContext() @@ -3506,6 +3529,8 @@ WebRequestContext* WebViewCore::webRequestContext() if (!m_webRequestContext) { Settings* settings = mainFrame()->settings(); m_webRequestContext = new WebRequestContext(settings && settings->privateBrowsingEnabled()); + setWebRequestContextUserAgent(); + setWebRequestContextCacheMode(m_cacheMode); } return m_webRequestContext.get(); } @@ -4361,6 +4386,7 @@ int registerWebViewCore(JNIEnv* env) "Unable to find android/webkit/WebViewCore.mDrawIsPaused"); gWebViewCoreFields.m_lowMemoryUsageMb = env->GetFieldID(widget, "mLowMemoryUsageThresholdMb", "I"); gWebViewCoreFields.m_highMemoryUsageMb = env->GetFieldID(widget, "mHighMemoryUsageThresholdMb", "I"); + gWebViewCoreFields.m_highUsageDeltaMb = env->GetFieldID(widget, "mHighUsageDeltaMb", "I"); gWebViewCoreStaticMethods.m_isSupportedMediaMimeType = env->GetStaticMethodID(widget, "isSupportedMediaMimeType", "(Ljava/lang/String;)Z"); diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 0338104..611ee59 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -136,6 +136,7 @@ namespace android { * @param Node The Node that blurred. */ void formDidBlur(const WebCore::Node*); + void focusNodeChanged(const WebCore::Node*); /** * Scroll to an absolute position. @@ -601,7 +602,7 @@ namespace android { WebCoreReply* m_popupReply; WebCore::Node* m_lastFocused; WebCore::IntRect m_lastFocusedBounds; - bool m_lastClickWasOnTextInput; + int m_blurringNodePointer; int m_lastFocusedSelStart; int m_lastFocusedSelEnd; PictureSet m_content; // the set of pictures to draw @@ -635,6 +636,7 @@ namespace android { bool m_check_domtree_version; PageGroup* m_groupForVisitedLinks; bool m_isPaused; + int m_cacheMode; SkTDArray<PluginWidgetAndroid*> m_plugins; WebCore::Timer<WebViewCore> m_pluginInvalTimer; diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index a9835bd..683c2a3 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -42,6 +42,7 @@ #include "IntRect.h" #include "LayerAndroid.h" #include "Node.h" +#include "utils/Functor.h" #include "PlatformGraphicsContext.h" #include "PlatformString.h" #include "ScrollableLayerAndroid.h" @@ -187,6 +188,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : m_lastDxTime = 0; m_ringAnimationEnd = 0; m_baseLayer = 0; + m_glDrawFunctor = 0; #if USE(ACCELERATED_COMPOSITING) m_glWebViewState = 0; #endif @@ -209,6 +211,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : delete m_frameCacheUI; delete m_navPictureUI; m_baseLayer->safeUnref(); + delete m_glDrawFunctor; } WebViewCore* getWebViewCore() const { @@ -1424,6 +1427,15 @@ bool hasContent() { return !m_baseLayer->content()->isEmpty(); } +void setFunctor(Functor* functor) { + delete m_glDrawFunctor; + m_glDrawFunctor = functor; +} + +Functor* getFunctor() { + return m_glDrawFunctor; +} + private: // local state for WebView // private to getFrameCache(); other functions operate in a different thread CachedRoot* m_frameCacheUI; // navigation data ready for use @@ -1439,11 +1451,47 @@ private: // local state for WebView FindOnPage m_findOnPage; CursorRing m_ring; BaseLayerAndroid* m_baseLayer; + Functor* m_glDrawFunctor; #if USE(ACCELERATED_COMPOSITING) GLWebViewState* m_glWebViewState; #endif }; // end of WebView class + +/** + * This class holds a function pointer and parameters for calling drawGL into a specific + * viewport. The pointer to the Functor will be put on a framework display list to be called + * when the display list is replayed. + */ +class GLDrawFunctor : Functor { + public: + GLDrawFunctor(WebView* _wvInstance, + bool(WebView::*_funcPtr)(WebCore::IntRect&, jfloat, jint), + WebCore::IntRect _viewRect, float _scale, int _extras) { + wvInstance = _wvInstance; + funcPtr = _funcPtr; + viewRect = _viewRect; + scale = _scale; + extras = _extras; + }; + status_t operator()() { + bool retVal = (*wvInstance.*funcPtr)(viewRect, scale, extras); + // return 1 if invalidation needed, 0 otherwise + return retVal ? 1 : 0; + } + void updateRect(WebCore::IntRect& _viewRect) { + viewRect = _viewRect; + } + private: + WebView* wvInstance; + bool (WebView::*funcPtr)(WebCore::IntRect&, float, int); + WebCore::IntRect viewRect; + jfloat scale; + jint extras; +}; + + + /* * Native JNI methods */ @@ -1668,6 +1716,27 @@ static jint nativeDraw(JNIEnv *env, jobject obj, jobject canv, jint color, return reinterpret_cast<jint>(GET_NATIVE_VIEW(env, obj)->draw(canvas, color, extras, split)); } +static jint nativeGetDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect, + jfloat scale, jint extras) { + WebCore::IntRect viewRect = jrect_to_webrect(env, jrect); + WebView *wvInstance = GET_NATIVE_VIEW(env, obj); + GLDrawFunctor* functor = new GLDrawFunctor(wvInstance, &android::WebView::drawGL, + viewRect, scale, extras); + wvInstance->setFunctor((Functor*) functor); + return (jint)functor; +} + +static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect) { + WebView *wvInstance = GET_NATIVE_VIEW(env, obj); + if (wvInstance != NULL) { + GLDrawFunctor* functor = (GLDrawFunctor*) wvInstance->getFunctor(); + if (functor != NULL) { + WebCore::IntRect viewRect = jrect_to_webrect(env, jrect); + functor->updateRect(viewRect); + } + } +} + static bool nativeDrawGL(JNIEnv *env, jobject obj, jobject jrect, jfloat scale, jint extras) { @@ -2353,6 +2422,10 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeDestroy }, { "nativeDraw", "(Landroid/graphics/Canvas;IIZ)I", (void*) nativeDraw }, + { "nativeGetDrawGLFunction", "(Landroid/graphics/Rect;FI)I", + (void*) nativeGetDrawGLFunction }, + { "nativeUpdateDrawGLFunction", "(Landroid/graphics/Rect;)V", + (void*) nativeUpdateDrawGLFunction }, { "nativeDrawGL", "(Landroid/graphics/Rect;FI)Z", (void*) nativeDrawGL }, { "nativeDumpDisplayTree", "(Ljava/lang/String;)V", |