OSDN Git Service

[hwc2] Add surfaceInterface/goldfishHwc2
authorLingfeng Yang <lfy@google.com>
Tue, 21 Mar 2017 21:46:26 +0000 (14:46 -0700)
committerLingfeng Yang <lfy@google.com>
Wed, 22 Mar 2017 18:47:28 +0000 (11:47 -0700)
bug: 36439031
bug: 36375335

When HWC2 is used (even the HWC2on1 adapter), one of the most fundamental
changes is that acquireBuffer/releaseBuffer by BufferQueue consumers
is coarsened, delaying releaseBuffer until the app has finished
with its eglSwapBuffers operation and handling releaseBuffer as part of
a post process (mPendingRelease/releasePendingBuffer/et al).

This would be OK, except for the fact that an acquired, unreleased buffer
takes up a free buffer slot.

Emulator uses GLES composition currently, so each eglSwapBuffers by an app
directly causes another eglSwapBuffers, each of which attempts to
dequeueBuffer, taking up 2 slots right there. This was usually OK, since
releaseBuffer would be interleaved, but now, with the delayed releaseBuffer,
there are no free buffer slots and we have a deadlock situation.

Fortunately, we can set the swapped-to Surface to "async mode", which takes
exactly this situation into account. Async mode, which is for Surfaces but
really affects the BufferQueueCore queue size, makes it so that there
is an extra buffer slot so that dequeueBuffer doesn't have to block.

This CL adds a small static library for setting the swapped-to Surface
to async mode. Note that one does not simply add libgui to the shared
libraries of system/egl/Android.mk, since libgui itself includes EGL/GLES2
as dependencies, putting us into DLL hell and causing all sorts of trouble!

Change-Id: I6ee4f0e6d0b668d60573887751ec6b02839df5c3

Android.mk
system/OpenglSystemCommon/Android.mk
system/OpenglSystemCommon/goldfishHwc2.cpp [new file with mode: 0644]
system/OpenglSystemCommon/goldfishHwc2.h [new file with mode: 0644]
system/egl/Android.mk
system/egl/egl.cpp
system/egl/eglDisplay.cpp
system/surfaceInterface/Android.mk [new file with mode: 0644]
system/surfaceInterface/surfaceInterface.cpp [new file with mode: 0644]
system/surfaceInterface/surfaceInterface.h [new file with mode: 0644]

index 566e737..9061c9b 100644 (file)
@@ -73,6 +73,7 @@ include $(EMUGL_PATH)/system/GLESv1/Android.mk
 include $(EMUGL_PATH)/system/GLESv2/Android.mk
 
 include $(EMUGL_PATH)/system/gralloc/Android.mk
+include $(EMUGL_PATH)/system/surfaceInterface/Android.mk
 include $(EMUGL_PATH)/system/egl/Android.mk
 
 endif # BUILD_EMULATOR_OPENGL == true
index 9853f29..b585971 100644 (file)
@@ -5,6 +5,7 @@ $(call emugl-import,libGLESv1_enc libGLESv2_enc lib_renderControl_enc)
 
 LOCAL_SRC_FILES := \
     goldfish_dma.cpp \
+    goldfishHwc2.cpp \
     FormatConversions.cpp \
     HostConnection.cpp \
     ProcessPipe.cpp    \
diff --git a/system/OpenglSystemCommon/goldfishHwc2.cpp b/system/OpenglSystemCommon/goldfishHwc2.cpp
new file mode 100644 (file)
index 0000000..888ba89
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include "goldfishHwc2.h"
+
+// Stub functions if not using HWC2.
+#ifndef USE_HWC2
+extern "C" void surfaceInterface_init() { }
+extern "C" void surfaceInterface_setAsyncModeForWindow(void* window) { }
+#endif
diff --git a/system/OpenglSystemCommon/goldfishHwc2.h b/system/OpenglSystemCommon/goldfishHwc2.h
new file mode 100644 (file)
index 0000000..cb1a396
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#pragma once
+
+// Set of functions that help support HWC2 in the emulator.
+
+#ifdef USE_HWC2
+#include "../surfaceInterface/surfaceInterface.h"
+#else
+extern "C" void surfaceInterface_init();
+extern "C" void surfaceInterface_setAsyncModeForWindow(void* window);
+#endif
index f7dcc70..37aadd7 100644 (file)
@@ -13,8 +13,12 @@ LOCAL_SRC_FILES := \
     egl.cpp \
     ClientAPIExts.cpp
 
-LOCAL_SHARED_LIBRARIES += libdl
+ifeq ($(TARGET_USES_HWC2), true)
+    LOCAL_CFLAGS += -DUSE_HWC2
+    LOCAL_STATIC_LIBRARIES += libsurfaceInterface
+endif
 
+LOCAL_SHARED_LIBRARIES += libdl
 # Used to access the Bionic private OpenGL TLS slot
 LOCAL_C_INCLUDES += bionic/libc/private
 
index 8273cb5..c00d380 100644 (file)
@@ -29,6 +29,7 @@
 #include "eglContext.h"
 #include "ClientAPIExts.h"
 #include "EGLImage.h"
+#include "goldfishHwc2.h"
 #include "ProcessPipe.h"
 
 #include "GLEncoder.h"
@@ -367,6 +368,8 @@ EGLBoolean egl_window_surface_t::init()
     rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
             ((cb_handle_t*)(buffer->handle))->hostHandle);
 
+    surfaceInterface_setAsyncModeForWindow((void*)nativeWindow);
+
     return EGL_TRUE;
 }
 
index 68ead6b..2239e99 100644 (file)
@@ -15,6 +15,8 @@
 */
 #include "eglDisplay.h"
 #include "HostConnection.h"
+#include "goldfishHwc2.h"
+
 #include <dlfcn.h>
 
 #include <string>
@@ -70,6 +72,7 @@ eglDisplay::eglDisplay() :
     pthread_mutex_init(&m_lock, NULL);
     pthread_mutex_init(&m_ctxLock, NULL);
     pthread_mutex_init(&m_surfaceLock, NULL);
+    surfaceInterface_init();
 }
 
 eglDisplay::~eglDisplay()
diff --git a/system/surfaceInterface/Android.mk b/system/surfaceInterface/Android.mk
new file mode 100644 (file)
index 0000000..194ae1f
--- /dev/null
@@ -0,0 +1,13 @@
+ifneq (false,$(BUILD_EMULATOR_OPENGL_DRIVER))
+
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-static-library,libsurfaceInterface)
+$(call emugl-import,libOpenglSystemCommon)
+
+LOCAL_SRC_FILES := surfaceInterface.cpp
+LOCAL_SHARED_LIBRARIES := libgui
+
+$(call emugl-end-module)
+
+endif # BUILD_EMULATOR_OPENGL_DRIVER != false
diff --git a/system/surfaceInterface/surfaceInterface.cpp b/system/surfaceInterface/surfaceInterface.cpp
new file mode 100644 (file)
index 0000000..68f9110
--- /dev/null
@@ -0,0 +1,36 @@
+#include "surfaceInterface.h"
+
+#include <cutils/log.h>
+#include <gui/Surface.h>
+
+class SurfaceInterface : public android::ANativeObjectBase<
+                                    ANativeWindow,
+                                    android::Surface,
+                                    android::RefBase> {
+public:
+    static SurfaceInterface* get();
+    void setAsyncMode(ANativeWindow* anw, bool async) {
+        ALOGD("SurfaceInterface::%s: set async mode %d", __func__, async);
+        window = anw;
+        android::Surface* s = android::Surface::getSelf(window);
+        s->setAsyncMode(async);
+        window = NULL;
+    }
+    ANativeWindow* window;
+};
+
+static SurfaceInterface* sSurfaceInterface = NULL;
+
+SurfaceInterface* SurfaceInterface::get() {
+    if (!sSurfaceInterface)
+        sSurfaceInterface = new SurfaceInterface;
+    return sSurfaceInterface;
+}
+
+extern "C" void surfaceInterface_init() {
+    SurfaceInterface::get();
+}
+
+extern "C" void surfaceInterface_setAsyncModeForWindow(void* window) {
+    SurfaceInterface::get()->setAsyncMode((ANativeWindow*)window, true);
+}
diff --git a/system/surfaceInterface/surfaceInterface.h b/system/surfaceInterface/surfaceInterface.h
new file mode 100644 (file)
index 0000000..6890847
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#pragma once
+
+#if PLATFORM_SDK_VERSION >= 16
+#include <system/window.h>
+#else // PLATFORM_SDK_VERSION >= 16
+#include <private/ui/android_natives_priv.h>
+#endif // PLATFORM_SDK_VERSION >= 16
+
+extern "C" void surfaceInterface_init();
+extern "C" void surfaceInterface_setAsyncModeForWindow(void* window);