From df0518c13b8d7e3faf0d491db5fa4e44afa0e787 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Thu, 27 Jul 2017 08:11:24 -0600 Subject: [PATCH] Add useful helper functions for tests Trying to reduce code duplication by putting common EGL functions used by opengl and surfaceflinger tests here. Test: adb shell /data/nativetest/test-opengl-gl2_basic/test-opengl-gl2_basic Merged-In: Id7a32aedc565f3fbe56fa62ceb79cbb1e8c80727 Change-Id: Id7a32aedc565f3fbe56fa62ceb79cbb1e8c80727 (cherry picked from commit fe98f50b02746f4a1980d0fd31fd8126c5d4e445) --- opengl/tests/lib/include/EGLUtils.h | 178 ++++++++++++++++++++++++++++++++++-- 1 file changed, 172 insertions(+), 6 deletions(-) diff --git a/opengl/tests/lib/include/EGLUtils.h b/opengl/tests/lib/include/EGLUtils.h index 014c2611ae..29f4fe442d 100644 --- a/opengl/tests/lib/include/EGLUtils.h +++ b/opengl/tests/lib/include/EGLUtils.h @@ -20,11 +20,16 @@ #include #include +#include +#include +#include +#include #include #include -#include +#include +EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); // ---------------------------------------------------------------------------- namespace android { @@ -47,6 +52,17 @@ public: EGLint const* attrs, EGLNativeWindowType window, EGLConfig* outConfig); + + static inline String8 printGLString(const char* name, GLenum s); + static inline String8 printEGLString(EGLDisplay dpy, const char* name, GLenum s); + static inline String8 checkEglError(const char* op, EGLBoolean returnVal); + static inline String8 checkGlError(const char* op); + static inline String8 printEGLConfiguration(EGLDisplay dpy, EGLConfig config); + static inline bool printEGLConfigurations(EGLDisplay dpy, String8& msg); + static inline bool printEGLConfigurations(FILE* output, EGLDisplay dpy); + static inline String8 decodeColorSpace(EGLint colorSpace); + static inline bool hasEglExtension(EGLDisplay dpy, const char* name); + static inline bool hasExtension(const char* exts, const char* name); }; // ---------------------------------------------------------------------------- @@ -91,9 +107,8 @@ status_t EGLUtils::selectConfigForPixelFormat( if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE) return BAD_VALUE; - EGLConfig* const configs = (EGLConfig*)malloc(sizeof(EGLConfig)*numConfigs); - if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) { - free(configs); + std::vector configs(numConfigs); + if (eglChooseConfig(dpy, attrs, configs.data(), numConfigs, &n) == EGL_FALSE) { return BAD_VALUE; } @@ -108,8 +123,6 @@ status_t EGLUtils::selectConfigForPixelFormat( } } - free(configs); - if (i(glGetString(s)); + msg.appendFormat("GL %s = %s\n", name, v); + return msg; +} + +String8 EGLUtils::printEGLString(EGLDisplay dpy, const char* name, GLenum s) { + String8 msg; + const char* v = static_cast(eglQueryString(dpy, s)); + msg.appendFormat("GL %s = %s\n", name, v); + const char* va = (const char*)eglQueryStringImplementationANDROID(dpy, s); + msg.appendFormat("ImplementationANDROID: %s = %s\n", name, va); + return msg; +} + +String8 EGLUtils::checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + String8 msg; + if (returnVal != EGL_TRUE) { + msg.appendFormat("%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) { + msg.appendFormat("after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), error); + } + return msg; +} + +String8 EGLUtils::checkGlError(const char* op) { + String8 msg; + for (GLint error = glGetError(); error != GL_NO_ERROR; error = glGetError()) { + msg.appendFormat("after %s() glError (0x%x)\n", op, error); + } + return msg; +} + +String8 EGLUtils::printEGLConfiguration(EGLDisplay dpy, EGLConfig config) { +#define X(VAL) \ + { VAL, #VAL } + struct { + EGLint attribute; + const char* name; + } names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + String8 msg; + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + msg.appendFormat(" %s: %d (0x%x)", names[j].name, value, value); + } + } + msg.append("\n"); + return msg; +} + +bool EGLUtils::printEGLConfigurations(EGLDisplay dpy, String8& msg) { + EGLint numConfig = 0; + EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig); + msg.append(checkEglError("eglGetConfigs", returnVal)); + if (!returnVal) { + return false; + } + + msg.appendFormat("Number of EGL configuration: %d\n", numConfig); + + std::vector configs(numConfig); + + returnVal = eglGetConfigs(dpy, configs.data(), numConfig, &numConfig); + msg.append(checkEglError("eglGetConfigs", returnVal)); + if (!returnVal) { + return false; + } + + for (int i = 0; i < numConfig; i++) { + msg.appendFormat("Configuration %d\n", i); + msg.append(printEGLConfiguration(dpy, configs[i])); + } + + return true; +} + +bool EGLUtils::printEGLConfigurations(FILE* output, EGLDisplay dpy) { + String8 msg; + bool status = printEGLConfigurations(dpy, msg); + fprintf(output, "%s", msg.c_str()); + return status; +} + +String8 EGLUtils::decodeColorSpace(EGLint colorSpace) { + switch (colorSpace) { + case EGL_GL_COLORSPACE_SRGB_KHR: + return String8("EGL_GL_COLORSPACE_SRGB_KHR"); + case EGL_GL_COLORSPACE_DISPLAY_P3_EXT: + return String8("EGL_GL_COLORSPACE_DISPLAY_P3_EXT"); + case EGL_GL_COLORSPACE_LINEAR_KHR: + return String8("EGL_GL_COLORSPACE_LINEAR_KHR"); + default: + return String8::format("UNKNOWN ColorSpace %d", colorSpace); + } +} + +bool EGLUtils::hasExtension(const char* exts, const char* name) { + size_t nameLen = strlen(name); + if (exts) { + for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) { + if (match[nameLen] == '\0' || match[nameLen] == ' ') { + return true; + } + } + } + return false; +} + +bool EGLUtils::hasEglExtension(EGLDisplay dpy, const char* name) { + return hasExtension(eglQueryString(dpy, EGL_EXTENSIONS), name); +} + // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- -- 2.11.0