summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/android/nav/WebView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/android/nav/WebView.cpp')
-rw-r--r--Source/WebKit/android/nav/WebView.cpp256
1 files changed, 148 insertions, 108 deletions
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index eddf0ab..a4381e6 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -30,13 +30,16 @@
#include "AndroidAnimation.h"
#include "AndroidLog.h"
#include "BaseLayerAndroid.h"
+#include "BaseRenderer.h"
#include "DrawExtra.h"
#include "Frame.h"
+#include "GLWebViewState.h"
#include "GraphicsJNI.h"
#include "HTMLInputElement.h"
#include "IntPoint.h"
#include "IntRect.h"
#include "LayerAndroid.h"
+#include "LayerContent.h"
#include "Node.h"
#include "utils/Functor.h"
#include "private/hwui/DrawGlInfo.h"
@@ -50,6 +53,7 @@
#include "SkRect.h"
#include "SkTime.h"
#include "TilesManager.h"
+#include "TransferQueue.h"
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebViewCore.h"
@@ -124,6 +128,10 @@ struct JavaGlue {
jfieldID m_rectTop;
jmethodID m_rectWidth;
jmethodID m_rectHeight;
+ jfieldID m_quadFP1;
+ jfieldID m_quadFP2;
+ jfieldID m_quadFP3;
+ jfieldID m_quadFP4;
AutoJObject object(JNIEnv* env) {
return getRealObject(env, m_obj);
}
@@ -155,6 +163,14 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir,
m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I");
env->DeleteLocalRef(rectClass);
+ jclass quadFClass = env->FindClass("android/webkit/QuadF");
+ ALOG_ASSERT(quadFClass, "Could not find QuadF class");
+ m_javaGlue.m_quadFP1 = env->GetFieldID(quadFClass, "p1", "Landroid/graphics/PointF;");
+ m_javaGlue.m_quadFP2 = env->GetFieldID(quadFClass, "p2", "Landroid/graphics/PointF;");
+ m_javaGlue.m_quadFP3 = env->GetFieldID(quadFClass, "p3", "Landroid/graphics/PointF;");
+ m_javaGlue.m_quadFP4 = env->GetFieldID(quadFClass, "p4", "Landroid/graphics/PointF;");
+ env->DeleteLocalRef(quadFClass);
+
env->SetIntField(javaWebView, gWebViewField, (jint)this);
m_viewImpl = (WebViewCore*) viewImpl;
m_generation = 0;
@@ -235,25 +251,18 @@ void scrollRectOnScreen(const IntRect& rect)
viewInvalidate();
}
-bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
+int drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
WebCore::IntRect& webViewRect, int titleBarHeight,
- WebCore::IntRect& clip, float scale, int extras)
+ WebCore::IntRect& clip, float scale, int extras, bool shouldDraw)
{
#if USE(ACCELERATED_COMPOSITING)
if (!m_baseLayer)
- return false;
+ return 0;
if (!m_glWebViewState) {
TilesManager::instance()->setHighEndGfx(m_isHighEndGfx);
m_glWebViewState = new GLWebViewState();
- if (m_baseLayer->content()) {
- SkRegion region;
- SkIRect rect;
- rect.set(0, 0, m_baseLayer->content()->width(), m_baseLayer->content()->height());
- region.setRect(rect);
- m_baseLayer->markAsDirty(region);
- m_glWebViewState->setBaseLayer(m_baseLayer, false, true);
- }
+ m_glWebViewState->setBaseLayer(m_baseLayer, false, true);
}
DrawExtra* extra = getDrawExtra((DrawExtras) extras);
@@ -264,12 +273,12 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
// if the zoom manager is still initializing. We will be redrawn
// once the correct scale is set
if (!m_visibleRect.isFinite())
- return false;
+ return 0;
bool treesSwapped = false;
bool newTreeHasAnim = false;
- bool ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect,
+ int ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect,
webViewRect, titleBarHeight, clip, scale,
- &treesSwapped, &newTreeHasAnim);
+ &treesSwapped, &newTreeHasAnim, shouldDraw);
if (treesSwapped) {
ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
@@ -279,10 +288,9 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
checkException(env);
}
}
- if (ret)
- return !m_isDrawingPaused;
+ return m_isDrawingPaused ? 0 : ret;
#endif
- return false;
+ return 0;
}
PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool split)
@@ -295,37 +303,24 @@ PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool spli
// draw the content of the base layer first
LayerContent* content = m_baseLayer->content();
-
int sc = canvas->save(SkCanvas::kClip_SaveFlag);
canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(),
content->height()), SkRegion::kDifference_Op);
canvas->drawColor(bgColor);
canvas->restoreToCount(sc);
- content->draw(canvas);
- DrawExtra* extra = getDrawExtra(extras);
- if (extra)
- extra->draw(canvas, 0);
+ // call this to be sure we've adjusted for any scrolling or animations
+ // before we actually draw
+ m_baseLayer->updateLayerPositions(m_visibleRect);
+ m_baseLayer->updatePositions();
+
+ // We have to set the canvas' matrix on the base layer
+ // (to have fixed layers work as intended)
+ SkAutoCanvasRestore restore(canvas, true);
+ m_baseLayer->setMatrix(canvas->getTotalMatrix());
+ canvas->resetMatrix();
+ m_baseLayer->draw(canvas, getDrawExtra(extras));
-#if USE(ACCELERATED_COMPOSITING)
- LayerAndroid* compositeLayer = compositeRoot();
- if (compositeLayer) {
- // call this to be sure we've adjusted for any scrolling or animations
- // before we actually draw
- compositeLayer->updateLayerPositions(m_visibleRect);
- compositeLayer->updatePositions();
- // We have to set the canvas' matrix on the base layer
- // (to have fixed layers work as intended)
- SkAutoCanvasRestore restore(canvas, true);
- m_baseLayer->setMatrix(canvas->getTotalMatrix());
- canvas->resetMatrix();
- m_baseLayer->draw(canvas, extra);
- }
- if (extra) {
- IntRect dummy; // inval area, unused for now
- extra->drawLegacy(canvas, compositeLayer, &dummy);
- }
-#endif
return ret;
}
@@ -415,11 +410,9 @@ static const ScrollableLayerAndroid* findScrollableLayer(
int scrollableLayer(int x, int y, SkIRect* layerRect, SkIRect* bounds)
{
#if USE(ACCELERATED_COMPOSITING)
- const LayerAndroid* layerRoot = compositeRoot();
- if (!layerRoot)
+ if (!m_baseLayer)
return 0;
- const ScrollableLayerAndroid* result = findScrollableLayer(layerRoot, x, y,
- bounds);
+ const ScrollableLayerAndroid* result = findScrollableLayer(m_baseLayer, x, y, bounds);
if (result) {
result->getScrollRect(layerRect);
return result->uniqueId();
@@ -500,16 +493,6 @@ void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds)
checkException(env);
}
-LayerAndroid* compositeRoot() const
-{
- ALOG_ASSERT(!m_baseLayer || m_baseLayer->countChildren() == 1,
- "base layer can't have more than one child %s", __FUNCTION__);
- if (m_baseLayer && m_baseLayer->countChildren() == 1)
- return static_cast<LayerAndroid*>(m_baseLayer->getChild(0));
- else
- return 0;
-}
-
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
static void copyScrollPositionRecursive(const LayerAndroid* from,
LayerAndroid* root)
@@ -529,28 +512,30 @@ static void copyScrollPositionRecursive(const LayerAndroid* from,
}
#endif
-bool setBaseLayer(BaseLayerAndroid* layer, SkRegion& inval, bool showVisualIndicator,
+BaseLayerAndroid* getBaseLayer() const { return m_baseLayer; }
+
+bool setBaseLayer(BaseLayerAndroid* newBaseLayer, SkRegion& inval, bool showVisualIndicator,
bool isPictureAfterFirstLayout)
{
bool queueFull = false;
#if USE(ACCELERATED_COMPOSITING)
if (m_glWebViewState) {
- if (layer)
- layer->markAsDirty(inval);
- queueFull = m_glWebViewState->setBaseLayer(layer, showVisualIndicator,
+ // TODO: mark as inval on webkit side
+ if (newBaseLayer)
+ newBaseLayer->markAsDirty(inval);
+ queueFull = m_glWebViewState->setBaseLayer(newBaseLayer, showVisualIndicator,
isPictureAfterFirstLayout);
}
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (layer) {
- // TODO: the below tree copies are only necessary in software rendering
- LayerAndroid* newCompositeRoot = static_cast<LayerAndroid*>(layer->getChild(0));
- copyScrollPositionRecursive(compositeRoot(), newCompositeRoot);
+ if (newBaseLayer) {
+ // TODO: the below tree position copies are only necessary in software rendering
+ copyScrollPositionRecursive(m_baseLayer, newBaseLayer);
}
#endif
SkSafeUnref(m_baseLayer);
- m_baseLayer = layer;
+ m_baseLayer = newBaseLayer;
return queueFull;
}
@@ -568,8 +553,8 @@ void copyBaseContentToPicture(SkPicture* picture)
if (!m_baseLayer)
return;
LayerContent* content = m_baseLayer->content();
- m_baseLayer->drawCanvas(picture->beginRecording(content->width(), content->height(),
- SkPicture::kUsePathBoundsForClip_RecordingFlag));
+ content->draw(picture->beginRecording(content->width(), content->height(),
+ SkPicture::kUsePathBoundsForClip_RecordingFlag));
picture->endRecording();
}
@@ -588,10 +573,6 @@ Functor* getFunctor() {
return m_glDrawFunctor;
}
-BaseLayerAndroid* getBaseLayer() {
- return m_baseLayer;
-}
-
void setVisibleRect(SkRect& visibleRect) {
m_visibleRect = visibleRect;
}
@@ -611,13 +592,34 @@ void setTextSelection(SelectText *selection) {
setDrawExtra(selection, DrawExtrasSelection);
}
-int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) {
+int getHandleLayerId(SelectText::HandleId handleId, SkIPoint& cursorPoint,
+ FloatQuad& textBounds) {
SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection));
if (!selectText || !m_baseLayer)
return -1;
int layerId = selectText->caretLayerId(handleId);
- cursorRect = selectText->caretRect(handleId);
- mapLayerRect(layerId, cursorRect);
+ IntRect cursorRect = selectText->caretRect(handleId);
+ IntRect textRect = selectText->textRect(handleId);
+ // Rects exclude the last pixel on right/bottom. We want only included pixels.
+ cursorPoint.set(cursorRect.x(), cursorRect.maxY() - 1);
+ textRect.setHeight(textRect.height() - 1);
+ textRect.setWidth(textRect.width() - 1);
+ textBounds = FloatQuad(textRect);
+
+ 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 = m_baseLayer;
+ LayerAndroid* layer = root ? root->findById(layerId) : 0;
+ if (layer && layer->drawTransform()) {
+ const TransformationMatrix* transform = layer->drawTransform();
+ // We're overloading the concept of Rect to be just the two
+ // points (bottom-left and top-right.
+ cursorPoint = transform->mapPoint(cursorPoint);
+ textBounds = transform->mapQuad(textBounds);
+ }
+ }
return layerId;
}
@@ -626,13 +628,40 @@ void mapLayerRect(int layerId, SkIRect& rect) {
// 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;
+ LayerAndroid* layer = m_baseLayer ? m_baseLayer->findById(layerId) : 0;
if (layer && layer->drawTransform())
rect = layer->drawTransform()->mapRect(rect);
}
}
+void floatQuadToQuadF(JNIEnv* env, const FloatQuad& nativeTextQuad,
+ jobject textQuad)
+{
+ jobject p1 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP1);
+ jobject p2 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP2);
+ jobject p3 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP3);
+ jobject p4 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP4);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p1(), env, p1);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p2(), env, p2);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p3(), env, p3);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p4(), env, p4);
+ env->DeleteLocalRef(p1);
+ env->DeleteLocalRef(p2);
+ env->DeleteLocalRef(p3);
+ env->DeleteLocalRef(p4);
+}
+
+// This is called when WebView switches rendering modes in a more permanent fashion
+// such as when the layer type is set or the view is attached/detached from the window
+int setHwAccelerated(bool hwAccelerated) {
+ if (!m_glWebViewState)
+ return 0;
+ LayerAndroid* root = m_baseLayer;
+ if (root)
+ return root->setHwAccelerated(hwAccelerated);
+ return 0;
+}
+
bool m_isDrawingPaused;
private: // local state for WebView
// private to getFrameCache(); other functions operate in a different thread
@@ -661,8 +690,8 @@ private: // local state for WebView
class GLDrawFunctor : Functor {
public:
GLDrawFunctor(WebView* _wvInstance,
- bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
- WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint),
+ int (WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
+ WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint, bool),
WebCore::IntRect _viewRect, float _scale, int _extras) {
wvInstance = _wvInstance;
funcPtr = _funcPtr;
@@ -687,16 +716,15 @@ class GLDrawFunctor : Functor {
WebCore::IntRect clip(info->clipLeft, info->clipTop,
info->clipRight - info->clipLeft,
info->clipBottom - info->clipTop);
+ bool shouldDraw = (messageId == uirenderer::DrawGlInfo::kModeDraw);
TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer);
-
- bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect,
- titlebarHeight, clip, scale, extras);
- if (retVal) {
+ int returnFlags = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect,
+ titlebarHeight, clip, scale, extras, shouldDraw);
+ if ((returnFlags & uirenderer::DrawGlInfo::kStatusDraw) != 0) {
IntRect finalInval;
- if (inval.isEmpty()) {
+ if (inval.isEmpty())
finalInval = webViewRect;
- retVal = true;
- } else {
+ else {
finalInval.setX(webViewRect.x() + inval.x());
finalInval.setY(webViewRect.y() + titlebarHeight + inval.y());
finalInval.setWidth(inval.width());
@@ -707,8 +735,9 @@ class GLDrawFunctor : Functor {
info->dirtyRight = finalInval.maxX();
info->dirtyBottom = finalInval.maxY();
}
- // return 1 if invalidation needed, 0 otherwise
- return retVal ? 1 : 0;
+ // return 1 if invalidation needed, 2 to request non-drawing functor callback, 0 otherwise
+ ALOGV("returnFlags are %d, shouldDraw %d", returnFlags, shouldDraw);
+ return returnFlags;
}
void updateRect(WebCore::IntRect& _viewRect) {
viewRect = _viewRect;
@@ -721,8 +750,8 @@ class GLDrawFunctor : Functor {
}
private:
WebView* wvInstance;
- bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
- WebCore::IntRect&, int, WebCore::IntRect&, float, int);
+ int (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
+ WebCore::IntRect&, int, WebCore::IntRect&, float, int, bool);
WebCore::IntRect viewRect;
WebCore::IntRect webViewRect;
jfloat scale;
@@ -815,10 +844,10 @@ static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint native
{
// only call in software rendering, initialize and evaluate animations
#if USE(ACCELERATED_COMPOSITING)
- LayerAndroid* root = ((WebView*)nativeView)->compositeRoot();
- if (root) {
- root->initAnimations();
- return root->evaluateAnimations();
+ BaseLayerAndroid* baseLayer = ((WebView*)nativeView)->getBaseLayer();
+ if (baseLayer) {
+ baseLayer->initAnimations();
+ return baseLayer->evaluateAnimations();
}
#endif
return false;
@@ -970,6 +999,7 @@ static void dumpToFile(const char text[], void* file) {
}
#endif
+// Return true to view invalidate WebView
static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jvalue)
{
WTF::String key = jstringToWtfString(env, jkey);
@@ -987,19 +1017,15 @@ static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jv
else if (key == "enable_cpu_upload_path") {
TilesManager::instance()->transferQueue()->setTextureUploadType(
value == "true" ? CpuUpload : GpuUpload);
- return true;
}
else if (key == "use_minimal_memory") {
TilesManager::instance()->setUseMinimalMemory(value == "true");
- return true;
}
else if (key == "use_double_buffering") {
TilesManager::instance()->setUseDoubleBuffering(value == "true");
- return true;
}
else if (key == "tree_updates") {
TilesManager::instance()->clearContentUpdates();
- return true;
}
return false;
}
@@ -1063,11 +1089,11 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
fclose(file);
}
#if USE(ACCELERATED_COMPOSITING)
- const LayerAndroid* rootLayer = view->compositeRoot();
- if (rootLayer) {
+ const LayerAndroid* baseLayer = view->getBaseLayer();
+ if (baseLayer) {
FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w");
if (file) {
- rootLayer->dumpLayers(file, 0);
+ baseLayer->dumpLayers(file, 0);
fclose(file);
}
}
@@ -1098,10 +1124,10 @@ static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x,
view->scrollLayer(layerId, x, y);
//TODO: the below only needed for the SW rendering path
- LayerAndroid* root = view->compositeRoot();
- if (!root)
+ LayerAndroid* baseLayer = view->getBaseLayer();
+ if (!baseLayer)
return false;
- LayerAndroid* layer = root->findById(layerId);
+ LayerAndroid* layer = baseLayer->findById(layerId);
if (!layer || !layer->contentIsScrollable())
return false;
return static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
@@ -1148,13 +1174,18 @@ static void nativeSetTextSelection(JNIEnv *env, jobject obj, jint nativeView,
}
static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView,
- jint handleIndex, jobject cursorRect)
+ jint handleIndex, jobject cursorPoint,
+ jobject textQuad)
{
WebView* webview = reinterpret_cast<WebView*>(nativeView);
- SkIRect nativeRect;
- int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex, nativeRect);
- if (cursorRect)
- GraphicsJNI::irect_to_jrect(nativeRect, env, cursorRect);
+ SkIPoint nativePoint;
+ FloatQuad nativeTextQuad;
+ int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex,
+ nativePoint, nativeTextQuad);
+ if (cursorPoint)
+ GraphicsJNI::ipoint_to_jpoint(nativePoint, env, cursorPoint);
+ if (textQuad)
+ webview->floatQuadToQuadF(env, nativeTextQuad, textQuad);
return layerId;
}
@@ -1176,6 +1207,13 @@ static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView,
GraphicsJNI::irect_to_jrect(nativeRect, env, rect);
}
+static jint nativeSetHwAccelerated(JNIEnv *env, jobject obj, jint nativeView,
+ jboolean hwAccelerated)
+{
+ WebView* webview = reinterpret_cast<WebView*>(nativeView);
+ return webview->setHwAccelerated(hwAccelerated);
+}
+
/*
* JNI registration
*/
@@ -1248,12 +1286,14 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetPauseDrawing },
{ "nativeSetTextSelection", "(II)V",
(void*) nativeSetTextSelection },
- { "nativeGetHandleLayerId", "(IILandroid/graphics/Rect;)I",
+ { "nativeGetHandleLayerId", "(IILandroid/graphics/Point;Landroid/webkit/QuadF;)I",
(void*) nativeGetHandleLayerId },
{ "nativeIsBaseFirst", "(I)Z",
(void*) nativeIsBaseFirst },
{ "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V",
(void*) nativeMapLayerRect },
+ { "nativeSetHwAccelerated", "(IZ)I",
+ (void*) nativeSetHwAccelerated },
};
int registerWebView(JNIEnv* env)