From 812ccbeb3ce55c50463fda1d161b2eeed8b19cd2 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 1 Jun 2010 14:07:24 -0700 Subject: [PATCH] Add new hardwareAccelerated manifest attribute to enable HW drawing. Change-Id: I2bb0252f3699cb720e7f5b6868419c9904e4fb35 --- api/current.xml | 22 + .../android/content/pm/ApplicationInfo.java | 6 + .../android/content/pm/PackageParser.java | 6 + core/java/android/view/View.java | 12 +- core/java/android/view/ViewGroup.java | 3 +- core/java/android/view/ViewRoot.java | 453 +++++++++--------- core/res/res/values/attrs_manifest.xml | 5 + core/res/res/values/public.xml | 1 + 8 files changed, 279 insertions(+), 229 deletions(-) diff --git a/api/current.xml b/api/current.xml index b72db987d07bc..2b31a64541228 100644 --- a/api/current.xml +++ b/api/current.xml @@ -4563,6 +4563,17 @@ visibility="public" > + + + + = 0; if (!handled) { deliverKeyEventToViewHierarchy(event, sendDone); - return; } else if (sendDone) { if (LOCAL_LOGV) Log.v( "ViewRoot", "Telling window manager key is finished"); @@ -2742,7 +2580,7 @@ public final class ViewRoot extends Handler implements ViewParent, void doDie() { checkThread(); - if (Config.LOGV) Log.v("ViewRoot", "DIE in " + this + " of " + mSurface); + if (LOCAL_LOGV) Log.v("ViewRoot", "DIE in " + this + " of " + mSurface); synchronized (this) { if (mAdded && !mFirst) { int viewVisibility = mView.getVisibility(); @@ -2803,13 +2641,12 @@ public final class ViewRoot extends Handler implements ViewParent, if (event.getAction() == KeyEvent.ACTION_DOWN) { //noinspection ConstantConditions if (false && event.getKeyCode() == KeyEvent.KEYCODE_CAMERA) { - if (Config.LOGD) Log.d("keydisp", - "==================================================="); - if (Config.LOGD) Log.d("keydisp", "Focused view Hierarchy is:"); + if (DBG) Log.d("keydisp", "==================================================="); + if (DBG) Log.d("keydisp", "Focused view Hierarchy is:"); + debug(); - if (Config.LOGD) Log.d("keydisp", - "==================================================="); + if (DBG) Log.d("keydisp", "==================================================="); } } @@ -3476,6 +3313,180 @@ public final class ViewRoot extends Handler implements ViewParent, } } + class HardwareRenderer { + private EGL10 mEgl; + private EGLDisplay mEglDisplay; + private EGLContext mEglContext; + private EGLSurface mEglSurface; + private GL11 mGL; + + private Canvas mGlCanvas; + + boolean mEnabled; + boolean mRequested = true; + + private void initializeGL() { + initializeGLInner(); + int err = mEgl.eglGetError(); + if (err != EGL10.EGL_SUCCESS) { + destroyGL(); + mRequested = false; + } + } + + private void initializeGLInner() { + final EGL10 egl = (EGL10) EGLContext.getEGL(); + mEgl = egl; + + final EGLDisplay eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + mEglDisplay = eglDisplay; + + int[] version = new int[2]; + egl.eglInitialize(eglDisplay, version); + + final int[] configSpec = { + EGL10.EGL_RED_SIZE, 8, + EGL10.EGL_GREEN_SIZE, 8, + EGL10.EGL_BLUE_SIZE, 8, + EGL10.EGL_DEPTH_SIZE, 0, + EGL10.EGL_NONE + }; + final EGLConfig[] configs = new EGLConfig[1]; + final int[] numConfig = new int[1]; + egl.eglChooseConfig(eglDisplay, configSpec, configs, 1, numConfig); + final EGLConfig config = configs[0]; + + /* + * Create an OpenGL ES context. This must be done only once, an + * OpenGL context is a somewhat heavy object. + */ + final EGLContext context = egl.eglCreateContext(eglDisplay, config, + EGL10.EGL_NO_CONTEXT, null); + mEglContext = context; + + /* + * Create an EGL surface we can render into. + */ + EGLSurface surface = egl.eglCreateWindowSurface(eglDisplay, config, mHolder, null); + mEglSurface = surface; + + /* + * Before we can issue GL commands, we need to make sure + * the context is current and bound to a surface. + */ + egl.eglMakeCurrent(eglDisplay, surface, surface, context); + + /* + * Get to the appropriate GL interface. + * This is simply done by casting the GL context to either + * GL10 or GL11. + */ + final GL11 gl = (GL11) context.getGL(); + mGL = gl; + mGlCanvas = new Canvas(gl); + mEnabled = true; + } + + void destroyGL() { + if (!mEnabled) return; + + // inform skia that the context is gone + nativeAbandonGlCaches(); + + mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, + EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); + mEgl.eglDestroyContext(mEglDisplay, mEglContext); + mEgl.eglDestroySurface(mEglDisplay, mEglSurface); + mEgl.eglTerminate(mEglDisplay); + + mEglContext = null; + mEglSurface = null; + mEglDisplay = null; + mEgl = null; + mGlCanvas = null; + mGL = null; + + mEnabled = false; + } + + private void checkErrors() { + if (mEnabled) { + int err = mEgl.eglGetError(); + if (err != EGL10.EGL_SUCCESS) { + // something bad has happened revert to + // normal rendering. + destroyGL(); + if (err != EGL11.EGL_CONTEXT_LOST) { + // we'll try again if it was context lost + mRequested = false; + } + } + } + } + + boolean initialize() { + if (mRequested && !mEnabled) { + initializeGL(); + return mGlCanvas != null; + } + return false; + } + + void setup(float appScale) { + mGlCanvas.setViewport((int) (mWidth * appScale + 0.5f), + (int) (mHeight * appScale + 0.5f)); + } + + void draw(int yoff, boolean scalingRequired) { + Canvas canvas = mGlCanvas; + if (mGL != null && canvas != null) { + mGL.glDisable(GL_SCISSOR_TEST); + mGL.glClearColor(0, 0, 0, 0); + mGL.glClear(GL_COLOR_BUFFER_BIT); + mGL.glEnable(GL_SCISSOR_TEST); + + mAttachInfo.mDrawingTime = SystemClock.uptimeMillis(); + mAttachInfo.mIgnoreDirtyState = true; + mView.mPrivateFlags |= View.DRAWN; + + int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); + try { + canvas.translate(0, -yoff); + if (mTranslator != null) { + mTranslator.translateCanvas(canvas); + } + canvas.setScreenDensity(scalingRequired ? + DisplayMetrics.DENSITY_DEVICE : 0); + + mView.draw(canvas); + + } finally { + canvas.restoreToCount(saveCount); + } + + mAttachInfo.mIgnoreDirtyState = false; + + mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); + checkErrors(); + } + } + + void initializeAndSetup() { + if (mRequested) { + checkErrors(); + // we lost the gl context, so recreate it. + if (mRequested && !mEnabled) { + initializeGL(); + if (mGlCanvas != null) { + float appScale = mAttachInfo.mApplicationScale; + mGlCanvas.setViewport((int) (mWidth * appScale + 0.5f), + (int) (mHeight * appScale + 0.5f)); + } + } + } + } + } + private static native void nativeShowFPS(Canvas canvas, int durationMillis); // inform skia to just abandon its texture cache IDs diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index b4c4811bec726..4c32ec9288234 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -235,6 +235,10 @@ the safe mode. --> + + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 9055970e0e619..1aa55e22a4959 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1281,6 +1281,7 @@ +