Mystery black window workaround: Druid back in development

Mystery black window workaround: Druid back in development

Months ago, I was forced to get a new laptop (thanksalot, kitty!) which uses an Intel HD Graphics 520 graphics card.  When I got around to working on druid4arduino I hit a mystery bug with the display, as described previously. In short, a nice black window that wouldn’t display anything but the void.  Development was thus stalled until I could actually see what I was doing again.

Since I couldn’t even run a “hello world” cordova-ubuntu program (which also resulted in a black window), and my bug report was apparently ignored for 5 months, I’d moved my focus to other things and everything with SerialUI/Druid4Arduino stalled.  Thankfully, I’ve found a workaround and I’ll describe the symptoms and fix here, in case anyone else is banging their head against this.  I’ll also describe the process and various error messages encountered, for reference and to help anyone struggling with the same issue to actually find this information.

If you’re only interested in the solution, head straight to the work-around.

The Bug

After a short detour during which I believed the underlying cause was the Oxide webviewer (which is the basis of the cordova-ubuntu display), I finally determined that the problem was somewhere below that in the QT layer.

To demonstrate this, a dead simple QtQuick application window was used:

    import QtQuick 2.1
    import QtQuick.Controls 1.0
    import QtQuick.Window 2.0
     
    ApplicationWindow {
        title: qsTr("Hello World")
        width: 640
        height: 480
     
        menuBar: MenuBar {
            Menu {
                title: qsTr("File")
                MenuItem {
                    text: qsTr("Exit")
                    onTriggered: Qt.quit();
                }
            }
        }
     
        Button {
            text: qsTr("Hello World")
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
        }
    }

and displayed using

qmlscene mytest.qml

This resulted in a window with black rectangles wherever controls/widgets were supposed to be

and an error message related to the texture atlas:

QSGTextureAtlas: texture atlas allocation failed, code=501

Sleuthing

I found I could use apitrace (a useful tool) to dig into the error further

apitrace trace qmlscene mytest.qml

and then

apitrace dump qmlscene.trace

to find errors like:

message: major api error 17: GL_INVALID_OPERATION in glTexSubImage2D(invalid texture image)

related to calls like

 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_BGRA, 
      width = 1024,height = 512, border = 0, format = GL_BGRA, -
      type = GL_UNSIGNED_BYTE, pixels = NULL)

and

 glTexSubImage2D(target = GL_TEXTURE_2D, level = 0, xoffset = 137, yoffset = 0, 
         width = 101, height = 1, format = GL_BGRA, type = GL_UNSIGNED_BYTE, 
         pixels = blob(404))

Since this was OpenGL texture related, I spent an inordinate amount of time trying to disable OpenGL.  Since the dev machine is using the intel i915 driver, I created an /usr/share/X11/xorg.conf.d/20-intel.conf device driver Xorg config file, tried everything I could think of and wound up with an config file that retains some traces of my past attempts:

Section "Device"
        Identifier  "Intel Graphics"
        Driver      "intel"
        #Option "NoAccel" "true"
        #Option      "AccelMethod"  "blt"
        #Option      "AccelMethod"  "uxa"
        #Option      "AccelMethod"  "none"
        #Option     "DRI"       "1"
        #Option "TearFree"       "true"
        #Option "XvPreferOverlay" "true"
        #Option "FallbackDebug"  "true"
EndSection

Nothing worked and it was all pretty frustrating.

Discovery and Work-around

After finding that this was likely due to an invalid request by Qt to use the BGRA format for the texture, I reported the bug to the Qt guys  (who were waaaay more responsive than the cordova-ubuntu maintainers) and kept looking.  I finally found this bit of code in the QtQuick scenegraph which was specifying different internal and external formats for the textures, e.g.

 m_internalFormat = GL_RGBA;
 m_externalFormat = GL_BGRA;

Though this may be the source of my issue, I really wanted to avoid messing around with Qt by trying to compile the whole thing and install it on my system.

Thankfully, qsgatlastexture.cpp provided a final clue… since it was configuring the formats based on the presence of various GL extensions:

 

if (strstr(ext, "GL_EXT_bgra")
     || strstr(ext, "GL_EXT_texture_format_BGRA8888")
     || strstr(ext, "GL_IMG_texture_format_BGRA8888")) {
 // ...
 }

 

maybe disabling these extensions might work..?  Using glxinfo, I could see that that I did have GL_EXT_bgra and GL_EXT_texture_format_BGRA8888 enabled. I found a page which lists Mesa debug environment settings.  Of specific interest: MESA_EXTENSION_OVERRIDE, which can be used to enable/disable extensions.

The magic command was then just:

MESA_EXTENSION_OVERRIDE="-GL_EXT_bgra -GL_EXT_texture_format_BGRA8888" qmlscene mytest.qml

and voila, hello world!

Thus, leaving everything else as-is but disabling the extensions with that flag was all it took.  Setting it in the environment

export MESA_EXTENSION_OVERRIDE="-GL_EXT_bgra -GL_EXT_texture_format_BGRA8888"

prior to running Cordova is all it takes. aaaaaaaagh!  So: not resolved but reported to Qt and druid development can finally proceed.  Fi.Nal.Ly!

Context

Some context to describe the affected system and graphics card/driver, for reference.

This is an Ubuntu system, which started at 16.04 but was upgraded twice since and is now at 17.something in the (vain) hopes of getting a fix from fresh packages.  The machine is an Asus laptop, with Intel Core i7-6500U CPU @ 2.50GHz × 4 and a Intel HD Graphics 520 (Skylake GT2) card, using the intel i915 driver.

GLX info:

direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Intel Open Source Technology Center (0x8086)
Device: Mesa DRI Intel(R) HD Graphics 520 (Skylake GT2)  (0x1916)
Version: 13.0.3
Accelerated: yes
Video memory: 3072MB
Unified memory: yes
Preferred profile: core (0x1)
Max core profile version: 4.5
Max compat profile version: 3.0
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.2
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) HD Graphics 520 (Skylake GT2)
OpenGL core profile version string: 4.5 (Core Profile) Mesa 13.0.3
OpenGL core profile shading language version string: 4.50
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

OpenGL version string: 3.0 Mesa 13.0.3
OpenGL shading language version string: 1.30
OpenGL context flags: (none)

OpenGL ES profile version string: OpenGL ES 3.2 Mesa 13.0.3
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20

Using Kernel Mode Setting driver: i915, version 1.6.0 20160919

with /sys/kernel/debug/dri/0/i915_dmc_info:
fw loaded: yes
path: i915/skl_dmc_ver1_26.bin
version: 1.26
DC3 -> DC5 count: 8706
DC5 -> DC6 count: 0
program base: 0x09004040
ssp base: 0x00002fc0
htp: 0x00b40068