Add basic backingstore implementation to kms

This allows using the kms plugin in QWidget apps having a single
(preferably fullscreen) top-level widget.

Based on eglfs' implementation. Dirty rectangle tracking is missing,
should be added later.

There is no composition so multiple TLWs will not work nicely.

Change-Id: Ia78589d1a375925ebdcc46aa20fc1619ec14d6cc
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Elvis Lee <kwangwoong.lee@lge.com>
This commit is contained in:
Laszlo Agocs 2012-07-21 14:20:33 +03:00 committed by Qt by Nokia
parent c2942cb7b6
commit 7a3dd20b98
2 changed files with 130 additions and 4 deletions

View File

@ -41,11 +41,31 @@
#include "qkmsbackingstore.h"
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QScreen>
QT_BEGIN_NAMESPACE
QKmsBackingStore::QKmsBackingStore(QWindow *window)
: QPlatformBackingStore(window)
, m_context(new QOpenGLContext)
, m_texture(0)
, m_program(0)
{
m_context->setFormat(window->requestedFormat());
m_context->setScreen(window->screen());
m_context->create();
window->setSurfaceType(QSurface::OpenGLSurface);
}
QKmsBackingStore::~QKmsBackingStore()
{
delete m_program;
if (m_texture)
glDeleteTextures(1, &m_texture);
delete m_context;
}
QPaintDevice *QKmsBackingStore::paintDevice()
@ -53,20 +73,115 @@ QPaintDevice *QKmsBackingStore::paintDevice()
return &m_image;
}
void QKmsBackingStore::beginPaint(const QRegion &)
{
}
void QKmsBackingStore::endPaint()
{
}
void QKmsBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
//'window' can be a child window, in which case 'region' is in child window coordinates and
// offset is the (child) window's offset in relation to the window surface.
Q_UNUSED(region)
Q_UNUSED(offset)
Q_UNUSED(window)
m_context->makeCurrent(window);
if (!m_program) {
static const char *textureVertexProgram =
"attribute highp vec2 vertexCoordEntry;\n"
"attribute highp vec2 textureCoordEntry;\n"
"varying highp vec2 textureCoord;\n"
"void main() {\n"
" textureCoord = textureCoordEntry;\n"
" gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n"
"}\n";
static const char *textureFragmentProgram =
"uniform sampler2D texture;\n"
"varying highp vec2 textureCoord;\n"
"void main() {\n"
" 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->bindAttributeLocation("vertexCoordEntry", 0);
m_program->bindAttributeLocation("textureCoordEntry", 1);
m_program->link();
}
m_program->bind();
QRectF r = window->geometry();
QRectF sr = window->screen()->geometry();
GLfloat x1 = (r.left() / sr.width()) * 2 - 1;
GLfloat x2 = (r.right() / sr.width()) * 2 - 1;
GLfloat y1 = -1 * ((r.top() / sr.height()) * 2 - 1);
GLfloat y2 = -1 * ((r.bottom() / sr.height()) * 2 - 1);
const GLfloat vertexCoordinates[] = {
x1, y1,
x2, y1,
x2, y2,
x1, y2
};
const GLfloat textureCoordinates[] = {
0, 0,
1, 0,
1, 1,
0, 1
};
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.constScanLine(0));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
m_program->release();
glBindTexture(GL_TEXTURE_2D, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
m_context->swapBuffers(window);
m_context->doneCurrent();
}
void QKmsBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
Q_UNUSED(staticContents)
m_image = QImage(size, QImage::Format_RGB32);
m_context->makeCurrent(window());
if (m_texture)
glDeleteTextures(1, &m_texture);
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
QT_END_NAMESPACE

View File

@ -47,17 +47,28 @@
QT_BEGIN_NAMESPACE
class QOpenGLContext;
class QOpenGLShaderProgram;
class QKmsBackingStore : public QPlatformBackingStore
{
public:
QKmsBackingStore(QWindow *window);
~QKmsBackingStore();
QPaintDevice *paintDevice();
void beginPaint(const QRegion &);
void endPaint();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
private:
QOpenGLContext *m_context;
QImage m_image;
uint m_texture;
QOpenGLShaderProgram *m_program;
};
QT_END_NAMESPACE