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

Commit 767d7c9f authored by Chia-I Wu's avatar Chia-I Wu
Browse files

surfaceflinger: support EGL extensions in GLExtensions

Add EGL_VERSION and EGL_EXTENSIONS support to GLExtensions.  This
also remove the unused mHaveFramebufferObject and rename
getExtension to getExtensions.

Test: boots and dumpsys
Change-Id: I759508f05d3255fc97eba14d298fa92938bafa75
parent 94563fc8
Loading
Loading
Loading
Loading
+47 −14
Original line number Diff line number Diff line
@@ -25,29 +25,30 @@ namespace android {

ANDROID_SINGLETON_STATIC_INSTANCE(GLExtensions)

GLExtensions::GLExtensions() : mHaveFramebufferObject(false) {}
SortedVector<String8> GLExtensions::parseExtensionString(char const* extensions) {
    SortedVector<String8> list;

void GLExtensions::initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer,
                                     GLubyte const* version, GLubyte const* extensions) {
    mVendor = (char const*)vendor;
    mRenderer = (char const*)renderer;
    mVersion = (char const*)version;
    mExtensions = (char const*)extensions;

    char const* curr = (char const*)extensions;
    char const* curr = extensions;
    char const* head = curr;
    do {
        head = strchr(curr, ' ');
        String8 s(curr, head ? head - curr : strlen(curr));
        if (s.length()) {
            mExtensionList.add(s);
            list.add(s);
        }
        curr = head + 1;
    } while (head);

    if (hasExtension("GL_OES_framebuffer_object")) {
        mHaveFramebufferObject = true;
    return list;
}

void GLExtensions::initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer,
                                     GLubyte const* version, GLubyte const* extensions) {
    mVendor = (char const*)vendor;
    mRenderer = (char const*)renderer;
    mVersion = (char const*)version;
    mExtensions = (char const*)extensions;
    mExtensionList = parseExtensionString(mExtensions);
}

bool GLExtensions::hasExtension(char const* extension) const {
@@ -67,9 +68,41 @@ char const* GLExtensions::getVersion() const {
    return mVersion.string();
}

char const* GLExtensions::getExtension() const {
char const* GLExtensions::getExtensions() const {
    return mExtensions.string();
}

void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExtensions) {
    mEGLVersion = eglVersion;
    mEGLExtensions = eglExtensions;
    mEGLExtensionList = parseExtensionString(mEGLExtensions);

    // EGL_ANDROIDX_no_config_context is an experimental extension with no
    // written specification. It will be replaced by something more formal.
    // SurfaceFlinger is using it to allow a single EGLContext to render to
    // both a 16-bit primary display framebuffer and a 32-bit virtual display
    // framebuffer.
    //
    // EGL_KHR_no_config_context is official extension to allow creating a
    // context that works with any surface of a display.
    if (hasEGLExtension("EGL_ANDROIDX_no_config_context") ||
        hasEGLExtension("EGL_KHR_no_config_context")) {
        mHasNoConfigContext = true;
    }
}

char const* GLExtensions::getEGLVersion() const {
    return mEGLVersion.string();
}

char const* GLExtensions::getEGLExtensions() const {
    return mEGLExtensions.string();
}

bool GLExtensions::hasEGLExtension(char const* extension) const {
    const String8 s(extension);
    return mEGLExtensionList.indexOf(s) >= 0;
}

// ---------------------------------------------------------------------------
}; // namespace android
+15 −6
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ namespace android {
class GLExtensions : public Singleton<GLExtensions> {
    friend class Singleton<GLExtensions>;

    bool mHaveFramebufferObject : 1;
    bool mHasNoConfigContext = false;

    String8 mVendor;
    String8 mRenderer;
@@ -43,24 +43,33 @@ class GLExtensions : public Singleton<GLExtensions> {
    String8 mExtensions;
    SortedVector<String8> mExtensionList;

    String8 mEGLVersion;
    String8 mEGLExtensions;
    SortedVector<String8> mEGLExtensionList;

    static SortedVector<String8> parseExtensionString(char const* extensions);

    GLExtensions(const GLExtensions&);
    GLExtensions& operator=(const GLExtensions&);

protected:
    GLExtensions();
    GLExtensions() = default;

public:
    inline bool haveFramebufferObject() const { return mHaveFramebufferObject; }
    bool hasNoConfigContext() const { return mHasNoConfigContext; }

    void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version,
                           GLubyte const* extensions);

    char const* getVendor() const;
    char const* getRenderer() const;
    char const* getVersion() const;
    char const* getExtension() const;

    char const* getExtensions() const;
    bool hasExtension(char const* extension) const;

    void initWithEGLStrings(char const* eglVersion, char const* eglExtensions);
    char const* getEGLVersion() const;
    char const* getEGLExtensions() const;
    bool hasEGLExtension(char const* extension) const;
};

// ---------------------------------------------------------------------------
+11 −33
Original line number Diff line number Diff line
@@ -32,19 +32,6 @@ extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy
namespace android {
// ---------------------------------------------------------------------------

static bool findExtension(const char* exts, const char* name) {
    if (!exts) return false;
    size_t len = strlen(name);

    const char* pos = exts;
    while ((pos = strstr(pos, name)) != NULL) {
        if (pos[len] == '\0' || pos[len] == ' ') return true;
        pos += len;
    }

    return false;
}

std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featureFlags) {
    // initialize EGL for the default display
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -52,22 +39,14 @@ std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featu
        LOG_ALWAYS_FATAL("failed to initialize EGL");
    }

    // EGL_ANDROIDX_no_config_context is an experimental extension with no
    // written specification. It will be replaced by something more formal.
    // SurfaceFlinger is using it to allow a single EGLContext to render to
    // both a 16-bit primary display framebuffer and a 32-bit virtual display
    // framebuffer.
    //
    // EGL_KHR_no_config_context is official extension to allow creating a
    // context that works with any surface of a display.
    //
    GLExtensions& extensions(GLExtensions::getInstance());
    extensions.initWithEGLStrings(eglQueryStringImplementationANDROID(display, EGL_VERSION),
                                  eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS));

    // The code assumes that ES2 or later is available if this extension is
    // supported.
    EGLConfig config = EGL_NO_CONFIG;
    if (!findExtension(eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS),
                       "EGL_ANDROIDX_no_config_context") &&
        !findExtension(eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS),
                       "EGL_KHR_no_config_context")) {
    if (!extensions.hasNoConfigContext()) {
        config = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);
    }

@@ -117,7 +96,6 @@ std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featu
    EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
    LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");

    GLExtensions& extensions(GLExtensions::getInstance());
    extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER),
                                 glGetString(GL_VERSION), glGetString(GL_EXTENSIONS));

@@ -142,7 +120,7 @@ std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featu
    ALOGI("vendor    : %s", extensions.getVendor());
    ALOGI("renderer  : %s", extensions.getRenderer());
    ALOGI("version   : %s", extensions.getVersion());
    ALOGI("extensions: %s", extensions.getExtension());
    ALOGI("extensions: %s", extensions.getExtensions());
    ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize());
    ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims());

@@ -315,14 +293,14 @@ void RenderEngine::readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t*
}

void RenderEngine::dump(String8& result) {
    result.appendFormat("EGL implementation : %s\n",
                        eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
    result.appendFormat("%s\n", eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));

    const GLExtensions& extensions(GLExtensions::getInstance());

    result.appendFormat("EGL implementation : %s\n", extensions.getEGLVersion());
    result.appendFormat("%s\n", extensions.getEGLExtensions());

    result.appendFormat("GLES: %s, %s, %s\n", extensions.getVendor(), extensions.getRenderer(),
                        extensions.getVersion());
    result.appendFormat("%s\n", extensions.getExtension());
    result.appendFormat("%s\n", extensions.getExtensions());
}

// ---------------------------------------------------------------------------