summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-05-26 08:58:30 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-05-27 10:43:18 (GMT)
commit855022d6108f6b3c90832e742217c50550af717d (patch)
tree8cf799d7c939ee7cb9434cf1d3a100e898af6ce6 /src/opengl
parent15c8f565973592c9929cdd6fc83d61641aa63afa (diff)
downloadQt-855022d6108f6b3c90832e742217c50550af717d.zip
Qt-855022d6108f6b3c90832e742217c50550af717d.tar.gz
Qt-855022d6108f6b3c90832e742217c50550af717d.tar.bz2
Avoided expensive image upload for GL pixmap backend for QPixmap::fill.
In the fill case we can simply set a flag saying the pixmap needs to be filled, and then when painting on the pixmap we start by filling the background using glClear via the existing QGLDrawable::autoFillBackground interface.
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp8
-rw-r--r--src/opengl/qgl.cpp4
-rw-r--r--src/opengl/qpixmapdata_gl.cpp46
-rw-r--r--src/opengl/qpixmapdata_gl_p.h12
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