OSDN Git Service

Combine base PictureSet with composite layers into
authorGrace Kloba <klobag@google.com>
Thu, 8 Jul 2010 21:50:52 +0000 (14:50 -0700)
committerGrace Kloba <klobag@google.com>
Fri, 9 Jul 2010 15:53:57 +0000 (08:53 -0700)
one SkLayer tree. The BaseLayerAndroid is the root
of the composite layers and it has the PictureSet
as its base content.

Before, WebViewCore uses m_contentMutex and both UI
and WebCore threads access the m_content. Now we use
the layer approach. When WebCore thread updates its
content in recordContent, it creates a new BaseLayerAndroid
and copy both PictureSet and composite layers into it.
Then it is sent to be consumed by UI thread.

Clean up sync layer in both ChromeClientAndroid and
GraphicsLayerAndroid.

splitContent can be a little tricky with this change.
Now UI has its own copy of PictureSet. When it takes
too long to draw, it will send a request to WebCore
to split the PictureSet. When it is done, a copy of
the new PictureSet will be sent back to UI.

There is a matching change in framework/base

WebCore/platform/android/PlatformBridge.h
WebCore/platform/graphics/android/BaseLayerAndroid.h [new file with mode: 0644]
WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
WebCore/platform/graphics/android/GraphicsLayerAndroid.h
WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
WebKit/android/WebCoreSupport/ChromeClientAndroid.h
WebKit/android/WebCoreSupport/PlatformBridge.cpp
WebKit/android/jni/WebViewCore.cpp
WebKit/android/jni/WebViewCore.h
WebKit/android/nav/WebView.cpp

index 80aada6..e8722e2 100644 (file)
@@ -81,10 +81,6 @@ class NPObject;
 
 namespace WebCore {
 
-#if USE(ACCELERATED_COMPOSITING)
-class LayerAndroid;
-#endif
-
 class FrameView;
 class Widget;
 
@@ -124,12 +120,6 @@ public:
     };
     static String* globalLocalizedName(rawResId resId);
 
-#if USE(ACCELERATED_COMPOSITING)
-    // Those methods are used by the layers system
-    static void setUIRootLayer(const FrameView* view, const LayerAndroid* layer);
-    static void immediateRepaint(const FrameView* view);
-#endif // USE(ACCELERATED_COMPOSITING)
-
     // Whether the WebView is paused.
     // ANDROID
     // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.h b/WebCore/platform/graphics/android/BaseLayerAndroid.h
new file mode 100644 (file)
index 0000000..b9e2f4e
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASELAYERANDROID_H_
+#define BASELAYERANDROID_H_
+
+#include "PictureSet.h"
+#include "SkLayer.h"
+
+namespace WebCore {
+
+class BaseLayerAndroid : public SkLayer {
+
+public:
+    BaseLayerAndroid() { }
+    virtual ~BaseLayerAndroid() { }
+
+    void setContent(const android::PictureSet& src) { m_content.set(src); }
+    android::PictureSet* content() { return &m_content; }
+
+private:
+    android::PictureSet m_content;
+};
+
+} // namespace WebCore
+
+#endif /* BASELAYERANDROID_H_ */
index 1fb36ec..6faee17 100644 (file)
@@ -407,33 +407,6 @@ void GraphicsLayerAndroid::setNeedsDisplay()
     setNeedsDisplayInRect(rect);
 }
 
-void GraphicsLayerAndroid::setFrame(Frame* f)
-{
-    m_frame = f;
-}
-
-void GraphicsLayerAndroid::sendImmediateRepaint()
-{
-    LOG("(%x) sendImmediateRepaint()", this);
-    GraphicsLayerAndroid* rootGraphicsLayer = this;
-
-    while (rootGraphicsLayer->parent())
-        rootGraphicsLayer = static_cast<GraphicsLayerAndroid*>(rootGraphicsLayer->parent());
-
-    if (rootGraphicsLayer->m_frame
-        && rootGraphicsLayer->m_frame->view()) {
-        LayerAndroid* rootLayer = new LayerAndroid(true);
-        LayerAndroid* copyLayer = new LayerAndroid(*m_contentLayer);
-        rootLayer->addChild(copyLayer);
-        copyLayer->unref();
-        TLOG("(%x) sendImmediateRepaint, copy the layer, (%.2f,%.2f => %.2f,%.2f)",
-            this, m_contentLayer->getSize().width(), m_contentLayer->getSize().height(),
-            copyLayer->getSize().width(), copyLayer->getSize().height());
-        PlatformBridge::setUIRootLayer(m_frame->view(), rootLayer);
-        PlatformBridge::immediateRepaint(m_frame->view());
-    }
-}
-
 bool GraphicsLayerAndroid::repaint()
 {
     LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
index b72877b..54a035b 100644 (file)
@@ -108,22 +108,21 @@ public:
 
     virtual void setZPosition(float);
 
-    void askForSync();
-    void syncPositionState();
-    void needsSyncChildren();
-    void syncChildren();
-    void syncMask();
     virtual void syncCompositingState();
-    void setFrame(Frame*);
     void notifyClientAnimationStarted();
 
-    void sendImmediateRepaint();
     LayerAndroid* contentLayer() { return m_contentLayer; }
 
     static int instancesCount();
 
 private:
 
+    void askForSync();
+    void syncPositionState();
+    void needsSyncChildren();
+    void syncChildren();
+    void syncMask();
+
     void updateFixedPosition();
 
     // with SkPicture, we always repaint the entire layer's content.
@@ -146,8 +145,6 @@ private:
 
     FloatPoint m_currentPosition;
 
-    RefPtr<Frame> m_frame;
-
     Vector<FloatRect> m_invalidatedRects;
 
     LayerAndroid* m_contentLayer;
index 7a18221..30ac36c 100644 (file)
@@ -56,27 +56,14 @@ static unsigned long long tryToReclaimDatabaseQuota(SecurityOrigin* originNeedin
 
 #if USE(ACCELERATED_COMPOSITING)
 
-void ChromeClientAndroid::layersSync()
+WebCore::GraphicsLayer* ChromeClientAndroid::layersSync()
 {
-    if (!m_rootGraphicsLayer)
-        return;
-
-    if (!m_needsLayerSync)
-        return;
-
-    m_needsLayerSync = false;
-
-    if (m_webFrame) {
-        FrameView* frameView = m_webFrame->page()->mainFrame()->view();
-        if (frameView && frameView->syncCompositingStateRecursive()) {
-            GraphicsLayerAndroid* androidGraphicsLayer =
-                    static_cast<GraphicsLayerAndroid*>(m_rootGraphicsLayer);
-            if (androidGraphicsLayer) {
-                androidGraphicsLayer->sendImmediateRepaint();
-                androidGraphicsLayer->notifyClientAnimationStarted();
-            }
-        }
+    if (m_rootGraphicsLayer && m_needsLayerSync && m_webFrame) {
+        if (FrameView* frameView = m_webFrame->page()->mainFrame()->view())
+            frameView->syncCompositingStateRecursive();
     }
+    m_needsLayerSync = false;
+    return m_rootGraphicsLayer;
 }
 
 void ChromeClientAndroid::scheduleCompositingLayerSync()
@@ -89,15 +76,12 @@ void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization()
     // This should not be needed
 }
 
-void ChromeClientAndroid::attachRootGraphicsLayer(WebCore::Frame* frame, WebCore::GraphicsLayer* layer)
+void ChromeClientAndroid::attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* layer)
 {
+    // frame is not used in Android as we should only get root graphics layer for the main frame
     m_rootGraphicsLayer = layer;
-    if (!layer) {
-        WebViewCore::getWebViewCore(frame->view())->setUIRootLayer(0);
+    if (!layer)
         return;
-    }
-    WebCore::GraphicsLayerAndroid* androidGraphicsLayer = static_cast<GraphicsLayerAndroid*>(layer);
-    androidGraphicsLayer->setFrame(frame);
     scheduleCompositingLayerSync();
 }
 
index 517a439..a1f097c 100644 (file)
@@ -169,7 +169,7 @@ namespace android {
         virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* g);
         virtual void setNeedsOneShotDrawingSynchronization();
         virtual void scheduleCompositingLayerSync();
-        void layersSync();
+        WebCore::GraphicsLayer* layersSync();
 #endif
 
 #if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
index b75cdfc..833deb5 100644 (file)
 #include <wtf/android/AndroidThreading.h>
 #include <wtf/MainThread.h>
 
-#if USE(ACCELERATED_COMPOSITING)
-#include "LayerAndroid.h"
-#endif
-
 using namespace android;
 
 namespace WebCore {
 
-#if USE(ACCELERATED_COMPOSITING)
-
-void PlatformBridge::setUIRootLayer(const WebCore::FrameView* view, const LayerAndroid* layer)
-{
-    android::WebViewCore* core = android::WebViewCore::getWebViewCore(view);
-    core->setUIRootLayer(layer);
-}
-
-void PlatformBridge::immediateRepaint(const WebCore::FrameView* view)
-{
-    android::WebViewCore* core = android::WebViewCore::getWebViewCore(view);
-    core->immediateRepaint();
-}
-
-#endif // USE(ACCELERATED_COMPOSITING)
-
 WTF::Vector<String> PlatformBridge::getSupportedKeyStrengthList()
 {
     KeyGeneratorClient* client = JavaSharedClient::GetKeyGeneratorClient();
index 955b654..daca51e 100644 (file)
@@ -29,6 +29,7 @@
 #include "WebViewCore.h"
 
 #include "AtomicString.h"
+#include "BaseLayerAndroid.h"
 #include "CachedNode.h"
 #include "CachedRoot.h"
 #include "Chrome.h"
@@ -230,8 +231,6 @@ struct WebViewCore::JavaGlue {
     jmethodID   m_updateViewport;
     jmethodID   m_sendNotifyProgressFinished;
     jmethodID   m_sendViewInvalidate;
-    jmethodID   m_sendImmediateRepaint;
-    jmethodID   m_setRootLayer;
     jmethodID   m_updateTextfield;
     jmethodID   m_updateTextSelection;
     jmethodID   m_clearTextEntry;
@@ -276,7 +275,6 @@ static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const
 Mutex WebViewCore::gFrameCacheMutex;
 Mutex WebViewCore::gButtonMutex;
 Mutex WebViewCore::gCursorBoundsMutex;
-Mutex WebViewCore::m_contentMutex;
 
 WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* mainframe)
         : m_pluginInvalTimer(this, &WebViewCore::pluginInvalTimerFired)
@@ -321,8 +319,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
     m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V");
     m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V");
     m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V");
-    m_javaGlue->m_sendImmediateRepaint = GetJMethod(env, clazz, "sendImmediateRepaint", "()V");
-    m_javaGlue->m_setRootLayer = GetJMethod(env, clazz, "setRootLayer", "(I)V");
     m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V");
     m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIII)V");
     m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V");
@@ -749,50 +745,11 @@ void WebViewCore::updateCursorBounds(const CachedRoot* root,
 void WebViewCore::clearContent()
 {
     DBG_SET_LOG("");
-    m_contentMutex.lock();
     m_content.clear();
-    m_contentMutex.unlock();
     m_addInval.setEmpty();
     m_rebuildInval.setEmpty();
 }
 
-void WebViewCore::copyContentToPicture(SkPicture* picture)
-{
-    DBG_SET_LOG("start");
-    m_contentMutex.lock();
-    PictureSet copyContent = PictureSet(m_content);
-    m_contentMutex.unlock();
-
-    int w = copyContent.width();
-    int h = copyContent.height();
-    copyContent.draw(picture->beginRecording(w, h, PICT_RECORD_FLAGS));
-    picture->endRecording();
-    DBG_SET_LOG("end");
-}
-
-bool WebViewCore::drawContent(SkCanvas* canvas, SkColor color)
-{
-#ifdef ANDROID_INSTRUMENT
-    TimeCounterAuto counter(TimeCounter::WebViewUIDrawTimeCounter);
-#endif
-    DBG_SET_LOG("start");
-    m_contentMutex.lock();
-    PictureSet copyContent = PictureSet(m_content);
-    m_contentMutex.unlock();
-    int sc = canvas->save(SkCanvas::kClip_SaveFlag);
-    SkRect clip;
-    clip.set(0, 0, copyContent.width(), copyContent.height());
-    canvas->clipRect(clip, SkRegion::kDifference_Op);
-    canvas->drawColor(color);
-    canvas->restoreToCount(sc);
-    bool tookTooLong = copyContent.draw(canvas);
-    m_contentMutex.lock();
-    m_content.setDrawTimes(copyContent);
-    m_contentMutex.unlock();
-    DBG_SET_LOG("end");
-    return tookTooLong;
-}
-
 bool WebViewCore::focusBoundsChanged()
 {
     bool result = m_focusBoundsChanged;
@@ -800,18 +757,6 @@ bool WebViewCore::focusBoundsChanged()
     return result;
 }
 
-bool WebViewCore::pictureReady()
-{
-    bool done;
-    m_contentMutex.lock();
-    PictureSet copyContent = PictureSet(m_content);
-    done = m_progressDone;
-    m_contentMutex.unlock();
-    DBG_NAV_LOGD("done=%s empty=%s", done ? "true" : "false",
-        copyContent.isEmpty() ? "true" : "false");
-    return done || !copyContent.isEmpty();
-}
-
 SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval)
 {
     WebCore::FrameView* view = m_mainFrame->view();
@@ -859,54 +804,52 @@ void WebViewCore::rebuildPictureSet(PictureSet* pictureSet)
     pictureSet->validate(__FUNCTION__);
 }
 
-bool WebViewCore::recordContent(SkRegion* region, SkIPoint* point)
+BaseLayerAndroid* WebViewCore::recordContent(SkRegion* region, SkIPoint* point)
 {
     DBG_SET_LOG("start");
     float progress = (float) m_mainFrame->page()->progress()->estimatedProgress();
-    m_contentMutex.lock();
-    PictureSet contentCopy(m_content);
     m_progressDone = progress <= 0.0f || progress >= 1.0f;
-    m_contentMutex.unlock();
-    recordPictureSet(&contentCopy);
-    if (!m_progressDone && contentCopy.isEmpty()) {
+    recordPictureSet(&m_content);
+    if (!m_progressDone && m_content.isEmpty()) {
         DBG_SET_LOGD("empty (progress=%g)", progress);
-        return false;
+        return 0;
     }
     region->set(m_addInval);
     m_addInval.setEmpty();
     region->op(m_rebuildInval, SkRegion::kUnion_Op);
     m_rebuildInval.setEmpty();
-    m_contentMutex.lock();
-    contentCopy.setDrawTimes(m_content);
-    m_content.set(contentCopy);
     point->fX = m_content.width();
     point->fY = m_content.height();
-    m_contentMutex.unlock();
     DBG_SET_LOGD("region={%d,%d,r=%d,b=%d}", region->getBounds().fLeft,
         region->getBounds().fTop, region->getBounds().fRight,
         region->getBounds().fBottom);
     DBG_SET_LOG("end");
 
+    BaseLayerAndroid* base = new BaseLayerAndroid();
+    base->setContent(m_content);
+
 #if USE(ACCELERATED_COMPOSITING)
     // We update the layers
     ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client());
-    chromeC->layersSync();
+    GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*>(chromeC->layersSync());
+    if (root) {
+        root->notifyClientAnimationStarted();
+        LayerAndroid* copyLayer = new LayerAndroid(*root->contentLayer());
+        base->addChild(copyLayer);
+        copyLayer->unref();
+    }
 #endif
-    return true;
+
+    return base;
 }
 
-void WebViewCore::splitContent()
+void WebViewCore::splitContent(PictureSet* content)
 {
     bool layoutSuceeded = layoutIfNeededRecursive(m_mainFrame);
     LOG_ASSERT(layoutSuceeded, "Can never be called recursively");
-    PictureSet tempPictureSet;
-    m_contentMutex.lock();
-    m_content.split(&tempPictureSet);
-    m_contentMutex.unlock();
-    rebuildPictureSet(&tempPictureSet);
-    m_contentMutex.lock();
-    m_content.set(tempPictureSet);
-    m_contentMutex.unlock();
+    content->split(&m_content);
+    rebuildPictureSet(&m_content);
+    content->set(m_content);
 }
 
 void WebViewCore::scrollTo(int x, int y, bool animate)
@@ -950,28 +893,6 @@ void WebViewCore::scrollBy(int dx, int dy, bool animate)
     checkException(env);
 }
 
-#if USE(ACCELERATED_COMPOSITING)
-
-void WebViewCore::immediateRepaint()
-{
-    LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
-    JNIEnv* env = JSC::Bindings::getJNIEnv();
-    env->CallVoidMethod(m_javaGlue->object(env).get(),
-                        m_javaGlue->m_sendImmediateRepaint);
-    checkException(env);
-}
-
-void WebViewCore::setUIRootLayer(const LayerAndroid* layer)
-{
-    JNIEnv* env = JSC::Bindings::getJNIEnv();
-    env->CallVoidMethod(m_javaGlue->object(env).get(),
-                        m_javaGlue->m_setRootLayer,
-                        reinterpret_cast<jint>(layer));
-    checkException(env);
-}
-
-#endif // USE(ACCELERATED_COMPOSITING)
-
 void WebViewCore::contentDraw()
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
@@ -3058,7 +2979,7 @@ void WebViewCore::addVisitedLink(const UChar* string, int length)
         m_groupForVisitedLinks->addVisitedLink(string, length);
 }
 
-static bool RecordContent(JNIEnv *env, jobject obj, jobject region, jobject pt)
+static jint RecordContent(JNIEnv *env, jobject obj, jobject region, jobject pt)
 {
 #ifdef ANDROID_INSTRUMENT
     TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
@@ -3066,18 +2987,18 @@ static bool RecordContent(JNIEnv *env, jobject obj, jobject region, jobject pt)
     WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
     SkRegion* nativeRegion = GraphicsJNI::getNativeRegion(env, region);
     SkIPoint nativePt;
-    bool result = viewImpl->recordContent(nativeRegion, &nativePt);
+    BaseLayerAndroid* result = viewImpl->recordContent(nativeRegion, &nativePt);
     GraphicsJNI::ipoint_to_jpoint(nativePt, env, pt);
-    return result;
+    return reinterpret_cast<jint>(result);
 }
 
-static void SplitContent(JNIEnv *env, jobject obj)
+static void SplitContent(JNIEnv *env, jobject obj, jint content)
 {
 #ifdef ANDROID_INSTRUMENT
     TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
 #endif
     WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
-    viewImpl->splitContent();
+    viewImpl->splitContent(reinterpret_cast<PictureSet*>(content));
 }
 
 static void SendListBoxChoice(JNIEnv* env, jobject obj, jint choice)
@@ -3366,45 +3287,11 @@ static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jstring scheme) {
     WebCore::SecurityOrigin::registerURLSchemeAsLocal(to_string(env, scheme));
 }
 
-static void ClearContent(JNIEnv *env, jobject obj)
-{
-#ifdef ANDROID_INSTRUMENT
-    TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
-#endif
-    WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
-    viewImpl->clearContent();
-}
-
-static void CopyContentToPicture(JNIEnv *env, jobject obj, jobject pict)
-{
-#ifdef ANDROID_INSTRUMENT
-    TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
-#endif
-    WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
-    if (!viewImpl)
-        return;
-    SkPicture* picture = GraphicsJNI::getNativePicture(env, pict);
-    viewImpl->copyContentToPicture(picture);
-}
-
-static bool DrawContent(JNIEnv *env, jobject obj, jobject canv, jint color)
-{
-    // Note: this is called from UI thread, don't count it for WebViewCoreTimeCounter
-    WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
-    SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
-    return viewImpl->drawContent(canvas, color);
-}
-
 static bool FocusBoundsChanged(JNIEnv* env, jobject obj)
 {
     return GET_NATIVE_VIEW(env, obj)->focusBoundsChanged();
 }
 
-static bool PictureReady(JNIEnv* env, jobject obj)
-{
-    return GET_NATIVE_VIEW(env, obj)->pictureReady();
-}
-
 static void Pause(JNIEnv* env, jobject obj)
 {
     // This is called for the foreground tab when the browser is put to the
@@ -3541,20 +3428,12 @@ static jobject GetTouchHighlightRects(JNIEnv* env, jobject obj, jint x, jint y,
  * JNI registration.
  */
 static JNINativeMethod gJavaWebViewCoreMethods[] = {
-    { "nativeClearContent", "()V",
-        (void*) ClearContent },
-    { "nativeCopyContentToPicture", "(Landroid/graphics/Picture;)V",
-        (void*) CopyContentToPicture },
-    { "nativeDrawContent", "(Landroid/graphics/Canvas;I)Z",
-        (void*) DrawContent } ,
     { "nativeFocusBoundsChanged", "()Z",
         (void*) FocusBoundsChanged } ,
     { "nativeKey", "(IIIZZZZ)Z",
         (void*) Key },
     { "nativeClick", "(II)V",
         (void*) Click },
-    { "nativePictureReady", "()Z",
-        (void*) PictureReady } ,
     { "nativeSendListBoxChoices", "([ZI)V",
         (void*) SendListBoxChoices },
     { "nativeSendListBoxChoice", "(I)V",
@@ -3601,11 +3480,11 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
         (void*) UpdateFrameCache },
     { "nativeGetContentMinPrefWidth", "()I",
         (void*) GetContentMinPrefWidth },
-    { "nativeRecordContent", "(Landroid/graphics/Region;Landroid/graphics/Point;)Z",
+    { "nativeRecordContent", "(Landroid/graphics/Region;Landroid/graphics/Point;)I",
         (void*) RecordContent },
     { "setViewportSettingsFromNative", "()V",
         (void*) SetViewportSettingsFromNative },
-    { "nativeSplitContent", "()V",
+    { "nativeSplitContent", "(I)V",
         (void*) SplitContent },
     { "nativeSetBackgroundColor", "(I)V",
         (void*) SetBackgroundColor },
index 42656d4..99f02e9 100644 (file)
@@ -61,10 +61,13 @@ namespace WebCore {
 #if USE(ACCELERATED_COMPOSITING)
 namespace WebCore {
     class GraphicsLayerAndroid;
-    class LayerAndroid;
 }
 #endif
 
+namespace WebCore {
+    class BaseLayerAndroid;
+}
+
 struct PluginWidgetAndroid;
 class SkPicture;
 class SkIRect;
@@ -137,8 +140,6 @@ namespace android {
 
 #if USE(ACCELERATED_COMPOSITING)
         GraphicsLayerAndroid* graphicsRootLayer() const;
-        void immediateRepaint();
-        void setUIRootLayer(const LayerAndroid* layer);
 #endif
 
         /** Invalidate the view/screen, NOT the content/DOM, but expressed in
@@ -449,16 +450,10 @@ namespace android {
         // reset the picture set to empty
         void clearContent();
 
-        // flatten the picture set to a picture
-        void copyContentToPicture(SkPicture* );
-
-        // draw the picture set with the specified background color
-        bool drawContent(SkCanvas* , SkColor );
         bool focusBoundsChanged();
-        bool pictureReady();
 
         // record the inval area, and the picture size
-        bool recordContent(SkRegion* , SkIPoint* );
+        BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* );
         int textWrapWidth() const { return m_textWrapWidth; }
         float scale() const { return m_scale; }
         float textWrapScale() const { return m_screenWidth * m_scale / m_textWrapWidth; }
@@ -468,7 +463,7 @@ namespace android {
         void updateFrameCacheIfLoading();
 
         // utility to split slow parts of the picture set
-        void splitContent();
+        void splitContent(PictureSet*);
 
         void notifyWebAppCanBeInstalled();
 
@@ -520,8 +515,7 @@ namespace android {
         WebCore::IntRect m_lastFocusedBounds;
         int m_lastFocusedSelStart;
         int m_lastFocusedSelEnd;
-        static Mutex m_contentMutex; // protects ui/core thread pictureset access
-        PictureSet m_content; // the set of pictures to draw (accessed by UI too)
+        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
         // Used in passToJS to avoid updating the UI text field until after the
index 9dbefd9..ac36b73 100644 (file)
@@ -30,6 +30,7 @@
 #include "AndroidAnimation.h"
 #include "AndroidLog.h"
 #include "AtomicString.h"
+#include "BaseLayerAndroid.h"
 #include "CachedFrame.h"
 #include "CachedNode.h"
 #include "CachedRoot.h"
@@ -177,7 +178,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
     m_lastDx = 0;
     m_lastDxTime = 0;
     m_ringAnimationEnd = 0;
-    m_rootLayer = 0;
+    m_baseLayer = 0;
 }
 
 ~WebView()
@@ -190,7 +191,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
     }
     delete m_frameCacheUI;
     delete m_navPictureUI;
-    delete m_rootLayer;
+    delete m_baseLayer;
 }
 
 WebViewCore* getWebViewCore() const {
@@ -303,10 +304,11 @@ void scrollRectOnScreen(const IntRect& rect)
     SkRect visible;
     calcOurContentVisibleRect(&visible);
 #if USE(ACCELERATED_COMPOSITING)
-    if (m_rootLayer) {
-        m_rootLayer->updateFixedLayersPositions(visible);
-        m_rootLayer->updatePositions();
-        visible = m_rootLayer->subtractLayers(visible);
+    LayerAndroid* root = compositeRoot();
+    if (root) {
+        root->updateFixedLayersPositions(visible);
+        root->updatePositions();
+        visible = root->subtractLayers(visible);
     }
 #endif
     int dx = 0;
@@ -394,14 +396,30 @@ void drawCursorPostamble()
     }
 }
 
-void drawExtras(SkCanvas* canvas, int extras)
+PictureSet* draw(SkCanvas* canvas, SkColor bgColor, int extras, bool split)
 {
+    PictureSet* ret = 0;
+    if (!m_baseLayer) {
+        canvas->drawColor(bgColor);
+        return ret;
+    }
+
+    // draw the content of the base layer first
+    PictureSet* 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);
+    if (content->draw(canvas))
+        ret = split ? new PictureSet(*content) : 0;
+
     CachedRoot* root = getFrameCache(AllowNewer);
     if (!root) {
         DBG_NAV_LOG("!root");
         if (extras == DrawExtrasCursorRing)
             resetCursorRing();
-        return;
+        return ret;
     }
     LayerAndroid mainPicture(m_navPictureUI);
     DrawExtra* extra = 0;
@@ -425,22 +443,24 @@ void drawExtras(SkCanvas* canvas, int extras)
     if (extra)
         extra->draw(canvas, &mainPicture);
 #if USE(ACCELERATED_COMPOSITING)
-    if (!m_rootLayer)
-        return;
-    m_rootLayer->setExtra(extra);
+    LayerAndroid* compositeLayer = compositeRoot();
+    if (!compositeLayer)
+        return ret;
+    compositeLayer->setExtra(extra);
     SkRect visible;
     calcOurContentVisibleRect(&visible);
     // call this to be sure we've adjusted for any scrolling or animations
     // before we actually draw
-    m_rootLayer->updateFixedLayersPositions(visible);
-    m_rootLayer->updatePositions();
-    // We have to set the canvas' matrix on the root layer
+    compositeLayer->updateFixedLayersPositions(visible);
+    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_rootLayer->setMatrix(canvas->getTotalMatrix());
+    m_baseLayer->setMatrix(canvas->getTotalMatrix());
     canvas->resetMatrix();
-    m_rootLayer->draw(canvas);
+    m_baseLayer->draw(canvas);
 #endif
+    return ret;
 }
 
 
@@ -565,7 +585,7 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer)
     m_viewImpl->m_navPictureKit = 0;
     m_viewImpl->gFrameCacheMutex.unlock();
     if (m_frameCacheUI)
-        m_frameCacheUI->setRootLayer(m_rootLayer);
+        m_frameCacheUI->setRootLayer(compositeRoot());
 #if USE(ACCELERATED_COMPOSITING)
     if (layerId >= 0) {
         SkRect visible;
@@ -1170,20 +1190,49 @@ int moveGeneration()
     return m_viewImpl->m_moveGeneration;
 }
 
-LayerAndroid* rootLayer() const
+LayerAndroid* compositeRoot() const
 {
-    return m_rootLayer;
+    LOG_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;
 }
 
-void setRootLayer(LayerAndroid* layer)
+void setBaseLayer(BaseLayerAndroid* layer)
 {
-    delete m_rootLayer;
-    m_rootLayer = layer;
+    delete m_baseLayer;
+    m_baseLayer = layer;
     CachedRoot* root = getFrameCache(DontAllowNewer);
     if (!root)
         return;
     root->resetLayers();
-    root->setRootLayer(m_rootLayer);
+    root->setRootLayer(compositeRoot());
+}
+
+void replaceBaseContent(PictureSet* set)
+{
+    if (!m_baseLayer)
+        return;
+    m_baseLayer->setContent(*set);
+    delete set;
+}
+
+void copyBaseContentToPicture(SkPicture* picture)
+{
+    if (!m_baseLayer)
+        return;
+    PictureSet* content = m_baseLayer->content();
+    content->draw(picture->beginRecording(content->width(), content->height(),
+            SkPicture::kUsePathBoundsForClip_RecordingFlag));
+    picture->endRecording();
+}
+
+bool hasContent() {
+    if (!m_baseLayer)
+        return false;
+    return !m_baseLayer->content()->isEmpty();
 }
 
 private: // local state for WebView
@@ -1200,7 +1249,7 @@ private: // local state for WebView
     SelectText m_selectText;
     FindOnPage m_findOnPage;
     CursorRing m_ring;
-    LayerAndroid* m_rootLayer;
+    BaseLayerAndroid* m_baseLayer;
 }; // end of WebView class
 
 /*
@@ -1431,28 +1480,43 @@ static void nativeDebugDump(JNIEnv *env, jobject obj)
 #endif
 }
 
-static void nativeDrawExtras(JNIEnv *env, jobject obj, jobject canv, jint extras)
-{
+static jint nativeDraw(JNIEnv *env, jobject obj, jobject canv, jint color,
+        jint extras, jboolean split) {
     SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
-    GET_NATIVE_VIEW(env, obj)->drawExtras(canvas, extras);
+    return reinterpret_cast<jint>(GET_NATIVE_VIEW(env, obj)->draw(canvas, color, extras, split));
 }
 
 static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj)
 {
 #if USE(ACCELERATED_COMPOSITING)
-    const LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->rootLayer();
+    const LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot();
     if (root)
         return root->evaluateAnimations();
 #endif
     return false;
 }
 
-static void nativeSetRootLayer(JNIEnv *env, jobject obj, jint layer)
+static void nativeSetBaseLayer(JNIEnv *env, jobject obj, jint layer)
 {
-#if USE(ACCELERATED_COMPOSITING)
-    LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
-    GET_NATIVE_VIEW(env, obj)->setRootLayer(layerImpl);
-#endif
+    BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(layer);
+    GET_NATIVE_VIEW(env, obj)->setBaseLayer(layerImpl);
+}
+
+static void nativeReplaceBaseContent(JNIEnv *env, jobject obj, jint content)
+{
+    PictureSet* set = reinterpret_cast<PictureSet*>(content);
+    GET_NATIVE_VIEW(env, obj)->replaceBaseContent(set);
+}
+
+static void nativeCopyBaseContentToPicture(JNIEnv *env, jobject obj, jobject pict)
+{
+    SkPicture* picture = GraphicsJNI::getNativePicture(env, pict);
+    GET_NATIVE_VIEW(env, obj)->copyBaseContentToPicture(picture);
+}
+
+static bool nativeHasContent(JNIEnv *env, jobject obj)
+{
+    return GET_NATIVE_VIEW(env, obj)->hasContent();
 }
 
 static jobject nativeImageURI(JNIEnv *env, jobject obj, jint x, jint y)
@@ -1642,7 +1706,7 @@ static jobject nativeSubtractLayers(JNIEnv* env, jobject obj, jobject jrect)
 {
     SkIRect irect = jrect_to_webrect(env, jrect);
 #if USE(ACCELERATED_COMPOSITING)
-    LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->rootLayer();
+    LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot();
     if (root) {
         SkRect rect;
         rect.set(irect);
@@ -1981,26 +2045,13 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
             SkDumpCanvas canvas(&dumper);
             // this will playback the picture into the canvas, which will
             // spew its contents to the dumper
-            view->getWebViewCore()->drawContent(&canvas, 0);
-#if USE(ACCELERATED_COMPOSITING)
-            if (true) {
-                LayerAndroid* rootLayer = view->rootLayer();
-                if (rootLayer) {
-                    // We have to set the canvas' matrix on the root layer
-                    // (to have fixed layers work as intended)
-                    SkAutoCanvasRestore restore(&canvas, true);
-                    rootLayer->setMatrix(canvas.getTotalMatrix());
-                    canvas.resetMatrix();
-                    rootLayer->draw(&canvas);
-                }
-            }
-#endif
+            view->draw(&canvas, 0, 0, false);
             // we're done with the file now
             fwrite("\n", 1, 1, file);
             fclose(file);
         }
 #if USE(ACCELERATED_COMPOSITING)
-        const LayerAndroid* rootLayer = view->rootLayer();
+        const LayerAndroid* rootLayer = view->compositeRoot();
         if (rootLayer) {
           FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w");
           if (file) {
@@ -2053,8 +2104,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
         (void*) nativeDebugDump },
     { "nativeDestroy", "()V",
         (void*) nativeDestroy },
-    { "nativeDrawExtras", "(Landroid/graphics/Canvas;I)V",
-        (void*) nativeDrawExtras },
+    { "nativeDraw", "(Landroid/graphics/Canvas;IIZ)I",
+        (void*) nativeDraw },
     { "nativeDumpDisplayTree", "(Ljava/lang/String;)V",
         (void*) nativeDumpDisplayTree },
     { "nativeEvaluateLayersAnimations", "()Z",
@@ -2147,8 +2198,14 @@ static JNINativeMethod gJavaWebViewMethods[] = {
         (void*) nativeSetFollowedLink },
     { "nativeSetHeightCanMeasure", "(Z)V",
         (void*) nativeSetHeightCanMeasure },
-    { "nativeSetRootLayer", "(I)V",
-        (void*) nativeSetRootLayer },
+    { "nativeSetBaseLayer", "(I)V",
+        (void*) nativeSetBaseLayer },
+    { "nativeReplaceBaseContent", "(I)V",
+        (void*) nativeReplaceBaseContent },
+    { "nativeCopyBaseContentToPicture", "(Landroid/graphics/Picture;)V",
+        (void*) nativeCopyBaseContentToPicture },
+    { "nativeHasContent", "()Z",
+        (void*) nativeHasContent },
     { "nativeSetSelectionPointer", "(ZFII)V",
         (void*) nativeSetSelectionPointer },
     { "nativeStartSelection", "(II)Z",