Wrap interactions with ANativeWindow-s in an interface
... so that upcoming end2end tests can set up a mock impl for
emulating ANativeWindow-s in single process tests.
Bug: b/292257025
Test: cvd start --gpu_mode=gfxstream
cvd start --gpu_mode=gfxstream_guest_angle_host_swiftshader
Change-Id: I3bdab77401e7236b7367f57b3a7e46bec7b08248
diff --git a/guest/OpenglSystemCommon/ANativeWindow.h b/guest/OpenglSystemCommon/ANativeWindow.h
new file mode 100644
index 0000000..a50d9c2
--- /dev/null
+++ b/guest/OpenglSystemCommon/ANativeWindow.h
@@ -0,0 +1,56 @@
+// Copyright 2023 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 expresso or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "Gralloc.h"
+
+namespace gfxstream {
+
+// Abstraction around libnativewindow to support testing.
+class ANativeWindowHelper {
+ public:
+ virtual ~ANativeWindowHelper() {}
+
+ virtual bool isValid(EGLNativeWindowType window) = 0;
+ virtual bool isValid(EGLClientBuffer buffer) = 0;
+
+ virtual void acquire(EGLNativeWindowType window) = 0;
+ virtual void release(EGLNativeWindowType window)= 0;
+
+ virtual void acquire(EGLClientBuffer buffer) = 0;
+ virtual void release(EGLClientBuffer buffer) = 0;
+
+ virtual int getConsumerUsage(EGLNativeWindowType window, int* usage) = 0;
+ virtual void setUsage(EGLNativeWindowType window, int usage) = 0;
+
+ virtual int getWidth(EGLNativeWindowType window) = 0;
+ virtual int getHeight(EGLNativeWindowType window) = 0;
+
+ virtual int getWidth(EGLClientBuffer buffer) = 0;
+ virtual int getHeight(EGLClientBuffer buffer) = 0;
+ virtual int getFormat(EGLClientBuffer buffer, Gralloc* helper) = 0;
+ virtual int getHostHandle(EGLClientBuffer buffer, Gralloc* helper) = 0;
+
+ virtual void setSwapInterval(EGLNativeWindowType window, int interval) = 0;
+
+ virtual int queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) = 0;
+ virtual int dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) = 0;
+ virtual int cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) = 0;
+};
+
+} // namespace gfxstream
diff --git a/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp b/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp
new file mode 100644
index 0000000..1edae70
--- /dev/null
+++ b/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp
@@ -0,0 +1,221 @@
+// Copyright 2023 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 expresso or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "ANativeWindowAndroid.h"
+
+#if defined(__ANDROID__)
+#include <android/native_window.h>
+#include <system/window.h>
+#endif // defined(__ANDROID__)
+
+namespace gfxstream {
+
+bool ANativeWindowHelperAndroid::isValid(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ return anw->common.magic == ANDROID_NATIVE_WINDOW_MAGIC;
+#else
+ (void)window;
+ return false;
+#endif // defined(__ANDROID__)
+}
+
+bool ANativeWindowHelperAndroid::isValid(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+ auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ if (anwb->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+ return false;
+ }
+ if (anwb->common.version != sizeof(android_native_buffer_t)) {
+ return false;
+ }
+ if (anwb->handle == nullptr) {
+ return false;
+ }
+ return true;
+#else
+ (void)buffer;
+ return false;
+#endif // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::acquire(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ ANativeWindow_acquire(anw);
+#else
+ (void)window;
+#endif // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::release(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ ANativeWindow_release(anw);
+#else
+ (void)window;
+#endif // defined(__ANDROID__)
+}
+
+
+void ANativeWindowHelperAndroid::acquire(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+ auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ anwb->incStrong(anwb);
+#else
+ (void)buffer;
+#endif // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::release(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+ auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ anwb->decStrong(anwb);
+#else
+ (void)buffer;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getConsumerUsage(EGLNativeWindowType window, int* usage) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ return anw->query(anw, NATIVE_WINDOW_CONSUMER_USAGE_BITS, usage);
+#else
+ (void)window;
+ (void)usage;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::setUsage(EGLNativeWindowType window, int usage) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ ANativeWindow_setUsage(anw, usage);
+#else
+ (void)window;
+ (void)usage;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getWidth(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ return ANativeWindow_getWidth(anw);
+#else
+ (void)window;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getHeight(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ return ANativeWindow_getHeight(anw);
+#else
+ (void)window;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getWidth(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+ auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ return anwb->width;
+#else
+ (void)buffer;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getHeight(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+ auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ return anwb->height;
+#else
+ (void)buffer;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getFormat(EGLClientBuffer buffer, Gralloc* gralloc) {
+#if defined(__ANDROID__)
+ auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ return gralloc->getFormat(anb->handle);
+#else
+ (void)buffer;
+ (void)gralloc;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::setSwapInterval(EGLNativeWindowType window, int interval) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ anw->setSwapInterval(anw, interval);
+#else
+ (void)window;
+ (void)interval;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ return ANativeWindow_queueBuffer(anw, anb, fence);
+#else
+ (void)window;
+ (void)buffer;
+ (void)fence;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ auto* anb = reinterpret_cast<ANativeWindowBuffer**>(buffer);
+ return ANativeWindow_dequeueBuffer(anw, anb, fence);
+#else
+ (void)window;
+ (void)buffer;
+ (void)fence;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+ auto* anw = reinterpret_cast<ANativeWindow*>(window);
+ auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ return ANativeWindow_cancelBuffer(anw, anb, -1);
+#else
+ (void)window;
+ (void)buffer;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getHostHandle(EGLClientBuffer buffer, Gralloc* gralloc) {
+#if defined(__ANDROID__)
+ auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+ return gralloc->getHostHandle(anb->handle);
+#else
+ (void)buffer;
+ (void)gralloc;
+ return -1;
+#endif // defined(__ANDROID__)
+}
+
+} // namespace gfxstream
\ No newline at end of file
diff --git a/guest/OpenglSystemCommon/ANativeWindowAndroid.h b/guest/OpenglSystemCommon/ANativeWindowAndroid.h
new file mode 100644
index 0000000..97eba6a
--- /dev/null
+++ b/guest/OpenglSystemCommon/ANativeWindowAndroid.h
@@ -0,0 +1,57 @@
+// Copyright 2023 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 expresso or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "ANativeWindow.h"
+
+namespace gfxstream {
+
+class ANativeWindowHelperAndroid : public ANativeWindowHelper {
+ public:
+ ANativeWindowHelperAndroid() = default;
+
+ bool isValid(EGLNativeWindowType window);
+ bool isValid(EGLClientBuffer buffer);
+
+ void acquire(EGLNativeWindowType window);
+ void release(EGLNativeWindowType window);
+
+ void acquire(EGLClientBuffer buffer);
+ void release(EGLClientBuffer buffer);
+
+ int getConsumerUsage(EGLNativeWindowType window, int* usage);
+ void setUsage(EGLNativeWindowType window, int usage);
+
+ int getWidth(EGLNativeWindowType window);
+ int getHeight(EGLNativeWindowType window);
+
+ int getWidth(EGLClientBuffer buffer);
+ int getHeight(EGLClientBuffer buffer);
+
+ int getFormat(EGLClientBuffer buffer, Gralloc* helper);
+
+ void setSwapInterval(EGLNativeWindowType window, int interval);
+
+ int queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence);
+ int dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence);
+ int cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer);
+
+ int getHostHandle(EGLClientBuffer buffer, Gralloc* helper);
+};
+
+} // namespace gfxstream
\ No newline at end of file
diff --git a/guest/OpenglSystemCommon/Android.bp b/guest/OpenglSystemCommon/Android.bp
index 97bccf9..09e454d 100644
--- a/guest/OpenglSystemCommon/Android.bp
+++ b/guest/OpenglSystemCommon/Android.bp
@@ -86,8 +86,12 @@
target: {
android: {
shared_libs: [
+ "libnativewindow",
"libsync",
],
+ srcs: [
+ "ANativeWindowAndroid.cpp",
+ ],
},
},
}
diff --git a/guest/OpenglSystemCommon/EGLImage.h b/guest/OpenglSystemCommon/EGLImage.h
index fe320b2..8ef99c2 100644
--- a/guest/OpenglSystemCommon/EGLImage.h
+++ b/guest/OpenglSystemCommon/EGLImage.h
@@ -35,7 +35,7 @@
union
{
- android_native_buffer_t *native_buffer;
+ EGLClientBuffer buffer;
uint32_t host_egl_image;
};
};
diff --git a/guest/OpenglSystemCommon/HostConnection.cpp b/guest/OpenglSystemCommon/HostConnection.cpp
index 41479e6..f0fac92 100644
--- a/guest/OpenglSystemCommon/HostConnection.cpp
+++ b/guest/OpenglSystemCommon/HostConnection.cpp
@@ -17,13 +17,17 @@
#include "GrallocGoldfish.h"
#include "GrallocMinigbm.h"
-#include "SyncAndroid.h"
#include "aemu/base/AndroidHealthMonitor.h"
#include "aemu/base/AndroidHealthMonitorConsumerBasic.h"
#include "aemu/base/threads/AndroidThread.h"
#include "cutils/properties.h"
#include "renderControl_types.h"
+#if defined(__ANDROID__)
+#include "ANativeWindowAndroid.h"
+#include "SyncAndroid.h"
+#endif
+
#ifdef HOST_BUILD
#include "aemu/base/Tracing.h"
#endif
@@ -367,6 +371,7 @@
}
#if defined(__ANDROID__)
+ con->m_anwHelper = new gfxstream::ANativeWindowHelperAndroid();
con->m_syncHelper = new gfxstream::SyncHelperAndroid();
#else
// Host builds are expected to set a sync helper for testing.
diff --git a/guest/OpenglSystemCommon/HostConnection.h b/guest/OpenglSystemCommon/HostConnection.h
index 6823981..0388912 100644
--- a/guest/OpenglSystemCommon/HostConnection.h
+++ b/guest/OpenglSystemCommon/HostConnection.h
@@ -16,6 +16,7 @@
#ifndef __COMMON_HOST_CONNECTION_H
#define __COMMON_HOST_CONNECTION_H
+#include "ANativeWindow.h"
#include "ChecksumCalculator.h"
#include "EmulatorFeatureInfo.h"
#include "Gralloc.h"
@@ -29,8 +30,6 @@
#include "goldfish_dma.h"
#endif
-#include <cutils/native_handle.h>
-
#ifdef GFXSTREAM
#include <mutex>
#else
@@ -180,6 +179,9 @@
gfxstream::SyncHelper* syncHelper() { return m_syncHelper; }
void setSyncHelperForTesting(gfxstream::SyncHelper* sync) { m_syncHelper = sync;}
+ gfxstream::ANativeWindowHelper* anwHelper() { return m_anwHelper; }
+ void setANativeWindowHelperForTesting(gfxstream::ANativeWindowHelper* anw) { m_anwHelper = anw; }
+
void flush() {
if (m_stream) {
m_stream->flush();
@@ -256,6 +258,7 @@
std::unique_ptr<ExtendedRCEncoderContext> m_rcEnc;
ChecksumCalculator m_checksumHelper;
+ gfxstream::ANativeWindowHelper* m_anwHelper = nullptr;
gfxstream::Gralloc* m_grallocHelper = nullptr;
gfxstream::SyncHelper* m_syncHelper = nullptr;
ProcessPipe* m_processPipe = nullptr;