diff options
| -rw-r--r-- | core/java/android/view/GLES20Canvas.java | 25 | ||||
| -rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 12 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Canvas.java | 47 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 23 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 2 |
5 files changed, 107 insertions, 2 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index b058685..65cb182 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -55,7 +55,9 @@ class GLES20Canvas extends Canvas { private final Rect mClipBounds = new Rect(); private DrawFilter mFilter; - + + private boolean mContextLocked; + /////////////////////////////////////////////////////////////////////////// // JNI /////////////////////////////////////////////////////////////////////////// @@ -149,6 +151,27 @@ class GLES20Canvas extends Canvas { private native void nPrepare(int renderer); + @Override + public boolean acquireContext() { + if (!mContextLocked) { + nAcquireContext(mRenderer); + mContextLocked = true; + } + return mContextLocked; + } + + private native void nAcquireContext(int renderer); + + @Override + public void releaseContext() { + if (mContextLocked) { + nReleaseContext(mRenderer); + mContextLocked = false; + } + } + + private native void nReleaseContext(int renderer); + /////////////////////////////////////////////////////////////////////////// // Clipping /////////////////////////////////////////////////////////////////////////// diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 98c03a6..aa71746 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -84,6 +84,16 @@ static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas, renderer->prepare(); } +static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject canvas, + OpenGLRenderer* renderer) { + renderer->acquireContext(); +} + +static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas, + OpenGLRenderer* renderer) { + renderer->releaseContext(); +} + // ---------------------------------------------------------------------------- // State // ---------------------------------------------------------------------------- @@ -374,6 +384,8 @@ static JNINativeMethod gMethods[] = { { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer }, { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport }, { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare }, + { "nAcquireContext", "(I)V", (void*) android_view_GLES20Canvas_acquireContext }, + { "nReleaseContext", "(I)V", (void*) android_view_GLES20Canvas_releaseContext }, { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save }, { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore }, diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 36a8e57..e75a19e 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1551,7 +1551,52 @@ public class Canvas { drawPicture(picture); restore(); } - + + /** + * <p>Acquires the Canvas context. After invoking this method, the Canvas + * context can be modified by the caller. For instance, if you acquire + * the context of an OpenGL Canvas you can reset the GL viewport, scissor, + * etc.</p> + * + * <p>A call to {@link #acquireContext()} should aways be followed by + * a call to {@link #releaseContext()}, preferrably using a try block:</p> + * + * <pre> + * try { + * if (canvas.acquireContext()) { + * // Use the canvas and/or its context + * } + * } finally { + * canvas.releaseContext(); + * } + * </pre> + * + * <p>Acquiring the context can be an expensive operation and should not + * be done unless absolutely necessary.</p> + * + * <p>Applications should never invoke this method directly.</p> + * + * @return True if the context could be acquired successfully, false + * otherwise (if the context is already acquired for instance.) + * + * @see #releaseContext() + * + * @hide + */ + public boolean acquireContext() { + return false; + } + + /** + * <p>Release the context acquired with {@link #acquireContext()}.</p> + * + * @see #acquireContext() + * + * @hide + */ + public void releaseContext() { + } + @Override protected void finalize() throws Throwable { try { diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 4ce30b0..02f5dc5 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -143,6 +143,29 @@ void OpenGLRenderer::prepare() { mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); } +void OpenGLRenderer::acquireContext() { + if (mCaches.currentProgram) { + if (mCaches.currentProgram->isInUse()) { + mCaches.currentProgram->remove(); + mCaches.currentProgram = NULL; + } + } +} + +void OpenGLRenderer::releaseContext() { + glViewport(0, 0, mSnapshot->viewport.getWidth(), mSnapshot->viewport.getHeight()); + + glEnable(GL_SCISSOR_TEST); + setScissorFromClip(); + + if (mCaches.blend) { + glEnable(GL_BLEND); + glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode); + } else { + glDisable(GL_BLEND); + } +} + /////////////////////////////////////////////////////////////////////////////// // State management /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 5748d57..d0e04b2 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -58,6 +58,8 @@ public: void setViewport(int width, int height); void prepare(); + void acquireContext(); + void releaseContext(); int getSaveCount() const; int save(int flags); |
