From 80cd06fd9d26aa7df02f71e001b449d65bb5b7a3 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 8 Oct 2013 14:55:28 +0200 Subject: eglfs: Separate compositor and improve raster window support Separating the compositor into a separate source file improves the chances of possible future reuse and paves the way to supporting multiple GL windows. Tooltips are now working too. Implemented a few window functions like raise() and lower(). Fixed the qFatal for multiple GL windows to be raised in non-SDK based Android builds too. Change-Id: Id94d2fb2a4382766f3d130eebe1e6f397a535852 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/eglfs/qeglfsbackingstore.cpp | 177 +++------------------ 1 file changed, 19 insertions(+), 158 deletions(-) (limited to 'src/plugins/platforms/eglfs/qeglfsbackingstore.cpp') diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp index ec2f4f9d91..8de8268616 100644 --- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp +++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp @@ -40,120 +40,24 @@ ****************************************************************************/ #include "qeglfsbackingstore.h" +#include "qeglfscompositor.h" #include "qeglfscursor.h" #include "qeglfswindow.h" +#include "qeglfscontext.h" -#include #include #include -#include - QT_BEGIN_NAMESPACE -QEglFSCompositor::QEglFSCompositor() - : m_rootWindow(0) -{ - m_updateTimer.setSingleShot(true); - m_updateTimer.setInterval(0); - connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll())); -} - -void QEglFSCompositor::schedule(QEglFSWindow *rootWindow) -{ - m_rootWindow = rootWindow; - if (!m_updateTimer.isActive()) - m_updateTimer.start(); -} - -void QEglFSCompositor::renderAll() -{ - Q_ASSERT(m_rootWindow); - QOpenGLContext *context = QEglFSBackingStore::makeRootCurrent(m_rootWindow); - - QEglFSScreen *screen = m_rootWindow->screen(); - QList 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 QEglFSCompositor::render(QEglFSWindow *window, QEglFSWindow *rootWindow) -{ - QEglFSBackingStore *rootBackingStore = rootWindow->backingStore(); - rootBackingStore->m_program->bind(); - - const GLfloat textureCoordinates[] = { - 0, 0, - 1, 0, - 1, 1, - 0, 1 - }; - - QRectF sr = window->screen()->geometry(); - QRect r = window->window()->geometry(); - QPoint tl = r.topLeft(); - QPoint br = r.bottomRight(); - - 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; - - const GLfloat vertexCoordinates[] = { - x1, y1, - x2, y1, - x2, y2, - x1, y2 - }; - - glViewport(0, 0, sr.width(), sr.height()); - - glEnableVertexAttribArray(rootBackingStore->m_vertexCoordEntry); - glEnableVertexAttribArray(rootBackingStore->m_textureCoordEntry); - - glVertexAttribPointer(rootBackingStore->m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates); - glVertexAttribPointer(rootBackingStore->m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates); - - glBindTexture(GL_TEXTURE_2D, window->backingStore()->m_texture); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - rootBackingStore->m_program->release(); - glBindTexture(GL_TEXTURE_2D, 0); - glDisableVertexAttribArray(rootBackingStore->m_vertexCoordEntry); - glDisableVertexAttribArray(rootBackingStore->m_textureCoordEntry); -} - -static QEglFSCompositor *compositor = 0; - -QEglFSCompositor *QEglFSCompositor::instance() -{ - if (!compositor) - compositor = new QEglFSCompositor; - return compositor; -} - QEglFSBackingStore::QEglFSBackingStore(QWindow *window) - : QPlatformBackingStore(window) - , m_window(static_cast(window->handle())) - , m_context(0) - , m_texture(0) - , m_program(0) + : QPlatformBackingStore(window), + m_window(static_cast(window->handle())), + m_texture(0) { m_window->setBackingStore(this); } -QEglFSBackingStore::~QEglFSBackingStore() -{ - delete m_program; - delete m_context; -} - QPaintDevice *QEglFSBackingStore::paintDevice() { return &m_image; @@ -186,7 +90,8 @@ void QEglFSBackingStore::updateTexture() // if the sub-rect is full-width we can pass the image data directly to // OpenGL instead of copying, since there's no gap between scanlines if (rect.width() == imageRect.width()) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_image.constScanLine(rect.y())); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + m_image.constScanLine(rect.y())); } else { glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_image.copy(rect).constBits()); @@ -207,63 +112,14 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo qWarning("QEglBackingStore::flush %p", window); #endif - m_window->create(); QEglFSWindow *rootWin = m_window->screen()->rootWindow(); - if (rootWin) { - makeRootCurrent(rootWin); - updateTexture(); - QEglFSCompositor::instance()->schedule(rootWin); - } -} - -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(); - } + if (!rootWin) + return; - m_context->makeCurrent(wnd); -} - -QOpenGLContext *QEglFSBackingStore::makeRootCurrent(QEglFSWindow *rootWin) -{ - 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; + m_window->create(); + rootWin->screen()->rootContext()->makeCurrent(rootWin->window()); + updateTexture(); + QEglFSCompositor::instance()->schedule(rootWin->screen()); } void QEglFSBackingStore::beginPaint(const QRegion &rgn) @@ -275,9 +131,14 @@ void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents { Q_UNUSED(staticContents); + QEglFSWindow *rootWin = m_window->screen()->rootWindow(); + if (!rootWin) + return; + m_image = QImage(size, QImage::Format_RGB32); m_window->create(); - makeRootCurrent(m_window->screen()->rootWindow()); + + rootWin->screen()->rootContext()->makeCurrent(rootWin->window()); if (m_texture) glDeleteTextures(1, &m_texture); -- cgit v1.2.3