// If copyBack is true, bind will copy the contents of the render // FBO to the texture (which is not bound to the texture, as it's // a multisample FBO). GLuint QGLPixmapData::bind(bool copyBack) const { if (m_renderFbo && copyBack) { copyBackFromRenderFbo(true); } else { ensureCreated(); } GLuint id = m_texture.id; glBindTexture(GL_TEXTURE_2D, id); if (m_hasFillColor) { if (!useFramebufferObjects()) { m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied); m_source.fill(PREMUL(m_fillColor.rgba())); } m_hasFillColor = false; GLenum format = qt_gl_preferredTextureFormat(); QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits()); } return id; }
QImage QGLPixmapData::toImage() const { if (!isValid()) return QImage(); if (m_renderFbo) { copyBackFromRenderFbo(true); } else if (!m_source.isNull()) { QImageData *data = const_cast<QImage &>(m_source).data_ptr(); if (data->paintEngine && data->paintEngine->isActive() && data->paintEngine->paintDevice() == &m_source) { return m_source.copy(); } return m_source; } else if (m_dirty || m_hasFillColor) { return fillImage(m_fillColor); } else { ensureCreated(); } QGLShareContextScope ctx(qt_gl_share_context()); glBindTexture(GL_TEXTURE_2D, m_texture.id); return qt_gl_read_texture(QSize(w, h), true, true); }
QPaintEngine* QEglGLPixmapData::paintEngine() const { TRACE(); if (!isValid()) return 0; TRACE(); if (m_fbo) return m_engine; ensureCreated(); TRACE(); QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); glGenFramebuffers(1, &m_fbo); glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo); glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture.id, 0); int status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { printf("FBO generation failed with error: 0x%08x\n", status); return 0; } TRACE(); m_engine = new QGL2PaintEngineEx; return m_engine; }
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 QMeeGoPixmapData::updateFromSoftImage() { m_dirty = true; m_source = softImage; ensureCreated(); if (softImage.width() != w || softImage.height() != h) qWarning("Ooops, looks like softImage changed dimensions since last updated! Corruption ahead?!"); }
void QMeeGoPixmapData::updateFromSoftImage() { // FIXME That's broken with recent 16bit textures changes. m_dirty = true; m_source = softImage; ensureCreated(); if (softImage.width() != w || softImage.height() != h) qWarning("Ooops, looks like softImage changed dimensions since last updated! Corruption ahead?!"); }
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; } }
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); }
GLuint QEglGLPixmapData::bind() const { TRACE(); ensureCreated(); GLuint id = m_texture.id; glBindTexture(GL_TEXTURE_2D, id); if (m_hasFillColor) { m_hasFillColor = false; const GLenum format = GL_RGBA; QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits()); } return id; }
void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const { if (!isValid()) return; m_hasFillColor = false; const QGLContext *share_ctx = qt_gl_share_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(); } }
GLuint QGLPixmapData::bind(bool copyBack) const { ensureCreated(); GLuint id = m_texture.id; glBindTexture(GL_TEXTURE_2D, id); if (m_hasFillColor) { m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied); m_source.fill(PREMUL(m_fillColor.rgba())); m_hasFillColor = false; GLenum format = qt_gl_preferredTextureFormat(); QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.constBits()); } return id; }
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_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); } }
QGLContext* QEglGLPixmapData::context() const { ensureCreated(); return m_ctx; }