OSDN Git Service

libhwui: make setSurface asynchronous
authorThomas Buhot <thomas.buhot@intel.com>
Mon, 11 Jan 2016 09:50:08 +0000 (10:50 +0100)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 20 Jul 2016 09:53:24 +0000 (17:53 +0800)
This is based on the commit 738a5d4f18e69c03700b77af0ea7e2a101da2c34
that has been merged in Google's master branch.
See: https://android-review.googlesource.com/#/c/183305/

On the critical path of the cold launch of applications
the main thread of the started application tells the RenderThread
to create a surface. This process is synchronous and blocks
the main thread of the application until the creation
of the EGLContext is complete.
As a consequence the launch time of the application is delayed
by time spent allocating the EGL Context in the RenderThread.

With this optimization the launch time of any application
is improved (for example settings by 20 to 40 ms).

Change-Id: I2fea7991abf290d35747b14dc5f9710d293de40a
Signed-off-by: Thomas Buhot <thomas.buhot@intel.com>
Tracked-On: https://jira01.devtools.intel.com/browse/OAM-15447
Reviewed-on: https://android.intel.com:443/456345

core/java/android/view/ThreadedRenderer.java
core/jni/android_view_ThreadedRenderer.cpp
libs/hwui/renderthread/CanvasContext.cpp
libs/hwui/renderthread/CanvasContext.h
libs/hwui/renderthread/RenderProxy.cpp
libs/hwui/renderthread/RenderProxy.h

index f6119e2..db147ab 100644 (file)
@@ -145,9 +145,10 @@ public class ThreadedRenderer extends HardwareRenderer {
 
     @Override
     boolean initialize(Surface surface) throws OutOfResourcesException {
+        boolean status = !mInitialized;
         mInitialized = true;
         updateEnabledState(surface);
-        boolean status = nInitialize(mNativeProxy, surface);
+        nInitialize(mNativeProxy, surface);
         return status;
     }
 
@@ -503,7 +504,7 @@ public class ThreadedRenderer extends HardwareRenderer {
     private static native boolean nLoadSystemProperties(long nativeProxy);
     private static native void nSetName(long nativeProxy, String name);
 
-    private static native boolean nInitialize(long nativeProxy, Surface window);
+    private static native void nInitialize(long nativeProxy, Surface window);
     private static native void nUpdateSurface(long nativeProxy, Surface window);
     private static native boolean nPauseSurface(long nativeProxy, Surface window);
     private static native void nSetup(long nativeProxy, int width, int height,
index 47132f4..7400ef0 100644 (file)
@@ -262,11 +262,11 @@ static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz,
     env->ReleaseStringUTFChars(jname, name);
 }
 
-static jboolean android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
+static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jobject jsurface) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
     sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface);
-    return proxy->initialize(window);
+    proxy->initialize(window);
 }
 
 static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
@@ -461,7 +461,7 @@ static JNINativeMethod gMethods[] = {
     { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
     { "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties },
     { "nSetName", "(JLjava/lang/String;)V", (void*) android_view_ThreadedRenderer_setName },
-    { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
+    { "nInitialize", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_initialize },
     { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
     { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
     { "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
index 33eb3f1..8ac9129 100644 (file)
@@ -111,16 +111,15 @@ void CanvasContext::setSwapBehavior(SwapBehavior swapBehavior) {
     mSwapBehavior = swapBehavior;
 }
 
-bool CanvasContext::initialize(ANativeWindow* window) {
+void CanvasContext::initialize(ANativeWindow* window) {
     setSurface(window);
-    if (mCanvas) return false;
+    if (mCanvas) return;
     mCanvas = new OpenGLRenderer(mRenderThread.renderState());
     mCanvas->initProperties();
     if (window) {
         Surface *s = static_cast<Surface*>(window);
         s->allocateBuffers();
     }
-    return true;
 }
 
 void CanvasContext::updateSurface(ANativeWindow* window) {
index f2fa9cd..1e6f830 100644 (file)
@@ -67,7 +67,7 @@ public:
     // Won't take effect until next EGLSurface creation
     void setSwapBehavior(SwapBehavior swapBehavior);
 
-    bool initialize(ANativeWindow* window);
+    void initialize(ANativeWindow* window);
     void updateSurface(ANativeWindow* window);
     bool pauseSurface(ANativeWindow* window);
     bool hasSurface() { return mNativeWindow.get(); }
index 6d9acd4..30f0073 100644 (file)
@@ -140,14 +140,15 @@ void RenderProxy::setName(const char* name) {
 }
 
 CREATE_BRIDGE2(initialize, CanvasContext* context, ANativeWindow* window) {
-    return (void*) args->context->initialize(args->window);
+    args->context->initialize(args->window);
+    return nullptr;
 }
 
-bool RenderProxy::initialize(const sp<ANativeWindow>& window) {
+void RenderProxy::initialize(const sp<ANativeWindow>& window) {
     SETUP_TASK(initialize);
     args->context = mContext;
     args->window = window.get();
-    return (bool) postAndWait(task);
+    post(task);
 }
 
 CREATE_BRIDGE2(updateSurface, CanvasContext* context, ANativeWindow* window) {
index 5febbe0..db03b29 100644 (file)
@@ -67,7 +67,7 @@ public:
     ANDROID_API bool loadSystemProperties();
     ANDROID_API void setName(const char* name);
 
-    ANDROID_API bool initialize(const sp<ANativeWindow>& window);
+    ANDROID_API void initialize(const sp<ANativeWindow>& window);
     ANDROID_API void updateSurface(const sp<ANativeWindow>& window);
     ANDROID_API bool pauseSurface(const sp<ANativeWindow>& window);
     ANDROID_API void setup(int width, int height, float lightRadius,