summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/eglfs/qeglfsbackingstore.cpp')
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp232
1 files changed, 151 insertions, 81 deletions
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
index 35f699d975..ec2f4f9d91 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
@@ -51,104 +51,123 @@
QT_BEGIN_NAMESPACE
-QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
- , m_context(new QOpenGLContext)
- , m_texture(0)
- , m_program(0)
+QEglFSCompositor::QEglFSCompositor()
+ : m_rootWindow(0)
{
- m_context->setFormat(window->requestedFormat());
- m_context->setScreen(window->screen());
- m_context->create();
+ m_updateTimer.setSingleShot(true);
+ m_updateTimer.setInterval(0);
+ connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
}
-QEglFSBackingStore::~QEglFSBackingStore()
+void QEglFSCompositor::schedule(QEglFSWindow *rootWindow)
{
- delete m_program;
- delete m_context;
+ m_rootWindow = rootWindow;
+ if (!m_updateTimer.isActive())
+ m_updateTimer.start();
}
-QPaintDevice *QEglFSBackingStore::paintDevice()
+void QEglFSCompositor::renderAll()
{
- return &m_image;
+ Q_ASSERT(m_rootWindow);
+ QOpenGLContext *context = QEglFSBackingStore::makeRootCurrent(m_rootWindow);
+
+ QEglFSScreen *screen = m_rootWindow->screen();
+ QList<QEglFSWindow *> windows = screen->windows();
+ for (int i = 0; i < windows.size(); ++i) {
+ if (windows.at(i)->backingStore())
+ render(windows.at(i), m_rootWindow);
+ }
+
+ context->swapBuffers(m_rootWindow->window());
+ context->doneCurrent();
}
-void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+void QEglFSCompositor::render(QEglFSWindow *window, QEglFSWindow *rootWindow)
{
- Q_UNUSED(region);
- Q_UNUSED(offset);
+ QEglFSBackingStore *rootBackingStore = rootWindow->backingStore();
+ rootBackingStore->m_program->bind();
- makeCurrent();
+ const GLfloat textureCoordinates[] = {
+ 0, 0,
+ 1, 0,
+ 1, 1,
+ 0, 1
+ };
QRectF sr = window->screen()->geometry();
- glViewport(0, 0, sr.width(), sr.height());
+ QRect r = window->window()->geometry();
+ QPoint tl = r.topLeft();
+ QPoint br = r.bottomRight();
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglBackingStore::flush %p", window);
-#endif
+ GLfloat x1 = (tl.x() / sr.width()) * 2 - 1;
+ GLfloat x2 = (br.x() / sr.width()) * 2 - 1;
+ GLfloat y1 = ((sr.height() - tl.y()) / sr.height()) * 2 - 1;
+ GLfloat y2 = ((sr.height() - br.y()) / sr.height()) * 2 - 1;
- 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";
+ const GLfloat vertexCoordinates[] = {
+ x1, y1,
+ x2, y1,
+ x2, y2,
+ x1, y2
+ };
- static const char *textureFragmentProgram =
- "uniform sampler2D texture;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
- "}\n";
+ glViewport(0, 0, sr.width(), sr.height());
- m_program = new QOpenGLShaderProgram;
+ glEnableVertexAttribArray(rootBackingStore->m_vertexCoordEntry);
+ glEnableVertexAttribArray(rootBackingStore->m_textureCoordEntry);
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->link();
+ glVertexAttribPointer(rootBackingStore->m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
+ glVertexAttribPointer(rootBackingStore->m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
- m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
- m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
- }
+ glBindTexture(GL_TEXTURE_2D, window->backingStore()->m_texture);
- m_program->bind();
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- const GLfloat textureCoordinates[] = {
- 0, 1,
- 1, 1,
- 1, 0,
- 0, 0
- };
+ rootBackingStore->m_program->release();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisableVertexAttribArray(rootBackingStore->m_vertexCoordEntry);
+ glDisableVertexAttribArray(rootBackingStore->m_textureCoordEntry);
+}
- QRectF r = window->geometry();
+static QEglFSCompositor *compositor = 0;
- GLfloat x1 = (r.left() / sr.width()) * 2 - 1;
- GLfloat x2 = (r.right() / sr.width()) * 2 - 1;
- GLfloat y1 = (r.top() / sr.height()) * 2 - 1;
- GLfloat y2 = (r.bottom() / sr.height()) * 2 - 1;
+QEglFSCompositor *QEglFSCompositor::instance()
+{
+ if (!compositor)
+ compositor = new QEglFSCompositor;
+ return compositor;
+}
- const GLfloat vertexCoordinates[] = {
- x1, y1,
- x2, y1,
- x2, y2,
- x1, y2
- };
+QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+ , m_window(static_cast<QEglFSWindow *>(window->handle()))
+ , m_context(0)
+ , m_texture(0)
+ , m_program(0)
+{
+ m_window->setBackingStore(this);
+}
- glEnableVertexAttribArray(m_vertexCoordEntry);
- glEnableVertexAttribArray(m_textureCoordEntry);
+QEglFSBackingStore::~QEglFSBackingStore()
+{
+ delete m_program;
+ delete m_context;
+}
- glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
- glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+QPaintDevice *QEglFSBackingStore::paintDevice()
+{
+ return &m_image;
+}
+void QEglFSBackingStore::updateTexture()
+{
glBindTexture(GL_TEXTURE_2D, m_texture);
if (!m_dirty.isNull()) {
+ QRegion fixed;
QRect imageRect = m_image.rect();
+ m_dirty |= imageRect;
- QRegion fixed;
foreach (const QRect &rect, m_dirty.rects()) {
// intersect with image rect to be sure
QRect r = imageRect & rect;
@@ -176,32 +195,80 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPo
m_dirty = QRegion();
}
+}
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
- m_program->release();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(m_vertexCoordEntry);
- glDisableVertexAttribArray(m_textureCoordEntry);
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglBackingStore::flush %p", window);
+#endif
- // draw the cursor
- if (QEglFSCursor *cursor = static_cast<QEglFSCursor *>(window->screen()->handle()->cursor()))
- cursor->paintOnScreen();
+ m_window->create();
+ QEglFSWindow *rootWin = m_window->screen()->rootWindow();
+ if (rootWin) {
+ makeRootCurrent(rootWin);
+ updateTexture();
+ QEglFSCompositor::instance()->schedule(rootWin);
+ }
+}
- m_context->swapBuffers(window);
+void QEglFSBackingStore::makeCurrent()
+{
+ Q_ASSERT(m_window->hasNativeWindow());
+
+ QWindow *wnd = window();
+ if (!m_context) {
+ m_context = new QOpenGLContext;
+ m_context->setFormat(wnd->requestedFormat());
+ m_context->setScreen(wnd->screen());
+ m_context->create();
+ }
- m_context->doneCurrent();
+ m_context->makeCurrent(wnd);
}
-void QEglFSBackingStore::makeCurrent()
+QOpenGLContext *QEglFSBackingStore::makeRootCurrent(QEglFSWindow *rootWin)
{
- (static_cast<QEglFSWindow *>(window()->handle()))->create();
- m_context->makeCurrent(window());
+ Q_ASSERT(rootWin->hasNativeWindow() && rootWin->isRasterRoot());
+
+ QEglFSBackingStore *rootBackingStore = rootWin->backingStore();
+ rootBackingStore->makeCurrent();
+ if (!rootBackingStore->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";
+
+ rootBackingStore->m_program = new QOpenGLShaderProgram;
+
+ rootBackingStore->m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ rootBackingStore->m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ rootBackingStore->m_program->link();
+
+ rootBackingStore->m_vertexCoordEntry = rootBackingStore->m_program->attributeLocation("vertexCoordEntry");
+ rootBackingStore->m_textureCoordEntry = rootBackingStore->m_program->attributeLocation("textureCoordEntry");
+ }
+ return rootBackingStore->m_context;
}
void QEglFSBackingStore::beginPaint(const QRegion &rgn)
{
- m_dirty = m_dirty | rgn;
+ m_dirty |= rgn;
}
void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents)
@@ -209,9 +276,12 @@ void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents
Q_UNUSED(staticContents);
m_image = QImage(size, QImage::Format_RGB32);
- makeCurrent();
+ m_window->create();
+ makeRootCurrent(m_window->screen()->rootWindow());
+
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);