eglfs: use GL API directly in QEglFSCursor
authorGirish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
Mon, 21 May 2012 22:41:55 +0000 (15:41 -0700)
committerQt by Nokia <qt-info@nokia.com>
Fri, 25 May 2012 15:23:20 +0000 (17:23 +0200)
The upcoming hardware cursor support for pi requires the cursor
code to render with it's own context. This is because the cursor
rendering happens in the input event (gui) thread which may be
different from the the scenegraph thread.

Currently, Qt can be informed about the current opengl context by
using QOpenGLContext::makeCurrent(). All of Qt's helper OpenGL
classes complain if that function has not been called. Usage of
makeCurrent API requires a QSurface. A big rewrite of EGLFS is
needed to make such a QSurface (QEglFSWindow) available to the
cursor code. There is no other way around this since Qt
has no other API to inform it that an opengl context is active.

The solution is not use Qt's OpenGL helper classes and use GL API
directly.

Change-Id: If47030d9a289686ebf2e758f90445323d1733dc0
Reviewed-by: Andy Nichols <andy.nichols@nokia.com>
src/plugins/platforms/eglfs/qeglfscursor.cpp
src/plugins/platforms/eglfs/qeglfscursor.h

index 0d068f3..63f7964 100644 (file)
@@ -41,7 +41,6 @@
 
 #include "qeglfscursor.h"
 #include <QtGui/qwindowsysteminterface_qpa.h>
-#include <QtGui/QOpenGLShaderProgram>
 #include <QtGui/QOpenGLContext>
 #include <QtCore/QJsonDocument>
 #include <QtCore/QJsonArray>
@@ -64,6 +63,8 @@ QEglFSCursor::QEglFSCursor(QEglFSScreen *screen)
 QEglFSCursor::~QEglFSCursor()
 {
     if (QOpenGLContext::currentContext()) {
+        glDeleteProgram(m_program);
+
         if (m_cursor.shape == Qt::BitmapCursor && m_cursor.texture)
             glDeleteTextures(1, &m_cursor.texture);
 
@@ -71,6 +72,45 @@ QEglFSCursor::~QEglFSCursor()
     }
 }
 
+static GLuint createShader(GLenum shaderType, const char *program)
+{
+    GLuint shader = glCreateShader(shaderType);
+    glShaderSource(shader, 1 /* count */, &program, NULL /* lengths */);
+    glCompileShader(shader);
+    GLint status;
+    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+    if (status == GL_TRUE)
+        return shader;
+
+    GLint length;
+    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
+    char *infoLog = new char[length];
+    glGetShaderInfoLog(shader, length, NULL, infoLog);
+    qDebug("%s shader compilation error: %s", shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment", infoLog);
+    delete [] infoLog;
+    return 0;
+}
+
+static GLuint createProgram(GLuint vshader, GLuint fshader)
+{
+    GLuint program = glCreateProgram();
+    glAttachShader(program, vshader);
+    glAttachShader(program, fshader);
+    glLinkProgram(program);
+    GLint status;
+    glGetProgramiv(program, GL_LINK_STATUS, &status);
+    if (status == GL_TRUE)
+        return program;
+
+    GLint length;
+    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
+    char *infoLog = new char[length];
+    glGetProgramInfoLog(program, length, NULL, infoLog);
+    qDebug("program link error: %s", infoLog);
+    delete [] infoLog;
+    return 0;
+}
+
 void QEglFSCursor::createShaderPrograms()
 {
     static const char *textureVertexProgram =
@@ -89,15 +129,15 @@ void QEglFSCursor::createShaderPrograms()
         "   gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
         "}\n";
 
-    m_program = new QOpenGLShaderProgram;
-
-    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
-    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
-    m_program->link();
+    GLuint vertexShader = createShader(GL_VERTEX_SHADER, textureVertexProgram);
+    GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, textureFragmentProgram);
+    m_program = createProgram(vertexShader, fragmentShader);
+    glDeleteShader(vertexShader);
+    glDeleteShader(fragmentShader);
 
-    m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
-    m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
-    m_textureEntry = m_program->uniformLocation("texture");
+    m_vertexCoordEntry = glGetAttribLocation(m_program, "vertexCoordEntry");
+    m_textureCoordEntry = glGetAttribLocation(m_program, "textureCoordEntry");
+    m_textureEntry = glGetUniformLocation(m_program, "texture");
 }
 
 void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
@@ -203,7 +243,7 @@ void QEglFSCursor::pointerEvent(const QMouseEvent &event)
 
 void QEglFSCursor::render()
 {
-    m_program->bind();
+    glUseProgram(m_program);
 
     const QRectF cr = cursorRect();
     const QRect screenRect(m_screen->geometry());
@@ -250,7 +290,7 @@ void QEglFSCursor::render()
     glDisableVertexAttribArray(m_vertexCoordEntry);
     glDisableVertexAttribArray(m_textureCoordEntry);
 
-    m_program->release();
+    glUseProgram(0);
 }
 
 QT_END_NAMESPACE
index 43f6b68..1fdb648 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <qpa/qplatformcursor.h>
 #include "qeglfsscreen.h"
+#include <GLES2/gl2.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -94,7 +95,7 @@ private:
 
     QPoint m_pos;
 
-    QOpenGLShaderProgram *m_program;
+    GLuint m_program;
     int m_vertexCoordEntry;
     int m_textureCoordEntry;
     int m_textureEntry;