Skip to content

Commit 658e999

Browse files
author
Teng-Hui Zhu
committed
Replace tree observer with a JNI call at draw time
webkit change: https://android-git.corp.google.com/g/#/c/188148/ bug:6447729 Change-Id: I8062583751cc10fc65b30d10277b2f2271b58661
1 parent 2fd54c4 commit 658e999

File tree

1 file changed

+38
-64
lines changed

1 file changed

+38
-64
lines changed

core/java/android/webkit/WebViewClassic.java

Lines changed: 38 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,6 @@
149149
@SuppressWarnings("deprecation")
150150
public final class WebViewClassic implements WebViewProvider, WebViewProvider.ScrollDelegate,
151151
WebViewProvider.ViewDelegate {
152-
private class InnerGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
153-
@Override
154-
public void onGlobalLayout() {
155-
if (mWebView.isShown()) {
156-
setInvScreenRect();
157-
}
158-
}
159-
}
160-
161-
private class InnerScrollChangedListener implements ViewTreeObserver.OnScrollChangedListener {
162-
@Override
163-
public void onScrollChanged() {
164-
if (mWebView.isShown()) {
165-
setInvScreenRect();
166-
}
167-
}
168-
}
169-
170152
/**
171153
* InputConnection used for ContentEditable. This captures changes
172154
* to the text and sends them either as key strokes or text changes.
@@ -617,12 +599,6 @@ protected void measureContent() {
617599
}
618600
}
619601

620-
// The listener to capture global layout change event.
621-
private InnerGlobalLayoutListener mGlobalLayoutListener = null;
622-
623-
// The listener to capture scroll event.
624-
private InnerScrollChangedListener mScrollChangedListener = null;
625-
626602
// if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
627603
// the screen all-the-time. Good for profiling our drawing code
628604
static private final boolean AUTO_REDRAW_HACK = false;
@@ -647,7 +623,7 @@ protected void measureContent() {
647623
private final Rect mInvScreenRect = new Rect();
648624
private final Rect mScreenRect = new Rect();
649625
private final RectF mVisibleContentRect = new RectF();
650-
private boolean mGLViewportEmpty = false;
626+
private boolean mIsWebViewVisible = true;
651627
WebViewInputConnection mInputConnection = null;
652628
private int mFieldPointer;
653629
private PastePopupWindow mPasteWindow;
@@ -3050,21 +3026,14 @@ private void calcOurContentVisibleRect(Rect r) {
30503026
r.bottom = viewToContentY(r.bottom);
30513027
}
30523028

3053-
private Rect mContentVisibleRect = new Rect();
3029+
private final Rect mTempContentVisibleRect = new Rect();
30543030
// Sets r to be our visible rectangle in content coordinates. We use this
30553031
// method on the native side to compute the position of the fixed layers.
30563032
// Uses floating coordinates (necessary to correctly place elements when
30573033
// the scale factor is not 1)
30583034
private void calcOurContentVisibleRectF(RectF r) {
3059-
calcOurVisibleRect(mContentVisibleRect);
3060-
r.left = viewToContentXf(mContentVisibleRect.left) / mWebView.getScaleX();
3061-
// viewToContentY will remove the total height of the title bar. Add
3062-
// the visible height back in to account for the fact that if the title
3063-
// bar is partially visible, the part of the visible rect which is
3064-
// displaying our content is displaced by that amount.
3065-
r.top = viewToContentYf(mContentVisibleRect.top + getVisibleTitleHeightImpl()) / mWebView.getScaleY();
3066-
r.right = viewToContentXf(mContentVisibleRect.right) / mWebView.getScaleX();
3067-
r.bottom = viewToContentYf(mContentVisibleRect.bottom) / mWebView.getScaleY();
3035+
calcOurVisibleRect(mTempContentVisibleRect);
3036+
viewToContentVisibleRect(r, mTempContentVisibleRect);
30683037
}
30693038

30703039
static class ViewSizeData {
@@ -4224,8 +4193,8 @@ && nativeEvaluateLayersAnimations(mNativeClass)) {
42244193

42254194
calcOurContentVisibleRectF(mVisibleContentRect);
42264195
if (canvas.isHardwareAccelerated()) {
4227-
Rect invScreenRect = mGLViewportEmpty ? null : mInvScreenRect;
4228-
Rect screenRect = mGLViewportEmpty ? null : mScreenRect;
4196+
Rect invScreenRect = mIsWebViewVisible ? mInvScreenRect : null;
4197+
Rect screenRect = mIsWebViewVisible ? mScreenRect : null;
42294198

42304199
int functor = nativeCreateDrawGLFunction(mNativeClass, invScreenRect,
42314200
screenRect, mVisibleContentRect, getScale(), extras);
@@ -5405,15 +5374,6 @@ String getSelection() {
54055374
@Override
54065375
public void onAttachedToWindow() {
54075376
if (mWebView.hasWindowFocus()) setActive(true);
5408-
final ViewTreeObserver treeObserver = mWebView.getViewTreeObserver();
5409-
if (mGlobalLayoutListener == null) {
5410-
mGlobalLayoutListener = new InnerGlobalLayoutListener();
5411-
treeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);
5412-
}
5413-
if (mScrollChangedListener == null) {
5414-
mScrollChangedListener = new InnerScrollChangedListener();
5415-
treeObserver.addOnScrollChangedListener(mScrollChangedListener);
5416-
}
54175377

54185378
addAccessibilityApisToJavaScript();
54195379

@@ -5426,16 +5386,6 @@ public void onDetachedFromWindow() {
54265386
mZoomManager.dismissZoomPicker();
54275387
if (mWebView.hasWindowFocus()) setActive(false);
54285388

5429-
final ViewTreeObserver treeObserver = mWebView.getViewTreeObserver();
5430-
if (mGlobalLayoutListener != null) {
5431-
treeObserver.removeGlobalOnLayoutListener(mGlobalLayoutListener);
5432-
mGlobalLayoutListener = null;
5433-
}
5434-
if (mScrollChangedListener != null) {
5435-
treeObserver.removeOnScrollChangedListener(mScrollChangedListener);
5436-
mScrollChangedListener = null;
5437-
}
5438-
54395389
removeAccessibilityApisFromJavaScript();
54405390
updateHwAccelerated();
54415391

@@ -5547,11 +5497,18 @@ public void onFocusChanged(boolean focused, int direction,
55475497
}
55485498
}
55495499

5550-
void setInvScreenRect() {
5500+
// updateRectsForGL() happens almost every draw call, in order to avoid creating
5501+
// any object in this code path, we move the local variable out to be a private
5502+
// final member, and we marked them as mTemp*.
5503+
private final Point mTempVisibleRectOffset = new Point();
5504+
private final Rect mTempVisibleRect = new Rect();
5505+
5506+
void updateRectsForGL() {
55515507
// Use the getGlobalVisibleRect() to get the intersection among the parents
55525508
// visible == false means we're clipped - send a null rect down to indicate that
55535509
// we should not draw
5554-
boolean visible = mWebView.getGlobalVisibleRect(mInvScreenRect);
5510+
boolean visible = mWebView.getGlobalVisibleRect(mTempVisibleRect, mTempVisibleRectOffset);
5511+
mInvScreenRect.set(mTempVisibleRect);
55555512
if (visible) {
55565513
// Then need to invert the Y axis, just for GL
55575514
View rootView = mWebView.getRootView();
@@ -5560,16 +5517,33 @@ void setInvScreenRect() {
55605517
int savedWebViewBottom = mInvScreenRect.bottom;
55615518
mInvScreenRect.bottom = rootViewHeight - mInvScreenRect.top - getVisibleTitleHeightImpl();
55625519
mInvScreenRect.top = rootViewHeight - savedWebViewBottom;
5563-
mGLViewportEmpty = false;
5520+
mIsWebViewVisible = true;
55645521
} else {
5565-
mGLViewportEmpty = true;
5522+
mIsWebViewVisible = false;
55665523
}
5567-
calcOurContentVisibleRectF(mVisibleContentRect);
5568-
nativeUpdateDrawGLFunction(mNativeClass, mGLViewportEmpty ? null : mInvScreenRect,
5569-
mGLViewportEmpty ? null : mScreenRect,
5524+
5525+
mTempVisibleRect.offset(-mTempVisibleRectOffset.x, -mTempVisibleRectOffset.y);
5526+
viewToContentVisibleRect(mVisibleContentRect, mTempVisibleRect);
5527+
5528+
nativeUpdateDrawGLFunction(mNativeClass, mIsWebViewVisible ? mInvScreenRect : null,
5529+
mIsWebViewVisible ? mScreenRect : null,
55705530
mVisibleContentRect, getScale());
55715531
}
55725532

5533+
// Input : viewRect, rect in view/screen coordinate.
5534+
// Output: contentRect, rect in content/document coordinate.
5535+
private void viewToContentVisibleRect(RectF contentRect, Rect viewRect) {
5536+
contentRect.left = viewToContentXf(viewRect.left) / mWebView.getScaleX();
5537+
// viewToContentY will remove the total height of the title bar. Add
5538+
// the visible height back in to account for the fact that if the title
5539+
// bar is partially visible, the part of the visible rect which is
5540+
// displaying our content is displaced by that amount.
5541+
contentRect.top = viewToContentYf(viewRect.top + getVisibleTitleHeightImpl())
5542+
/ mWebView.getScaleY();
5543+
contentRect.right = viewToContentXf(viewRect.right) / mWebView.getScaleX();
5544+
contentRect.bottom = viewToContentYf(viewRect.bottom) / mWebView.getScaleY();
5545+
}
5546+
55735547
@Override
55745548
public boolean setFrame(int left, int top, int right, int bottom) {
55755549
boolean changed = mWebViewPrivate.super_setFrame(left, top, right, bottom);
@@ -5582,7 +5556,7 @@ public boolean setFrame(int left, int top, int right, int bottom) {
55825556
// notify the WebKit about the new dimensions.
55835557
sendViewSizeZoom(false);
55845558
}
5585-
setInvScreenRect();
5559+
updateRectsForGL();
55865560
return changed;
55875561
}
55885562

0 commit comments

Comments
 (0)