diff options
Diffstat (limited to 'Source/WebKit/android')
18 files changed, 487 insertions, 352 deletions
diff --git a/Source/WebKit/android/AndroidLog.h b/Source/WebKit/android/AndroidLog.h index 4090ab9..3ac210f 100644 --- a/Source/WebKit/android/AndroidLog.h +++ b/Source/WebKit/android/AndroidLog.h @@ -26,8 +26,14 @@ #ifndef AndroidLog_h #define AndroidLog_h +#ifndef LOG_TAG +#define LOG_TAG __FILE__ +#endif + +#include <cutils/log.h> +#include <wtf/CurrentTime.h> + #ifdef ANDROID_DOM_LOGGING -#include <utils/Log.h> #include <stdio.h> extern FILE* gDomTreeFile; #define DOM_TREE_LOG_FILE "/sdcard/domTree.txt" @@ -46,4 +52,21 @@ extern FILE* gRenderTreeFile; #define DISPLAY_TREE_LOG_FILE "/sdcard/displayTree.txt" #define LAYERS_TREE_LOG_FILE "/sdcard/layersTree.plist" +#define TIME_METHOD() MethodTimer __method_timer(__func__) +class MethodTimer { +public: + MethodTimer(const char* name) + : m_methodName(name) + { + m_startTime = currentTimeMS(); + } + virtual ~MethodTimer() { + double duration = currentTimeMS() - m_startTime; + ALOGD("%s took %.2fms", m_methodName, duration); + } +private: + const char* m_methodName; + double m_startTime; +}; + #endif // AndroidLog_h diff --git a/Source/WebKit/android/RenderSkinMediaButton.cpp b/Source/WebKit/android/RenderSkinMediaButton.cpp index febf575..b3aa57d 100644 --- a/Source/WebKit/android/RenderSkinMediaButton.cpp +++ b/Source/WebKit/android/RenderSkinMediaButton.cpp @@ -95,6 +95,9 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT Decode(); } + if (!canvas) + return; + // If we failed to decode, do nothing. This way the browser still works, // and webkit will still draw the label and layout space for us. if (gDecodingFailed) diff --git a/Source/WebKit/android/RenderSkinNinePatch.cpp b/Source/WebKit/android/RenderSkinNinePatch.cpp index ec748f7..9ef0b4a 100644 --- a/Source/WebKit/android/RenderSkinNinePatch.cpp +++ b/Source/WebKit/android/RenderSkinNinePatch.cpp @@ -73,7 +73,7 @@ bool RenderSkinNinePatch::decodeAsset(AssetManager* am, const char* filename, Ni } asset->close(); - if (!peeker.fPatchIsValid) { + if (!peeker.fPatch) { ALOGE("RenderSkinNinePatch::Patch data not valid"); return false; } diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index 5e16152..207fe9a 100644 --- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -238,11 +238,7 @@ void ChromeClientAndroid::addMessageToConsole(MessageSource, MessageType, Messag android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->addMessageToConsole(message, lineNumber, sourceID, msgLevel); } -void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) -{ - android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->formDidBlur(node); -} - +void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) { notImplemented(); } bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; } bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) { String url = frame->document()->documentURI(); diff --git a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp index fea45de..52aeb23 100644 --- a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp @@ -264,7 +264,9 @@ public: if (!m_poster || (!m_poster->getPixels() && !m_poster->pixelRef())) return; - SkCanvas* canvas = ctxt->platformContext()->mCanvas; + SkCanvas* canvas = ctxt->platformContext()->getCanvas(); + if (!canvas) + return; // We paint with the following rules in mind: // - only downscale the poster, never upscale // - maintain the natural aspect ratio of the poster @@ -611,14 +613,9 @@ static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex, BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(baseLayer); if (!layerImpl) return false; - if (!layerImpl->countChildren()) - return false; - LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(layerImpl->getChild(0)); - if (!compositedRoot) - return false; VideoLayerAndroid* videoLayer = - static_cast<VideoLayerAndroid*>(compositedRoot->findById(videoLayerId)); + static_cast<VideoLayerAndroid*>(layerImpl->findById(videoLayerId)); if (!videoLayer) return false; diff --git a/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp b/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp index 77e3c32..d846daf 100644 --- a/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp +++ b/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp @@ -30,6 +30,7 @@ #include "UrlInterceptResponse.h" #include "WebCoreJni.h" +#include <ScopedLocalRef.h> #include <utils/Log.h> namespace android { @@ -38,15 +39,14 @@ class JavaInputStreamWrapper { public: JavaInputStreamWrapper(JNIEnv* env, jobject inputStream) : m_inputStream(env->NewGlobalRef(inputStream)) - , m_buffer(0) { - LOG_ALWAYS_FATAL_IF(!inputStream); - jclass inputStreamClass = env->FindClass("java/io/InputStream"); - LOG_ALWAYS_FATAL_IF(!inputStreamClass); - m_read = env->GetMethodID(inputStreamClass, "read", "([B)I"); + , m_buffer(NULL) { + LOG_ALWAYS_FATAL_IF(!m_inputStream); + ScopedLocalRef<jclass> inputStreamClass(env, env->FindClass("java/io/InputStream")); + LOG_ALWAYS_FATAL_IF(!inputStreamClass.get()); + m_read = env->GetMethodID(inputStreamClass.get(), "read", "([B)I"); LOG_ALWAYS_FATAL_IF(!m_read); - m_close = env->GetMethodID(inputStreamClass, "close", "()V"); + m_close = env->GetMethodID(inputStreamClass.get(), "close", "()V"); LOG_ALWAYS_FATAL_IF(!m_close); - env->DeleteLocalRef(inputStreamClass); } ~JavaInputStreamWrapper() { @@ -63,10 +63,10 @@ public: JNIEnv* env = JSC::Bindings::getJNIEnv(); // Initialize our read buffer to the capacity of out. if (!m_buffer) { - m_buffer = env->NewByteArray(out->capacity()); - m_buffer = (jbyteArray) env->NewGlobalRef(m_buffer); + ScopedLocalRef<jbyteArray> buffer_local(env, env->NewByteArray(out->capacity())); + m_buffer = static_cast<jbyteArray>(env->NewGlobalRef(buffer_local.get())); } - int size = (int) env->CallIntMethod(m_inputStream, m_read, m_buffer); + int size = env->CallIntMethod(m_inputStream, m_read, m_buffer); if (checkException(env) || size < 0) return; // Copy from m_buffer to out. @@ -82,40 +82,32 @@ private: }; UrlInterceptResponse::UrlInterceptResponse(JNIEnv* env, jobject response) { - jclass javaResponse = env->FindClass("android/webkit/WebResourceResponse"); - LOG_ALWAYS_FATAL_IF(!javaResponse); - jfieldID mimeType = env->GetFieldID(javaResponse, "mMimeType", - "Ljava/lang/String;"); + ScopedLocalRef<jclass> javaResponse(env, env->FindClass("android/webkit/WebResourceResponse")); + LOG_ALWAYS_FATAL_IF(!javaResponse.get()); + jfieldID mimeType = env->GetFieldID(javaResponse.get(), "mMimeType", "Ljava/lang/String;"); LOG_ALWAYS_FATAL_IF(!mimeType); - jfieldID encoding = env->GetFieldID(javaResponse, "mEncoding", - "Ljava/lang/String;"); + jfieldID encoding = env->GetFieldID(javaResponse.get(), "mEncoding", "Ljava/lang/String;"); LOG_ALWAYS_FATAL_IF(!encoding); - jfieldID inputStream = env->GetFieldID(javaResponse, "mInputStream", - "Ljava/io/InputStream;"); + jfieldID inputStream = env->GetFieldID(javaResponse.get(), "mInputStream", "Ljava/io/InputStream;"); LOG_ALWAYS_FATAL_IF(!inputStream); - jobject stream = env->GetObjectField(response, inputStream); - if (stream) - m_inputStream.set(new JavaInputStreamWrapper(env, stream)); + ScopedLocalRef<jobject> stream(env, env->GetObjectField(response, inputStream)); + if (stream.get()) + m_inputStream.set(new JavaInputStreamWrapper(env, stream.get())); - jstring mimeStr = (jstring) env->GetObjectField(response, mimeType); - jstring encodingStr = (jstring) env->GetObjectField(response, encoding); + ScopedLocalRef<jstring> mimeStr(env, static_cast<jstring>(env->GetObjectField(response, mimeType))); + ScopedLocalRef<jstring> encodingStr(env, static_cast<jstring>(env->GetObjectField(response, encoding))); - if (mimeStr) { - const char* s = env->GetStringUTFChars(mimeStr, NULL); - m_mimeType.assign(s, env->GetStringUTFLength(mimeStr)); - env->ReleaseStringUTFChars(mimeStr, s); + if (mimeStr.get()) { + const char* s = env->GetStringUTFChars(mimeStr.get(), NULL); + m_mimeType.assign(s, env->GetStringUTFLength(mimeStr.get())); + env->ReleaseStringUTFChars(mimeStr.get(), s); } - if (encodingStr) { - const char* s = env->GetStringUTFChars(encodingStr, NULL); - m_encoding.assign(s, env->GetStringUTFLength(encodingStr)); - env->ReleaseStringUTFChars(encodingStr, s); + if (encodingStr.get()) { + const char* s = env->GetStringUTFChars(encodingStr.get(), NULL); + m_encoding.assign(s, env->GetStringUTFLength(encodingStr.get())); + env->ReleaseStringUTFChars(encodingStr.get(), s); } - - env->DeleteLocalRef(javaResponse); - env->DeleteLocalRef(stream); - env->DeleteLocalRef(mimeStr); - env->DeleteLocalRef(encodingStr); } UrlInterceptResponse::~UrlInterceptResponse() { diff --git a/Source/WebKit/android/jni/PictureSet.cpp b/Source/WebKit/android/jni/PictureSet.cpp index f3534eb..8beb0ef 100644 --- a/Source/WebKit/android/jni/PictureSet.cpp +++ b/Source/WebKit/android/jni/PictureSet.cpp @@ -38,6 +38,8 @@ #include "SkRegion.h" #include "SkStream.h" +#include "PlatformGraphicsContext.h" + #define MAX_DRAW_TIME 100 #define MIN_SPLITTABLE 400 #define MAX_ADDITIONAL_AREA 0.65 @@ -133,6 +135,9 @@ void PictureSet::add(const Pictures* temp) { Pictures pictureAndBounds = *temp; SkSafeRef(pictureAndBounds.mPicture); +#ifdef CONTEXT_RECORDING + SkSafeRef(pictureAndBounds.mGraphicsOperationCollection); +#endif pictureAndBounds.mWroteElapsed = false; mPictures.append(pictureAndBounds); } @@ -478,13 +483,20 @@ void PictureSet::add(const SkIRect& area, uint32_t elapsed, bool split, bool emp working->mArea.setEmpty(); SkSafeUnref(working->mPicture); working->mPicture = 0; +#ifdef CONTEXT_RECORDING + SkSafeUnref(working->mGraphicsOperationCollection); + working->mGraphicsOperationCollection = 0; +#endif } } // Now we can add the new Picture to the list, with the correct area // that need to be repainted - Pictures pictureAndBounds = {totalArea, 0, totalArea, - elapsed, split, false, false, empty}; + Pictures pictureAndBounds = {totalArea, 0, +#ifdef CONTEXT_RECORDING + 0, +#endif + totalArea, elapsed, split, false, false, empty}; #ifdef FAST_PICTURESET if (mPictures.size() == 0) @@ -525,6 +537,10 @@ void PictureSet::add(const SkIRect& area, uint32_t elapsed, bool split, bool emp working->mArea.setEmpty(); SkSafeUnref(working->mPicture); working->mPicture = 0; +#ifdef CONTEXT_RECORDING + SkSafeUnref(working->mGraphicsOperationCollection); + working->mGraphicsOperationCollection = 0; +#endif } } @@ -677,6 +693,9 @@ void PictureSet::clear() for (Pictures* working = mPictures.begin(); working != last; working++) { working->mArea.setEmpty(); SkSafeUnref(working->mPicture); +#ifdef CONTEXT_RECORDING + SkSafeUnref(working->mGraphicsOperationCollection); +#endif } mPictures.clear(); #endif // FAST_PICTURESET @@ -797,7 +816,14 @@ bool PictureSet::draw(SkCanvas* canvas) canvas->translate(pathBounds.fLeft, pathBounds.fTop); canvas->save(); uint32_t startTime = getThreadMsec(); + +#ifdef CONTEXT_RECORDING + WebCore::PlatformGraphicsContextSkia context(canvas); + working->mGraphicsOperationCollection->apply(&context); +#else canvas->drawPicture(*working->mPicture); +#endif + size_t elapsed = working->mElapsed = getThreadMsec() - startTime; working->mWroteElapsed = true; if (maxElapsed < elapsed && (pathBounds.width() >= MIN_SPLITTABLE || @@ -1060,6 +1086,14 @@ void PictureSet::setPicture(size_t i, SkPicture* p) mPictures[i].mEmpty = emptyPicture(p); } +#ifdef CONTEXT_RECORDING +void PictureSet::setGraphicsOperationCollection(size_t i, WebCore::GraphicsOperationCollection* p) +{ + SkSafeUnref(mPictures[i].mGraphicsOperationCollection); + mPictures[i].mGraphicsOperationCollection = p; +} +#endif + void PictureSet::split(PictureSet* out) const { dump(__FUNCTION__); diff --git a/Source/WebKit/android/jni/PictureSet.h b/Source/WebKit/android/jni/PictureSet.h index 1d9a14d..1e639da 100644 --- a/Source/WebKit/android/jni/PictureSet.h +++ b/Source/WebKit/android/jni/PictureSet.h @@ -45,7 +45,10 @@ #include <wtf/Vector.h> #include <wtf/HashMap.h> +#include "GraphicsOperationCollection.h" + // #define FAST_PICTURESET // use a hierarchy of pictures +// #define CONTEXT_RECORDING // use the new PlatformGraphicsContextRecording class SkCanvas; class SkPicture; @@ -100,6 +103,9 @@ namespace android { const SkIRect& bounds(size_t i) const { return mPictures[i].mArea; } void setPicture(size_t i, SkPicture* p); +#ifdef CONTEXT_RECORDING + void setGraphicsOperationCollection(size_t i, WebCore::GraphicsOperationCollection* p); +#endif void setDrawTimes(const PictureSet& ); size_t size() const { return mPictures.size(); } void split(PictureSet* result) const; @@ -119,9 +125,13 @@ namespace android { int mBucketCountX; int mBucketCountY; #else + struct Pictures { SkIRect mArea; SkPicture* mPicture; +#ifdef CONTEXT_RECORDING + WebCore::GraphicsOperationCollection* mGraphicsOperationCollection; +#endif SkIRect mUnsplit; uint32_t mElapsed; bool mSplit : 8; diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp index 2be3ecb..3fdc3e6 100644 --- a/Source/WebKit/android/jni/ViewStateSerializer.cpp +++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp @@ -40,6 +40,7 @@ #include "PictureLayerContent.h" #include "PictureSet.h" #include "ScrollableLayerAndroid.h" +#include "SkFlattenable.h" #include "SkPicture.h" #include "TilesManager.h" @@ -92,14 +93,13 @@ static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint v SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage); if (!stream) return 0; - BaseLayerAndroid* layer = new BaseLayerAndroid(); Color color = stream->readU32(); -#if USE(ACCELERATED_COMPOSITING) - layer->setBackgroundColor(color); -#endif SkPicture* picture = new SkPicture(stream); PictureLayerContent* content = new PictureLayerContent(picture); - layer->setContent(content); + + BaseLayerAndroid* layer = new BaseLayerAndroid(content); + layer->setBackgroundColor(color); + SkSafeUnref(content); SkSafeUnref(picture); int childCount = stream->readS32(); diff --git a/Source/WebKit/android/jni/WebFrameView.cpp b/Source/WebKit/android/jni/WebFrameView.cpp index a9b90cb..10e31dc 100644 --- a/Source/WebKit/android/jni/WebFrameView.cpp +++ b/Source/WebKit/android/jni/WebFrameView.cpp @@ -54,45 +54,15 @@ WebFrameView::~WebFrameView() { Release(mWebViewCore); } -void WebFrameView::draw(WebCore::GraphicsContext* ctx, const WebCore::IntRect& rect) { +void WebFrameView::draw(WebCore::GraphicsContext* gc, const WebCore::IntRect& rect) { WebCore::Frame* frame = mFrameView->frame(); - if (NULL == frame->contentRenderer()) { - // We only do this if there is nothing else to draw. - // If there is a renderer, it will fill the bg itself, so we don't want to - // double-draw (slow) - SkCanvas* canvas = ctx->platformContext()->mCanvas; - canvas->drawColor(SK_ColorWHITE); - } else if (frame->tree()->parent()) { - // Note: this code was moved from FrameLoaderClientAndroid - // - // For subframe, create a new translated rect from the given rectangle. - WebCore::IntRect transRect(rect); - // In Frame::markAllMatchesForText(), it does a fake paint. So we need - // to handle the case where platformContext() is null. However, we still - // want to call paint, since WebKit must have called the paint for a reason. - SkCanvas* canvas = ctx->platformContext() ? ctx->platformContext()->mCanvas : NULL; - if (canvas) { - const WebCore::IntRect& bounds = getBounds(); - - // Grab the intersection of transRect and the frame's bounds. - transRect.intersect(bounds); - if (transRect.isEmpty()) - return; - - // Move the transRect into the frame's local coordinates. - transRect.move(-bounds.x(), -bounds.y()); - - // Translate the canvas, add a clip. - canvas->save(); - canvas->translate(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y())); - canvas->clipRect(transRect); - } - mFrameView->paintContents(ctx, transRect); - if (canvas) - canvas->restore(); - } else { - mFrameView->paintContents(ctx, rect); + if (frame->contentRenderer()) + mFrameView->paintContents(gc, rect); + else { + // FIXME: I'm not entirely sure this ever happens or is needed + gc->setFillColor(WebCore::Color::white, WebCore::ColorSpaceDeviceRGB); + gc->fillRect(rect); } } diff --git a/Source/WebKit/android/jni/WebSettings.cpp b/Source/WebKit/android/jni/WebSettings.cpp index 65ac360..cec44c1 100644 --- a/Source/WebKit/android/jni/WebSettings.cpp +++ b/Source/WebKit/android/jni/WebSettings.cpp @@ -118,6 +118,9 @@ struct FieldIds { mGeolocationEnabled = env->GetFieldID(clazz, "mGeolocationEnabled", "Z"); mGeolocationDatabasePath = env->GetFieldID(clazz, "mGeolocationDatabasePath", "Ljava/lang/String;"); mXSSAuditorEnabled = env->GetFieldID(clazz, "mXSSAuditorEnabled", "Z"); +#if ENABLE(LINK_PREFETCH) + mLinkPrefetchEnabled = env->GetFieldID(clazz, "mLinkPrefetchEnabled", "Z"); +#endif mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz, "mJavaScriptCanOpenWindowsAutomatically", "Z"); mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z"); @@ -245,6 +248,9 @@ struct FieldIds { jfieldID mGeolocationEnabled; jfieldID mGeolocationDatabasePath; jfieldID mXSSAuditorEnabled; +#if ENABLE(LINK_PREFETCH) + jfieldID mLinkPrefetchEnabled; +#endif #if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) jfieldID mDatabasePath; jfieldID mDatabasePathHasBeenSet; @@ -545,6 +551,11 @@ public: flag = env->GetBooleanField(obj, gFieldIds->mXSSAuditorEnabled); s->setXSSAuditorEnabled(flag); +#if ENABLE(LINK_PREFETCH) + flag = env->GetBooleanField(obj, gFieldIds->mLinkPrefetchEnabled); + s->setLinkPrefetchEnabled(flag); +#endif + size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity); if (size > 0) { s->setUsesPageCache(true); diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 9aaec25..a4cd94f 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -31,7 +31,6 @@ #include "AccessibilityObject.h" #include "AndroidHitTestResult.h" #include "Attribute.h" -#include "BaseLayerAndroid.h" #include "content/address_detector.h" #include "Chrome.h" #include "ChromeClientAndroid.h" @@ -63,6 +62,7 @@ #include "Geolocation.h" #include "GraphicsContext.h" #include "GraphicsJNI.h" +#include "GraphicsOperationCollection.h" #include "HTMLAnchorElement.h" #include "HTMLAreaElement.h" #include "HTMLElement.h" @@ -160,6 +160,8 @@ FILE* gDomTreeFile = 0; FILE* gRenderTreeFile = 0; #endif +#include "BaseLayerAndroid.h" + #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayerAndroid.h" #include "RenderLayerCompositor.h" @@ -309,7 +311,6 @@ struct WebViewCoreFields { jfieldID m_viewportMaximumScale; jfieldID m_viewportUserScalable; jfieldID m_viewportDensityDpi; - jfieldID m_webView; jfieldID m_drawIsPaused; jfieldID m_lowMemoryUsageMb; jfieldID m_highMemoryUsageMb; @@ -331,6 +332,7 @@ struct WebViewCore::JavaGlue { jmethodID m_jsPrompt; jmethodID m_jsUnload; jmethodID m_jsInterrupt; + jmethodID m_getWebView; jmethodID m_didFirstLayout; jmethodID m_updateViewport; jmethodID m_sendNotifyProgressFinished; @@ -350,7 +352,6 @@ struct WebViewCore::JavaGlue { jmethodID m_getDeviceMotionService; jmethodID m_getDeviceOrientationService; jmethodID m_addMessageToConsole; - jmethodID m_formDidBlur; jmethodID m_focusNodeChanged; jmethodID m_getPluginClass; jmethodID m_showFullScreenPlugin; @@ -370,7 +371,6 @@ struct WebViewCore::JavaGlue { jmethodID m_setWebTextViewAutoFillable; jmethodID m_selectAt; jmethodID m_initEditField; - jmethodID m_updateMatchCount; jmethodID m_chromeCanTakeFocus; jmethodID m_chromeTakeFocus; AutoJObject object(JNIEnv* env) { @@ -420,7 +420,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m , m_textFieldInitDataGlue(new TextFieldInitDataGlue) , m_mainFrame(mainframe) , m_popupReply(0) - , m_blurringNodePointer(0) , m_blockTextfieldUpdates(false) , m_focusBoundsChanged(false) , m_skipContentDraw(false) @@ -466,6 +465,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_jsPrompt = GetJMethod(env, clazz, "jsPrompt", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); m_javaGlue->m_jsUnload = GetJMethod(env, clazz, "jsUnload", "(Ljava/lang/String;Ljava/lang/String;)Z"); m_javaGlue->m_jsInterrupt = GetJMethod(env, clazz, "jsInterrupt", "()Z"); + m_javaGlue->m_getWebView = GetJMethod(env, clazz, "getWebView", "()Landroid/webkit/WebView;"); m_javaGlue->m_didFirstLayout = GetJMethod(env, clazz, "didFirstLayout", "(Z)V"); m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V"); m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V"); @@ -485,7 +485,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_getDeviceMotionService = GetJMethod(env, clazz, "getDeviceMotionService", "()Landroid/webkit/DeviceMotionService;"); m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;"); m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V"); - m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V"); m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(ILandroid/webkit/WebViewCore$WebKitHitTest;)V"); m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;"); m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;II)V"); @@ -507,7 +506,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m 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", "(IIILandroid/webkit/WebViewCore$TextFieldInitData;)V"); - m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V"); m_javaGlue->m_chromeCanTakeFocus = GetJMethod(env, clazz, "chromeCanTakeFocus", "(I)Z"); m_javaGlue->m_chromeTakeFocus = GetJMethod(env, clazz, "chromeTakeFocus", "(I)V"); env->DeleteLocalRef(clazz); @@ -788,7 +786,7 @@ SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval) SkAutoMemoryUsageProbe mup(__FUNCTION__); SkCanvas* recordingCanvas = arp.getRecordingCanvas(); - WebCore::PlatformGraphicsContext pgc(recordingCanvas); + WebCore::PlatformGraphicsContextSkia pgc(recordingCanvas); WebCore::GraphicsContext gc(&pgc); IntPoint origin = view->minimumScrollPosition(); WebCore::IntRect drawArea(inval.fLeft + origin.x(), inval.fTop + origin.y(), @@ -804,6 +802,27 @@ SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval) return picture; } +#ifdef CONTEXT_RECORDING +GraphicsOperationCollection* WebViewCore::rebuildGraphicsOperationCollection(const SkIRect& inval) +{ + WebCore::FrameView* view = m_mainFrame->view(); + int width = view->contentsWidth(); + int height = view->contentsHeight(); + + IntPoint origin = view->minimumScrollPosition(); + WebCore::IntRect drawArea(inval.fLeft + origin.x(), inval.fTop + origin.y(), + inval.width(), inval.height()); + + AutoGraphicsOperationCollection autoPicture(drawArea); + view->platformWidget()->draw(autoPicture.context(), drawArea); + + m_rebuildInval.op(inval, SkRegion::kUnion_Op); + + SkSafeRef(autoPicture.picture()); + return autoPicture.picture(); +} +#endif + void WebViewCore::rebuildPictureSet(PictureSet* pictureSet) { #ifdef FAST_PICTURESET @@ -829,6 +848,10 @@ void WebViewCore::rebuildPictureSet(PictureSet* pictureSet) DBG_SET_LOGD("pictSet=%p [%d] {%d,%d,w=%d,h=%d}", pictureSet, index, inval.fLeft, inval.fTop, inval.width(), inval.height()); pictureSet->setPicture(index, rebuildPicture(inval)); +#ifdef CONTEXT_RECORDING + pictureSet->setGraphicsOperationCollection(index, + rebuildGraphicsOperationCollection(inval)); +#endif } pictureSet->validate(__FUNCTION__); @@ -860,10 +883,8 @@ void WebViewCore::notifyAnimationStarted() BaseLayerAndroid* WebViewCore::createBaseLayer(SkRegion* region) { - BaseLayerAndroid* base = new BaseLayerAndroid(); - PictureSetLayerContent* content = new PictureSetLayerContent(m_content); - base->setContent(content); + BaseLayerAndroid* base = new BaseLayerAndroid(content); SkSafeUnref(content); m_skipContentDraw = true; @@ -874,16 +895,25 @@ BaseLayerAndroid* WebViewCore::createBaseLayer(SkRegion* region) #if USE(ACCELERATED_COMPOSITING) // We set the background color + Color background = Color::white; if (m_mainFrame && m_mainFrame->document() && m_mainFrame->document()->body()) { + bool hasCSSBackground = false; + Document* document = m_mainFrame->document(); RefPtr<RenderStyle> style = document->styleForElementIgnoringPendingStylesheets(document->body()); if (style->hasBackground()) { - Color color = style->visitedDependentColor(CSSPropertyBackgroundColor); - if (color.isValid() && color.alpha() > 0) - base->setBackgroundColor(color); + background = style->visitedDependentColor(CSSPropertyBackgroundColor); + hasCSSBackground = true; + } + + WebCore::FrameView* view = m_mainFrame->view(); + if (view) { + Color viewBackground = view->baseBackgroundColor(); + background = hasCSSBackground ? viewBackground.blend(background) : viewBackground; } } + base->setBackgroundColor(background); // We update the layers ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client()); @@ -1483,7 +1513,7 @@ VisiblePosition WebViewCore::visiblePositionForContentPoint(const IntPoint& poin return node->renderer()->positionForPoint(result.localPoint()); } -void WebViewCore::selectWordAt(int x, int y) +bool WebViewCore::selectWordAt(int x, int y) { HitTestResult hoverResult; moveMouse(x, y, &hoverResult); @@ -1505,25 +1535,29 @@ void WebViewCore::selectWordAt(int x, int y) // Matching the logic in MouseEventWithHitTestResults::targetNode() Node* node = result.innerNode(); if (!node) - return; + return false; Element* element = node->parentElement(); if (!node->inDocument() && element && element->inDocument()) node = element; SelectionController* sc = focusedFrame()->selection(); + bool wordSelected = false; 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())); - selectWordAroundPosition(node->document()->frame(), pos); + wordSelected = selectWordAroundPosition(node->document()->frame(), pos); } + return wordSelected; } -void WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos) +bool WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos) { VisibleSelection selection(pos); selection.expandUsingGranularity(WordGranularity); + SelectionController* selectionController = frame->selection(); - if (frame->selection()->shouldChangeSelection(selection)) { + bool wordSelected = false; + if (selectionController->shouldChangeSelection(selection)) { bool allWhitespaces = true; RefPtr<Range> firstRange = selection.firstRange(); String text = firstRange.get() ? firstRange->text() : ""; @@ -1533,13 +1567,15 @@ void WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos) break; } } - if (allWhitespaces) { - VisibleSelection emptySelection(selection.visibleStart(), selection.visibleStart()); - frame->selection()->setSelection(emptySelection); + VisibleSelection emptySelection(pos); + selectionController->setSelection(emptySelection); + } else { + selectionController->setSelection(selection); + wordSelected = true; } - frame->selection()->setSelection(selection); } + return wordSelected; } int WebViewCore::platformLayerIdFromNode(Node* node, LayerAndroid** outLayer) @@ -1661,10 +1697,50 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) selectTextContainer->setCaretRect(SelectText::EndHandle, endHandle); selectTextContainer->setText(range->text()); + selectTextContainer->setTextRect(SelectText::StartHandle, + positionToTextRect(selection.start())); + selectTextContainer->setTextRect(SelectText::EndHandle, + positionToTextRect(selection.end())); return selectTextContainer; } +IntRect WebViewCore::positionToTextRect(const Position& position) +{ + IntRect textRect; + InlineBox* inlineBox; + int offset; + position.getInlineBoxAndOffset(VP_DEFAULT_AFFINITY, inlineBox, offset); + if (inlineBox && inlineBox->isInlineTextBox()) { + InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox); + RootInlineBox* root = box->root(); + RenderText* renderText = box->textRenderer(); + int left = root->logicalLeft(); + int width = root->logicalWidth(); + int top = root->selectionTop(); + int height = root->selectionHeight(); + + Node* node = position.anchorNode(); + LayerAndroid* layer = 0; + int layerId = platformLayerIdFromNode(node, &layer); + IntPoint layerOffset; + layerToAbsoluteOffset(layer, layerOffset); + + if (!renderText->style()->isHorizontalWritingMode()) { + swap(left, top); + swap(width, height); + } + FloatPoint origin(left, top); + FloatPoint absoluteOrigin = renderText->localToAbsolute(origin); + + textRect.setX(absoluteOrigin.x() - layerOffset.x()); + textRect.setWidth(width); + textRect.setY(absoluteOrigin.y() - layerOffset.y()); + textRect.setHeight(height); + } + return textRect; +} + IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point, WebCore::Frame* frame) { if (!frame) frame = focusedFrame(); @@ -3430,15 +3506,6 @@ void WebViewCore::popupReply(const int* array, int count) } } -void WebViewCore::formDidBlur(const WebCore::Node* node) -{ - // If the blur is on a text input, keep track of the node so we can - // hide the soft keyboard when the new focus is set, if it is not a - // text input. - if (isTextInput(node)) - m_blurringNodePointer = reinterpret_cast<int>(node); -} - // This is a slightly modified Node::nextNodeConsideringAtomicNodes() with the // extra constraint of limiting the search to inside a containing parent WebCore::Node* nextNodeWithinParent(WebCore::Node* parent, WebCore::Node* start) @@ -3462,6 +3529,7 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake) { if (node) { if (isTextInput(node)) { + bool showKeyboard = true; initEditField(node); WebCore::RenderTextControl* rtc = toRenderTextControl(node); if (rtc && node->hasTagName(HTMLNames::inputTag)) { @@ -3478,10 +3546,11 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake) autoFill->formFieldFocused(inputElement); } #endif - } else if (!fake) { - requestKeyboard(false); - } + } else + showKeyboard = false; } + if (!fake) + requestKeyboard(showKeyboard); } else if (!fake && !nodeIsPlugin(node)) { // not a text entry field, put away the keyboard. clearTextEntry(); @@ -3499,12 +3568,7 @@ void WebViewCore::focusNodeChanged(WebCore::Node* newFocus) if (!javaObject.get()) return; if (isTextInput(newFocus)) - initializeTextInput(newFocus); - else if (m_blurringNodePointer) { - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_formDidBlur, m_blurringNodePointer); - checkException(env); - m_blurringNodePointer = 0; - } + initializeTextInput(newFocus, true); HitTestResult focusHitResult; focusHitResult.setInnerNode(newFocus); focusHitResult.setInnerNonSharedNode(newFocus); @@ -3733,7 +3797,7 @@ WebViewCore::getWebViewJavaObject() AutoJObject javaObject = m_javaGlue->object(env); if (!javaObject.get()) return 0; - return env->GetObjectField(javaObject.get(), gWebViewCoreFields.m_webView); + return env->CallObjectMethod(javaObject.get(), m_javaGlue->m_getWebView); } RenderTextControl* WebViewCore::toRenderTextControl(Node* node) @@ -4236,19 +4300,15 @@ int WebViewCore::findTextOnPage(const WTF::String &text) frame = frame->tree()->traverseNextWithWrap(false); } while (frame); m_activeMatchIndex = m_matchCount - 1; // prime first findNext - if (!m_matchCount) // send at least one update, even if no hits - updateMatchCount(); - else - findNextOnPage(true); return m_matchCount; } -void WebViewCore::findNextOnPage(bool forward) +int WebViewCore::findNextOnPage(bool forward) { if (!m_mainFrame) - return; + return -1; if (!m_matchCount) - return; + return -1; EditorClientAndroid* client = static_cast<EditorClientAndroid*>( m_mainFrame->editor()->client()); @@ -4295,24 +4355,12 @@ void WebViewCore::findNextOnPage(bool forward) m_mainFrame->selection()->revealSelection( ScrollAlignment::alignCenterIfNeeded, true); } - updateMatchCount(); } // Clear selection so it doesn't display. m_mainFrame->selection()->clear(); client->setUiGeneratedSelectionChange(false); -} - -void WebViewCore::updateMatchCount() const -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue->object(env); - if (!javaObject.get()) - return; - jstring javaText = wtfStringToJstring(env, m_searchText, true); - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateMatchCount, - m_activeMatchIndex, m_matchCount, javaText); - checkException(env); + return m_activeMatchIndex; } String WebViewCore::getText(int startX, int startY, int endX, int endY) @@ -4984,10 +5032,10 @@ static void ClearSelection(JNIEnv* env, jobject obj, jint nativeClass) viewImpl->focusedFrame()->selection()->clear(); } -static void SelectWordAt(JNIEnv* env, jobject obj, jint nativeClass, jint x, jint y) +static bool SelectWordAt(JNIEnv* env, jobject obj, jint nativeClass, jint x, jint y) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - viewImpl->selectWordAt(x, y); + return viewImpl->selectWordAt(x, y); } static void SelectAll(JNIEnv* env, jobject obj, jint nativeClass) @@ -5004,11 +5052,11 @@ static int FindAll(JNIEnv* env, jobject obj, jint nativeClass, return viewImpl->findTextOnPage(wtfText); } -static void FindNext(JNIEnv* env, jobject obj, jint nativeClass, +static int FindNext(JNIEnv* env, jobject obj, jint nativeClass, jboolean forward) { WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass); - viewImpl->findNextOnPage(forward); + return viewImpl->findNextOnPage(forward); } // ---------------------------------------------------------------------------- @@ -5123,7 +5171,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) SelectText }, { "nativeClearTextSelection", "(I)V", (void*) ClearSelection }, - { "nativeSelectWordAt", "(III)V", + { "nativeSelectWordAt", "(III)Z", (void*) SelectWordAt }, { "nativeSelectAll", "(I)V", (void*) SelectAll }, @@ -5131,7 +5179,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) nativeCertTrustChanged }, { "nativeFindAll", "(ILjava/lang/String;)I", (void*) FindAll }, - { "nativeFindNext", "(IZ)V", + { "nativeFindNext", "(IZ)I", (void*) FindNext }, }; @@ -5172,10 +5220,6 @@ int registerWebViewCore(JNIEnv* env) "mViewportDensityDpi", "I"); ALOG_ASSERT(gWebViewCoreFields.m_viewportDensityDpi, "Unable to find android/webkit/WebViewCore.mViewportDensityDpi"); - gWebViewCoreFields.m_webView = env->GetFieldID(widget, - "mWebView", "Landroid/webkit/WebViewClassic;"); - ALOG_ASSERT(gWebViewCoreFields.m_webView, - "Unable to find android/webkit/WebViewCore.mWebView"); gWebViewCoreFields.m_drawIsPaused = env->GetFieldID(widget, "mDrawIsPaused", "Z"); ALOG_ASSERT(gWebViewCoreFields.m_drawIsPaused, diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index 6850111..5e2bafb 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -53,6 +53,7 @@ namespace WebCore { class Color; + class GraphicsOperationCollection; class FrameView; class HTMLAnchorElement; class HTMLElement; @@ -85,9 +86,6 @@ class SkPicture; class SkIRect; namespace android { - // TODO: This file hasn't been good about namespace. Remove this temporary - // workaround to build - using namespace WebCore; enum Direction { DIRECTION_BACKWARD = 0, @@ -138,12 +136,6 @@ namespace android { // Followings are called from native WebCore to Java - /** - * Notification that a form was blurred. Pass a message to hide the - * keyboard if it was showing for that Node. - * @param Node The Node that blurred. - */ - void formDidBlur(const WebCore::Node*); void focusNodeChanged(WebCore::Node*); /** @@ -174,7 +166,7 @@ namespace android { void layersDraw(); #if USE(ACCELERATED_COMPOSITING) - GraphicsLayerAndroid* graphicsRootLayer() const; + WebCore::GraphicsLayerAndroid* graphicsRootLayer() const; #endif /** Invalidate the view/screen, NOT the content/DOM, but expressed in @@ -214,7 +206,7 @@ namespace android { * Tell the java side to update the focused textfield * @param pointer Pointer to the node for the input field. * @param changeToPassword If true, we are changing the textfield to - * a password field, and ignore the String + * a password field, and ignore the WTF::String * @param text If changeToPassword is false, this is the new text that * should go into the textfield. */ @@ -290,12 +282,13 @@ namespace android { jobject getDeviceMotionService(); jobject getDeviceOrientationService(); - void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID, int msgLevel); + void addMessageToConsole(const WTF::String& message, unsigned int lineNumber, const WTF::String& sourceID, int msgLevel); /** * Tell the Java side of the scrollbar mode */ - void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode); + void setScrollbarModes(WebCore::ScrollbarMode horizontalMode, + WebCore::ScrollbarMode verticalMode); // // Followings support calls from Java to native WebCore @@ -310,7 +303,7 @@ namespace android { // scroll the selection on screen (if necessary). void revealSelection(); - void moveMouse(int x, int y, HitTestResult* hoveredNode = 0); + void moveMouse(int x, int y, WebCore::HitTestResult* hoveredNode = 0); // set the scroll amount that webview.java is currently showing void setScrollOffset(bool sendScrollEvent, int dx, int dy); @@ -326,8 +319,8 @@ namespace android { * @return Whether keyCode was handled by this class. */ bool key(const WebCore::PlatformKeyboardEvent& event); - bool chromeCanTakeFocus(FocusDirection direction); - void chromeTakeFocus(FocusDirection direction); + bool chromeCanTakeFocus(WebCore::FocusDirection direction); + void chromeTakeFocus(WebCore::FocusDirection direction); /** * Handle (trackball) click event / dpad center press from Java. @@ -339,7 +332,9 @@ namespace android { /** * Handle touch event */ - bool handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint>& points, int actionIndex, int metaState); + bool handleTouchEvent(int action, WTF::Vector<int>& ids, + WTF::Vector<WebCore::IntPoint>& points, + int actionIndex, int metaState); /** * Handle motionUp event from the UI thread (called touchUp in the @@ -382,11 +377,11 @@ namespace android { * direction - The direction in which to alter the selection. * granularity - The granularity of the selection modification. * - * returns - The selected HTML as a string. This is not a well formed + * returns - The selected HTML as a WTF::String. This is not a well formed * HTML, rather the selection annotated with the tags of all * intermediary elements it crosses. */ - String modifySelection(const int direction, const int granularity); + WTF::String modifySelection(const int direction, const int granularity); /** * Moves the selection to the given node in a given frame i.e. selects that node. @@ -396,11 +391,11 @@ namespace android { * frame - The frame in which to select is the node to be selected. * node - The node to be selected. * - * returns - The selected HTML as a string. This is not a well formed + * returns - The selected HTML as a WTF::String. This is not a well formed * HTML, rather the selection annotated with the tags of all * intermediary elements it crosses. */ - String moveSelection(WebCore::Frame* frame, WebCore::Node* node); + WTF::String moveSelection(WebCore::Frame* frame, WebCore::Node* node); /** * In the currently focused textfield, replace the characters from oldStart to oldEnd @@ -457,7 +452,7 @@ namespace android { void sendPluginSurfaceReady(); // send onLoad event to plugins who are descendents of the given frame - void notifyPluginsOnFrameLoad(const Frame*); + void notifyPluginsOnFrameLoad(const WebCore::Frame*); // gets a rect representing the current on-screen portion of the document void getVisibleScreen(ANPRectI&); @@ -515,11 +510,11 @@ namespace android { void centerFitRect(int x, int y, int width, int height); // return a list of rects matching the touch point (x, y) with the slop - Vector<IntRect> getTouchHighlightRects(int x, int y, int slop, - Node** node, HitTestResult* hitTestResult); + WTF::Vector<WebCore::IntRect> getTouchHighlightRects(int x, int y, int slop, + WebCore::Node** node, WebCore::HitTestResult* hitTestResult); // This does a sloppy hit test AndroidHitTestResult hitTestAtPoint(int x, int y, int slop, bool doMoveMouse = false); - static bool nodeIsClickableOrFocusable(Node* node); + static bool nodeIsClickableOrFocusable(WebCore::Node* node); // Open a file chooser for selecting a file to upload void openFileChooser(PassRefPtr<WebCore::FileChooser> ); @@ -530,13 +525,13 @@ namespace android { bool focusBoundsChanged(); // record the inval area, and the picture size - BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* ); + WebCore::BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* ); // This creates a new BaseLayerAndroid by copying the current m_content // and doing a copy of the layers. The layers' content may be updated // as we are calling layersSync(). - BaseLayerAndroid* createBaseLayer(SkRegion*); - bool updateLayers(LayerAndroid*); + WebCore::BaseLayerAndroid* createBaseLayer(SkRegion*); + bool updateLayers(WebCore::LayerAndroid*); void notifyAnimationStarted(); int textWrapWidth() const { return m_textWrapWidth; } @@ -557,7 +552,7 @@ namespace android { // find on page void resetFindOnPage(); int findTextOnPage(const WTF::String &text); - void findNextOnPage(bool forward); + int findNextOnPage(bool forward); void updateMatchCount() const; #if ENABLE(VIDEO) @@ -600,14 +595,16 @@ namespace android { */ Vector<WebCore::VisibleSelection> getTextRanges( int startX, int startY, int endX, int endY); - static int platformLayerIdFromNode(Node* node, LayerAndroid** outLayer = 0); + static int platformLayerIdFromNode(WebCore::Node* node, + WebCore::LayerAndroid** outLayer = 0); void selectText(int startX, int startY, int endX, int endY); - void selectWordAt(int x, int y); + bool 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, WebCore::Frame* frame = 0); - static void layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& offset); + WebCore::IntPoint convertGlobalContentToFrameContent(const WebCore::IntPoint& point, WebCore::Frame* frame = 0); + static void layerToAbsoluteOffset(const WebCore::LayerAndroid* layer, + WebCore::IntPoint& offset); /** * Returns a text position at a given coordinate. @@ -615,7 +612,7 @@ namespace android { WebCore::VisiblePosition visiblePositionForWindowPoint(int x, int y); // Retrieves the current locale from system properties - void getLocale(String& language, String& region); + void getLocale(String& language, WTF::String& region); // Handles changes in system locale void updateLocale(); @@ -645,6 +642,9 @@ namespace android { void recordPictureSet(PictureSet* master); SkPicture* rebuildPicture(const SkIRect& inval); +#ifdef CONTEXT_RECORDING + WebCore::GraphicsOperationCollection* rebuildGraphicsOperationCollection(const SkIRect& inval); +#endif void rebuildPictureSet(PictureSet* ); void sendNotifyProgressFinished(); /* @@ -660,28 +660,38 @@ namespace android { const WebCore::QualifiedName& ); WebCore::HTMLImageElement* retrieveImageElement(int x, int y); // below are members responsible for accessibility support - String modifySelectionTextNavigationAxis(DOMSelection* selection, int direction, int granularity); - String modifySelectionDomNavigationAxis(DOMSelection* selection, int direction, int granularity); - Text* traverseNextContentTextNode(Node* fromNode, Node* toNode ,int direction); - bool isVisible(Node* node); - bool isHeading(Node* node); - String formatMarkup(DOMSelection* selection); + WTF::String modifySelectionTextNavigationAxis(WebCore::DOMSelection* selection, + int direction, int granularity); + WTF::String modifySelectionDomNavigationAxis(WebCore::DOMSelection* selection, + int direction, int granularity); + WebCore::Text* traverseNextContentTextNode(WebCore::Node* fromNode, + WebCore::Node* toNode, + int direction); + bool isVisible(WebCore::Node* node); + bool isHeading(WebCore::Node* node); + WTF::String formatMarkup(WebCore::DOMSelection* selection); void selectAt(int x, int y); - void scrollNodeIntoView(Frame* frame, Node* node); - bool isContentTextNode(Node* node); - Node* getIntermediaryInputElement(Node* fromNode, Node* toNode, int direction); - bool isContentInputElement(Node* node); - bool isDescendantOf(Node* parent, Node* node); - void advanceAnchorNode(DOMSelection* selection, int direction, String& markup, bool ignoreFirstNode, ExceptionCode& ec); - Node* getNextAnchorNode(Node* anchorNode, bool skipFirstHack, int direction); - Node* getImplicitBoundaryNode(Node* node, unsigned offset, int direction); - jobject createTextFieldInitData(Node* node); + void scrollNodeIntoView(WebCore::Frame* frame, WebCore::Node* node); + bool isContentTextNode(WebCore::Node* node); + WebCore::Node* getIntermediaryInputElement(WebCore::Node* fromNode, + WebCore::Node* toNode, + int direction); + bool isContentInputElement(WebCore::Node* node); + bool isDescendantOf(WebCore::Node* parent, WebCore::Node* node); + void advanceAnchorNode(WebCore::DOMSelection* selection, int direction, + WTF::String& markup, bool ignoreFirstNode, + WebCore::ExceptionCode& ec); + WebCore::Node* getNextAnchorNode(WebCore::Node* anchorNode, + bool skipFirstHack, int direction); + WebCore::Node* getImplicitBoundaryNode(WebCore::Node* node, + unsigned offset, int direction); + jobject createTextFieldInitData(WebCore::Node* node); /** * Calls into java to reset the text edit field with the * current contents and selection. */ - void initEditField(Node* node); + void initEditField(WebCore::Node* node); /** * If node is not a text input field or if it explicitly requests @@ -689,55 +699,58 @@ namespace android { * it is a text input field then initEditField is called and * auto-fill information is requested for HTML form input fields. */ - void initializeTextInput(Node* node, bool fake = false); + void initializeTextInput(WebCore::Node* node, bool fake); /** * Gets the input type a Node. NONE is returned if it isn't an * input field. */ - InputType getInputType(Node* node); + InputType getInputType(WebCore::Node* node); /** * If node is an input field, the spellcheck value for the * field is returned. Otherwise true is returned. */ - static bool isSpellCheckEnabled(Node* node); + static bool isSpellCheckEnabled(WebCore::Node* node); /** * Returns the offsets of the selection area for both normal text * fields and content editable fields. start and end are modified * by this method. */ - static void getSelectionOffsets(Node* node, int& start, int& end); + static void getSelectionOffsets(WebCore::Node* node, int& start, int& end); /** * Gets the plain text of the specified editable text field. node * may be content-editable or a plain text fields. */ - static String getInputText(Node* node); + static WTF::String getInputText(WebCore::Node* node); /** * Gets the RenderTextControl for the given node if it has one. * If its renderer isn't a RenderTextControl, then NULL is returned. */ - static RenderTextControl* toRenderTextControl(Node *node); + static WebCore::RenderTextControl* toRenderTextControl(WebCore::Node *node); /** * Sets the selection for node's editable field to the offsets * between start (inclusive) and end (exclusive). */ - static void setSelection(Node* node, int start, int end); + static void setSelection(WebCore::Node* node, int start, int end); /** * Returns the Position for the given offset for an editable * field. The offset is relative to the node start. */ - static WebCore::Position getPositionForOffset(Node* node, int offset); + static WebCore::Position getPositionForOffset(WebCore::Node* node, int offset); - VisiblePosition visiblePositionForContentPoint(int x, int y); - VisiblePosition visiblePositionForContentPoint(const IntPoint& point); - void selectWordAroundPosition(Frame* frame, VisiblePosition pos); - SelectText* createSelectText(const VisibleSelection&); - static int getMaxLength(Node* node); - static String getFieldName(Node* node); - static bool isAutoCompleteEnabled(Node* node); - IntRect boundingRect(Node* node, LayerAndroid* layer); + WebCore::VisiblePosition visiblePositionForContentPoint(int x, int y); + WebCore::VisiblePosition visiblePositionForContentPoint(const WebCore::IntPoint& point); + bool selectWordAroundPosition(WebCore::Frame* frame, + WebCore::VisiblePosition pos); + SelectText* createSelectText(const WebCore::VisibleSelection&); + static int getMaxLength(WebCore::Node* node); + static WTF::String getFieldName(WebCore::Node* node); + static bool isAutoCompleteEnabled(WebCore::Node* node); + WebCore::IntRect boundingRect(WebCore::Node* node, + WebCore::LayerAndroid* layer); + static WebCore::IntRect positionToTextRect(const WebCore::Position& position); // called from constructor, to add this to a global list static void addInstance(WebViewCore*); @@ -751,7 +764,6 @@ namespace android { struct TextFieldInitDataGlue* m_textFieldInitDataGlue; WebCore::Frame* m_mainFrame; WebCoreReply* m_popupReply; - int m_blurringNodePointer; PictureSet m_content; // the set of pictures to draw SkRegion m_addInval; // the accumulated inval region (not yet drawn) SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures @@ -773,7 +785,7 @@ namespace android { int m_screenHeight;// height of the visible rect in document coordinates int m_textWrapWidth; float m_scale; - PageGroup* m_groupForVisitedLinks; + WebCore::PageGroup* m_groupForVisitedLinks; bool m_isPaused; int m_cacheMode; bool m_fullscreenVideoMode; @@ -791,7 +803,7 @@ namespace android { } int m_screenOnCounter; - Node* m_currentNodeDomNavigationAxis; + WebCore::Node* m_currentNodeDomNavigationAxis; DeviceMotionAndOrientationManager m_deviceMotionAndOrientationManager; #if ENABLE(TOUCH_EVENTS) diff --git a/Source/WebKit/android/nav/DrawExtra.h b/Source/WebKit/android/nav/DrawExtra.h index 83e7dcd..cc94476 100644 --- a/Source/WebKit/android/nav/DrawExtra.h +++ b/Source/WebKit/android/nav/DrawExtra.h @@ -54,7 +54,6 @@ namespace android { class DrawExtra { public: virtual ~DrawExtra() {} - virtual void drawLegacy(SkCanvas* , LayerAndroid* , IntRect* ) {} virtual void draw(SkCanvas*, LayerAndroid*) {} virtual void drawGL(GLExtras*, const LayerAndroid*) {} }; diff --git a/Source/WebKit/android/nav/SelectText.h b/Source/WebKit/android/nav/SelectText.h index 904b2b9..50bc82e 100644 --- a/Source/WebKit/android/nav/SelectText.h +++ b/Source/WebKit/android/nav/SelectText.h @@ -43,6 +43,8 @@ public: IntRect& caretRect(HandleId id) { return m_caretRects[mapId(id)]; } void setCaretRect(HandleId id, const IntRect& rect) { m_caretRects[mapId(id)] = rect; } + IntRect& textRect(HandleId id) { return m_textRects[mapId(id)]; } + void setTextRect(HandleId id, const IntRect& rect) { m_textRects[mapId(id)] = rect; } int caretLayerId(HandleId id) { return m_caretLayerId[mapId(id)]; } void setCaretLayerId(HandleId id, int layerId) { m_caretLayerId[mapId(id)] = layerId; } @@ -56,6 +58,7 @@ private: HandleId mapId(HandleId id); IntRect m_caretRects[2]; + IntRect m_textRects[2]; int m_caretLayerId[2]; bool m_baseIsFirst; String m_text; 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) diff --git a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp index 513d251..92dbbcd 100644 --- a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp +++ b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp @@ -47,7 +47,7 @@ static struct ANPSurfaceInterfaceJavaGlue { jfieldID surfacePointer; } gSurfaceJavaGlue; -static inline sp<Surface> getSurface(JNIEnv* env, jobject view) { +static inline sp<android::Surface> getSurface(JNIEnv* env, jobject view) { if (!env || !view) { return NULL; } @@ -80,7 +80,7 @@ static inline sp<Surface> getSurface(JNIEnv* env, jobject view) { env->DeleteLocalRef(holder); env->DeleteLocalRef(surface); - return sp<Surface>((Surface*) surfacePointer); + return sp<android::Surface>((android::Surface*) surfacePointer); } static inline ANPBitmapFormat convertPixelFormat(PixelFormat format) { @@ -96,9 +96,9 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec return false; } - sp<Surface> surface = getSurface(env, surfaceView); + sp<android::Surface> surface = getSurface(env, surfaceView); - if (!bitmap || !Surface::isValid(surface)) { + if (!bitmap || !android::Surface::isValid(surface)) { return false; } @@ -112,7 +112,7 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec dirtyRegion.set(Rect(0x3FFF, 0x3FFF)); } - Surface::SurfaceInfo info; + android::Surface::SurfaceInfo info; status_t err = surface->lock(&info, &dirtyRegion); if (err < 0) { return false; @@ -150,9 +150,9 @@ static void anp_unlock(JNIEnv* env, jobject surfaceView) { return; } - sp<Surface> surface = getSurface(env, surfaceView); + sp<android::Surface> surface = getSurface(env, surfaceView); - if (!Surface::isValid(surface)) { + if (!android::Surface::isValid(surface)) { return; } diff --git a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp index d0af1a5..09bb24e 100644 --- a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp +++ b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp @@ -160,7 +160,8 @@ bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) { if (model == kOpenGL_ANPDrawingModel && m_layer == 0) { jobject webview = m_core->getWebViewJavaObject(); - m_layer = new WebCore::MediaLayer(webview); + AutoJObject webViewCore = m_core->getJavaObject(); + m_layer = new WebCore::MediaLayer(webview, webViewCore.get()); } else if (model != kOpenGL_ANPDrawingModel && m_layer != 0) { m_layer->unref(); |
