Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e354bd2 authored by Courtney Goeltzenleuchter's avatar Courtney Goeltzenleuchter Committed by android-build-merger
Browse files

Merge "Add useful helper functions for tests" into oc-mr1-dev

am: 77dd2aaf

Change-Id: Ic782b6d5efeb0dbff0fe70f80d0802fad07733d1
parents e5e1d4f4 77dd2aaf
Loading
Loading
Loading
Loading
+172 −6
Original line number Diff line number Diff line
@@ -20,11 +20,16 @@

#include <stdint.h>
#include <stdlib.h>
#include <vector>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <system/window.h>
#include <utils/Errors.h>
#include <EGL/egl.h>
#include <utils/String8.h>

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<EGLConfig> 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<n) {
        *outConfig = config;
        return NO_ERROR;
@@ -137,6 +150,159 @@ status_t EGLUtils::selectConfigForNativeWindow(
    return selectConfigForPixelFormat(dpy, attrs, format, outConfig);
}

String8 EGLUtils::printGLString(const char* name, GLenum s) {
    String8 msg;
    const char* v = reinterpret_cast<const char*>(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<const char*>(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<EGLConfig> 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
// ----------------------------------------------------------------------------