Esempio n. 1
0
QImage QEglGLPixmapData::toImage() const
{
    TRACE();
    // We should not do so many toImage calls alltogether. This is what is slowing us down right now.
    // QWK should keep a cache of transformed images instead of re-doing it every frame.
    // FIXME make QWebKit not do so many QPixmap(QImage(pixmap.toImage).transform()) style transformations.
    if (!isValid())
        return QImage();

    if (!m_source.isNull()) {
        return m_source;
    } else if (m_dirty || m_hasFillColor) {
        m_source = fillImage(m_fillColor);
        return m_source;
    } else {
        ensureCreated();
    }
    // read the image from the FBO to memory
    if(m_fbo) {
        // we read the data back from the fbo
        m_ctx->makeCurrent();
        QGLShareContextScope ctx(qt_gl_share_widget()->context());
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
        // this does glReadPixels - not very fast!
        QImage temp=qt_gl_read_framebuffer(QSize(w, h), true, true);
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
        m_source=temp;
        m_ctx->doneCurrent();
        return temp;
    }
    else if (m_texture.id) {
        // we read back from the texture by binding its id as a framebuffer
        // is this in the OpenGL standard? It seems to work
        m_ctx->makeCurrent();
        QGLShareContextScope ctx(qt_gl_share_widget()->context());
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_texture.id);
        // this does glReadPixels - not very fast
        QImage temp=qt_gl_read_framebuffer(QSize(w, h), true, true);
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
        // should we cache the fetched image locally to speed up future access?
        // m_source=temp;
        m_ctx->doneCurrent();
        return temp;
    }
    else {
        QImage temp(w,h, QImage::Format_ARGB32_Premultiplied);
        // FIXME indicating something went wrong, neither of above cases worked - look out for yellow images
        temp.fill(Qt::yellow);
        m_source=temp;
        return temp;
    }

}
Esempio n. 2
0
/*!
    \fn QImage QGLFramebufferObject::toImage() const

    Returns the contents of this framebuffer object as a QImage.
*/
QImage QGLFramebufferObject::toImage() const
{
    Q_D(const QGLFramebufferObject);
    if (!d->valid)
        return QImage();

    // qt_gl_read_framebuffer doesn't work on a multisample FBO
    if (format().samples() != 0) {
        QGLFramebufferObject temp(size(), QGLFramebufferObjectFormat());

        QRect rect(QPoint(0, 0), size());
        blitFramebuffer(&temp, rect, const_cast<QGLFramebufferObject *>(this), rect);

        return temp.toImage();
    }

    bool wasBound = isBound();
    if (!wasBound)
        const_cast<QGLFramebufferObject *>(this)->bind();
    QImage image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat() != GL_RGB, true);
    if (!wasBound)
        const_cast<QGLFramebufferObject *>(this)->release();

    return image;
}
Esempio n. 3
0
void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
{
    m_context->markLayerComposited();
    blitMultisampleFramebufferAndRestoreContext();

    if (textureMapper->accelerationMode() == TextureMapper::OpenGLMode) {
        TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper);
        TextureMapperGL::Flags flags = TextureMapperGL::ShouldFlipTexture | (m_context->m_attrs.alpha ? TextureMapperGL::ShouldBlend : 0);
        IntSize textureSize(m_context->m_currentWidth, m_context->m_currentHeight);
        texmapGL->drawTexture(m_context->m_texture, flags, textureSize, targetRect, matrix, opacity);
        return;
    }

    // Alternatively read pixels to a memory buffer.
    GraphicsContext* context = textureMapper->graphicsContext();
    QPainter* painter = context->platformContext();
    painter->save();
    painter->setTransform(matrix);
    painter->setOpacity(opacity);

    const int height = m_context->m_currentHeight;
    const int width = m_context->m_currentWidth;

    painter->beginNativePainting();
    makeCurrentIfNeeded();
    glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_fbo);
    QImage offscreenImage = qt_gl_read_framebuffer(QSize(width, height), true, true);
    glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_state.boundFBO);

    painter->endNativePainting();

    painter->drawImage(targetRect, offscreenImage);
    painter->restore();
}
Esempio n. 4
0
/*!
    Returns the contents of the pbuffer as a QImage.
*/
QImage QGLPixelBuffer::toImage() const
{
    Q_D(const QGLPixelBuffer);
    if (d->invalid)
        return QImage();

    const_cast<QGLPixelBuffer *>(this)->makeCurrent();
    return qt_gl_read_framebuffer(d->req_size, d->format.alpha(), true);
}
Esempio n. 5
0
QImage QSGWindowsRenderLoop::grab(QQuickWindow *window)
{
    RLDEBUG("grab");
    if (!m_gl)
        return QImage();

    m_gl->makeCurrent(window);

    QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
    d->polishItems();
    d->syncSceneGraph();
    d->renderSceneGraph(window->size());

    QImage image = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), false, false);
    return image;
}
QImage QSGWindowsRenderLoop::grab(QQuickWindow *window)
{
    RLDEBUG("grab");
    if (!m_gl)
        return QImage();

    m_gl->makeCurrent(window);

    QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
    d->polishItems();
    d->syncSceneGraph();
    d->renderSceneGraph(window->size());

    bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
    QImage image = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), alpha, alpha);
    return image;
}
void QQuickTrivialWindowManager::renderWindow(QQuickWindow *window)
{
    bool renderWithoutShowing = QQuickWindowPrivate::get(window)->renderWithoutShowing;
    if ((!window->isExposed() && !renderWithoutShowing) || !m_windows.contains(window))
        return;

    WindowData &data = const_cast<WindowData &>(m_windows[window]);

    QQuickWindow *masterWindow = 0;
    if (!window->isVisible() && !renderWithoutShowing) {
        // Find a "proper surface" to bind...
        for (QHash<QQuickWindow *, WindowData>::const_iterator it = m_windows.constBegin();
             it != m_windows.constEnd() && !masterWindow; ++it) {
            if (it.key()->isVisible())
                masterWindow = it.key();
        }
    } else {
        masterWindow = window;
    }

    if (!masterWindow)
        return;

    if (!QQuickWindowPrivate::get(masterWindow)->isRenderable()) {
        qWarning().nospace()
            << "Unable to find a renderable master window "
            << masterWindow << "when trying to render"
            << window << " (" << window->geometry() << ").";
        return;
    }

    if (!gl) {
        gl = new QOpenGLContext();
        gl->setFormat(masterWindow->requestedFormat());
        gl->create();
        if (!gl->makeCurrent(masterWindow))
            qWarning("QQuickWindow: makeCurrent() failed...");
        sg->initialize(gl);
    } else {
        gl->makeCurrent(masterWindow);
    }

    bool alsoSwap = data.updatePending;
    data.updatePending = false;

    QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
    cd->polishItems();

    int renderTime = 0, syncTime = 0;
    QTime renderTimer;
    if (qquick_render_timing())
        renderTimer.start();

    cd->syncSceneGraph();

    if (qquick_render_timing())
        syncTime = renderTimer.elapsed();

    cd->renderSceneGraph(window->size());

    if (qquick_render_timing())
        renderTime = renderTimer.elapsed() - syncTime;

    if (data.grabOnly) {
        grabContent = qt_gl_read_framebuffer(window->size(), false, false);
        data.grabOnly = false;
    }

    if (alsoSwap && window->isVisible()) {
        gl->swapBuffers(window);
        cd->fireFrameSwapped();
    }

    if (qquick_render_timing()) {
        static QTime lastFrameTime = QTime::currentTime();
        const int swapTime = renderTimer.elapsed() - renderTime - syncTime;
        qDebug() << "- Breakdown of frame time; sync:" << syncTime
                 << "ms render:" << renderTime << "ms swap:" << swapTime
                 << "ms total:" << swapTime + renderTime + syncTime
                 << "ms time since last frame:" << (lastFrameTime.msecsTo(QTime::currentTime()))
                 << "ms";
        lastFrameTime = QTime::currentTime();
    }

    // Might have been set during syncSceneGraph()
    if (data.updatePending)
        maybeUpdate(window);
}