のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

SaveViewState その2

7:webkit/WebViewCore.java

   2274     private void saveViewState(OutputStream stream,
   2275             ValueCallback<Boolean> callback) {
   2276         // TODO: Create a native method to do this better without overloading
   2277         // the draw path (and fix saving <canvas&>)
   2278         DrawData draw = new DrawData(); <=8
   2279         if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "saveViewState start");
   2280         draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mContentSize); =>10へ
   2281         boolean result = false;
   2282         try {
   2283             result = ViewStateSerializer.serializeViewState(stream, draw);
   2284         } catch (Throwable t) {
   2285             Log.w(LOGTAG, "Failed to save view state", t);
   2286         }
   2287         callback.onReceiveValue(result);
   2288         if (draw.mBaseLayer != 0) {
   2289             if (mDrawIsScheduled) {
   2290                 mDrawIsScheduled = false;
   2291                 mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
   2292             }
   2293             mLastDrawData = draw;
   2294             webkitDraw(draw);
   2295         }
   2296     }

8:DrawDataは、以下のようなクラスです。

   2182     static class DrawData {
   2183         DrawData() {
   2184             mBaseLayer = 0;
   2185             mContentSize = new Point();
   2186         }
   2187         int mBaseLayer;
   2188         // view size that was used by webkit during the most recent layout
   2189         Point mViewSize;
   2190         Point mContentSize;
   2191         int mMinPrefWidth;
   2192         // only non-null if it is for the first picture set after the first layout
   2193         ViewState mViewState; <= 9
   2194         boolean mFirstLayoutForNonStandardLoad;
   2195         boolean mFocusSizeChanged;
   2196     }

9:ViewStateは以下のようなクラスです。

   2169    static class ViewState {
   2170         float mMinScale;
   2171         float mMaxScale;
   2172         float mViewScale;
   2173         float mTextWrapScale;
   2174         float mDefaultScale;
   2175         int mScrollX;
   2176         int mScrollY;
   2177         boolean mMobileSite;
   2178         boolean mIsRestored;
   2179         boolean mShouldStartScrolledRight;
   2180     }

C++の方へ入る。

10:jni/WebViewCore.cpp

    908 BaseLayerAndroid* WebViewCore::recordContent(SkIPoint* point)
    909 {
    910     m_skipContentDraw = true;
    911     layout(); =>11へ
    912     ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>
                                           (m_mainFrame->page()->chrome()->client());
    913     GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*>
                                           (chromeC->layersSync());
    914     m_skipContentDraw = false;
    915     recordPicturePile(); =>12
    916 
    917     BaseLayerAndroid* baseLayer = createBaseLayer(root);
    918 
    919     baseLayer-&gt;markAsDirty(m_content.dirtyRegion());
    920     m_content.dirtyRegion().setEmpty();
    921 #if USE(ACCELERATED_COMPOSITING)
    922 #else
    923     baseLayer->markAsDirty(m_rebuildInval);
    924 #endif
    925     point-&gt;fX = m_content.size().width();
    926     point-&gt;fY = m_content.size().height();
    927 
    928     return baseLayer;
    929 }

11:jni/WebViewCore.cpp

    628 void WebViewCore::layout()
    629 {
    630     TRACE_METHOD();
    631 
    632     // if there is no document yet, just return
    633     if (!m_mainFrame->document()) {
    634         ALOGV("!m_mainFrame->document()");
    635         return;
    636     }
    637 
    638     // Call layout to ensure that the contentWidth and contentHeight are correct
    639     // it's fine for layout to gather invalidates, but defeat sending a message
    640     // back to java to call webkitDraw, since we're already in the middle of
    641     // doing that
    642     bool success = layoutIfNeededRecursive(m_mainFrame);
    643 
    644     // We may be mid-layout and thus cannot draw.
    645     if (!success)
    646         return;
    647 
    648     // if the webkit page dimensions changed, discard the pictureset and redraw.
    649     WebCore::FrameView* view = m_mainFrame->view();
    650     int width = view->contentsWidth();
    651     int height = view->contentsHeight();
    652 
    653     // Use the contents width and height as a starting point.
    654     SkIRect contentRect;
    655     contentRect.set(0, 0, width, height);
    656     SkIRect total(contentRect);
    657 
    658     // Traverse all the frames and add their sizes if they are in the visible
    659     // rectangle.
    660     for (WebCore::Frame* frame = m_mainFrame->tree()->traverseNext(); frame;
    661             frame = frame->tree()->traverseNext()) {
    662         // If the frame doesn't have an owner then it is the top frame and the
    663         // view size is the frame size.
    664         WebCore::RenderPart* owner = frame->ownerRenderer();
    665         if (owner && owner->style()->visibility() == VISIBLE) {
    666             int x = owner->x();
    667             int y = owner->y();
    668 
    669             // Traverse the tree up to the parent to find the absolute position
    670             // of this frame.
    671             WebCore::Frame* parent = frame->tree()->parent();
    672             while (parent) {
    673                 WebCore::RenderPart* parentOwner = parent->ownerRenderer();
    674                 if (parentOwner) {
    675                     x += parentOwner->x();
    676                     y += parentOwner->y();
    677                 }
    678                 parent = parent->tree()->parent();
    679             }
    680             // Use the owner dimensions so that padding and border are
    681             // included.
    682             int right = x + owner->width();
    683             int bottom = y + owner->height();
    684             SkIRect frameRect = {x, y, right, bottom};
    685             // Ignore a width or height that is smaller than 1. Some iframes
    686             // have small dimensions in order to be hidden. The iframe
    687             // expansion code does not expand in that case so we should ignore
    688             // them here.
    689             if (frameRect.width() > 1 && frameRect.height() > 1
    690                     && SkIRect::Intersects(total, frameRect))
    691                 total.join(x, y, right, bottom);
    692         }
    693     }
    694 
    695     // If the new total is larger than the content, resize the view to include
    696     // all the content.
    697     if (!contentRect.contains(total)) {
    698         // TODO: Does this ever happen? Is this needed now that we don't flatten
    699         // frames?
    700         // Resize the view to change the overflow clip.
    701         view->resize(total.fRight, total.fBottom);
    702 
    703         // We have to force a layout in order for the clip to change.
    704         m_mainFrame->contentRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
    705         view->forceLayout();
    706 
    707         // Relayout similar to above
    708         layoutIfNeededRecursive(m_mainFrame);
    709     }
    710 }
    711 

12:jni/WebViewCore.cpp

    712 void WebViewCore::recordPicturePile()
    713 {
    714     // if the webkit page dimensions changed, discard the pictureset and redraw.
    715     WebCore::FrameView* view = m_mainFrame->view();
    716     int width = view ? view->contentsWidth() : 0;
    717     int height = view ? view->contentsHeight() : 0;
    718 
    719     m_content.setSize(IntSize(width, height));
    720 
    721     // Rebuild the pictureset (webkit repaint)
    722     m_content.updatePicturesIfNeeded(this);
    723 }

SaveViewState その3