[EGL] Runtime support for RGB565 pixel layout
authorphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Feb 2019 15:11:29 +0000 (15:11 +0000)
committerphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Feb 2019 15:11:29 +0000 (15:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194817

Reviewed by Carlos Garcia Campos.

Currently our graphics pipeline always relies on a ARGB8888 (32
bpp) pixel configuration. On some low-end (old) embedded platforms
the graphics driver is sometimes optimized for 16 bpp
configurations, such as RGB565. On those platforms the application
can now set the WEBKIT_EGL_PIXEL_LAYOUT environment variable to
"RGB565" to adjust to the best pixel configuration supported by
the screen and graphics driver.

* platform/graphics/egl/GLContextEGL.cpp:
(WebCore::GLContextEGL::getEGLConfig):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242084 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/egl/GLContextEGL.cpp

index 2cb6e2b..1f6bf23 100644 (file)
@@ -1,3 +1,21 @@
+2019-02-26  Philippe Normand  <pnormand@igalia.com>
+
+        [EGL] Runtime support for RGB565 pixel layout
+        https://bugs.webkit.org/show_bug.cgi?id=194817
+
+        Reviewed by Carlos Garcia Campos.
+
+        Currently our graphics pipeline always relies on a ARGB8888 (32
+        bpp) pixel configuration. On some low-end (old) embedded platforms
+        the graphics driver is sometimes optimized for 16 bpp
+        configurations, such as RGB565. On those platforms the application
+        can now set the WEBKIT_EGL_PIXEL_LAYOUT environment variable to
+        "RGB565" to adjust to the best pixel configuration supported by
+        the screen and graphics driver.
+
+        * platform/graphics/egl/GLContextEGL.cpp:
+        (WebCore::GLContextEGL::getEGLConfig):
+
 2019-02-26  Philippe Normand  <pnormand@igalia.com> and Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [WPE] Add API for webview background color configuration
index 24d06ba..e09b2d5 100644 (file)
@@ -53,6 +53,8 @@
 #include <cairo-gl.h>
 #endif
 
+#include <wtf/Vector.h>
+
 namespace WebCore {
 
 #if USE(OPENGL_ES)
@@ -100,15 +102,31 @@ bool GLContextEGL::getEGLConfig(EGLDisplay display, EGLConfig* config, EGLSurfac
 #else
         EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
 #endif
-        EGL_RED_SIZE, 8,
-        EGL_GREEN_SIZE, 8,
-        EGL_BLUE_SIZE, 8,
+        EGL_RED_SIZE, 1,
+        EGL_GREEN_SIZE, 1,
+        EGL_BLUE_SIZE, 1,
+        EGL_ALPHA_SIZE, 1,
         EGL_STENCIL_SIZE, 8,
-        EGL_ALPHA_SIZE, 8,
         EGL_SURFACE_TYPE, EGL_NONE,
         EGL_NONE
     };
 
+    bool isRGB565 = false;
+    if (const char* environmentVariable = getenv("WEBKIT_EGL_PIXEL_LAYOUT")) {
+        if (!strcmp(environmentVariable, "RGB565")) {
+            isRGB565 = true;
+            // EGL_RED_SIZE
+            attributeList[3] = 5;
+            // EGL_GREEN_SIZE
+            attributeList[5] = 6;
+            // EGL_BLUE_SIZE
+            attributeList[7] = 5;
+            // EGL_ALPHA_SIZE
+            attributeList[9] = 0;
+        } else
+            WTFLogAlways("Unknown pixel layout %s, falling back to RGBA8888", environmentVariable);
+    }
+
     switch (surfaceType) {
     case GLContextEGL::PbufferSurface:
         attributeList[13] = EGL_PBUFFER_BIT;
@@ -122,8 +140,32 @@ bool GLContextEGL::getEGLConfig(EGLDisplay display, EGLConfig* config, EGLSurfac
         break;
     }
 
+    EGLint count;
+    if (!eglChooseConfig(display, attributeList, nullptr, 0, &count))
+        return false;
+
     EGLint numberConfigsReturned;
-    return eglChooseConfig(display, attributeList, config, 1, &numberConfigsReturned) && numberConfigsReturned;
+    Vector<EGLConfig> configs(count);
+    if (!eglChooseConfig(display, attributeList, isRGB565 ? reinterpret_cast<EGLConfig*>(configs.data()) : config, isRGB565 ? count : 1, &numberConfigsReturned) || !numberConfigsReturned)
+        return false;
+
+    if (!isRGB565)
+        return true;
+
+    auto index = configs.findMatching([&](EGLConfig value) {
+        EGLint redSize, greenSize, blueSize, alphaSize;
+        eglGetConfigAttrib(display, value, EGL_RED_SIZE, &redSize);
+        eglGetConfigAttrib(display, value, EGL_GREEN_SIZE, &greenSize);
+        eglGetConfigAttrib(display, value, EGL_BLUE_SIZE, &blueSize);
+        eglGetConfigAttrib(display, value, EGL_ALPHA_SIZE, &alphaSize);
+        return (redSize == 5 && greenSize == 6 && blueSize == 5 && !alphaSize);
+    });
+
+    if (index != notFound) {
+        *config = configs[index];
+        return true;
+    }
+    return false;
 }
 
 std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(GLNativeWindowType window, PlatformDisplay& platformDisplay, EGLContext sharingContext)