summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/GLRenderer.java26
-rw-r--r--core/java/android/view/HardwareRenderer.java11
-rw-r--r--core/java/android/view/ThreadedRenderer.java6
-rw-r--r--core/jni/android_view_GLRenderer.cpp11
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp8
-rw-r--r--include/private/hwui/DrawGlInfo.h5
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp17
-rw-r--r--libs/hwui/renderthread/CanvasContext.h1
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp16
-rw-r--r--libs/hwui/renderthread/RenderProxy.h1
10 files changed, 100 insertions, 2 deletions
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index 125d11e..d6e1781 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -555,6 +555,32 @@ public class GLRenderer extends HardwareRenderer {
}
@Override
+ public void invokeFunctor(long functor, boolean waitForCompletion) {
+ boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
+ boolean hasContext = !needsContext;
+
+ if (needsContext) {
+ GLRendererEglContext managedContext =
+ (GLRendererEglContext) sEglContextStorage.get();
+ if (managedContext != null) {
+ usePbufferSurface(managedContext.getContext());
+ hasContext = true;
+ }
+ }
+
+ try {
+ nInvokeFunctor(functor, hasContext);
+ } finally {
+ if (needsContext) {
+ sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ }
+ }
+ }
+
+ private static native void nInvokeFunctor(long functor, boolean hasContext);
+
+ @Override
void destroyHardwareResources(final View view) {
if (view != null) {
safelyRun(new Runnable() {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 34efcf5..4f646e1 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -438,6 +438,17 @@ public abstract class HardwareRenderer {
abstract void attachFunctor(View.AttachInfo attachInfo, long functor);
/**
+ * Schedules the functor for execution in either kModeProcess or
+ * kModeProcessNoContext, depending on whether or not there is an EGLContext.
+ *
+ * @param functor The native functor to invoke
+ * @param waitForCompletion If true, this will not return until the functor
+ * has invoked. If false, the functor may be invoked
+ * asynchronously.
+ */
+ public abstract void invokeFunctor(long functor, boolean waitForCompletion);
+
+ /**
* Initializes the hardware renderer for the specified surface and setup the
* renderer for drawing, if needed. This is invoked when the ViewAncestor has
* potentially lost the hardware renderer. The hardware renderer should be
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 2a488a0..7b8a1ff 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -186,6 +186,11 @@ public class ThreadedRenderer extends HardwareRenderer {
}
@Override
+ public void invokeFunctor(long functor, boolean waitForCompletion) {
+ nInvokeFunctor(mNativeProxy, functor, waitForCompletion);
+ }
+
+ @Override
HardwareLayer createDisplayListLayer(int width, int height) {
long layer = nCreateDisplayListLayer(mNativeProxy, width, height);
return HardwareLayer.adoptDisplayListLayer(this, layer);
@@ -266,6 +271,7 @@ public class ThreadedRenderer extends HardwareRenderer {
private static native void nAttachFunctor(long nativeProxy, long functor);
private static native void nDetachFunctor(long nativeProxy, long functor);
+ private static native void nInvokeFunctor(long nativeProxy, long functor, boolean waitForCompletion);
private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
private static native long nCreateTextureLayer(long nativeProxy);
diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
index e45c1b9..180c625 100644
--- a/core/jni/android_view_GLRenderer.cpp
+++ b/core/jni/android_view_GLRenderer.cpp
@@ -26,6 +26,8 @@
#include <utils/Timers.h>
+#include <private/hwui/DrawGlInfo.h>
+
#include <Caches.h>
#include <Extensions.h>
#include <LayerRenderer.h>
@@ -155,6 +157,14 @@ static void android_view_GLRenderer_updateRenderNodeProperties(JNIEnv* env, jobj
renderNode->updateProperties();
}
+static void android_view_GLRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
+ jlong functorPtr, jboolean hasContext) {
+ using namespace android::uirenderer;
+ Functor* functor = reinterpret_cast<Functor*>(functorPtr);
+ DrawGlInfo::Mode mode = hasContext ? DrawGlInfo::kModeProcess : DrawGlInfo::kModeProcessNoContext;
+ (*functor)(mode, NULL);
+}
+
#endif // USE_OPENGL_RENDERER
// ----------------------------------------------------------------------------
@@ -187,6 +197,7 @@ static JNINativeMethod gMethods[] = {
{ "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer },
{ "nSetDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_setDisplayListData },
{ "nUpdateRenderNodeProperties", "(J)V", (void*) android_view_GLRenderer_updateRenderNodeProperties },
+ { "nInvokeFunctor", "(JZ)V", (void*) android_view_GLRenderer_invokeFunctor },
#endif
{ "setupShadersDiskCache", "(Ljava/lang/String;)V",
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 28cee4b..98bec1b 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -139,6 +139,13 @@ static void android_view_ThreadedRenderer_detachFunctor(JNIEnv* env, jobject cla
proxy->detachFunctor(functor);
}
+static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jlong functorPtr, jboolean waitForCompletion) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ Functor* functor = reinterpret_cast<Functor*>(functorPtr);
+ proxy->invokeFunctor(functor, waitForCompletion);
+}
+
static void android_view_ThreadedRenderer_runWithGlContext(JNIEnv* env, jobject clazz,
jlong proxyPtr, jobject jrunnable) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -196,6 +203,7 @@ static JNINativeMethod gMethods[] = {
{ "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas },
{ "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor },
{ "nDetachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_detachFunctor },
+ { "nInvokeFunctor", "(JJZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
{ "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext },
{ "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer },
{ "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
diff --git a/include/private/hwui/DrawGlInfo.h b/include/private/hwui/DrawGlInfo.h
index 3b7ba8b..a357a01 100644
--- a/include/private/hwui/DrawGlInfo.h
+++ b/include/private/hwui/DrawGlInfo.h
@@ -55,7 +55,10 @@ struct DrawGlInfo {
kModeDraw,
// Indicates the the functor is called only to perform
// processing and that no draw should be attempted
- kModeProcess
+ kModeProcess,
+ // Same as kModeProcess, however there is no GL context because it was
+ // lost or destroyed
+ kModeProcessNoContext
};
/**
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 017fb56..fa82627 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -82,6 +82,8 @@ public:
// Returns true on success, false on failure
void initialize();
+ bool hasContext();
+
void usePBufferSurface();
EGLSurface createSurface(EGLNativeWindowType window);
void destroySurface(EGLSurface surface);
@@ -138,7 +140,7 @@ GlobalContext::GlobalContext()
}
void GlobalContext::initialize() {
- if (mEglDisplay != EGL_NO_DISPLAY) return;
+ if (hasContext()) return;
mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
@@ -157,6 +159,10 @@ void GlobalContext::initialize() {
initAtlas();
}
+bool GlobalContext::hasContext() {
+ return mEglDisplay != EGL_NO_DISPLAY;
+}
+
void GlobalContext::loadConfig() {
EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
EGLint attribs[] = {
@@ -440,6 +446,15 @@ void CanvasContext::detachFunctor(Functor* functor) {
mCanvas->detachFunctor(functor);
}
+void CanvasContext::invokeFunctor(Functor* functor) {
+ DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
+ if (mGlobalContext->hasContext()) {
+ requireGlContext();
+ mode = DrawGlInfo::kModeProcess;
+ }
+ (*functor)(mode, NULL);
+}
+
void CanvasContext::invokeFunctors() {
mInvokeFunctorsPending = false;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 746c1bf..eb9096d 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -72,6 +72,7 @@ public:
void attachFunctor(Functor* functor);
void detachFunctor(Functor* functor);
+ void invokeFunctor(Functor* functor);
void runWithGlContext(RenderTask* task);
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 16b93c3..cd711b0 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -167,6 +167,22 @@ void RenderProxy::detachFunctor(Functor* functor) {
post(task);
}
+CREATE_BRIDGE2(invokeFunctor, CanvasContext* context, Functor* functor) {
+ args->context->invokeFunctor(args->functor);
+ return NULL;
+}
+
+void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
+ SETUP_TASK(invokeFunctor);
+ args->context = mContext;
+ args->functor = functor;
+ if (waitForCompletion) {
+ postAndWait(task);
+ } else {
+ post(task);
+ }
+}
+
CREATE_BRIDGE2(runWithGlContext, CanvasContext* context, RenderTask* task) {
args->context->runWithGlContext(args->task);
return NULL;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index ee7a4c7..f1ca534 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -69,6 +69,7 @@ public:
ANDROID_API void attachFunctor(Functor* functor);
ANDROID_API void detachFunctor(Functor* functor);
+ ANDROID_API void invokeFunctor(Functor* functor, bool waitForCompletion);
ANDROID_API void runWithGlContext(RenderTask* task);