summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/Android.mk312
-rw-r--r--Source/WebCore/css/mediaControlsAndroid.css5
-rw-r--r--Source/WebCore/editing/SelectionController.cpp7
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/BaseRenderer.cpp20
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp89
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h1
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.cpp38
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.h4
-rw-r--r--Source/WebCore/platform/graphics/android/RasterRenderer.cpp10
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp73
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.h5
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp193
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h17
-rw-r--r--Source/WebKit/android/nav/DrawExtra.cpp5
-rw-r--r--Source/WebKit/android/nav/DrawExtra.h3
-rw-r--r--Source/WebKit/android/nav/WebView.cpp11
17 files changed, 292 insertions, 503 deletions
diff --git a/Source/Android.mk b/Source/Android.mk
deleted file mode 100644
index 6612cae..0000000
--- a/Source/Android.mk
+++ /dev/null
@@ -1,312 +0,0 @@
-##
-## Copyright 2009, 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.
-##
-
-LOCAL_PATH := $(call my-dir)
-
-# Two ways to control which JS engine is used:
-# 1. use JS_ENGINE environment variable, value can be either 'jsc' or 'v8'
-# This is the preferred way.
-# 2. if JS_ENGINE is not set, or is not 'jsc' or 'v8', this makefile picks
-# up a default engine to build.
-# To help setup buildbot, a new environment variable, USE_ALT_JS_ENGINE,
-# can be set to true, so that two builds can be different but without
-# specifying which JS engine to use.
-# To enable JIT in Android's JSC, please set ENABLE_JSC_JIT environment
-# variable to true.
-
-# Read JS_ENGINE environment variable
-JAVASCRIPT_ENGINE = $(JS_ENGINE)
-
-ifneq ($(JAVASCRIPT_ENGINE),jsc)
- ifneq ($(JAVASCRIPT_ENGINE),v8)
- # No JS engine is specified, pickup the one we want as default.
- ifeq ($(USE_ALT_JS_ENGINE),true)
- JAVASCRIPT_ENGINE = v8
- else
- JAVASCRIPT_ENGINE = jsc
- endif
- endif
-endif
-
-BASE_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# Define our module and find the intermediates directory
-LOCAL_MODULE := libwebcore
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-base_intermediates := $(call local-intermediates-dir)
-
-# Using := here prevents recursive expansion
-WEBKIT_SRC_FILES :=
-
-# We have to use bison 2.3
-include $(BASE_PATH)/bison_check.mk
-
-# Build our list of include paths. We include WebKit/android/icu first so that
-# any files that include <unicode/ucnv.h> will include our ucnv.h first. We
-# also add external/ as an include directory so that we can specify the real
-# icu header directory as a more exact reference to avoid including our ucnv.h.
-#
-# Note that JavasCriptCore/ must be included after WebCore/, so that we pick up
-# the right config.h.
-LOCAL_C_INCLUDES := \
- $(JNI_H_INCLUDE) \
- $(LOCAL_PATH)/WebKit/android/icu \
- external/ \
- 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 \
- external/skia/include/utils \
- external/skia/src/ports \
- external/sqlite/dist \
- frameworks/base/core/jni/android/graphics
-
-LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
- $(LOCAL_PATH)/WebCore \
- $(LOCAL_PATH)/WebCore/accessibility \
- $(LOCAL_PATH)/WebCore/bindings/generic \
- $(LOCAL_PATH)/WebCore/css \
- $(LOCAL_PATH)/WebCore/dom \
- $(LOCAL_PATH)/WebCore/editing \
- $(LOCAL_PATH)/WebCore/history \
- $(LOCAL_PATH)/WebCore/history/android \
- $(LOCAL_PATH)/WebCore/html \
- $(LOCAL_PATH)/WebCore/html/canvas \
- $(LOCAL_PATH)/WebCore/inspector \
- $(LOCAL_PATH)/WebCore/loader \
- $(LOCAL_PATH)/WebCore/loader/appcache \
- $(LOCAL_PATH)/WebCore/loader/icon \
- $(LOCAL_PATH)/WebCore/notifications \
- $(LOCAL_PATH)/WebCore/page \
- $(LOCAL_PATH)/WebCore/page/android \
- $(LOCAL_PATH)/WebCore/page/animation \
- $(LOCAL_PATH)/WebCore/platform \
- $(LOCAL_PATH)/WebCore/platform/android \
- $(LOCAL_PATH)/WebCore/platform/animation \
- $(LOCAL_PATH)/WebCore/platform/graphics \
- $(LOCAL_PATH)/WebCore/platform/graphics/android \
- $(LOCAL_PATH)/WebCore/platform/graphics/network \
- $(LOCAL_PATH)/WebCore/platform/graphics/skia \
- $(LOCAL_PATH)/WebCore/platform/graphics/transforms \
- $(LOCAL_PATH)/WebCore/platform/image-decoders \
- $(LOCAL_PATH)/WebCore/platform/leveldb \
- $(LOCAL_PATH)/WebCore/platform/mock \
- $(LOCAL_PATH)/WebCore/platform/network \
- $(LOCAL_PATH)/WebCore/platform/network/android \
- $(LOCAL_PATH)/WebCore/platform/sql \
- $(LOCAL_PATH)/WebCore/platform/text \
- $(LOCAL_PATH)/WebCore/plugins \
- $(LOCAL_PATH)/WebCore/plugins/android \
- $(LOCAL_PATH)/WebCore/rendering \
- $(LOCAL_PATH)/WebCore/rendering/style \
- $(LOCAL_PATH)/WebCore/storage \
- $(LOCAL_PATH)/WebCore/workers \
- $(LOCAL_PATH)/WebCore/xml
-
-LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
- $(LOCAL_PATH)/WebKit/android \
- $(LOCAL_PATH)/WebKit/android/WebCoreSupport \
- $(LOCAL_PATH)/WebKit/android/jni \
- $(LOCAL_PATH)/WebKit/android/nav \
- $(LOCAL_PATH)/WebKit/android/plugins \
- $(LOCAL_PATH)/WebKit/android/stl
-
-LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
- $(LOCAL_PATH)/JavaScriptCore \
- $(LOCAL_PATH)/JavaScriptCore/wtf \
- $(LOCAL_PATH)/JavaScriptCore/wtf/unicode \
- $(LOCAL_PATH)/JavaScriptCore/wtf/unicode/icu
-
-LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
- $(base_intermediates)/WebCore/ \
- $(base_intermediates)/WebCore/css \
- $(base_intermediates)/WebCore/html \
- $(base_intermediates)/WebCore/platform
-
-ifeq ($(ENABLE_SVG), true)
-LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
- $(LOCAL_PATH)/WebCore/platform/graphics/filters \
- $(LOCAL_PATH)/WebCore/svg \
- $(LOCAL_PATH)/WebCore/svg/animation \
- $(LOCAL_PATH)/WebCore/svg/graphics \
- $(LOCAL_PATH)/WebCore/svg/graphics/filters \
- $(base_intermediates)/WebCore/svg
-endif
-
-ifeq ($(JAVASCRIPT_ENGINE),v8)
-# Include WTF source file.
-d := JavaScriptCore
-LOCAL_PATH := $(BASE_PATH)/$d
-intermediates := $(base_intermediates)/$d
-include $(LOCAL_PATH)/Android.v8.wtf.mk
-WEBKIT_SRC_FILES += $(addprefix $d/,$(LOCAL_SRC_FILES))
-endif # JAVASCRIPT_ENGINE == v8
-
-# Include source files for WebCore
-d := WebCore
-LOCAL_PATH := $(BASE_PATH)/$d
-JAVASCRIPTCORE_PATH := $(BASE_PATH)/JavaScriptCore
-intermediates := $(base_intermediates)/$d
-include $(LOCAL_PATH)/Android.mk
-ifeq ($(JAVASCRIPT_ENGINE),jsc)
-include $(LOCAL_PATH)/Android.jscbindings.mk
-endif
-ifeq ($(JAVASCRIPT_ENGINE),v8)
-include $(LOCAL_PATH)/Android.v8bindings.mk
-endif
-WEBKIT_SRC_FILES += $(addprefix $d/,$(LOCAL_SRC_FILES))
-LOCAL_C_INCLUDES += $(BINDING_C_INCLUDES)
-
-# Include the derived source files for WebCore. Uses the same path as
-# WebCore
-include $(LOCAL_PATH)/Android.derived.mk
-ifeq ($(JAVASCRIPT_ENGINE),jsc)
-include $(LOCAL_PATH)/Android.derived.jscbindings.mk
-endif
-ifeq ($(JAVASCRIPT_ENGINE),v8)
-include $(LOCAL_PATH)/Android.derived.v8bindings.mk
-endif
-
-# Redefine LOCAL_PATH here so the build system is not confused
-LOCAL_PATH := $(BASE_PATH)
-
-# Define our compiler flags
-LOCAL_CFLAGS += -Wno-endif-labels -Wno-import -Wno-format
-LOCAL_CFLAGS += -fno-strict-aliasing
-LOCAL_CFLAGS += -include "WebCorePrefix.h"
-LOCAL_CFLAGS += -fvisibility=hidden
-
-# Enable JSC JIT if JSC is used and ENABLE_JSC_JIT environment
-# variable is set to true
-ifeq ($(JAVASCRIPT_ENGINE),jsc)
-ifeq ($(ENABLE_JSC_JIT),true)
-LOCAL_CFLAGS += -DENABLE_ANDROID_JSC_JIT=1
-endif
-endif
-
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_CFLAGS += -Darm
-endif
-
-ifeq ($(ENABLE_SVG),true)
-LOCAL_CFLAGS += -DENABLE_SVG=1
-endif
-
-# Temporary disable SVG_ANIMATION.
-ifeq ($(ENABLE_SVG_ANIMATION),true)
-LOCAL_CFLAGS += -DENABLE_SVG_ANIMATION=1
-endif
-
-# LOCAL_LDLIBS is used in simulator builds only and simulator builds are only
-# valid on Linux
-LOCAL_LDLIBS += -lpthread -ldl
-
-# Build the list of shared libraries
-LOCAL_SHARED_LIBRARIES := \
- libandroid_runtime \
- libnativehelper \
- libsqlite \
- libskia \
- libutils \
- libui \
- libcutils \
- libicuuc \
- libicudata \
- libicui18n \
- libmedia
-
-# We have to use the android version of libdl.
-LOCAL_SHARED_LIBRARIES += libdl
-
-# Build the list of static libraries
-LOCAL_STATIC_LIBRARIES := libxml2
-ifeq ($(JAVASCRIPT_ENGINE),v8)
-LOCAL_STATIC_LIBRARIES += libv8
-endif
-
-# Redefine LOCAL_SRC_FILES to be all the WebKit source files
-LOCAL_SRC_FILES := $(WEBKIT_SRC_FILES)
-
-# Define this for use in other makefiles.
-WEBKIT_C_INCLUDES := $(LOCAL_C_INCLUDES)
-WEBKIT_CFLAGS := $(LOCAL_CFLAGS)
-WEBKIT_GENERATED_SOURCES := $(LOCAL_GENERATED_SOURCES)
-WEBKIT_LDLIBS := $(LOCAL_LDLIBS)
-WEBKIT_SHARED_LIBRARIES := $(LOCAL_SHARED_LIBRARIES)
-WEBKIT_STATIC_LIBRARIES := $(LOCAL_STATIC_LIBRARIES)
-
-# Build the library all at once
-include $(BUILD_STATIC_LIBRARY)
-
-ifeq ($(JAVASCRIPT_ENGINE),jsc)
-# Now build libjs as a static library.
-include $(CLEAR_VARS)
-LOCAL_MODULE := libjs
-LOCAL_LDLIBS := $(WEBKIT_LDLIBS)
-LOCAL_SHARED_LIBRARIES := $(WEBKIT_SHARED_LIBRARIES)
-LOCAL_STATIC_LIBRARIES := $(WEBKIT_STATIC_LIBRARIES)
-LOCAL_CFLAGS := $(WEBKIT_CFLAGS)
-# Include source files for JavaScriptCore
-d := JavaScriptCore
-LOCAL_PATH := $(BASE_PATH)/$d
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-# Cannot use base_intermediates as this is a new module
-intermediates := $(call local-intermediates-dir)
-include $(LOCAL_PATH)/Android.mk
-# Redefine LOCAL_SRC_FILES with the correct prefix
-LOCAL_SRC_FILES := $(addprefix $d/,$(LOCAL_SRC_FILES))
-# Use the base path to resolve file names
-LOCAL_PATH := $(BASE_PATH)
-# Append jsc intermediate include paths to the WebKit include list.
-LOCAL_C_INCLUDES := $(WEBKIT_C_INCLUDES) \
- $(intermediates) \
- $(intermediates)/parser \
- $(intermediates)/runtime \
-# Build libjs
-include $(BUILD_STATIC_LIBRARY)
-endif # JAVASCRIPT_ENGINE == jsc
-
-# Now build the shared library using only the exported jni entry point. This
-# will strip out any unused code from the entry point.
-include $(CLEAR_VARS)
-# if you need to make webcore huge (for debugging), enable this line
-#LOCAL_PRELINK_MODULE := false
-LOCAL_MODULE := libwebcore
-LOCAL_LDLIBS := $(WEBKIT_LDLIBS)
-LOCAL_SHARED_LIBRARIES := $(WEBKIT_SHARED_LIBRARIES)
-LOCAL_STATIC_LIBRARIES := libwebcore $(WEBKIT_STATIC_LIBRARIES)
-ifeq ($(JAVASCRIPT_ENGINE),jsc)
-LOCAL_STATIC_LIBRARIES += libjs
-endif
-LOCAL_LDFLAGS := -fvisibility=hidden
-LOCAL_CFLAGS := $(WEBKIT_CFLAGS)
-LOCAL_C_INCLUDES := $(WEBKIT_C_INCLUDES)
-LOCAL_PATH := $(BASE_PATH)
-include $(BUILD_SHARED_LIBRARY)
diff --git a/Source/WebCore/css/mediaControlsAndroid.css b/Source/WebCore/css/mediaControlsAndroid.css
index 77f8b08..614c92f 100644
--- a/Source/WebCore/css/mediaControlsAndroid.css
+++ b/Source/WebCore/css/mediaControlsAndroid.css
@@ -49,10 +49,7 @@ video:-webkit-full-page-media::-webkit-media-controls-panel {
}
audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button {
- -webkit-appearance: media-mute-button;
- display: -webkit-box;
- width: 48px;
- height: 48px;
+ display: none;
}
audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
diff --git a/Source/WebCore/editing/SelectionController.cpp b/Source/WebCore/editing/SelectionController.cpp
index 3eec640..e9bdd6a 100644
--- a/Source/WebCore/editing/SelectionController.cpp
+++ b/Source/WebCore/editing/SelectionController.cpp
@@ -1562,9 +1562,6 @@ bool SelectionController::isFocusedAndActive() const
void SelectionController::updateAppearance()
{
-#if PLATFORM(ANDROID)
- return;
-#endif
ASSERT(!m_isDragCaretController);
#if ENABLE(TEXT_CARET)
@@ -1595,6 +1592,10 @@ void SelectionController::updateAppearance()
// We need to update style in case the node containing the selection is made display:none.
m_frame->document()->updateStyleIfNeeded();
+#if PLATFORM(ANDROID)
+ return;
+#endif
+
RenderView* view = m_frame->contentRenderer();
if (!view)
return;
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index ae0571c..5cd2ddd 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -2429,7 +2429,7 @@ void HTMLMediaElement::defaultEventHandler(Event* event)
// This allows user to click the video area to toggle play/pause state.
if (event->type() == eventNames().clickEvent
&& !hasEventListeners(eventNames().clickEvent)) {
- m_userGestureInitiated = true;
+ m_userGestureInitiated = processingUserGesture();
togglePlayState();
}
#endif
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
index 57baee8..b708ad1 100644
--- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
@@ -141,7 +141,13 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
// only color the invalidated area
SkPaint invalPaint;
invalPaint.setARGB(color, 0, 255, 0);
- canvas.drawIRect(*renderInfo.invalRect, invalPaint);
+ if (renderInfo.invalRect)
+ canvas.drawIRect(*renderInfo.invalRect, invalPaint);
+ else {
+ SkIRect rect;
+ rect.set(0, 0, tileSize.width(), tileSize.height());
+ canvas.drawIRect(rect, invalPaint);
+ }
// paint the tile boundaries
SkPaint paint;
@@ -154,6 +160,18 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
canvas.drawLine(0, 0, tileSize.width(), 0, paint);
canvas.drawLine(tileSize.width(), 0, tileSize.width(), tileSize.height(), paint);
+ if (renderInfo.invalRect) {
+ // if partial inval...
+ int x = renderInfo.invalRect->fLeft;
+ int y = renderInfo.invalRect->fTop;
+ int w = renderInfo.invalRect->width();
+ int h = renderInfo.invalRect->height();
+
+ paint.setARGB(128, 255, 255, 0);
+ canvas.drawLine(x, y, x + w, y + h, paint);
+ canvas.drawLine(x, y + h, x + w, y, paint);
+ }
+
if (renderInfo.measurePerf)
drawTileInfo(&canvas, renderInfo, pictureCount);
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index 76ee1e7..42d02a5 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -54,6 +54,13 @@
#endif // DEBUG
+// If the dirty portion of a tile exceeds this ratio, fully repaint.
+// Lower values give fewer partial repaints, thus fewer front-to-back
+// texture copies (cost will vary by device). It's a tradeoff between
+// the rasterization cost and the FBO texture recopy cost when using
+// GPU for the transfer queue.
+#define MAX_INVAL_AREA 0.6
+
namespace WebCore {
BaseTile::BaseTile(bool isLayerTile)
@@ -369,55 +376,65 @@ void BaseTile::paintBitmap()
fullRepaint = true;
}
- // With SurfaceTexture, just repaint the entire tile if we intersect.
- // TODO: Implement the partial invalidate in Surface Texture Mode.
- // Such that the code of partial invalidation below is preserved.
+ // For now, only do full repaint
fullRepaint = true;
- while (!fullRepaint && !cliperator.done()) {
- SkRect realTileRect;
- SkRect dirtyRect;
- dirtyRect.set(cliperator.rect());
- bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
- scale, dirtyRect, realTileRect);
-
- if (intersect) {
- // initialize finalRealRect to the rounded values of realTileRect
- SkIRect finalRealRect;
- realTileRect.roundOut(&finalRealRect);
-
- // stash the int values of the current width and height
- const int iWidth = finalRealRect.width();
- const int iHeight = finalRealRect.height();
-
- if (iWidth == tileWidth || iHeight == tileHeight) {
- fullRepaint = true;
- break;
+ if (!fullRepaint) {
+ // compute the partial inval area
+ SkIRect totalRect;
+ totalRect.set(0, 0, 0, 0);
+ float tileSurface = tileWidth * tileHeight;
+ float tileSurfaceCap = MAX_INVAL_AREA * tileSurface;
+
+ // We join all the invals in the same tile for now
+ while (!fullRepaint && !cliperator.done()) {
+ SkRect realTileRect;
+ SkRect dirtyRect;
+ dirtyRect.set(cliperator.rect());
+ bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
+ scale, dirtyRect, realTileRect);
+ if (intersect) {
+ // initialize finalRealRect to the rounded values of realTileRect
+ SkIRect finalRealRect;
+ realTileRect.roundOut(&finalRealRect);
+
+ // stash the int values of the current width and height
+ const int iWidth = finalRealRect.width();
+ const int iHeight = finalRealRect.height();
+
+ if (iWidth == tileWidth || iHeight == tileHeight) {
+ fullRepaint = true;
+ break;
+ }
+
+ // translate the rect into tile space coordinates
+ finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
+ finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
+ finalRealRect.fRight = finalRealRect.fLeft + iWidth;
+ finalRealRect.fBottom = finalRealRect.fTop + iHeight;
+ totalRect.join(finalRealRect);
+ float repaintSurface = totalRect.width() * totalRect.height();
+
+ if (repaintSurface > tileSurfaceCap) {
+ fullRepaint = true;
+ break;
+ }
}
- // translate the rect into tile space coordinates
- finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
- finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
- finalRealRect.fRight = finalRealRect.fLeft + iWidth;
- finalRealRect.fBottom = finalRealRect.fTop + iHeight;
+ cliperator.next();
+ }
- renderInfo.invalRect = &finalRealRect;
+ if (!fullRepaint) {
+ renderInfo.invalRect = &totalRect;
renderInfo.measurePerf = false;
-
pictureCount = m_renderer->renderTiledContent(renderInfo);
}
-
- cliperator.next();
}
// Do a full repaint if needed
if (fullRepaint) {
- SkIRect rect;
- rect.set(0, 0, tileWidth, tileHeight);
-
- renderInfo.invalRect = &rect;
+ renderInfo.invalRect = 0;
renderInfo.measurePerf = TilesManager::instance()->getShowVisualIndicator();
-
pictureCount = m_renderer->renderTiledContent(renderInfo);
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
index 55314c7..67eeeb9 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
@@ -60,6 +60,7 @@ public:
TilePainter* m_painter;
unsigned int m_picture;
bool m_inverted;
+ IntRect m_inval;
};
class BaseTileTexture {
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp
index efd611b..39d8755 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp
@@ -36,12 +36,14 @@
#include <wtf/CurrentTime.h>
#include <wtf/text/CString.h>
-
-#ifdef DEBUG
-
#include <cutils/log.h>
#include <wtf/text/CString.h>
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__)
+
+#ifdef DEBUG
+
#undef XLOG
#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__)
@@ -425,6 +427,10 @@ bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
bool skipTransfer = false;
BaseTile* tilePtr = renderInfo->baseTile;
+ // TODO: use pure color for partial invals as well
+ if (renderInfo->invalRect)
+ return false;
+
if (tilePtr) {
BaseTileTexture* tileTexture = tilePtr->backTexture();
// Check the bitmap, and make everything ready here.
@@ -450,8 +456,6 @@ void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
{
if (!renderInfo)
return;
- const int x = renderInfo->invalRect->fLeft;
- const int y = renderInfo->invalRect->fTop;
const SkSize& requiredSize = renderInfo->tileSize;
TextureInfo* textureInfo = renderInfo->textureInfo;
@@ -459,14 +463,14 @@ void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
return;
if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height))
- GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, x, y, bitmap);
+ GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, bitmap);
else {
if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
XLOG("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
bitmap.width(), bitmap.height(),
requiredSize.width(), requiredSize.height());
}
- GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, 0, 0, bitmap);
+ GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, bitmap);
textureInfo->m_width = bitmap.width();
textureInfo->m_height = bitmap.height();
@@ -474,14 +478,14 @@ void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
}
}
-void GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap)
+void GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
{
if (!renderInfo
|| !renderInfo->textureInfo
|| !renderInfo->baseTile)
return;
- TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, x, y, bitmap);
+ TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, bitmap);
}
void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
@@ -515,7 +519,8 @@ void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GL
glDeleteFramebuffers(1, &fboID);
}
-void GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitmap& bitmap, GLint filter)
+void GLUtils::updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap,
+ const IntRect& inval, GLint filter)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
@@ -524,13 +529,18 @@ void GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitm
int internalformat = getInternalFormat(config);
int type = getType(config);
bitmap.lockPixels();
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, bitmap.width(), bitmap.height(),
- internalformat, type, bitmap.getPixels());
+ if (inval.isEmpty()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+ internalformat, type, bitmap.getPixels());
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), inval.width(), inval.height(),
+ internalformat, type, bitmap.getPixels());
+ }
bitmap.unlockPixels();
if (GLUtils::checkGlError("glTexSubImage2D")) {
XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
- " x %d, y %d, internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
- bitmap.width(), bitmap.height(), x, y, internalformat, type, bitmap.getPixels());
+ " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
+ bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.h b/Source/WebCore/platform/graphics/android/GLUtils.h
index 3475760..b198d35 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.h
+++ b/Source/WebCore/platform/graphics/android/GLUtils.h
@@ -74,12 +74,12 @@ public:
static GLuint createBaseTileGLTexture(int width, int height);
static void createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
- static void updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
+ static void updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, const IntRect&, GLint filter = GL_LINEAR);
static void createEGLImageFromTexture(GLuint texture, EGLImageKHR* image);
static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR);
static void paintTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap);
- static void updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap);
+ static void updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* , const SkBitmap& bitmap);
static void convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix);
static bool isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor);
diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
index 0c92de4..4b6d2de 100644
--- a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
@@ -112,8 +112,14 @@ void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
device->unref();
- // ensure the canvas origin is translated to the coordinates of our inval rect
- canvas->translate(-renderInfo.invalRect->fLeft, -renderInfo.invalRect->fTop);
+ // If we have a partially painted bitmap
+ if (renderInfo.invalRect) {
+ SkRect clipRect = SkRect::MakeWH(renderInfo.invalRect->width(),
+ renderInfo.invalRect->height());
+ // ensure the canvas origin is translated to the coordinates of our inval rect
+ canvas->clipRect(clipRect);
+ canvas->translate(-renderInfo.invalRect->fLeft, -renderInfo.invalRect->fTop);
+ }
}
void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas)
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index 56d79a1..00f851b 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -107,7 +107,8 @@ void TransferQueue::initGLResources(int width, int height)
glGenTextures(1, &m_sharedSurfaceTextureId);
m_sharedSurfaceTexture =
#if GPU_UPLOAD_WITHOUT_DRAW
- new android::SurfaceTexture(m_sharedSurfaceTextureId, true, GL_TEXTURE_2D);
+ new android::SurfaceTexture(m_sharedSurfaceTextureId, true,
+ GL_TEXTURE_2D, false);
#else
new android::SurfaceTexture(m_sharedSurfaceTextureId);
#endif
@@ -162,20 +163,46 @@ bool TransferQueue::checkObsolete(const TileTransferData* data)
}
void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
+ BaseTileTexture* frontTex,
GLuint srcTexId, GLenum srcTexTarget,
int index)
{
#if GPU_UPLOAD_WITHOUT_DRAW
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
+ glBindTexture(GL_TEXTURE_2D, destTex->m_ownTextureId);
+
+ int textureWidth = destTex->getSize().width();
+ int textureHeight = destTex->getSize().height();
+
+ IntRect inval = m_transferQueue[index].tileInfo.m_inval;
+ bool partialInval = !inval.isEmpty();
+
+ if (partialInval && frontTex) {
+ // recopy the previous texture to the new one, as
+ // the partial update will not cover the entire texture
+ glFramebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ frontTex->m_ownTextureId,
+ 0);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
+ textureWidth, textureHeight);
+ }
+
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
srcTexId,
0);
- glBindTexture(GL_TEXTURE_2D, destTex->m_ownTextureId);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
- destTex->getSize().width(),
- destTex->getSize().height());
+
+ if (!partialInval) {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
+ textureWidth, textureHeight);
+ } else {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), 0, 0,
+ inval.width(), inval.height());
+ }
+
#else
// Then set up the FBO and copy the SurfTex content in.
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
@@ -356,8 +383,14 @@ void TransferQueue::updateDirtyBaseTiles()
// Save the needed info, update the Surf Tex, clean up the item in
// the queue. Then either move on to next item or copy the content.
BaseTileTexture* destTexture = 0;
- if (!obsoleteBaseTile)
+ BaseTileTexture* frontTexture = 0;
+ if (!obsoleteBaseTile) {
destTexture = m_transferQueue[index].savedBaseTilePtr->backTexture();
+ // while destTexture is guaranteed to not be null, frontTexture
+ // might be (first transfer)
+ frontTexture = m_transferQueue[index].savedBaseTilePtr->frontTexture();
+ }
+
if (m_transferQueue[index].uploadType == GpuUpload) {
status_t result = m_sharedSurfaceTexture->updateTexImage();
if (result != OK)
@@ -376,14 +409,15 @@ void TransferQueue::updateDirtyBaseTiles()
if (m_transferQueue[index].uploadType == CpuUpload) {
// Here we just need to upload the bitmap content to the GL Texture
- GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId, 0, 0,
- *m_transferQueue[index].bitmap);
+ GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId,
+ *m_transferQueue[index].bitmap,
+ m_transferQueue[index].tileInfo.m_inval);
} else {
if (!usedFboForUpload) {
saveGLState();
usedFboForUpload = true;
}
- blitTileFromQueue(m_fboID, destTexture,
+ blitTileFromQueue(m_fboID, destTexture, frontTexture,
m_sharedSurfaceTextureId,
m_sharedSurfaceTexture->getCurrentTextureTarget(),
index);
@@ -420,9 +454,9 @@ void TransferQueue::updateDirtyBaseTiles()
}
void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
- int x, int y, const SkBitmap& bitmap)
+ const SkBitmap& bitmap)
{
- if (!tryUpdateQueueWithBitmap(renderInfo, x, y, bitmap)) {
+ if (!tryUpdateQueueWithBitmap(renderInfo, bitmap)) {
// failed placing bitmap in queue, discard tile's texture so it will be
// re-enqueued (and repainted)
BaseTile* tile = renderInfo->baseTile;
@@ -432,7 +466,7 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
}
bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
- int x, int y, const SkBitmap& bitmap)
+ const SkBitmap& bitmap)
{
// This lock need to cover the full update since it is possible that queue
// will be cleaned up in the middle of this update without the lock.
@@ -462,9 +496,10 @@ bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
int bpp = 4; // Now we only deal with RGBA8888 format.
int width = TilesManager::instance()->tileWidth();
int height = TilesManager::instance()->tileHeight();
- if (!x && !y && bitmap.width() == width && bitmap.height() == height) {
+ if (bitmap.width() == width && bitmap.height() == height) {
bitmap.lockPixels();
uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
+
if (buffer.stride != bitmap.width())
// Copied line by line since we need to handle the offsets and stride.
for (row = 0 ; row < bitmap.height(); row ++) {
@@ -476,9 +511,6 @@ bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
bitmap.unlockPixels();
- } else {
- // TODO: implement the partial invalidate here!
- XLOG("ERROR: don't expect to get here yet before we support partial inval");
}
ANativeWindow_unlockAndPost(m_ANW.get());
@@ -517,6 +549,15 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo,
// Now fill the tileInfo.
TextureTileInfo* textureInfo = &(data->tileInfo);
+ IntRect inval(0, 0, 0, 0);
+ if (renderInfo->invalRect) {
+ inval.setX(renderInfo->invalRect->fLeft);
+ inval.setY(renderInfo->invalRect->fTop);
+ inval.setWidth(renderInfo->invalRect->width());
+ inval.setHeight(renderInfo->invalRect->height());
+ }
+ textureInfo->m_inval = inval;
+
textureInfo->m_x = renderInfo->x;
textureInfo->m_y = renderInfo->y;
textureInfo->m_scale = renderInfo->scale;
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h
index a18d448..ec3e5e2 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.h
@@ -119,7 +119,7 @@ public:
void initGLResources(int width, int height);
// insert the bitmap into the queue, mark the tile dirty if failing
- void updateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
+ void updateQueueWithBitmap(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap);
void addItemInTransferQueue(const TileRenderInfo* info,
@@ -151,7 +151,7 @@ public:
private:
// return true if successfully inserted into queue
- bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
+ bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap);
bool getHasGLContext();
void setHasGLContext(bool hasContext);
@@ -172,6 +172,7 @@ private:
void cleanupPendingDiscard();
void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
+ BaseTileTexture* frontTex,
GLuint srcTexId, GLenum srcTexTarget,
int index);
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index fd1a833..1fb3c75 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -283,7 +283,6 @@ struct WebViewCore::JavaGlue {
jmethodID m_restoreScale;
jmethodID m_needTouchEvents;
jmethodID m_requestKeyboard;
- jmethodID m_requestKeyboardWithSelection;
jmethodID m_exceededDatabaseQuota;
jmethodID m_reachedMaxAppCacheSize;
jmethodID m_populateVisitedLinks;
@@ -417,7 +416,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_restoreScale = GetJMethod(env, clazz, "restoreScale", "(FF)V");
m_javaGlue->m_needTouchEvents = GetJMethod(env, clazz, "needTouchEvents", "(Z)V");
m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(Z)V");
- m_javaGlue->m_requestKeyboardWithSelection = GetJMethod(env, clazz, "requestKeyboardWithSelection", "(IIII)V");
m_javaGlue->m_exceededDatabaseQuota = GetJMethod(env, clazz, "exceededDatabaseQuota", "(Ljava/lang/String;Ljava/lang/String;JJ)V");
m_javaGlue->m_reachedMaxAppCacheSize = GetJMethod(env, clazz, "reachedMaxAppCacheSize", "(J)V");
m_javaGlue->m_populateVisitedLinks = GetJMethod(env, clazz, "populateVisitedLinks", "()V");
@@ -447,7 +445,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
#endif
m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V");
m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V");
- m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(Ljava/lang/String;II)V");
+ m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;II)V");
env->DeleteLocalRef(clazz);
env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
@@ -1156,22 +1154,6 @@ void WebViewCore::needTouchEvents(bool need)
#endif
}
-void WebViewCore::requestKeyboardWithSelection(const WebCore::Node* node,
- int selStart, int selEnd)
-{
- DEBUG_NAV_UI_LOGD("%s", __FUNCTION__);
- ALOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
-
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject javaObject = m_javaGlue->object(env);
- if (!javaObject.get())
- return;
- env->CallVoidMethod(javaObject.get(),
- m_javaGlue->m_requestKeyboardWithSelection,
- reinterpret_cast<int>(node), selStart, selEnd, m_textGeneration);
- checkException(env);
-}
-
void WebViewCore::requestKeyboard(bool showKeyboard)
{
DEBUG_NAV_UI_LOGD("%s", __FUNCTION__);
@@ -1660,48 +1642,55 @@ static IntRect getAbsoluteBoundingBox(Node* node) {
return rect;
}
+WebCore::Frame* WebViewCore::focusedFrame() const
+{
+ return m_mainFrame->page()->focusController()->focusedOrMainFrame();
+}
+
VisiblePosition WebViewCore::visiblePositionForContentPoint(int x, int y)
{
- IntPoint point(x, y);
+ return visiblePositionForContentPoint(IntPoint(x, y));
+}
+VisiblePosition WebViewCore::visiblePositionForContentPoint(const IntPoint& point)
+{
// Hit test of this kind required for this to work inside input fields
- HitTestRequest request(HitTestRequest::Active | HitTestRequest::MouseMove | HitTestRequest::ReadOnly);
-
- // Look for the inner-most frame containing the hit. Its document
- // contains the document with the selected text.
- Frame* frame = m_mainFrame;
- Frame* hitFrame = m_mainFrame;
- Node* node = 0;
- IntPoint localPoint = point;
- do {
- HitTestResult result(localPoint);
- frame = hitFrame;
- frame->document()->renderView()->layer()->hitTest(request, result);
- node = result.innerNode();
- if (!node)
- return VisiblePosition();
-
- if (node->isFrameOwnerElement())
- hitFrame = static_cast<HTMLFrameOwnerElement*>(node)->contentFrame();
- localPoint = result.localPoint();
- } while (hitFrame && hitFrame != frame);
+ HitTestRequest request(HitTestRequest::Active
+ | HitTestRequest::MouseMove
+ | HitTestRequest::ReadOnly
+ | HitTestRequest::IgnoreClipping);
+ HitTestResult result(point);
+ focusedFrame()->document()->renderView()->layer()->hitTest(request, result);
+ // Matching the logic in MouseEventWithHitTestResults::targetNode()
+ Node* node = result.innerNode();
+ if (!node)
+ return VisiblePosition();
Element* element = node->parentElement();
if (!node->inDocument() && element && element->inDocument())
node = element;
- RenderObject* renderer = node->renderer();
- return renderer->positionForPoint(localPoint);
+ return node->renderer()->positionForPoint(result.localPoint());
}
void WebViewCore::selectWordAt(int x, int y)
{
- IntPoint point(x, y);
+ HitTestResult hoverResult;
+ moveMouse(m_mainFrame, x, y, &hoverResult);
+ if (hoverResult.innerNode()) {
+ Node* node = hoverResult.innerNode();
+ Frame* frame = node->document()->frame();
+ Page* page = m_mainFrame->document()->page();
+ page->focusController()->setFocusedFrame(frame);
+ }
+
+ IntPoint point = convertGlobalContentToFrameContent(IntPoint(x, y));
// Hit test of this kind required for this to work inside input fields
HitTestRequest request(HitTestRequest::Active);
HitTestResult result(point);
- m_mainFrame->document()->renderView()->layer()->hitTest(request, result);
+
+ focusedFrame()->document()->renderView()->layer()->hitTest(request, result);
// Matching the logic in MouseEventWithHitTestResults::targetNode()
Node* node = result.innerNode();
@@ -1711,7 +1700,7 @@ void WebViewCore::selectWordAt(int x, int y)
if (!node->inDocument() && element && element->inDocument())
node = element;
- SelectionController* sc = m_mainFrame->selection();
+ SelectionController* sc = focusedFrame()->selection();
if (!sc->contains(point) && (node->isContentEditable() || node->isTextNode()) && !result.isLiveLink()
&& node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true))) {
VisiblePosition pos(node->renderer()->positionForPoint(result.localPoint()));
@@ -1775,22 +1764,11 @@ void WebViewCore::layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& off
}
}
-void setCaretInfo(const VisiblePosition& pos, SelectText::HandleId handle,
- SelectText* target)
-{
- IntPoint offset;
- LayerAndroid* layer = 0;
- IntRect rect = pos.absoluteCaretBounds();
- int layerId = WebViewCore::platformLayerIdFromNode(pos.deepEquivalent().anchorNode(), &layer);
- WebViewCore::layerToAbsoluteOffset(layer, offset);
- rect.move(-offset.x(), -offset.y());
- target->setCaretRect(handle, rect);
- target->setCaretLayerId(handle, layerId);
-}
-
SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
{
- if (!selection.isRange())
+ // We need to agressively check to see if this is an empty selection to prevent
+ // accidentally entering text selection mode
+ if (!selection.isRange() || !comparePositions(selection.start(), selection.end()))
return 0;
RefPtr<Range> range = selection.firstRange();
@@ -1799,9 +1777,14 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
if (!startContainer || !endContainer)
return 0;
+ if (startContainer == endContainer && range->startOffset() == range->endOffset())
+ return 0;
SelectText* selectTextContainer = new SelectText();
+ IntPoint frameOffset = convertGlobalContentToFrameContent(IntPoint());
+ IntRect startHandle;
+ IntRect endHandle;
Node* stopNode = range->pastLastNode();
for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) {
RenderObject* r = node->renderer();
@@ -1811,33 +1794,59 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
int startOffset = node == startContainer ? range->startOffset() : 0;
int endOffset = node == endContainer ? range->endOffset() : numeric_limits<int>::max();
LayerAndroid* layer = 0;
- platformLayerIdFromNode(node, &layer);
+ int layerId = platformLayerIdFromNode(node, &layer);
Vector<IntRect> rects;
renderText->absoluteRectsForRange(rects, startOffset, endOffset, true);
- selectTextContainer->addHighlightRegion(layer, rects);
+ if (rects.size()) {
+ IntPoint offset;
+ layerToAbsoluteOffset(layer, offset);
+ endHandle = rects[rects.size() - 1];
+ endHandle.move(-offset.x(), -offset.y());
+ selectTextContainer->setCaretLayerId(SelectText::EndHandle, layerId);
+ if (startHandle.isEmpty()) {
+ startHandle = rects[0];
+ startHandle.move(-offset.x(), -offset.y());
+ selectTextContainer->setCaretLayerId(SelectText::StartHandle, layerId);
+ }
+ }
+ selectTextContainer->addHighlightRegion(layer, rects, frameOffset);
}
IntRect caretRect;
int layerId;
selectTextContainer->setBaseFirst(selection.isBaseFirst());
- ALOGD("isBaseFirst: %s", selectTextContainer->isBaseFirst() ? "true" : "false");
- setCaretInfo(selection.visibleStart(), SelectText::StartHandle, selectTextContainer);
- setCaretInfo(selection.visibleEnd(), SelectText::EndHandle, selectTextContainer);
+
+ // Squish the handle rects
+ startHandle.setWidth(1);
+ endHandle.move(endHandle.width() - 1, 0);
+ endHandle.setWidth(1);
+ startHandle.move(-frameOffset.x(), -frameOffset.y());
+ selectTextContainer->setCaretRect(SelectText::StartHandle, startHandle);
+ endHandle.move(-frameOffset.x(), -frameOffset.y());
+ selectTextContainer->setCaretRect(SelectText::EndHandle, endHandle);
selectTextContainer->setText(range->text());
return selectTextContainer;
}
+IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point)
+{
+ IntPoint frameOffset(-m_scrollOffsetX, -m_scrollOffsetY);
+ frameOffset = focusedFrame()->view()->windowToContents(frameOffset);
+ return IntPoint(point.x() + frameOffset.x(), point.y() + frameOffset.y());
+}
+
void WebViewCore::selectText(int startX, int startY, int endX, int endY)
{
- SelectionController* sc = m_mainFrame->selection();
- VisiblePosition startPosition(visiblePositionForContentPoint(startX, startY));
- VisiblePosition endPosition(visiblePositionForContentPoint(endX, endY));
+ SelectionController* sc = focusedFrame()->selection();
+ IntPoint startPoint = convertGlobalContentToFrameContent(IntPoint(startX, startY));
+ VisiblePosition startPosition(visiblePositionForContentPoint(startPoint));
+ IntPoint endPoint = convertGlobalContentToFrameContent(IntPoint(endX, endY));
+ VisiblePosition endPosition(visiblePositionForContentPoint(endPoint));
- if (startPosition.isNull() || endPosition.isNull() || startPosition == endPosition) {
+ if (startPosition.isNull() || endPosition.isNull() || startPosition == endPosition)
return;
- }
// Ensure startPosition is before endPosition
if (comparePositions(startPosition, endPosition) > 0)
@@ -1865,9 +1874,8 @@ void WebViewCore::selectText(int startX, int startY, int endX, int endY)
}
VisibleSelection selection(startPosition, endPosition);
- if (selection.isRange() && sc->shouldChangeSelection(selection)) {
+ if (selection.isRange() && sc->shouldChangeSelection(selection))
sc->setSelection(selection);
- }
}
// get the highlight rectangles for the touch point (x, y) with the slop
@@ -2336,7 +2344,7 @@ void WebViewCore::moveFocus(WebCore::Frame* frame, WebCore::Node* node)
}
// Update mouse position
-void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y)
+void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y, HitTestResult* hoveredNode)
{
DBG_NAV_LOGD("frame=%p x=%d y=%d scrollOffset=(%d,%d)", frame,
x, y, m_scrollOffsetX, m_scrollOffsetY);
@@ -2349,7 +2357,7 @@ void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y)
WebCore::PlatformMouseEvent mouseEvent(m_mousePos, m_mousePos,
WebCore::NoButton, WebCore::MouseEventMoved, 1, false, false, false,
false, WTF::currentTime());
- frame->eventHandler()->handleMouseMoveEvent(mouseEvent);
+ frame->eventHandler()->handleMouseMoveEvent(mouseEvent, hoveredNode);
#if ENABLE(ANDROID_NAVCACHE)
updateCacheOnNodeChange();
#endif
@@ -2357,12 +2365,8 @@ void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y)
Position WebViewCore::getPositionForOffset(Node* node, int offset)
{
- Position positionInNode(node, 0);
- Node* highest = highestEditableRoot(positionInNode);
- if (!highest)
- highest = node;
- Position start = firstPositionInNode(highest);
- Position end = lastPositionInNode(highest);
+ Position start = firstPositionInNode(node);
+ Position end = lastPositionInNode(node);
Document* document = node->document();
PassRefPtr<Range> range = Range::create(document, start, end);
WebCore::CharacterIterator iterator(range.get());
@@ -3325,7 +3329,11 @@ bool WebViewCore::key(const PlatformKeyboardEvent& event)
WebFrame* webFrame = WebFrame::getWebFrame(frame);
eventHandler = frame->eventHandler();
VisibleSelection old = frame->selection()->selection();
+ EditorClientAndroid* client = static_cast<EditorClientAndroid*>(
+ m_mainFrame->editor()->client());
+ client->setUiGeneratedSelectionChange(true);
bool handled = eventHandler->keyEvent(event);
+ client->setUiGeneratedSelectionChange(false);
if (isContentEditable(focusNode)) {
// keyEvent will return true even if the contentEditable did not
// change its selection. In the case that it does not, we want to
@@ -3563,8 +3571,7 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
m_frameCacheOutOfDate = true;
updateFrameCache();
#endif
- requestKeyboardWithSelection(focusNode, rtc->selectionStart(),
- rtc->selectionEnd());
+ initEditField(focusNode);
}
} else if (!fake) {
requestKeyboard(false);
@@ -3575,7 +3582,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
// input is needed.
if (isContentEditable(focusNode)) {
initEditField(focusNode);
- requestKeyboard(true);
} else if (!nodeIsPlugin(focusNode)) {
clearTextEntry();
}
@@ -3597,9 +3603,10 @@ void WebViewCore::initEditField(Node* node)
AutoJObject javaObject = m_javaGlue->object(env);
if (!javaObject.get())
return;
+ m_textGeneration = 0;
jstring fieldText = wtfStringToJstring(env, text, true);
env->CallVoidMethod(javaObject.get(), m_javaGlue->m_initEditField,
- fieldText, start, end);
+ reinterpret_cast<int>(node), fieldText, start, end);
checkException(env);
}
@@ -3867,8 +3874,7 @@ void WebViewCore::getSelectionOffsets(Node* node, int& start, int& end)
SelectionController* selector = frame->selection();
Position selectionStart = selector->start();
Position selectionEnd = selector->end();
- Node* editable = highestEditableRoot(selectionStart);
- Position startOfNode = firstPositionInNode(editable);
+ Position startOfNode = firstPositionInNode(node);
RefPtr<Range> startRange = Range::create(document, startOfNode,
selectionStart);
start = TextIterator::rangeLength(startRange.get(), true);
@@ -3887,13 +3893,10 @@ String WebViewCore::getInputText(Node* node)
else {
// It must be content editable field.
Position inNode(node, 0);
- Node* editable = highestEditableRoot(inNode);
- if (editable) {
- Position start = firstPositionInNode(editable);
- Position end = lastPositionInNode(editable);
- VisibleSelection allEditableText(start, end);
- text = allEditableText.firstRange()->text();
- }
+ Position start = firstPositionInNode(node);
+ Position end = lastPositionInNode(node);
+ VisibleSelection allEditableText(start, end);
+ text = allEditableText.firstRange()->text();
}
return text;
}
@@ -3909,7 +3912,7 @@ void WebViewCore::updateTextSelection()
int end = 0;
if (focusNode)
getSelectionOffsets(focusNode, start, end);
- SelectText* selectText = createSelectText(m_mainFrame->selection()->selection());
+ SelectText* selectText = createSelectText(focusedFrame()->selection()->selection());
env->CallVoidMethod(javaObject.get(),
m_javaGlue->m_updateTextSelection, reinterpret_cast<int>(focusNode),
start, end, m_textGeneration, selectText);
@@ -5002,7 +5005,7 @@ static void SelectText(JNIEnv* env, jobject obj, jint nativeClass,
static void ClearSelection(JNIEnv* env, jobject obj, jint nativeClass)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- viewImpl->mainFrame()->selection()->clear();
+ viewImpl->focusedFrame()->selection()->clear();
}
static void SelectWordAt(JNIEnv* env, jobject obj, jint nativeClass, jint x, jint y)
@@ -5014,7 +5017,7 @@ static void SelectWordAt(JNIEnv* env, jobject obj, jint nativeClass, jint x, jin
static void SelectAll(JNIEnv* env, jobject obj, jint nativeClass)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- viewImpl->mainFrame()->selection()->selectAll();
+ viewImpl->focusedFrame()->selection()->selectAll();
}
// ----------------------------------------------------------------------------
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index cb345dd..034229d 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -305,7 +305,7 @@ namespace android {
void recordPicture(SkPicture* picture);
void moveFocus(WebCore::Frame* frame, WebCore::Node* node);
- void moveMouse(WebCore::Frame* frame, int x, int y);
+ void moveMouse(WebCore::Frame* frame, int x, int y, HitTestResult* hoveredNode = 0);
void moveMouseIfLatest(int moveGeneration,
WebCore::Frame* frame, int x, int y);
@@ -547,6 +547,7 @@ namespace android {
float scale() const { return m_scale; }
float textWrapScale() const { return m_screenWidth * m_scale / m_textWrapWidth; }
WebCore::Frame* mainFrame() const { return m_mainFrame; }
+ WebCore::Frame* focusedFrame() const;
void updateCursorBounds(const CachedRoot* root,
const CachedFrame* cachedFrame, const CachedNode* cachedNode);
@@ -607,6 +608,9 @@ namespace android {
void selectText(int startX, int startY, int endX, int endY);
void selectWordAt(int x, int y);
+ // Converts from the global content coordinates that WebView sends
+ // to frame-local content coordinates using the focused frame
+ IntPoint convertGlobalContentToFrameContent(const IntPoint& point);
static void layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& offset);
/**
@@ -675,13 +679,12 @@ namespace android {
Node* getImplicitBoundaryNode(Node* node, unsigned offset, int direction);
/**
* Calls into java to reset the text edit field with the
- * current contents and selection. This currently works only with
- * content-editable fields.
+ * current contents and selection.
*/
void initEditField(Node* node);
/**
* Returns the offsets of the selection area for both normal text
- * fields and content-editable fields. start and end are modified
+ * fields and content editable fields. start and end are modified
* by this method.
*/
static void getSelectionOffsets(Node* node, int& start, int& end);
@@ -702,14 +705,14 @@ namespace android {
static void setSelection(Node* node, int start, int end);
/**
* Returns the Position for the given offset for an editable
- * field. If node is editable the offset relative to the highest
- * editable node. If it is not editable, the offset is relative to node.
+ * field. The offset is relative to the node start.
*/
static WebCore::Position getPositionForOffset(Node* node, int offset);
VisiblePosition visiblePositionForContentPoint(int x, int y);
+ VisiblePosition visiblePositionForContentPoint(const IntPoint& point);
void selectWordAroundPosition(Frame* frame, VisiblePosition pos);
- static SelectText* createSelectText(const VisibleSelection&);
+ SelectText* createSelectText(const VisibleSelection&);
// called from constructor, to add this to a global list
static void addInstance(WebViewCore*);
diff --git a/Source/WebKit/android/nav/DrawExtra.cpp b/Source/WebKit/android/nav/DrawExtra.cpp
index 564cc21..2f57dc1 100644
--- a/Source/WebKit/android/nav/DrawExtra.cpp
+++ b/Source/WebKit/android/nav/DrawExtra.cpp
@@ -51,7 +51,8 @@ SkRegion* RegionLayerDrawExtra::getHighlightRegionsForLayer(const LayerAndroid*
return m_highlightRegions.get(layerId);
}
-void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects)
+void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects,
+ const IntPoint& additionalOffset)
{
if (rects.isEmpty())
return;
@@ -61,7 +62,7 @@ void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const V
region = new SkRegion();
m_highlightRegions.set(layerId, region);
}
- IntPoint offset;
+ IntPoint offset = additionalOffset;
WebViewCore::layerToAbsoluteOffset(layer, offset);
for (size_t i = 0; i < rects.size(); i++) {
IntRect r = rects.at(i);
diff --git a/Source/WebKit/android/nav/DrawExtra.h b/Source/WebKit/android/nav/DrawExtra.h
index 0cee861..83e7dcd 100644
--- a/Source/WebKit/android/nav/DrawExtra.h
+++ b/Source/WebKit/android/nav/DrawExtra.h
@@ -65,7 +65,8 @@ public:
RegionLayerDrawExtra();
virtual ~RegionLayerDrawExtra();
- void addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects);
+ void addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects,
+ const IntPoint& additionalOffset = IntPoint());
virtual void draw(SkCanvas*, LayerAndroid*);
virtual void drawGL(GLExtras*, const LayerAndroid*);
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 8e819fb..c12adb5 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -1418,15 +1418,16 @@ int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) {
if (!selectText)
return -1;
int layerId = selectText->caretLayerId(handleId);
- const IntRect& r = selectText->caretRect(handleId);
- cursorRect.set(r.x(), r.y(), r.maxX(), r.maxY());
+ IntRect rect = selectText->caretRect(handleId);
if (layerId != -1) {
+ // We need to make sure the drawTransform is up to date as this is
+ // called before a draw() or drawGL()
+ m_baseLayer->updateLayerPositions(m_visibleRect);
LayerAndroid* root = compositeRoot();
LayerAndroid* layer = root ? root->findById(layerId) : 0;
- IntPoint offset;
- WebViewCore::layerToAbsoluteOffset(layer, offset);
- cursorRect.offset(offset.x(), offset.y());
+ rect = layer->drawTransform()->mapRect(rect);
}
+ cursorRect.set(rect.x(), rect.y(), rect.maxX(), rect.maxY());
return layerId;
}