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
diff --git a/services/surfaceflinger/RenderEngine/GLExtensions.cpp b/services/surfaceflinger/RenderEngine/GLExtensions.cpp
index 7ffcc96..b7f8664 100644
--- a/services/surfaceflinger/RenderEngine/GLExtensions.cpp
+++ b/services/surfaceflinger/RenderEngine/GLExtensions.cpp
@@ -25,7 +25,22 @@
ANDROID_SINGLETON_STATIC_INSTANCE(GLExtensions)
-GLExtensions::GLExtensions() : mHaveFramebufferObject(false) {}
+SortedVector<String8> GLExtensions::parseExtensionString(char const* extensions) {
+ SortedVector<String8> list;
+
+ char const* curr = extensions;
+ char const* head = curr;
+ do {
+ head = strchr(curr, ' ');
+ String8 s(curr, head ? head - curr : strlen(curr));
+ if (s.length()) {
+ list.add(s);
+ }
+ curr = head + 1;
+ } while (head);
+
+ return list;
+}
void GLExtensions::initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer,
GLubyte const* version, GLubyte const* extensions) {
@@ -33,21 +48,7 @@
mRenderer = (char const*)renderer;
mVersion = (char const*)version;
mExtensions = (char const*)extensions;
-
- char const* curr = (char const*)extensions;
- char const* head = curr;
- do {
- head = strchr(curr, ' ');
- String8 s(curr, head ? head - curr : strlen(curr));
- if (s.length()) {
- mExtensionList.add(s);
- }
- curr = head + 1;
- } while (head);
-
- if (hasExtension("GL_OES_framebuffer_object")) {
- mHaveFramebufferObject = true;
- }
+ mExtensionList = parseExtensionString(mExtensions);
}
bool GLExtensions::hasExtension(char const* extension) const {
@@ -67,9 +68,41 @@
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
diff --git a/services/surfaceflinger/RenderEngine/GLExtensions.h b/services/surfaceflinger/RenderEngine/GLExtensions.h
index ee7b446..47f2f67 100644
--- a/services/surfaceflinger/RenderEngine/GLExtensions.h
+++ b/services/surfaceflinger/RenderEngine/GLExtensions.h
@@ -35,7 +35,7 @@
class GLExtensions : public Singleton<GLExtensions> {
friend class Singleton<GLExtensions>;
- bool mHaveFramebufferObject : 1;
+ bool mHasNoConfigContext = false;
String8 mVendor;
String8 mRenderer;
@@ -43,24 +43,33 @@
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;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 883ae26..d3bda17 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -32,19 +32,6 @@
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 @@
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 @@
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 @@
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::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());
}
// ---------------------------------------------------------------------------