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

Commit f7521e32 authored by Tom Murphy's avatar Tom Murphy
Browse files

Implement EGL_TELEMETRY_HINT_ANDROID in EGL loader

We want eglCreateContext telemetry to give us insights into how
developers use EGL. Implement the new EGL_TELEMETRY_HINT_ANDROID extension to allow us to remove HWUI contexts from telemetry

Test: Tested with new dEQP tests to be merged separately
Test: ran dEQP-EGL.functional.create_context_ext* tests
Bug: 347911216
Flag: EXEMPT flag is used in linked CL
Change-Id: If987c9eb144a380d90fb129f3f49effce73b33df
parent 229ec057
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -125,6 +125,11 @@ public:
        VULKAN_DEVICE_EXTENSION = 9,
    };

    enum GLTelemetryHints {
        NO_HINT = 0,
        SKIP_TELEMETRY = 1,
    };

    GpuStatsInfo() = default;
    GpuStatsInfo(const GpuStatsInfo&) = default;
    virtual ~GpuStatsInfo() = default;
+50 −20
Original line number Diff line number Diff line
@@ -916,42 +916,72 @@ EGLContext eglCreateContextImpl(EGLDisplay dpy, EGLConfig config, EGLContext sha
            egl_context_t* const c = get_context(share_list);
            share_list = c->context;
        }

        bool skip_telemetry = false;

        auto findAttribute = [](const EGLint* attrib_ptr, GLint attribute, GLint* value) {
            while (attrib_ptr && *attrib_ptr != EGL_NONE) {
                GLint attr = *attrib_ptr++;
                GLint val = *attrib_ptr++;
                if (attr == attribute) {
                    if (value) {
                        *value = val;
                    }
                    return true;
                }
            }
            return false;
        };

        std::vector<EGLint> replacement_attrib_list;
        GLint telemetry_value;
        if (findAttribute(attrib_list, EGL_TELEMETRY_HINT_ANDROID, &telemetry_value)) {
            skip_telemetry = (telemetry_value == android::GpuStatsInfo::SKIP_TELEMETRY);

            // We need to remove EGL_TELEMETRY_HINT_ANDROID or the underlying drivers will
            // complain about an unexpected attribute
            const EGLint* attrib_ptr = attrib_list;
            while (attrib_ptr && *attrib_ptr != EGL_NONE) {
                GLint attr = *attrib_ptr++;
                GLint val = *attrib_ptr++;
                if (attr != EGL_TELEMETRY_HINT_ANDROID) {
                    replacement_attrib_list.push_back(attr);
                    replacement_attrib_list.push_back(val);
                }
            }
            replacement_attrib_list.push_back(EGL_NONE);
            attrib_list = replacement_attrib_list.data();
        }
        // b/111083885 - If we are presenting EGL 1.4 interface to apps
        // error out on robust access attributes that are invalid
        // in EGL 1.4 as the driver may be fine with them but dEQP expects
        // tests to fail according to spec.
        if (attrib_list && (cnx->driverVersion < EGL_MAKE_VERSION(1, 5, 0))) {
            const EGLint* attrib_ptr = attrib_list;
            while (*attrib_ptr != EGL_NONE) {
                GLint attr = *attrib_ptr++;
                GLint value = *attrib_ptr++;
                if (attr == EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR) {
                    // We are GL ES context with EGL 1.4, this is an invalid
                    // attribute
            if (findAttribute(attrib_list, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
                              nullptr)) {
                // We are GL ES context with EGL 1.4, this is an invalid attribute
                return setError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
            }
            };
        }
        EGLContext context =
                cnx->egl.eglCreateContext(dp->disp.dpy, config, share_list, attrib_list);
        if (context != EGL_NO_CONTEXT) {
            // figure out if it's a GLESv1 or GLESv2
            int version = egl_connection_t::GLESv1_INDEX;
            if (attrib_list) {
                while (*attrib_list != EGL_NONE) {
                    GLint attr = *attrib_list++;
                    GLint value = *attrib_list++;
                    if (attr == EGL_CONTEXT_CLIENT_VERSION && (value == 2 || value == 3)) {
            GLint version_value;
            if (findAttribute(attrib_list, EGL_CONTEXT_CLIENT_VERSION, &version_value)) {
                if (version_value == 2 || version_value == 3) {
                    version = egl_connection_t::GLESv2_INDEX;
                }
                };
            }
            if (version == egl_connection_t::GLESv1_INDEX) {
                android::GraphicsEnv::getInstance().setTargetStats(
                        android::GpuStatsInfo::Stats::GLES_1_IN_USE);
            }
            if (!skip_telemetry) {
                android::GraphicsEnv::getInstance().setTargetStats(
                        android::GpuStatsInfo::Stats::CREATED_GLES_CONTEXT);
            }
            egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version);
            return c;
        }