From b8420c9fc246428cf26ace2970f252ca7580aef5 Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Mon, 21 May 2012 15:41:55 -0700 Subject: eglfs: use GL API directly in QEglFSCursor 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 --- src/plugins/platforms/eglfs/qeglfscursor.cpp | 62 +++++++++++++++++++++++----- src/plugins/platforms/eglfs/qeglfscursor.h | 3 +- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp index 0d068f38c0..63f7964ca4 100644 --- a/src/plugins/platforms/eglfs/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp @@ -41,7 +41,6 @@ #include "qeglfscursor.h" #include -#include #include #include #include @@ -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 diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/plugins/platforms/eglfs/qeglfscursor.h index 43f6b681a8..1fdb648fc6 100644 --- a/src/plugins/platforms/eglfs/qeglfscursor.h +++ b/src/plugins/platforms/eglfs/qeglfscursor.h @@ -44,6 +44,7 @@ #include #include "qeglfsscreen.h" +#include 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; -- cgit v1.2.3