Exemple #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;
    }

}
Exemple #2
0
QImage QGLPixmapData::toImage() const
{
    if (!isValid())
        return QImage();

    if (m_renderFbo) {
        copyBackFromRenderFbo(true);
    } else if (!m_source.isNull()) {
        // QVolatileImage::toImage() will make a copy always so no check
        // for active painting is needed.
        QImage img = m_source.toImage();
        if (img.format() == QImage::Format_MonoLSB) {
            img.setColorCount(2);
            img.setColor(0, QColor(Qt::color0).rgba());
            img.setColor(1, QColor(Qt::color1).rgba());
        }
        return img;
    } else if (m_dirty || m_hasFillColor) {
        return fillImage(m_fillColor);
    } else {
        ensureCreated();
    }

    QGLShareContextScope ctx(qt_gl_share_widget()->context());
    glBindTexture(GL_TEXTURE_2D, m_texture.id);
    return qt_gl_read_texture(QSize(w, h), true, true);
}
void QGLPixmapData::resize(int width, int height)
{
    if (width == w && height == h)
        return;

    if (width <= 0 || height <= 0) {
        width = 0;
        height = 0;
    }

    w = width;
    h = height;
    is_null = (w <= 0 || h <= 0);
    d = pixelType() == QPixmapData::PixmapType ? 32 : 1;

    if (m_texture.id) {
        QGLShareContextScope ctx(qt_gl_share_widget()->context());
        glDeleteTextures(1, &m_texture.id);
        m_texture.id = 0;
    }

    m_source = QImage();
    m_dirty = isValid();
    setSerialNumber(++qt_gl_pixmap_serial);
}
Exemple #4
0
Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image)
{
    QGLShareContextScope ctx(qt_gl_share_widget()->context());

    QMeeGoExtensions::ensureInitialized();

    glFinish();
    QGLPixmapData pixmapData(QPixmapData::PixmapType);
    pixmapData.fromImage(image, 0);
    GLuint textureId = pixmapData.bind();

    glFinish();
    EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(),
                                                                                                EGL_GL_TEXTURE_2D_KHR,
                                                                                                (EGLClientBuffer) textureId,
                                                                                                preserved_image_attribs);
    glFinish();

    if (eglimage) {
        EGLNativeSharedImageTypeNOK handle = QMeeGoExtensions::eglCreateSharedImageNOK(QEgl::display(), eglimage, NULL);
        QEgl::eglDestroyImageKHR(QEgl::display(), eglimage);
        glFinish();
        return (Qt::HANDLE) handle;
    } else {
        qWarning("Failed to create shared image from pixmap/texture!");
        return 0;
    }
}
bool QGLPixmapData::fromFile(const QString &filename, const char *format,
                             Qt::ImageConversionFlags flags)
{
    if (pixelType() == QPixmapData::BitmapType)
        return QPixmapData::fromFile(filename, format, flags);
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly))
        return false;
    QByteArray data = file.peek(64);
    bool alpha;
    if (m_texture.canBindCompressedTexture
            (data.constData(), data.size(), format, &alpha)) {
        resize(0, 0);
        data = file.readAll();
        file.close();
        QGLShareContextScope ctx(qt_gl_share_widget()->context());
        QSize size = m_texture.bindCompressedTexture
            (data.constData(), data.size(), format);
        if (!size.isEmpty()) {
            w = size.width();
            h = size.height();
            is_null = false;
            d = 32;
            m_hasAlpha = alpha;
            m_source = QImage();
            m_dirty = isValid();
            return true;
        }
        return false;
    }
    fromImage(QImageReader(&file, format).read(), flags);
    return !isNull();
}
void QMeeGoLivePixmapData::initializeThroughEGLImage()
{
    if (texture()->id != 0)
        return;

    QGLShareContextScope ctx(qt_gl_share_widget()->context());
    QMeeGoExtensions::ensureInitialized();

    EGLImageKHR eglImage = EGL_NO_IMAGE_KHR;
    GLuint newTextureId = 0;

    eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
                                       (EGLClientBuffer) backingX11Pixmap->handle(), preserved_attribs);

    if (eglImage == EGL_NO_IMAGE_KHR) {
        qWarning("eglCreateImageKHR failed (live texture)!");
        return;
    }

    glGenTextures(1, &newTextureId);
    glBindTexture(GL_TEXTURE_2D, newTextureId);

    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (EGLImageKHR) eglImage);
    if (glGetError() == GL_NO_ERROR) {
        resize(backingX11Pixmap->width(), backingX11Pixmap->height());
        texture()->id = newTextureId;
        texture()->options &= ~QGLContext::InvertedYBindOption;
        m_hasAlpha = backingX11Pixmap->hasAlphaChannel();
    } else {
        qWarning("Failed to create a texture from an egl image (live texture)!");
        glDeleteTextures(1, &newTextureId);
    }

    QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
}
Exemple #7
0
bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
                             Qt::ImageConversionFlags flags)
{
    bool alpha;
    const char *buf = reinterpret_cast<const char *>(buffer);
    if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
        resize(0, 0);
        QGLShareContextScope ctx(qt_gl_share_widget()->context());
        QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
        if (!size.isEmpty()) {
            w = size.width();
            h = size.height();
            is_null = false;
            d = 32;
            m_hasAlpha = alpha;
            m_source = QVolatileImage();
            m_dirty = isValid();
            return true;
        }
    }

    QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
    QBuffer b(&a);
    b.open(QIODevice::ReadOnly);
    QImage image = QImageReader(&b, format).read();
    if (image.isNull())
        return false;

    createPixmapForImage(image, flags, true);

    return !isNull();
}
Exemple #8
0
void QEglGLPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
    TRACE();
    resize(image.width(), image.height());

    if (pixelType() == BitmapType) {
        m_source = image.convertToFormat(QImage::Format_MonoLSB);

    } else {
        QImage::Format format = QImage::Format_RGB32;
        if (qApp->desktop()->depth() == 16)
            format = QImage::Format_RGB16;

        if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())
            format = QImage::Format_ARGB32_Premultiplied;;

        m_source = image.convertToFormat(format);
    }

    m_dirty = true;
    m_hasFillColor = false;

    m_hasAlpha = m_source.hasAlphaChannel();
    w = image.width();
    h = image.height();
    is_null = (w <= 0 || h <= 0);
    d = m_source.depth();

    if (m_texture.id) {
        QGLShareContextScope ctx(qt_gl_share_widget()->context());
        glDeleteTextures(1, &m_texture.id);
        m_texture.id = 0;
    }    
}
bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
{
    if (ctx == m_ctx)
        return true;

    const QGLContext *share_ctx = qt_gl_share_widget()->context();
    return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
}
Exemple #10
0
bool QEglGLPixmapData::isValidContext(const QGLContext *ctx) const
{
    TRACE();
    if (ctx == m_ctx)
        return true;

    const QGLContext *share_ctx = qt_gl_share_widget()->context();
    bool ret = ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
    return ret;
}
Exemple #11
0
QPaintEngine* QGLPixmapData::paintEngine() const
{
    if (!isValid())
        return 0;

    if (m_renderFbo)
        return m_engine;

    if (useFramebufferObjects()) {
        extern QGLWidget* qt_gl_share_widget();

        if (!QGLContext::currentContext())
            qt_gl_share_widget()->makeCurrent();
        QGLShareContextScope ctx(qt_gl_share_widget()->context());

        QGLFramebufferObjectFormat format;
        format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
        format.setSamples(4);
        format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));

        m_renderFbo = qgl_fbo_pool()->acquire(size(), format);

        if (m_renderFbo) {
            if (!m_engine)
                m_engine = new QGL2PaintEngineEx;
            return m_engine;
        }

        qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
    }

    // If the application wants to paint into the QPixmap, we first
    // force it to QImage format and then paint into that.
    // This is simpler than juggling multiple GL contexts.
    const_cast<QGLPixmapData *>(this)->forceToImage();

    if (m_hasFillColor) {
        m_source.fill(PREMUL(m_fillColor.rgba()));
        m_hasFillColor = false;
    }
    return m_source.paintEngine();
}
void QGLPixmapData::ensureCreated() const
{
    if (!m_dirty)
        return;

    m_dirty = false;

    if (nativeImageHandleProvider && !nativeImageHandle)
        const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider();

    QGLShareContextScope ctx(qt_gl_share_widget()->context());
    m_ctx = ctx;

#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
    if (m_sgImage) {
        qt_resolve_eglimage_gl_extensions(ctx); // ensure initialized

        bool textureIsBound = false;
        GLuint newTextureId;

        EGLint imgAttr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
        EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display()
                                                , EGL_NO_CONTEXT
                                                , EGL_NATIVE_PIXMAP_KHR
                                                , (EGLClientBuffer)m_sgImage
                                                , imgAttr);

        glGenTextures(1, &newTextureId);
        glBindTexture( GL_TEXTURE_2D, newTextureId);

        if (image != EGL_NO_IMAGE_KHR) {
            glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
            GLint err = glGetError();
            if (err == GL_NO_ERROR)
                textureIsBound = true;

            QEgl::eglDestroyImageKHR(QEgl::display(), image);
        }

        if (textureIsBound) {
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

            m_texture.id = newTextureId;
            m_texture.boundPixmap = const_cast<QGLPixmapData*>(this);
            QGLSgImageTextureCleanup::cleanupForContext(m_ctx)->insert(m_texture.id, const_cast<QGLPixmapData*>(this));
        } else {
            qWarning("QGLPixmapData: Failed to create texture from a SgImage image of size %dx%d", w, h);
            glDeleteTextures(1, &newTextureId);
        }
    }
#endif
}
Exemple #13
0
void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture)
{
    // Very simple strategy at the moment: just destroy the texture.
    if (data)
        removeFromLRU(data);

    QGLWidget *shareWidget = qt_gl_share_widget();
    if (shareWidget) {
        QGLShareContextScope ctx(shareWidget->context());
        glDeleteTextures(1, &texture);
    }
}
QPaintEngine* QGLPixmapData::paintEngine() const
{
    if (!isValid())
        return 0;

    if (m_renderFbo)
        return m_engine;

    if (useFramebufferObjects()) {
        extern QGLWidget* qt_gl_share_widget();

        if (!QGLContext::currentContext())
            qt_gl_share_widget()->makeCurrent();
        QGLShareContextScope ctx(qt_gl_share_widget()->context());

        QGLFramebufferObjectFormat format;
        format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
        format.setSamples(4);
        format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));

        m_renderFbo = qgl_fbo_pool()->acquire(size(), format);

        if (m_renderFbo) {
            if (!m_engine)
                m_engine = new QGL2PaintEngineEx;
            return m_engine;
        }

        qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
    }

    m_dirty = true;
    if (m_source.size() != size())
        m_source = QImage(size(), QImage::Format_ARGB32_Premultiplied);
    if (m_hasFillColor) {
        m_source.fill(PREMUL(m_fillColor.rgba()));
        m_hasFillColor = false;
    }
    return m_source.paintEngine();
}
QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync)
{
    QGLShareContextScope ctx(qt_gl_share_widget()->context());
    QMeeGoExtensions::ensureInitialized();

    if (fenceSync) {
        QMeeGoExtensions::eglClientWaitSyncKHR(QEgl::display(),
                                               fenceSync,
                                               EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                               EGL_FOREVER_KHR);
    }

    void *data = 0;
    int pitch = 0;
    int surfaceWidth = 0;
    int surfaceHeight = 0;
    EGLSurface surface = 0;
    QImage::Format format;
    lockedImage = QImage();

    surface = getSurfaceForBackingPixmap();
    if (! QMeeGoExtensions::eglLockSurfaceKHR(QEgl::display(), surface, lock_attribs)) {
        qWarning("Failed to lock surface (live texture)!");
        return &lockedImage;
    }

    eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) &data);
    eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) &pitch);
    eglQuerySurface(QEgl::display(), surface, EGL_WIDTH, (EGLint*) &surfaceWidth);
    eglQuerySurface(QEgl::display(), surface, EGL_HEIGHT, (EGLint*) &surfaceHeight);

    // Ok, here we know we just support those two formats. Real solution would be:
    // query also the format.
    if (backingX11Pixmap->depth() > 16)
        format = QImage::Format_ARGB32_Premultiplied;
    else
        format = QImage::Format_RGB16;

    if (data == NULL || pitch == 0) {
        qWarning("Failed to query the live texture!");
        return &lockedImage;
    }

    if (width() != surfaceWidth || height() != surfaceHeight) {
        qWarning("Live texture dimensions don't match!");
        QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface);
        return &lockedImage;
    }

    lockedImage = QImage((uchar *) data, width(), height(), pitch, format);
    return &lockedImage;
}
QGLPixmapData::~QGLPixmapData()
{
    QGLWidget *shareWidget = qt_gl_share_widget();
    if (!shareWidget)
        return;

    delete m_engine;

    if (m_texture.id) {
        QGLShareContextScope ctx(shareWidget->context());
        glDeleteTextures(1, &m_texture.id);
    }
}
bool QMeeGoLivePixmapData::release(QImage* /*img*/)
{
    QGLShareContextScope ctx(qt_gl_share_widget()->context());
    QMeeGoExtensions::ensureInitialized();

    if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), getSurfaceForBackingPixmap())) {
        lockedImage = QImage();
        return true;
    } else {
        lockedImage = QImage();
        return false;
    }
}
bool QMeeGoPixmapData::destroyEGLSharedImage(Qt::HANDLE h)
{
    QGLShareContextScope ctx(qt_gl_share_widget()->context());   
    QMeeGoExtensions::ensureInitialized();

    QMutableHashIterator <void*, QMeeGoImageInfo*> i(sharedImagesMap);
    while (i.hasNext()) {
        i.next();
        if (i.value()->handle == h)
            i.remove();
    }

    return QMeeGoExtensions::eglDestroySharedImageNOK(QEgl::display(), (EGLNativeSharedImageTypeNOK) h);
}
Exemple #19
0
void QEglGLPixmapData::ensureCreated() const
{
    TRACE();
    if (!m_dirty)
        return;

    m_dirty = false;

    QGLShareContextScope ctx(qt_gl_share_widget()->context());
    m_ctx = ctx;

    const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB;
    const GLenum external_format = internal_format;
    const GLenum target = GL_TEXTURE_2D;

    TRACE();
    
    if (!m_texture.id) {

        TRACE();
        glGenTextures(1, &m_texture.id);
        glBindTexture(target, m_texture.id);
        glTexImage2D(target, 0, internal_format, w, h, 0, external_format, GL_UNSIGNED_BYTE, 0);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            
    }

    if (!m_source.isNull()) {
        TRACE();
        if (external_format == GL_RGB) {
            const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true);

            glBindTexture(target, m_texture.id);
            glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
                            GL_UNSIGNED_BYTE, tx.bits());
        } else {
            const QImage tx = m_ctx->d_func()->convertToGLFormat(m_source, true, external_format);

            glBindTexture(target, m_texture.id);
            glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
                            GL_UNSIGNED_BYTE, tx.bits());
        }

        m_source = QImage();
    }

    m_texture.options &= ~QGLContext::MemoryManagedBindOption;    
}
Exemple #20
0
void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
{
    if (si.isNull())
        qFatal("Trying to build pixmap with an empty/null softimage!");
        
    QGLShareContextScope ctx(qt_gl_share_widget()->context());
   
    QMeeGoExtensions::ensureInitialized();
 
    bool textureIsBound = false;
    GLuint newTextureId;
    GLint newWidth, newHeight;

    glGenTextures(1, &newTextureId);
    glBindTexture(GL_TEXTURE_2D, newTextureId);
    
    glFinish();
    EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_SHARED_IMAGE_NOK,
                                                (EGLClientBuffer)handle, preserved_image_attribs);

    if (image != EGL_NO_IMAGE_KHR) {
        glFinish();
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
        GLint err = glGetError();
        if (err == GL_NO_ERROR)
            textureIsBound = true;
        
        QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_WIDTH, &newWidth);
        QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_HEIGHT, &newHeight);
          
        QEgl::eglDestroyImageKHR(QEgl::display(), image);
        glFinish();
    }
        
    if (textureIsBound) {
        // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix
        // for QGLPixmapData.
        fromTexture(newTextureId, newWidth, newHeight, 
                    (si.hasAlphaChannel() && const_cast<QImage &>(si).data_ptr()->checkForAlphaPixels()));
        softImage = si;
        QMeeGoPixmapData::registerSharedImage(handle, softImage);
    } else {
        qWarning("Failed to create a texture from a shared image!");
        glDeleteTextures(1, &newTextureId);
    }
}
void QGLPixmapData::destroyTexture()
{
    if (m_texture.id) {
        QGLWidget *shareWidget = qt_gl_share_widget();
        if (shareWidget) {
            m_texture.options |= QGLContext::MemoryManagedBindOption;
            m_texture.freeTexture();
            m_texture.options &= ~QGLContext::MemoryManagedBindOption;
        } else if(QGLContext::currentContext()) {
            glDeleteTextures(1, &m_texture.id);
            m_texture.id = 0;
            m_texture.boundPixmap = 0;
            m_texture.boundKey = 0;
        }
        m_ctx = 0;
        m_dirty = true;
    }
}
QImage QGLPixmapData::toImage() const
{
    if (!isValid())
        return QImage();

    if (m_renderFbo) {
        copyBackFromRenderFbo(true);
    } else if (!m_source.isNull()) {
        return m_source;
    } else if (m_dirty || m_hasFillColor) {
        return fillImage(m_fillColor);
    } else {
        ensureCreated();
    }

    QGLShareContextScope ctx(qt_gl_share_widget()->context());
    glBindTexture(GL_TEXTURE_2D, m_texture.id);
    return qt_gl_read_texture(QSize(w, h), true, true);
}
bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
{
    // On Symbian, we usually want to treat QGLPixmapData as
    // raster pixmap data because that's well known and tested
    // execution path which is used on other platforms as well.
    // That's why if source pixels are valid we return false
    // to simulate raster pixmaps. Only QPixmaps created from
    // SgImage will enable usage of QGLPixmapData.
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
    if (m_sgImage) {
        // SgImage texture
        if (ctx == m_ctx)
            return true;

        const QGLContext *share_ctx = qt_gl_share_widget()->context();
        return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
    }
#endif
    return false;
}
Exemple #24
0
QEglGLPixmapData::~QEglGLPixmapData()
{
    TRACE();

    QGLWidget *shareWidget = qt_gl_share_widget();
    if (!shareWidget)
        return;

    delete m_engine;

    if (m_fbo) {
        QGLShareContextScope ctx(shareWidget->context());
        glDeleteFramebuffers(1, &m_fbo);
    }

    if (m_texture.id) {
        QGLShareContextScope ctx(shareWidget->context());
        glDeleteTextures(1, &m_texture.id);
    }    
}
Exemple #25
0
void QGLPixmapData::destroyTexture()
{
    if (inTexturePool) {
        QGLTexturePool *pool = QGLTexturePool::instance();
        if (m_texture.id)
            pool->releaseTexture(this, m_texture.id);
    } else {
        if (m_texture.id) {
            QGLWidget *shareWidget = qt_gl_share_widget();
            if (shareWidget) {
                QGLShareContextScope ctx(shareWidget->context());
                glDeleteTextures(1, &m_texture.id);
            }
        }
    }
    m_texture.id = 0;
    inTexturePool = false;

    releaseNativeImageHandle();
}
void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
{
    if (!isValid())
        return;

    m_hasFillColor = false;

    const QGLContext *share_ctx = qt_gl_share_widget()->context();
    QGLShareContextScope ctx(share_ctx);

    ensureCreated();

    if (!ctx->d_ptr->fbo)
        glGenFramebuffers(1, &ctx->d_ptr->fbo);

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
        GL_TEXTURE_2D, m_texture.id, 0);

    const int x0 = 0;
    const int x1 = w;
    const int y0 = 0;
    const int y1 = h;

    if (!m_renderFbo->isBound())
        glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());

    glDisable(GL_SCISSOR_TEST);

    glBlitFramebufferEXT(x0, y0, x1, y1,
            x0, y0, x1, y1,
            GL_COLOR_BUFFER_BIT,
            GL_NEAREST);

    if (keepCurrentFboBound) {
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    } else {
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle());
        ctx->d_ptr->current_fbo = m_renderFbo->handle();
    }
}
Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image)
{
    QGLShareContextScope ctx(qt_gl_share_widget()->context());

    QMeeGoExtensions::ensureInitialized();

    GLuint textureId;

    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) {
        void *converted = convertBGRA32_to_RGBA32(image.bits(), image.width(), image.height(), image.bytesPerLine());
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, converted);
        free(converted);
    } else {
        void *converted = convertRGB32_to_RGB565(image.bits(), image.width(), image.height(), image.bytesPerLine());
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, converted);
        free(converted);
    }

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);

    EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(),
                                                                                                EGL_GL_TEXTURE_2D_KHR,
                                                                                                (EGLClientBuffer) textureId,
                                                                                                preserved_image_attribs);
    glDeleteTextures(1, &textureId);
    if (eglimage) {
        EGLNativeSharedImageTypeNOK handle = QMeeGoExtensions::eglCreateSharedImageNOK(QEgl::display(), eglimage, NULL);
        QEgl::eglDestroyImageKHR(QEgl::display(), eglimage);
        return (Qt::HANDLE) handle;
    } else {
        qWarning("Failed to create shared image from pixmap/texture!");
        return 0;
    }
}
Exemple #28
0
void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect)
{
    if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) {
        QPixmapData::copy(data, rect);
        return;
    }

    const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data);
    if (other->m_renderFbo) {
        QGLShareContextScope ctx(qt_gl_share_widget()->context());

        resize(rect.width(), rect.height());
        m_hasAlpha = other->m_hasAlpha;
        ensureCreated();

        if (!ctx->d_ptr->fbo)
            glGenFramebuffers(1, &ctx->d_ptr->fbo);

        glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                GL_TEXTURE_2D, m_texture.id, 0);

        if (!other->m_renderFbo->isBound())
            glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle());

        glDisable(GL_SCISSOR_TEST);
        if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2)
            static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState();

        glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(),
                0, 0, w, h,
                GL_COLOR_BUFFER_BIT,
                GL_NEAREST);

        glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    } else {
        QPixmapData::copy(data, rect);
    }
}
bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
                             Qt::ImageConversionFlags flags)
{
    bool alpha;
    const char *buf = reinterpret_cast<const char *>(buffer);
    if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
        resize(0, 0);
        QGLShareContextScope ctx(qt_gl_share_widget()->context());
        QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
        if (!size.isEmpty()) {
            w = size.width();
            h = size.height();
            is_null = false;
            d = 32;
            m_hasAlpha = alpha;
            m_source = QImage();
            m_dirty = isValid();
            return true;
        }
    }
    return QPixmapData::fromData(buffer, len, format, flags);
}
Exemple #30
0
void QGLWidget::resizeEvent(QResizeEvent *e)
{
    Q_D(QGLWidget);
    if (!isValid())
        return;

    // Shared widget can ignore resize events which
    // may happen due to orientation change
    if (this == qt_gl_share_widget())
        return;

    if (!d->surfaceSizeInitialized || e->oldSize() != e->size()) {
        // On Symbian we need to recreate the surface on resize.
        d->recreateEglSurface();
        d->surfaceSizeInitialized = true;
    }

    makeCurrent();

    if (!d->glcx->initialized())
        glInit();

    resizeGL(width(), height());
}