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
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
LOCAL_SRC_FILES := \
goldfish_dma.cpp \
+ goldfishHwc2.cpp \
FormatConversions.cpp \
HostConnection.cpp \
ProcessPipe.cpp \
--- /dev/null
+/*
+* 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
--- /dev/null
+/*
+* 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
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
#include "eglContext.h"
#include "ClientAPIExts.h"
#include "EGLImage.h"
+#include "goldfishHwc2.h"
#include "ProcessPipe.h"
#include "GLEncoder.h"
rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
((cb_handle_t*)(buffer->handle))->hostHandle);
+ surfaceInterface_setAsyncModeForWindow((void*)nativeWindow);
+
return EGL_TRUE;
}
*/
#include "eglDisplay.h"
#include "HostConnection.h"
+#include "goldfishHwc2.h"
+
#include <dlfcn.h>
#include <string>
pthread_mutex_init(&m_lock, NULL);
pthread_mutex_init(&m_ctxLock, NULL);
pthread_mutex_init(&m_surfaceLock, NULL);
+ surfaceInterface_init();
}
eglDisplay::~eglDisplay()
--- /dev/null
+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
--- /dev/null
+#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);
+}
--- /dev/null
+/*
+* 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);