summaryrefslogtreecommitdiffstats
path: root/android_webview/test
diff options
context:
space:
mode:
authorsievers <sievers@chromium.org>2014-08-29 16:32:28 -0700
committerCommit bot <commit-bot@chromium.org>2014-08-29 23:45:19 +0000
commit386f9301889efde34b202a4600496b1e10aa06c8 (patch)
tree0afea8a65c625eb7eefdf7bd2e8c60ce5f6b9ab9 /android_webview/test
parente79241d8e2f7f17ea1c55fbb3c26674527bd58cd (diff)
downloadchromium_src-386f9301889efde34b202a4600496b1e10aa06c8.zip
chromium_src-386f9301889efde34b202a4600496b1e10aa06c8.tar.gz
chromium_src-386f9301889efde34b202a4600496b1e10aa06c8.tar.bz2
android: Use hw acceleration in android_webview_shell
This creates a (GL)SurfaceView overlay on top of the shell container view which runs its own thread for rendering. It calls into the native draw functor through a small dynamic library (drawgl.so). NOTRY=True Review URL: https://codereview.chromium.org/414503004 Cr-Commit-Position: refs/heads/master@{#292718}
Diffstat (limited to 'android_webview/test')
-rw-r--r--android_webview/test/shell/AndroidManifest.xml8
-rw-r--r--android_webview/test/shell/src/draw_gl/DEPS7
-rw-r--r--android_webview/test/shell/src/draw_gl/draw_gl.cc61
-rw-r--r--android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java2
-rw-r--r--android_webview/test/shell/src/org/chromium/android_webview/shell/DrawGL.java18
-rw-r--r--android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java219
6 files changed, 307 insertions, 8 deletions
diff --git a/android_webview/test/shell/AndroidManifest.xml b/android_webview/test/shell/AndroidManifest.xml
index 3c21ab8..5b3bf94 100644
--- a/android_webview/test/shell/AndroidManifest.xml
+++ b/android_webview/test/shell/AndroidManifest.xml
@@ -10,17 +10,19 @@
package="org.chromium.android_webview.shell">
<application android:name="org.chromium.android_webview.shell.AwShellApplication"
- android:label="AwShellApplication" android:hardwareAccelerated="false">
+ android:label="AwShellApplication">
<activity android:name="org.chromium.android_webview.shell.AwShellActivity"
android:label="Android WebView Test Shell"
- android:configChanges="orientation|keyboardHidden|keyboard|screenSize">
+ android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
+ android:hardwareAccelerated="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="org.chromium.android_webview.test.AwTestRunnerActivity"
- android:label="AwTestRunnerActivity">
+ android:label="AwTestRunnerActivity"
+ android:hardwareAccelerated="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
diff --git a/android_webview/test/shell/src/draw_gl/DEPS b/android_webview/test/shell/src/draw_gl/DEPS
new file mode 100644
index 0000000..c55f31a
--- /dev/null
+++ b/android_webview/test/shell/src/draw_gl/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+ # draw_gl compiles its own shared library for a single entry point
+ # for testing. Therefore it cannot depend on any other module,
+ # except for shared definitions.
+ "-android_webview",
+ "+android_webview/public/browser",
+]
diff --git a/android_webview/test/shell/src/draw_gl/draw_gl.cc b/android_webview/test/shell/src/draw_gl/draw_gl.cc
new file mode 100644
index 0000000..260a3f5
--- /dev/null
+++ b/android_webview/test/shell/src/draw_gl/draw_gl.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <jni.h>
+
+#include "android_webview/public/browser/draw_gl.h"
+
+extern "C" {
+
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ return JNI_VERSION_1_4;
+}
+
+// This code goes into its own dynamic library, so we cannot depend on
+// any other components like base.
+JNIEXPORT void JNICALL
+ Java_org_chromium_android_1webview_shell_DrawGL_nativeDrawGL(
+ JNIEnv*,
+ jclass,
+ jlong draw_gl,
+ jlong view,
+ jint width,
+ jint height,
+ jint scroll_x,
+ jint scroll_y,
+ jint mode) {
+ AwDrawGLInfo draw_info;
+ draw_info.mode = static_cast<AwDrawGLInfo::Mode>(mode);
+ draw_info.version = kAwDrawGLInfoVersion;
+ draw_info.is_layer = false;
+ draw_info.width = width;
+ draw_info.height = height;
+ draw_info.clip_left = 0;
+ draw_info.clip_top = 0;
+ draw_info.clip_bottom = height;
+ draw_info.clip_right = width;
+ draw_info.transform[0] = 1.0;
+ draw_info.transform[1] = 0.0;
+ draw_info.transform[2] = 0.0;
+ draw_info.transform[3] = 0.0;
+
+ draw_info.transform[4] = 0.0;
+ draw_info.transform[5] = 1.0;
+ draw_info.transform[6] = 0.0;
+ draw_info.transform[7] = 0.0;
+
+ draw_info.transform[8] = 0.0;
+ draw_info.transform[9] = 0.0;
+ draw_info.transform[10] = 1.0;
+ draw_info.transform[11] = 0.0;
+
+ draw_info.transform[12] = -scroll_x;
+ draw_info.transform[13] = -scroll_y;
+ draw_info.transform[14] = 0.0;
+ draw_info.transform[15] = 1.0;
+ AwDrawGLFunction* draw_func = reinterpret_cast<AwDrawGLFunction*>(draw_gl);
+ draw_func(view, &draw_info, 0);
+}
+
+}
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
index 8c9cf82..0e6070b 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
@@ -80,7 +80,7 @@ public class AwShellActivity extends Activity {
private AwTestContainerView createAwTestContainerView() {
AwBrowserProcess.start(this);
- AwTestContainerView testContainerView = new AwTestContainerView(this);
+ AwTestContainerView testContainerView = new AwTestContainerView(this, true);
AwContentsClient awContentsClient = new NullContentsClient() {
private View mCustomView;
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/DrawGL.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/DrawGL.java
new file mode 100644
index 0000000..ee0d395
--- /dev/null
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/DrawGL.java
@@ -0,0 +1,18 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview.shell;
+
+/**
+ * Provides an entry point to the native draw functor.
+ */
+public class DrawGL {
+ public static void drawGL(long drawGL, long viewContext, int width, int height,
+ int scrollX, int scrollY, int mode) {
+ nativeDrawGL(drawGL, viewContext, width, height, scrollX, scrollY, mode);
+ }
+
+ private static native void nativeDrawGL(long drawGL, long viewContext,
+ int width, int height, int scrollX, int scrollY, int mode);
+}
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
index 153a280..e853957 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
@@ -7,10 +7,13 @@ package org.chromium.android_webview.test;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
+import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.SurfaceHolder;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -20,8 +23,12 @@ import android.view.inputmethod.InputConnection;
import android.widget.FrameLayout;
import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.shell.DrawGL;
import org.chromium.content.browser.ContentViewCore;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
/**
* A View used for testing the AwContents internals.
*
@@ -32,8 +39,180 @@ public class AwTestContainerView extends FrameLayout {
private AwContents.NativeGLDelegate mNativeGLDelegate;
private AwContents.InternalAccessDelegate mInternalAccessDelegate;
- public AwTestContainerView(Context context) {
+ HardwareView mHardwareView = null;
+ private boolean mAttachedContents = false;
+
+ private class HardwareView extends GLSurfaceView {
+ private static final int MODE_DRAW = 0;
+ private static final int MODE_PROCESS = 1;
+ private static final int MODE_PROCESS_NO_CONTEXT = 2;
+ private static final int MODE_SYNC = 3;
+
+ // mSyncLock is used to synchronized requestRender on the UI thread
+ // and drawGL on the rendering thread. The variables following
+ // are protected by it.
+ private final Object mSyncLock = new Object();
+ private boolean mNeedsProcessGL = false;
+ private boolean mNeedsDrawGL = false;
+ private boolean mWaitForCompletion = false;
+ private int mLastScrollX = 0;
+ private int mLastScrollY = 0;
+
+ private int mCommittedScrollX = 0;
+ private int mCommittedScrollY = 0;
+
+ private boolean mHaveSurface = false;
+ private Runnable mReadyToRenderCallback = null;
+
+ private long mDrawGL = 0;
+ private long mViewContext = 0;
+
+ public HardwareView(Context context) {
+ super(context);
+ setEGLContextClientVersion(2); // GLES2
+ getHolder().setFormat(PixelFormat.OPAQUE);
+ setPreserveEGLContextOnPause(true);
+ setRenderer(new Renderer() {
+ private int mWidth = 0;
+ private int mHeight = 0;
+
+ @Override
+ public void onDrawFrame(GL10 gl) {
+ HardwareView.this.drawGL(mWidth, mHeight);
+ }
+
+ @Override
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ gl.glViewport(0, 0, width, height);
+ gl.glScissor(0, 0, width, height);
+ mWidth = width;
+ mHeight = height;
+ }
+
+ @Override
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ }
+ });
+
+ setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+ }
+
+ public void initialize(long drawGL, long viewContext) {
+ mDrawGL = drawGL;
+ mViewContext = viewContext;
+ }
+
+ public boolean isReadyToRender() {
+ return mHaveSurface;
+ }
+
+ public void setReadyToRenderCallback(Runnable runner) {
+ assert !isReadyToRender() || runner == null;
+ mReadyToRenderCallback = runner;
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ boolean didHaveSurface = mHaveSurface;
+ mHaveSurface = true;
+ if (!didHaveSurface && mReadyToRenderCallback != null) {
+ mReadyToRenderCallback.run();
+ mReadyToRenderCallback = null;
+ }
+ super.surfaceCreated(holder);
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ mHaveSurface = false;
+ super.surfaceDestroyed(holder);
+ }
+
+ public void updateScroll(int x, int y) {
+ synchronized (mSyncLock) {
+ mLastScrollX = x;
+ mLastScrollY = y;
+ }
+ }
+
+ public void requestRender(Canvas canvas, boolean waitForCompletion) {
+ synchronized (mSyncLock) {
+ super.requestRender();
+ mWaitForCompletion = waitForCompletion;
+ if (canvas == null) {
+ mNeedsProcessGL = true;
+ } else {
+ mNeedsDrawGL = true;
+ if (!waitForCompletion) {
+ // Wait until SYNC is complete only.
+ // Do this every time there was a new frame.
+ try {
+ while (mNeedsDrawGL) {
+ mSyncLock.wait();
+ }
+ } catch (InterruptedException e) {
+ // ...
+ }
+ }
+ }
+ if (waitForCompletion) {
+ try {
+ while (mWaitForCompletion) {
+ mSyncLock.wait();
+ }
+ } catch (InterruptedException e) {
+ // ...
+ }
+ }
+ }
+ }
+
+ public void drawGL(int width, int height) {
+ final boolean draw;
+ final boolean process;
+ final boolean waitForCompletion;
+
+ synchronized (mSyncLock) {
+ draw = mNeedsDrawGL;
+ process = mNeedsProcessGL;
+ waitForCompletion = mWaitForCompletion;
+
+ if (draw) {
+ DrawGL.drawGL(mDrawGL, mViewContext, width, height, 0, 0, MODE_SYNC);
+ mCommittedScrollX = mLastScrollX;
+ mCommittedScrollY = mLastScrollY;
+ }
+ mNeedsDrawGL = false;
+ mNeedsProcessGL = false;
+ if (!waitForCompletion) {
+ mSyncLock.notifyAll();
+ }
+ }
+ if (draw) {
+ DrawGL.drawGL(mDrawGL, mViewContext, width, height,
+ mCommittedScrollX, mCommittedScrollY, MODE_DRAW);
+ } else if (process) {
+ DrawGL.drawGL(mDrawGL, mViewContext, width, height, 0, 0, MODE_PROCESS);
+ }
+
+ if (waitForCompletion) {
+ synchronized (mSyncLock) {
+ mWaitForCompletion = false;
+ mSyncLock.notifyAll();
+ }
+ }
+ }
+ }
+
+ public AwTestContainerView(Context context, boolean hardwareAccelerated) {
super(context);
+ if (hardwareAccelerated) {
+ mHardwareView = new HardwareView(context);
+ addView(mHardwareView,
+ new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT));
+ }
mNativeGLDelegate = new NativeGLDelegate();
mInternalAccessDelegate = new InternalAccessAdapter();
setOverScrollMode(View.OVER_SCROLL_ALWAYS);
@@ -43,6 +222,11 @@ public class AwTestContainerView extends FrameLayout {
public void initialize(AwContents awContents) {
mAwContents = awContents;
+ if (mHardwareView != null) {
+ System.loadLibrary("drawgl");
+ mHardwareView.initialize(
+ mAwContents.getAwDrawGLFunction(), mAwContents.getAwDrawGLViewContext());
+ }
}
public ContentViewCore getContentViewCore() {
@@ -74,13 +258,28 @@ public class AwTestContainerView extends FrameLayout {
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
- mAwContents.onAttachedToWindow();
+ if (mHardwareView == null || mHardwareView.isReadyToRender()) {
+ mAwContents.onAttachedToWindow();
+ mAttachedContents = true;
+ } else {
+ mHardwareView.setReadyToRenderCallback(new Runnable() {
+ public void run() {
+ assert !mAttachedContents;
+ mAwContents.onAttachedToWindow();
+ mAttachedContents = true;
+ }
+ });
+ }
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAwContents.onDetachedFromWindow();
+ if (mHardwareView != null) {
+ mHardwareView.setReadyToRenderCallback(null);
+ }
+ mAttachedContents = false;
}
@Override
@@ -107,6 +306,7 @@ public class AwTestContainerView extends FrameLayout {
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mAwContents.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
@@ -153,6 +353,9 @@ public class AwTestContainerView extends FrameLayout {
@Override
public void onDraw(Canvas canvas) {
+ if (mHardwareView != null) {
+ mHardwareView.updateScroll(getScrollX(), getScrollY());
+ }
mAwContents.onDraw(canvas);
super.onDraw(canvas);
}
@@ -183,11 +386,13 @@ public class AwTestContainerView extends FrameLayout {
return mAwContents.performAccessibilityAction(action, arguments);
}
- private static class NativeGLDelegate implements AwContents.NativeGLDelegate {
+ private class NativeGLDelegate implements AwContents.NativeGLDelegate {
@Override
public boolean requestDrawGL(Canvas canvas, boolean waitForCompletion,
View containerview) {
- return false;
+ if (mHardwareView == null) return false;
+ mHardwareView.requestRender(canvas, waitForCompletion);
+ return true;
}
@Override
@@ -234,6 +439,12 @@ public class AwTestContainerView extends FrameLayout {
public void super_scrollTo(int scrollX, int scrollY) {
// We're intentionally not calling super.scrollTo here to make testing easier.
AwTestContainerView.this.scrollTo(scrollX, scrollY);
+ if (mHardwareView != null) {
+ // Undo the scroll that will be applied because of mHardwareView
+ // being a child of |this|.
+ mHardwareView.setTranslationX(scrollX);
+ mHardwareView.setTranslationY(scrollY);
+ }
}
@Override