Merge "Add invokeFunctor"

This commit is contained in:
John Reck
2014-03-31 18:04:06 +00:00
committed by Android (Google) Code Review
10 changed files with 100 additions and 2 deletions

View File

@@ -554,6 +554,32 @@ public class GLRenderer extends HardwareRenderer {
return true; return true;
} }
@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 @Override
void destroyHardwareResources(final View view) { void destroyHardwareResources(final View view) {
if (view != null) { if (view != null) {

View File

@@ -437,6 +437,17 @@ public abstract class HardwareRenderer {
*/ */
abstract void attachFunctor(View.AttachInfo attachInfo, long functor); 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 * Initializes the hardware renderer for the specified surface and setup the
* renderer for drawing, if needed. This is invoked when the ViewAncestor has * renderer for drawing, if needed. This is invoked when the ViewAncestor has

View File

@@ -185,6 +185,11 @@ public class ThreadedRenderer extends HardwareRenderer {
nAttachFunctor(mNativeProxy, functor); nAttachFunctor(mNativeProxy, functor);
} }
@Override
public void invokeFunctor(long functor, boolean waitForCompletion) {
nInvokeFunctor(mNativeProxy, functor, waitForCompletion);
}
@Override @Override
HardwareLayer createDisplayListLayer(int width, int height) { HardwareLayer createDisplayListLayer(int width, int height) {
long layer = nCreateDisplayListLayer(mNativeProxy, width, height); long layer = nCreateDisplayListLayer(mNativeProxy, width, height);
@@ -266,6 +271,7 @@ public class ThreadedRenderer extends HardwareRenderer {
private static native void nAttachFunctor(long nativeProxy, long functor); private static native void nAttachFunctor(long nativeProxy, long functor);
private static native void nDetachFunctor(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 nCreateDisplayListLayer(long nativeProxy, int width, int height);
private static native long nCreateTextureLayer(long nativeProxy); private static native long nCreateTextureLayer(long nativeProxy);

View File

@@ -26,6 +26,8 @@
#include <utils/Timers.h> #include <utils/Timers.h>
#include <private/hwui/DrawGlInfo.h>
#include <Caches.h> #include <Caches.h>
#include <Extensions.h> #include <Extensions.h>
#include <LayerRenderer.h> #include <LayerRenderer.h>
@@ -155,6 +157,14 @@ static void android_view_GLRenderer_updateRenderNodeProperties(JNIEnv* env, jobj
renderNode->updateProperties(); 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 #endif // USE_OPENGL_RENDERER
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -187,6 +197,7 @@ static JNINativeMethod gMethods[] = {
{ "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer }, { "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer },
{ "nSetDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_setDisplayListData }, { "nSetDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_setDisplayListData },
{ "nUpdateRenderNodeProperties", "(J)V", (void*) android_view_GLRenderer_updateRenderNodeProperties }, { "nUpdateRenderNodeProperties", "(J)V", (void*) android_view_GLRenderer_updateRenderNodeProperties },
{ "nInvokeFunctor", "(JZ)V", (void*) android_view_GLRenderer_invokeFunctor },
#endif #endif
{ "setupShadersDiskCache", "(Ljava/lang/String;)V", { "setupShadersDiskCache", "(Ljava/lang/String;)V",

View File

@@ -139,6 +139,13 @@ static void android_view_ThreadedRenderer_detachFunctor(JNIEnv* env, jobject cla
proxy->detachFunctor(functor); 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, static void android_view_ThreadedRenderer_runWithGlContext(JNIEnv* env, jobject clazz,
jlong proxyPtr, jobject jrunnable) { jlong proxyPtr, jobject jrunnable) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -196,6 +203,7 @@ static JNINativeMethod gMethods[] = {
{ "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas }, { "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas },
{ "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor }, { "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor },
{ "nDetachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_detachFunctor }, { "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 }, { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext },
{ "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer }, { "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer },
{ "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer }, { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },

View File

@@ -55,7 +55,10 @@ struct DrawGlInfo {
kModeDraw, kModeDraw,
// Indicates the the functor is called only to perform // Indicates the the functor is called only to perform
// processing and that no draw should be attempted // 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
}; };
/** /**

View File

@@ -82,6 +82,8 @@ public:
// Returns true on success, false on failure // Returns true on success, false on failure
void initialize(); void initialize();
bool hasContext();
void usePBufferSurface(); void usePBufferSurface();
EGLSurface createSurface(EGLNativeWindowType window); EGLSurface createSurface(EGLNativeWindowType window);
void destroySurface(EGLSurface surface); void destroySurface(EGLSurface surface);
@@ -138,7 +140,7 @@ GlobalContext::GlobalContext()
} }
void GlobalContext::initialize() { void GlobalContext::initialize() {
if (mEglDisplay != EGL_NO_DISPLAY) return; if (hasContext()) return;
mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
@@ -157,6 +159,10 @@ void GlobalContext::initialize() {
initAtlas(); initAtlas();
} }
bool GlobalContext::hasContext() {
return mEglDisplay != EGL_NO_DISPLAY;
}
void GlobalContext::loadConfig() { void GlobalContext::loadConfig() {
EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
EGLint attribs[] = { EGLint attribs[] = {
@@ -440,6 +446,15 @@ void CanvasContext::detachFunctor(Functor* functor) {
mCanvas->detachFunctor(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() { void CanvasContext::invokeFunctors() {
mInvokeFunctorsPending = false; mInvokeFunctorsPending = false;

View File

@@ -72,6 +72,7 @@ public:
void attachFunctor(Functor* functor); void attachFunctor(Functor* functor);
void detachFunctor(Functor* functor); void detachFunctor(Functor* functor);
void invokeFunctor(Functor* functor);
void runWithGlContext(RenderTask* task); void runWithGlContext(RenderTask* task);

View File

@@ -167,6 +167,22 @@ void RenderProxy::detachFunctor(Functor* functor) {
post(task); 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) { CREATE_BRIDGE2(runWithGlContext, CanvasContext* context, RenderTask* task) {
args->context->runWithGlContext(args->task); args->context->runWithGlContext(args->task);
return NULL; return NULL;

View File

@@ -69,6 +69,7 @@ public:
ANDROID_API void attachFunctor(Functor* functor); ANDROID_API void attachFunctor(Functor* functor);
ANDROID_API void detachFunctor(Functor* functor); ANDROID_API void detachFunctor(Functor* functor);
ANDROID_API void invokeFunctor(Functor* functor, bool waitForCompletion);
ANDROID_API void runWithGlContext(RenderTask* task); ANDROID_API void runWithGlContext(RenderTask* task);