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/GLESv1/gl.cpp b/guest/GLESv1/gl.cpp
index 9f4a69c..adede19 100644
--- a/guest/GLESv1/gl.cpp
+++ b/guest/GLESv1/gl.cpp
@@ -50,6 +50,11 @@
if (!grallocHelper) { \
ALOGE("egl: Failed to get grallocHelper\n"); \
return ret; \
+ } \
+ auto* anwHelper = hostCon->anwHelper(); \
+ if (!anwHelper) { \
+ ALOGE("egl: Failed to get anwHelper\n"); \
+ return ret; \
}
//GL extensions
@@ -62,26 +67,22 @@
EGLImage_t *image = (EGLImage_t*)img;
if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
- //TODO: check error - we don't have a way to set gl error
- android_native_buffer_t* native_buffer = image->native_buffer;
+ DEFINE_AND_VALIDATE_HOST_CONNECTION();
- if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
- return;
- }
-
- if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+ EGLClientBuffer buffer = image->buffer;
+ if (!anwHelper->isValid(buffer)) {
+ ALOGE("Invalid native buffer.");
return;
}
GET_CONTEXT;
- DEFINE_AND_VALIDATE_HOST_CONNECTION();
-
ctx->override2DTextureTarget(target);
- rcEnc->rcBindTexture(rcEnc,
- grallocHelper->getHostHandle(native_buffer->handle));
+
+ const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+ rcEnc->rcBindTexture(rcEnc, hostHandle);
+
ctx->restore2DTextureTarget();
- }
- else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
+ } else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
GET_CONTEXT;
ctx->override2DTextureTarget(target);
GLeglImageOES hostImage = reinterpret_cast<GLeglImageOES>((intptr_t)image->host_egl_image);
@@ -100,19 +101,16 @@
EGLImage_t *image = (EGLImage_t*)img;
if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
- android_native_buffer_t* native_buffer = ((EGLImage_t*)image)->native_buffer;
-
- if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
- return;
- }
-
- if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
- return;
- }
-
DEFINE_AND_VALIDATE_HOST_CONNECTION();
- rcEnc->rcBindRenderbuffer(rcEnc,
- grallocHelper->getHostHandle(native_buffer->handle));
+
+ EGLClientBuffer buffer = image->buffer;
+ if (!anwHelper->isValid(buffer)) {
+ ALOGE("Invalid native buffer.");
+ return;
+ }
+
+ const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+ rcEnc->rcBindRenderbuffer(rcEnc, hostHandle);
} else {
//TODO
}
diff --git a/guest/GLESv2/gl2.cpp b/guest/GLESv2/gl2.cpp
index f143aa5..f4b04b1 100644
--- a/guest/GLESv2/gl2.cpp
+++ b/guest/GLESv2/gl2.cpp
@@ -50,6 +50,11 @@
if (!grallocHelper) { \
ALOGE("egl: Failed to get grallocHelper\n"); \
return ret; \
+ } \
+ auto* anwHelper = hostCon->anwHelper(); \
+ if (!anwHelper) { \
+ ALOGE("egl: Failed to get anwHelper\n"); \
+ return ret; \
}
//GL extensions
@@ -63,29 +68,24 @@
EGLImage_t *image = (EGLImage_t*)img;
GLeglImageOES hostImage = reinterpret_cast<GLeglImageOES>((intptr_t)image->host_egl_image);
+ GET_CONTEXT;
+ DEFINE_AND_VALIDATE_HOST_CONNECTION();
+
if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
- //TODO: check error - we don't have a way to set gl error
- android_native_buffer_t* native_buffer = image->native_buffer;
+ EGLClientBuffer buffer = image->buffer;
- if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+ if (!anwHelper->isValid(buffer)) {
+ ALOGE("Invalid native buffer.");
return;
}
- if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
- return;
- }
-
- GET_CONTEXT;
- DEFINE_AND_VALIDATE_HOST_CONNECTION();
-
ctx->override2DTextureTarget(target);
ctx->associateEGLImage(target, hostImage, image->width, image->height);
- rcEnc->rcBindTexture(rcEnc,
- grallocHelper->getHostHandle(native_buffer->handle));
+
+ const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+ rcEnc->rcBindTexture(rcEnc, hostHandle);
ctx->restore2DTextureTarget(target);
- }
- else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
- GET_CONTEXT;
+ } else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
ctx->override2DTextureTarget(target);
ctx->associateEGLImage(target, hostImage, image->width, image->height);
ctx->m_glEGLImageTargetTexture2DOES_enc(self, GL_TEXTURE_2D, hostImage);
@@ -104,21 +104,19 @@
GLeglImageOES hostImage = reinterpret_cast<GLeglImageOES>((intptr_t)image->host_egl_image);
if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
- android_native_buffer_t* native_buffer = ((EGLImage_t*)image)->native_buffer;
-
- if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
- return;
- }
-
- if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
- return;
- }
-
DEFINE_AND_VALIDATE_HOST_CONNECTION();
+
+ EGLClientBuffer buffer = image->buffer;
+ if (!anwHelper->isValid(buffer)) {
+ ALOGE("Invalid native buffer.");
+ return;
+ }
+
GET_CONTEXT;
ctx->associateEGLImage(target, hostImage, image->width, image->height);
- rcEnc->rcBindRenderbuffer(rcEnc,
- grallocHelper->getHostHandle(native_buffer->handle));
+
+ const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+ rcEnc->rcBindRenderbuffer(rcEnc, hostHandle);
} else {
//TODO
}
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;
diff --git a/guest/egl/egl.cpp b/guest/egl/egl.cpp
index d373682..ad9ef1f 100644
--- a/guest/egl/egl.cpp
+++ b/guest/egl/egl.cpp
@@ -62,7 +62,6 @@
#endif
#include <cutils/trace.h>
-#include <system/window.h>
using android::base::guest::getCurrentThreadId;
@@ -164,6 +163,11 @@
if (!grallocHelper) { \
ALOGE("egl: Failed to get grallocHelper\n"); \
return ret; \
+ } \
+ auto* anwHelper = hostCon->anwHelper(); \
+ if (!anwHelper) { \
+ ALOGE("egl: Failed to get anwHelper\n"); \
+ return ret; \
}
#define DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(ret, tls) \
@@ -181,6 +185,11 @@
if (!grallocHelper) { \
ALOGE("egl: Failed to get grallocHelper\n"); \
return ret; \
+ } \
+ auto* anwHelper = hostCon->anwHelper(); \
+ if (!anwHelper) { \
+ ALOGE("egl: Failed to get anwHelper\n"); \
+ return ret; \
}
#define VALIDATE_CONTEXT_RETURN(context,ret) \
@@ -447,7 +456,7 @@
struct egl_window_surface_t : public egl_surface_t {
static egl_window_surface_t* create(
EGLDisplay dpy, EGLConfig config, EGLint surfType,
- ANativeWindow* window);
+ EGLNativeWindowType window);
virtual ~egl_window_surface_t();
@@ -462,53 +471,71 @@
private:
egl_window_surface_t(
EGLDisplay dpy, EGLConfig config, EGLint surfType,
- ANativeWindow* window);
+ EGLNativeWindowType window);
EGLBoolean init();
- ANativeWindow* nativeWindow;
- android_native_buffer_t* buffer;
+ EGLNativeWindowType nativeWindow;
+ EGLClientBuffer buffer;
bool collectingTimestamps;
};
egl_window_surface_t::egl_window_surface_t (
EGLDisplay dpy, EGLConfig config, EGLint surfType,
- ANativeWindow* window)
+ EGLNativeWindowType window)
: egl_surface_t(dpy, config, surfType),
nativeWindow(window),
buffer(NULL),
collectingTimestamps(false)
{
- // keep a reference on the window
- nativeWindow->common.incRef(&nativeWindow->common);
}
-
EGLBoolean egl_window_surface_t::init()
{
-#ifndef HOST_BUILD
+ DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+ // keep a reference on the window
+ anwHelper->acquire(nativeWindow);
+
int consumerUsage = 0;
- if (nativeWindow->query(nativeWindow, NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage) != 0) {
+ if (anwHelper->getConsumerUsage(nativeWindow, &consumerUsage) != 0) {
setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
} else {
int producerUsage = GRALLOC_USAGE_HW_RENDER;
- native_window_set_usage(nativeWindow, consumerUsage | producerUsage);
+ anwHelper->setUsage(nativeWindow, consumerUsage | producerUsage);
}
-#endif
- if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer) != 0) {
+ int acquireFenceFd = -1;
+ if (anwHelper->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd) != 0) {
setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
}
- setWidth(buffer->width);
- setHeight(buffer->height);
+ if (acquireFenceFd >= 0) {
+ auto* syncHelper = hostCon->syncHelper();
- int nativeWidth, nativeHeight;
- nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &nativeWidth);
- nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &nativeHeight);
+ int waitRet = syncHelper->wait(acquireFenceFd, /* wait forever */-1);
+ if (waitRet < 0) {
+ ALOGE("Failed to wait for window surface's dequeued buffer.");
+ anwHelper->cancelBuffer(nativeWindow, buffer);
+ }
+
+ syncHelper->close(acquireFenceFd);
+
+ if (waitRet < 0) {
+ setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
+ }
+ }
+
+ int bufferWidth = anwHelper->getWidth(buffer);
+ int bufferHeight = anwHelper->getHeight(buffer);
+
+ setWidth(bufferWidth);
+ setHeight(bufferHeight);
+
+ int nativeWidth = anwHelper->getWidth(nativeWindow);
+ int nativeHeight = anwHelper->getHeight(nativeWindow);
setNativeWidth(nativeWidth);
setNativeHeight(nativeHeight);
- DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)s_display.getIndexOfConfig(config),
getWidth(), getHeight());
@@ -516,15 +543,16 @@
ALOGE("rcCreateWindowSurface returned 0");
return EGL_FALSE;
}
- rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
- grallocHelper->getHostHandle(buffer->handle));
+
+ const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+ rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, hostHandle);
return EGL_TRUE;
}
egl_window_surface_t* egl_window_surface_t::create(
EGLDisplay dpy, EGLConfig config, EGLint surfType,
- ANativeWindow* window)
+ EGLNativeWindowType window)
{
egl_window_surface_t* wnd = new egl_window_surface_t(
dpy, config, surfType, window);
@@ -541,15 +569,17 @@
rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
}
+ auto* anwHelper = hostCon->anwHelper();
if (buffer) {
- nativeWindow->cancelBuffer_DEPRECATED(nativeWindow, buffer);
+ anwHelper->cancelBuffer(nativeWindow, buffer);
}
- nativeWindow->common.decRef(&nativeWindow->common);
+ anwHelper->release(nativeWindow);
}
void egl_window_surface_t::setSwapInterval(int interval)
{
- nativeWindow->setSwapInterval(nativeWindow, interval);
+ DEFINE_HOST_CONNECTION;
+ hostCon->anwHelper()->setSwapInterval(nativeWindow, interval);
}
// createNativeSync() creates an OpenGL sync object on the host
@@ -788,14 +818,14 @@
sFrameTracingState.frameNumber, &presentFenceFd);
DPRINT("queueBuffer with fence %d", presentFenceFd);
- nativeWindow->queueBuffer(nativeWindow, buffer, presentFenceFd);
+ anwHelper->queueBuffer(nativeWindow, buffer, presentFenceFd);
appTimeMetric.onQueueBufferReturn();
DPRINT("calling dequeueBuffer...");
int acquireFenceFd = -1;
- if (nativeWindow->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd)) {
+ if (anwHelper->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd)) {
buffer = NULL;
setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
}
@@ -807,11 +837,11 @@
syncHelper->close(acquireFenceFd);
}
- rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
- grallocHelper->getHostHandle(buffer->handle));
+ const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+ rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, hostHandle);
- setWidth(buffer->width);
- setHeight(buffer->height);
+ setWidth(anwHelper->getWidth(buffer));
+ setHeight(anwHelper->getHeight(buffer));
sFrameTracingState.onSwapBuffersSuccesful(rcEnc);
appTimeMetric.onSwapBuffersReturn();
@@ -1279,12 +1309,12 @@
setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
}
- if (reinterpret_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
+ DEFINE_HOST_CONNECTION;
+ if (!hostCon->anwHelper()->isValid(win)) {
setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
}
- egl_surface_t* surface = egl_window_surface_t::create(
- &s_display, config, EGL_WINDOW_BIT, reinterpret_cast<ANativeWindow*>(win));
+ egl_surface_t* surface = egl_window_surface_t::create(&s_display, config, EGL_WINDOW_BIT, win);
if (!surface) {
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
@@ -2205,19 +2235,12 @@
setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
}
- android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
-
- if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
- setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
- if (native_buffer->common.version != sizeof(android_native_buffer_t))
- setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
- if (native_buffer->handle == NULL)
- setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
- int format = grallocHelper->getFormat(native_buffer->handle);
+ if (!anwHelper->isValid(buffer)) {
+ setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+ }
+
+ int format = anwHelper->getFormat(buffer, grallocHelper);
switch (format) {
case HAL_PIXEL_FORMAT_R8:
case HAL_PIXEL_FORMAT_RGBA_8888:
@@ -2245,14 +2268,14 @@
setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
- native_buffer->common.incRef(&native_buffer->common);
+ anwHelper->acquire(buffer);
EGLImage_t *image = new EGLImage_t();
image->dpy = dpy;
image->target = target;
- image->native_buffer = native_buffer;
- image->width = native_buffer->width;
- image->height = native_buffer->width;
+ image->buffer = buffer;
+ image->width = anwHelper->getWidth(buffer);
+ image->height = anwHelper->getHeight(buffer);
return (EGLImageKHR)image;
}
@@ -2287,24 +2310,22 @@
RETURN_ERROR(EGL_FALSE, EGL_BAD_PARAMETER);
}
+ DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
- android_native_buffer_t* native_buffer = image->native_buffer;
-
- if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+ EGLClientBuffer buffer = image->buffer;
+ if (!anwHelper->isValid(buffer)) {
setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
- if (native_buffer->common.version != sizeof(android_native_buffer_t))
- setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
-
- native_buffer->common.decRef(&native_buffer->common);
+ anwHelper->release(buffer);
delete image;
return EGL_TRUE;
- }
- else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
+ } else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
uint32_t host_egl_image = image->host_egl_image;
delete image;
- DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
return rcEnc->rcDestroyClientImage(rcEnc, host_egl_image);
}