diff options
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 8 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 4 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 46 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl_p.h | 12 |
4 files changed, 59 insertions, 11 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index a7c7426..aafa6de 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1095,7 +1095,13 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glDisable(GL_SCISSOR_TEST); QGLPixmapData *source = d->drawable.copyOnBegin(); - if (source) { + if (d->drawable.autoFillBackground()) { + QColor color = d->drawable.backgroundColor(); + + float alpha = color.alphaF(); + glClearColor(color.redF() * alpha, color.greenF() * alpha, color.blueF() * alpha, alpha); + glClear(GL_COLOR_BUFFER_BIT); + } else if (source) { d->transferMode(ImageDrawingMode); source->bind(false); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 62a592a..0be70d7 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4525,6 +4525,8 @@ QColor QGLDrawable::backgroundColor() const { if (widget) return widget->palette().brush(widget->backgroundRole()).color(); + else if (pixmapData) + return pixmapData->fillColor(); return QApplication::palette().brush(QPalette::Background).color(); } @@ -4547,6 +4549,8 @@ bool QGLDrawable::autoFillBackground() const { if (widget) return widget->autoFillBackground(); + else if (pixmapData) + return pixmapData->needsFill(); else return false; } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index c89b99b..85bcda5 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -103,6 +103,7 @@ QGLPixmapData::QGLPixmapData(PixelType type) , m_engine(0) , m_ctx(0) , m_dirty(false) + , m_hasFillColor(false) { setSerialNumber(++qt_gl_pixmap_serial); } @@ -196,6 +197,13 @@ void QGLPixmapData::fromImage(const QImage &image, resize(image.width(), image.height()); m_source = image; m_dirty = true; + m_hasFillColor = false; + + if (m_textureId) { + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + glDeleteTextures(1, &m_textureId); + m_textureId = 0; + } } bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) @@ -222,7 +230,11 @@ void QGLPixmapData::fill(const QColor &color) if (!isValid()) return; - if (!m_source.isNull()) { + if (useFramebufferObjects()) { + m_source = QImage(); + m_hasFillColor = true; + m_fillColor = color; + } else if (!m_source.isNull()) { m_source.fill(PREMUL(color.rgba())); } else { // ## TODO: improve performance here @@ -243,14 +255,18 @@ QImage QGLPixmapData::toImage() const if (!isValid()) return QImage(); - if (m_renderFbo) + if (m_renderFbo) { copyBackFromRenderFbo(true); - else if (!m_source.isNull()) + } else if (!m_source.isNull()) { return m_source; - else if (m_dirty) - return QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); - else + } else if (m_dirty || m_hasFillColor) { + QImage img(m_width, m_height, QImage::Format_ARGB32_Premultiplied); + if (m_hasFillColor) + img.fill(PREMUL(m_fillColor.rgba())); + return img; + } else { ensureCreated(); + } QGLShareContextScope ctx(qt_gl_share_widget()->context()); extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); @@ -272,6 +288,8 @@ 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); @@ -356,9 +374,12 @@ QPaintEngine* QGLPixmapData::paintEngine() const return m_engine; else if (!useFramebufferObjects()) { 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(); } @@ -394,10 +415,17 @@ QPaintEngine* QGLPixmapData::paintEngine() const GLuint QGLPixmapData::bind(bool copyBack) const { - if (m_renderFbo && copyBack) + if (m_renderFbo && copyBack) { copyBackFromRenderFbo(true); - else + } else { + if (m_hasFillColor) { + m_dirty = true; + m_source = QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); + m_source.fill(PREMUL(m_fillColor.rgba())); + m_hasFillColor = false; + } ensureCreated(); + } GLuint id = m_textureId; glBindTexture(GL_TEXTURE_2D, id); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 7e06db9..1b6b7ae 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -91,6 +91,9 @@ public: bool isUninitialized() const { return m_dirty && m_source.isNull(); } + bool needsFill() const { return m_hasFillColor; } + QColor fillColor() const { return m_fillColor; } + QSize size() const { return QSize(m_width, m_height); } int width() const { return m_width; } int height() const { return m_height; } @@ -119,8 +122,15 @@ private: mutable GLuint m_textureId; mutable QPaintEngine *m_engine; mutable QGLContext *m_ctx; - mutable bool m_dirty; mutable QImage m_source; + + // the texture is not in sync with the source image + mutable bool m_dirty; + + // fill has been called and no painting has been done, so the pixmap is + // represented by a single fill color + mutable QColor m_fillColor; + mutable bool m_hasFillColor; }; QT_END_NAMESPACE |