diff options
-rw-r--r-- | Android.mk | 3 | ||||
-rw-r--r-- | WebCore/Android.mk | 2 | ||||
-rw-r--r-- | WebCore/WebCorePrefixAndroid.h | 6 | ||||
-rw-r--r-- | WebCore/loader/FrameLoader.cpp | 11 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BitmapAllocatorAndroid.cpp | 63 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BitmapAllocatorAndroid.h | 47 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/FontAndroid.cpp | 67 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/FontDataAndroid.cpp | 8 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GlyphMapAndroid.cpp | 30 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/ImageSourceAndroid.cpp | 74 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/SharedBufferStream.cpp | 45 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/SharedBufferStream.h | 46 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 38 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 2 |
14 files changed, 341 insertions, 101 deletions
@@ -80,11 +80,12 @@ LOCAL_LDLIBS += -lpthread -ldl # Build our list of include paths LOCAL_C_INCLUDES := \ - $(call include-path-for, corecg graphics) \ $(JNI_H_INCLUDE) \ external/icu4c/common \ external/icu4c/i18n \ external/libxml2/include \ + external/skia/emoji \ + external/skia/include/core \ external/skia/include/effects \ external/skia/include/images \ external/skia/include/ports \ diff --git a/WebCore/Android.mk b/WebCore/Android.mk index 3c5970c..5b0880e 100644 --- a/WebCore/Android.mk +++ b/WebCore/Android.mk @@ -630,6 +630,7 @@ LOCAL_SRC_FILES := \ platform/graphics/SimpleFontData.cpp \ platform/graphics/StringTruncator.cpp \ \ + platform/graphics/android/BitmapAllocatorAndroid.cpp \ platform/graphics/android/FontAndroid.cpp \ platform/graphics/android/FontCacheAndroid.cpp \ platform/graphics/android/FontCustomPlatformData.cpp \ @@ -644,6 +645,7 @@ LOCAL_SRC_FILES := \ platform/graphics/android/PathAndroid.cpp \ platform/graphics/android/PatternAndroid.cpp \ platform/graphics/android/PlatformGraphicsContext.cpp \ + platform/graphics/android/SharedBufferStream.cpp \ platform/graphics/android/TransformationMatrixAndroid.cpp \ platform/graphics/android/android_graphics.cpp \ \ diff --git a/WebCore/WebCorePrefixAndroid.h b/WebCore/WebCorePrefixAndroid.h index 3c45b69..d69c122 100644 --- a/WebCore/WebCorePrefixAndroid.h +++ b/WebCore/WebCorePrefixAndroid.h @@ -156,3 +156,9 @@ typedef unsigned char flex_uint8_t; // Enable dumping the display tree to a file (triggered in WebView.java) #define ANDROID_DUMP_DISPLAY_TREE + +// Allow webkit to initiate scroll when going to an anchor on a page +// The implementation is not acceptable to webkit. Either scrollRectToVisible +// needs additional flavor or parameter to know that it can't be ignored, +// and/or script engine must keep whether event was user initiated. +#define ANDROID_SCROLL_ON_GOTO_ANCHOR diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp index adaea61..151ab37 100644 --- a/WebCore/loader/FrameLoader.cpp +++ b/WebCore/loader/FrameLoader.cpp @@ -113,6 +113,10 @@ #include "RenderArena.h" #endif +#if PLATFORM(ANDROID) +#include "WebCoreFrameBridge.h" +#endif + namespace WebCore { #if ENABLE(SVG) @@ -1697,9 +1701,14 @@ bool FrameLoader::gotoAnchor(const String& name) renderer = anchorNode->renderer(); rect = anchorNode->getRect(); } +#ifdef ANDROID_SCROLL_ON_GOTO_ANCHOR + android::WebFrame::getWebFrame(m_frame)->setUserInitiatedClick(true); +#endif if (renderer) renderer->enclosingLayer()->scrollRectToVisible(rect, true, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways); - +#ifdef ANDROID_SCROLL_ON_GOTO_ANCHOR + android::WebFrame::getWebFrame(m_frame)->setUserInitiatedClick(false); +#endif return true; } diff --git a/WebCore/platform/graphics/android/BitmapAllocatorAndroid.cpp b/WebCore/platform/graphics/android/BitmapAllocatorAndroid.cpp new file mode 100644 index 0000000..0f6057d --- /dev/null +++ b/WebCore/platform/graphics/android/BitmapAllocatorAndroid.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "BitmapAllocatorAndroid.h" +#include "SharedBufferStream.h" +#include "SkImageRef_GlobalPool.h" +#include "SkImageRef_ashmem.h" + +// made this up, so we don't waste a file-descriptor on small images, plus +// we don't want to lose too much on the round-up to a page size (4K) +#define MIN_ASHMEM_ALLOC_SIZE (32*1024) + + +static bool should_use_ashmem(const SkBitmap& bm) { + return bm.getSize() >= MIN_ASHMEM_ALLOC_SIZE; +} + +/////////////////////////////////////////////////////////////////////////////// + +namespace WebCore { + +BitmapAllocatorAndroid::BitmapAllocatorAndroid(SharedBuffer* data, + int sampleSize) +{ + fStream = new SharedBufferStream(data); + fSampleSize = sampleSize; +} + +BitmapAllocatorAndroid::~BitmapAllocatorAndroid() +{ + fStream->unref(); +} + +bool BitmapAllocatorAndroid::allocPixelRef(SkBitmap* bitmap, SkColorTable*) +{ + SkPixelRef* ref; + if (should_use_ashmem(*bitmap)) { +// SkDebugf("ashmem [%d %d]\n", bitmap->width(), bitmap->height()); + ref = new SkImageRef_ashmem(fStream, bitmap->config(), fSampleSize); + } else { +// SkDebugf("globalpool [%d %d]\n", bitmap->width(), bitmap->height()); + ref = new SkImageRef_GlobalPool(fStream, bitmap->config(), fSampleSize); + } + bitmap->setPixelRef(ref)->unref(); + return true; +} + +} + diff --git a/WebCore/platform/graphics/android/BitmapAllocatorAndroid.h b/WebCore/platform/graphics/android/BitmapAllocatorAndroid.h new file mode 100644 index 0000000..f2b2223 --- /dev/null +++ b/WebCore/platform/graphics/android/BitmapAllocatorAndroid.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WebCore_BitmapAllocatorAndroid_DEFINED +#define WebCore_BitmapAllocatorAndroid_DEFINED + +#include "SkBitmap.h" + +namespace WebCore { + + class SharedBuffer; + class SharedBufferStream; + + /** Returns a custom allocator that takes advantage of ashmem and global + pools to best manage the pixel memory for a decoded image. This should + be used for images that are logically immutable, and can be re-decoded + at will based on available memory. + */ + class BitmapAllocatorAndroid : public SkBitmap::Allocator { + public: + BitmapAllocatorAndroid(SharedBuffer* data, int sampleSize); + virtual ~BitmapAllocatorAndroid(); + + // overrides + virtual bool allocPixelRef(SkBitmap*, SkColorTable*); + + private: + SharedBufferStream* fStream; + int fSampleSize; + }; + +} + +#endif diff --git a/WebCore/platform/graphics/android/FontAndroid.cpp b/WebCore/platform/graphics/android/FontAndroid.cpp index 54a1a08..a5f5640 100644 --- a/WebCore/platform/graphics/android/FontAndroid.cpp +++ b/WebCore/platform/graphics/android/FontAndroid.cpp @@ -25,15 +25,15 @@ */ #include "config.h" -#include "Font.h" +#include "EmojiFont.h" +#include "Font.h" #include "FontData.h" #include "FontFallbackList.h" #include "GraphicsContext.h" #include "GlyphBuffer.h" -#include "PlatformGraphicsContext.h" #include "IntRect.h" - +#include "PlatformGraphicsContext.h" #include "SkCanvas.h" #include "SkLayerDrawLooper.h" #include "SkPaint.h" @@ -41,6 +41,8 @@ #include "SkTypeface.h" #include "SkUtils.h" +using namespace android; + namespace WebCore { static void updateForFont(SkPaint* paint, const SimpleFontData* font) { @@ -104,11 +106,13 @@ static bool setupForText(SkPaint* paint, GraphicsContext* gc, } return true; } - + void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, - const FloatPoint& point) const { - SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); // compile-time assert + const FloatPoint& point) const +{ + // compile-time assert + SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); SkPaint paint; if (!setupForText(&paint, gc, font)) { @@ -122,20 +126,49 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); SkPoint* pos = storage.get(); + SkCanvas* canvas = gc->platformContext()->mCanvas; + /* We need an array of [x,y,x,y,x,y,...], but webkit is giving us point.xy + [width, height, width, height, ...], so we have to convert */ - for (int i = 0; i < numGlyphs; i++) { - pos[i].set(x, y); - x += SkFloatToScalar(adv[i].width()); - y += SkFloatToScalar(adv[i].height()); - } - SkCanvas* canvas = gc->platformContext()->mCanvas; - canvas->drawPosText(glyphs, numGlyphs * sizeof(*glyphs), pos, paint); + if (EmojiFont::IsAvailable()) { + int localIndex = 0; + int localCount = 0; + for (int i = 0; i < numGlyphs; i++) { + if (EmojiFont::IsEmojiGlyph(glyphs[i])) { + if (localCount) + canvas->drawPosText(&glyphs[localIndex], + localCount * sizeof(uint16_t), + &pos[localIndex], paint); + EmojiFont::Draw(canvas, glyphs[i], x, y, &paint); + // reset local index/count track for "real" glyphs + localCount = 0; + localIndex = i + 1; + } else { + pos[i].set(x, y); + localCount += 1; + } + x += SkFloatToScalar(adv[i].width()); + y += SkFloatToScalar(adv[i].height()); + } + // draw the last run of glyphs (if any) + if (localCount) + canvas->drawPosText(&glyphs[localIndex], + localCount * sizeof(uint16_t), + &pos[localIndex], paint); + } else { + for (int i = 0; i < numGlyphs; i++) { + pos[i].set(x, y); + x += SkFloatToScalar(adv[i].width()); + y += SkFloatToScalar(adv[i].height()); + } + canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint); + } } -FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int, int) const +FloatRect Font::selectionRectForComplexText(const TextRun& run, + const IntPoint& point, int h, int, int) const { SkPaint paint; SkScalar width, left; @@ -152,7 +185,8 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& roundf(SkScalarToFloat(spacing))); } -void Font::drawComplexText(GraphicsContext* gc, TextRun const& run, FloatPoint const& point, int, int) const +void Font::drawComplexText(GraphicsContext* gc, TextRun const& run, + FloatPoint const& point, int, int) const { SkCanvas* canvas = gc->platformContext()->mCanvas; SkPaint paint; @@ -181,7 +215,8 @@ float Font::floatWidthForComplexText(const TextRun& run) const return SkScalarToFloat(width); } -int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const +int Font::offsetForPositionForComplexText(const TextRun& run, int x, + bool includePartialGlyphs) const { SkPaint paint; int count = run.length(); diff --git a/WebCore/platform/graphics/android/FontDataAndroid.cpp b/WebCore/platform/graphics/android/FontDataAndroid.cpp index 3dd9789..af98398 100644 --- a/WebCore/platform/graphics/android/FontDataAndroid.cpp +++ b/WebCore/platform/graphics/android/FontDataAndroid.cpp @@ -28,16 +28,19 @@ */ #include "config.h" + +#include "EmojiFont.h" #include "Font.h" #include "FontCache.h" #include "SimpleFontData.h" #include "FloatRect.h" #include "FontDescription.h" - #include "SkPaint.h" #include "SkTypeface.h" #include "SkTime.h" +using namespace android; + namespace WebCore { void SimpleFontData::platformInit() @@ -109,6 +112,9 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const { SkASSERT(sizeof(glyph) == 2); // compile-time assert + if (EmojiFont::IsEmojiGlyph(glyph)) + return EmojiFont::GetAdvanceWidth(glyph); + SkPaint paint; m_font.setupPaint(&paint); diff --git a/WebCore/platform/graphics/android/GlyphMapAndroid.cpp b/WebCore/platform/graphics/android/GlyphMapAndroid.cpp index 1df06b1..fe64c9a 100644 --- a/WebCore/platform/graphics/android/GlyphMapAndroid.cpp +++ b/WebCore/platform/graphics/android/GlyphMapAndroid.cpp @@ -28,12 +28,15 @@ */ #include "config.h" -#include "GlyphPageTreeNode.h" -#include "SimpleFontData.h" +#include "EmojiFont.h" +#include "GlyphPageTreeNode.h" #include "SkTemplates.h" #include "SkPaint.h" #include "SkUtils.h" +#include "SimpleFontData.h" + +using namespace android; namespace WebCore { @@ -59,9 +62,26 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b } unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero - for (unsigned i = 0; i < length; i++) { - setGlyphDataForIndex(offset + i, glyphs[i], fontData); - allGlyphs |= glyphs[i]; + + // search for emoji. If we knew for sure that buffer was a contiguous range + // of chars, we could quick-reject the range to avoid this loop (usually) + if (EmojiFont::IsAvailable()) { + const UChar* curr = buffer; + for (unsigned i = 0; i < length; i++) { + SkUnichar uni = SkUTF16_NextUnichar(&curr); + uint16_t glyphID = glyphs[i]; + // only sniff if the normal font failed to recognize it + if (!glyphID) + glyphID = EmojiFont::UnicharToGlyph(uni); + setGlyphDataForIndex(offset + i, glyphID, fontData); + allGlyphs |= glyphID; + } + } else { + for (unsigned i = 0; i < length; i++) { + uint16_t glyphID = glyphs[i]; + setGlyphDataForIndex(offset + i, glyphID, fontData); + allGlyphs |= glyphID; + } } return allGlyphs != 0; } diff --git a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp index c8fe8dd..4bf8f8e 100644 --- a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp +++ b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp @@ -24,6 +24,7 @@ */ #include "config.h" +#include "BitmapAllocatorAndroid.h" #include "ImageDecoder.h" #include "ImageSource.h" #include "IntSize.h" @@ -31,8 +32,6 @@ #include "SharedBuffer.h" #include "PlatformString.h" -#include "JavaSharedClient.h" - #include "SkBitmapRef.h" #include "SkImageRef.h" #include "SkImageDecoder.h" @@ -44,21 +43,11 @@ SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src); //#define TRACE_SUBSAMPLE_BITMAPS //#define TRACE_RLE_BITMAPS -#include "SkImageRef_GlobalPool.h" -#include "SkImageRef_ashmem.h" - -// made this up, so we don't waste a file-descriptor on small images, plus -// we don't want to lose too much on the round-up to a page size (4K) -#define MIN_ASHMEM_ALLOC_SIZE (32*1024) // don't use RLE for images smaller than this, since they incur a drawing cost // (and don't work as patterns yet) we only want to use RLE when we must #define MIN_RLE_ALLOC_SIZE (512*1024) -static bool should_use_ashmem(const SkBitmap& bm) { - return bm.getSize() >= MIN_ASHMEM_ALLOC_SIZE; -} - /* Images larger than this should be subsampled. Using ashmem, the decoded pixels will be purged as needed, so this value can be pretty large. Making it too small hurts image quality (e.g. abc.com background). 2Meg works for @@ -102,47 +91,8 @@ public: bool fAllDataReceived; }; -using namespace android; - namespace WebCore { -class SharedBufferStream : public SkMemoryStream { -public: - SharedBufferStream(SharedBuffer* buffer) - : SkMemoryStream(buffer->data(), buffer->size(), false) { - fBuffer = buffer; - buffer->ref(); - } - - virtual ~SharedBufferStream() { - // we can't necessarily call fBuffer->deref() here, as we may be - // in a different thread from webkit, and SharedBuffer is not - // threadsafe. Therefore we defer it until it can be executed in the - // webkit thread. -// SkDebugf("-------- enqueue buffer %p for deref\n", fBuffer); - JavaSharedClient::EnqueueFunctionPtr(CallDeref, fBuffer); - } - -private: - // don't allow this to change our data. should not get called, but we - // override here just to be sure - virtual void setMemory(const void* data, size_t length, bool copyData) { - sk_throw(); - } - - // we share ownership of this with webkit - SharedBuffer* fBuffer; - - // will be invoked in the webkit thread - static void CallDeref(void* buffer) { -// SkDebugf("-------- call deref on buffer %p\n", buffer); - ((SharedBuffer*)buffer)->deref(); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// - ImageSource::ImageSource() { m_decoder.m_image = NULL; } @@ -253,28 +203,20 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived) SkBitmap* bm = &decoder->bitmap(); SkPixelRef* ref = convertToRLE(bm, data->data(), data->size()); - if (NULL == ref) { - SkStream* strm = new SharedBufferStream(data); - // imageref now owns the stream object - if (should_use_ashmem(*bm)) { -// SkDebugf("---- use ashmem for image [%d %d]\n", bm->width(), bm->height()); - ref = new SkImageRef_ashmem(strm, bm->config(), decoder->fSampleSize); - } else { -// SkDebugf("---- use globalpool for image [%d %d]\n", bm->width(), bm->height()); - ref = new SkImageRef_GlobalPool(strm, bm->config(), decoder->fSampleSize); + if (ref) { + bm->setPixelRef(ref)->unref(); + } else { + BitmapAllocatorAndroid alloc(data, decoder->fSampleSize); + if (!alloc.allocPixelRef(bm, NULL)) { + return; } - - // SkDebugf("----- allDataReceived [%d %d]\n", bm->width(), bm->height()); + ref = bm->pixelRef(); } // we promise to never change the pixels (makes picture recording fast) ref->setImmutable(); // give it the URL if we have one ref->setURI(m_decoder.m_url); - // our bitmap is now the only owner of the imageref - bm->setPixelRef(ref)->unref(); - -// SkDebugf("---- finished: [%d %d] %s\n", bm->width(), bm->height(), ref->getURI()); } } diff --git a/WebCore/platform/graphics/android/SharedBufferStream.cpp b/WebCore/platform/graphics/android/SharedBufferStream.cpp new file mode 100644 index 0000000..fd63423 --- /dev/null +++ b/WebCore/platform/graphics/android/SharedBufferStream.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "JavaSharedClient.h" +#include "SharedBuffer.h" +#include "SharedBufferStream.h" + +using namespace android; + +namespace WebCore { + + static void CallDeref(void* buffer) { + ((SharedBuffer*)buffer)->deref(); + } + + SharedBufferStream::SharedBufferStream(SharedBuffer* buffer) + : SkMemoryStream(buffer->data(), buffer->size(), false) { + fBuffer = buffer; + buffer->ref(); + } + + SharedBufferStream::~SharedBufferStream() { + // we can't necessarily call fBuffer->deref() here, as we may be + // in a different thread from webkit, and SharedBuffer is not + // threadsafe. Therefore we defer it until it can be executed in the + // webkit thread. + JavaSharedClient::EnqueueFunctionPtr(CallDeref, fBuffer); + } + +} + diff --git a/WebCore/platform/graphics/android/SharedBufferStream.h b/WebCore/platform/graphics/android/SharedBufferStream.h new file mode 100644 index 0000000..929aa9b --- /dev/null +++ b/WebCore/platform/graphics/android/SharedBufferStream.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WebCore_SharedBufferStream_DEFINED +#define WebCore_SharedBufferStream_DEFINED + +#include "SkStream.h" +#include "SharedBuffer.h" + +namespace WebCore { + + /** Subclass of SkStream that wrapps a webcore SharedBuffer object. To + allow this object to be deleted from any thread, the impl will ensure + that we unref the SharedBuffer object from the correct webcore thread. + */ + class SharedBufferStream : public SkMemoryStream { + public: + SharedBufferStream(SharedBuffer* buffer); + virtual ~SharedBufferStream(); + + private: + // don't allow this to change our data. should not get called, but we + // override here just to be sure + virtual void setMemory(const void* data, size_t length, bool copyData) { + sk_throw(); + } + + // we share ownership of this with webkit + SharedBuffer* fBuffer; + }; +} + +#endif diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index a84a67f..72ee605 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -201,7 +201,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_maxYScroll = 240/4; m_textGeneration = 0; m_screenWidth = 320; - m_scale = 1; + m_scale = 100; LOG_ASSERT(m_mainFrame, "Uh oh, somehow a frameview was made without an initial frame!"); @@ -287,6 +287,7 @@ void WebViewCore::reset(bool fromConstructor) m_skipContentDraw = false; m_findIsUp = false; m_domtree_version = 0; + m_check_domtree_version = true; } static bool layoutIfNeededRecursive(WebCore::Frame* f) @@ -361,6 +362,12 @@ void WebViewCore::recordPictureSet(PictureSet* content) // We may be mid-layout and thus cannot draw. if (!success) return; + + { // collect WebViewCoreRecordTimeCounter after layoutIfNeededRecursive +#ifdef ANDROID_INSTRUMENT + TimeCounterAuto counter(TimeCounter::WebViewCoreRecordTimeCounter); +#endif + // if the webkit page dimensions changed, discard the pictureset and redraw. WebCore::FrameView* view = m_mainFrame->view(); int width = view->contentsWidth(); @@ -385,6 +392,7 @@ void WebViewCore::recordPictureSet(PictureSet* content) // and check to see if any already split pieces need to be redrawn. if (content->build()) rebuildPictureSet(content); + } // WebViewCoreRecordTimeCounter CacheBuilder& builder = FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder(); WebCore::Node* oldFocusNode = builder.currentFocus(); m_frameCacheOutOfDate = true; @@ -396,13 +404,15 @@ void WebViewCore::recordPictureSet(PictureSet* content) m_lastFocusedBounds.x(), m_lastFocusedBounds.y(), m_lastFocusedBounds.width(), m_lastFocusedBounds.height(), oldBounds.x(), oldBounds.y(), oldBounds.width(), oldBounds.height()); unsigned latestVersion = 0; - // as domTreeVersion only increment, we can just check the sum to see whether - // we need to update the frame cache - for (Frame* frame = m_mainFrame; frame; frame = frame->tree()->traverseNext()) { - latestVersion += frame->document()->domTreeVersion(); + if (m_check_domtree_version) { + // as domTreeVersion only increment, we can just check the sum to see + // whether we need to update the frame cache + for (Frame* frame = m_mainFrame; frame; frame = frame->tree()->traverseNext()) { + latestVersion += frame->document()->domTreeVersion(); + } } - if (m_lastFocused != oldFocusNode || m_lastFocusedBounds != oldBounds - || m_findIsUp || latestVersion != m_domtree_version) { + if (m_lastFocused != oldFocusNode || m_lastFocusedBounds != oldBounds || m_findIsUp + || (m_check_domtree_version && latestVersion != m_domtree_version)) { m_lastFocused = oldFocusNode; m_lastFocusedBounds = oldBounds; DBG_NAV_LOGD("call updateFrameCache m_domtree_version=%d latest=%d", @@ -456,6 +466,7 @@ void WebViewCore::clearContent() m_content.clear(); m_contentMutex.unlock(); m_addInval.setEmpty(); + m_rebuildInval.setEmpty(); } void WebViewCore::copyContentToPicture(SkPicture* picture) @@ -515,6 +526,10 @@ SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval) recordingCanvas->save(); view->platformWidget()->draw(&gc, WebCore::IntRect(inval.fLeft, inval.fTop, inval.width(), inval.height())); + m_rebuildInval.op(inval, SkRegion::kUnion_Op); + DBG_SET_LOGD("m_rebuildInval={%d,%d,r=%d,b=%d}", + m_rebuildInval.getBounds().fLeft, m_rebuildInval.getBounds().fTop, + m_rebuildInval.getBounds().fRight, m_rebuildInval.getBounds().fBottom); gButtonMutex.lock(); updateButtonList(&buttons); @@ -540,9 +555,6 @@ void WebViewCore::rebuildPictureSet(PictureSet* pictureSet) bool WebViewCore::recordContent(SkRegion* region, SkIPoint* point) { -#ifdef ANDROID_INSTRUMENT - TimeCounterAuto counter(TimeCounter::WebViewCoreRecordTimeCounter); -#endif DBG_SET_LOG("start"); m_contentMutex.lock(); PictureSet contentCopy(m_content); @@ -555,6 +567,8 @@ bool WebViewCore::recordContent(SkRegion* region, SkIPoint* point) } region->set(m_addInval); m_addInval.setEmpty(); + region->op(m_rebuildInval, SkRegion::kUnion_Op); + m_rebuildInval.setEmpty(); m_contentMutex.lock(); contentCopy.setDrawTimes(m_content); m_content.set(contentCopy); @@ -700,6 +714,7 @@ void WebViewCore::didFirstLayout() checkException(env); DBG_NAV_LOG("call updateFrameCache"); + m_check_domtree_version = false; updateFrameCache(); m_history.setDidFirstLayout(true); } @@ -734,6 +749,7 @@ void WebViewCore::notifyFocusSet() void WebViewCore::notifyProgressFinished() { DBG_NAV_LOG("call updateFrameCache"); + m_check_domtree_version = true; updateFrameCache(); sendNotifyProgressFinished(); } @@ -1745,7 +1761,7 @@ void WebViewCore::touchUp(int touchGeneration, int buildGeneration, // so just leave the function now. if (!isClick) return; - if (frame) { + if (frame && FrameLoaderClientAndroid::get(m_mainFrame)->getCacheBuilder().validNode(frame, 0)) { frame->loader()->resetMultipleFormSubmissionProtection(); } EditorClientAndroid* client = static_cast<EditorClientAndroid*>(m_mainFrame->editor()->client()); diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index d9549de..a2d7395 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -362,6 +362,7 @@ namespace android { static Mutex m_contentMutex; // protects ui/core thread pictureset access PictureSet m_content; // the set of pictures to draw (accessed by UI too) SkRegion m_addInval; // the accumulated inval region (not yet drawn) + SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures // Used in passToJS to avoid updating the UI text field until after the // key event has been processed. bool m_blockTextfieldUpdates; @@ -386,6 +387,7 @@ namespace android { int m_screenWidth; int m_scale; unsigned m_domtree_version; + bool m_check_domtree_version; SkTDArray<PluginWidgetAndroid*> m_plugins; WebCore::Timer<WebViewCore> m_pluginInvalTimer; |