diff options
author | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-06-17 09:36:40 (GMT) |
---|---|---|
committer | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-06-17 09:44:48 (GMT) |
commit | fa8030a935acaacee570eee320e7510a4cfdc853 (patch) | |
tree | 51d48d56c94739aa569bb60f5ef6998da35ff110 /src/opengl | |
parent | 24580f35a58390b4177aef8edef1192dc05f8ac2 (diff) | |
download | Qt-fa8030a935acaacee570eee320e7510a4cfdc853.zip Qt-fa8030a935acaacee570eee320e7510a4cfdc853.tar.gz Qt-fa8030a935acaacee570eee320e7510a4cfdc853.tar.bz2 |
Speed up QPixmap::width(), height(), isNull() and depth().
This change moves the w, h, d variables to QPixmapData and introduces
is_null to keep track of nullness. This is possible only because
QPixmapData is internal API; otherwise we'd have to be smarter.
The optimization makes the QPixmap::width() function take 7 instructions,
down from 34 before. For the calculator demo in the declarative ui branch
this reduces a block of 750000 instructions (out of 30000000) to around
100000-150000 instructions.
Tested on Windows, Linux, Mac. Raster, X11 and OpenGL paint engines. Have
not tested the DirectFB engine.
Reviewed-by: Trond
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 60 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl_p.h | 7 |
2 files changed, 33 insertions, 34 deletions
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index f745aae..8a2187c 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -96,8 +96,6 @@ static int qt_gl_pixmap_serial = 0; QGLPixmapData::QGLPixmapData(PixelType type) : QPixmapData(type, OpenGLClass) - , m_width(0) - , m_height(0) , m_renderFbo(0) , m_textureId(0) , m_engine(0) @@ -123,7 +121,7 @@ QGLPixmapData::~QGLPixmapData() bool QGLPixmapData::isValid() const { - return m_width > 0 && m_height > 0; + return w > 0 && h > 0; } bool QGLPixmapData::isValidContext(const QGLContext *ctx) const @@ -137,7 +135,7 @@ bool QGLPixmapData::isValidContext(const QGLContext *ctx) const void QGLPixmapData::resize(int width, int height) { - if (width == m_width && height == m_height) + if (width == w && height == h) return; if (width <= 0 || height <= 0) { @@ -145,8 +143,10 @@ void QGLPixmapData::resize(int width, int height) height = 0; } - m_width = width; - m_height = height; + w = width; + h = height; + is_null = (w <= 0 || h <= 0); + d = pixelType() == QPixmapData::PixmapType ? 32 : 1; if (m_textureId) { QGLShareContextScope ctx(qt_gl_share_widget()->context()); @@ -176,7 +176,7 @@ void QGLPixmapData::ensureCreated() const glGenTextures(1, &m_textureId); glBindTexture(target, m_textureId); GLenum format = m_hasAlpha ? GL_RGBA : GL_RGB; - glTexImage2D(target, 0, format, m_width, m_height, 0, + glTexImage2D(target, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -186,7 +186,7 @@ void QGLPixmapData::ensureCreated() const const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, format); glBindTexture(target, m_textureId); - glTexSubImage2D(target, 0, 0, 0, m_width, m_height, format, + glTexSubImage2D(target, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits()); if (useFramebufferObjects()) @@ -202,7 +202,7 @@ QGLFramebufferObject *QGLPixmapData::fbo() const void QGLPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags) { - if (image.size() == QSize(m_width, m_height)) + if (image.size() == QSize(w, h)) setSerialNumber(++qt_gl_pixmap_serial); resize(image.width(), image.height()); @@ -218,6 +218,10 @@ void QGLPixmapData::fromImage(const QImage &image, m_hasFillColor = false; m_hasAlpha = image.hasAlphaChannel(); + w = image.width(); + h = image.height(); + is_null = (w <= 0 || h <= 0); + d = pixelType() == QPixmapData::PixmapType ? 32 : 1; if (m_textureId) { QGLShareContextScope ctx(qt_gl_share_widget()->context()); @@ -272,7 +276,7 @@ QImage QGLPixmapData::fillImage(const QColor &color) const { QImage img; if (pixelType() == BitmapType) { - img = QImage(m_width, m_height, QImage::Format_MonoLSB); + img = QImage(w, h, QImage::Format_MonoLSB); img.setNumColors(2); img.setColor(0, QColor(Qt::color0).rgba()); img.setColor(1, QColor(Qt::color1).rgba()); @@ -283,7 +287,7 @@ QImage QGLPixmapData::fillImage(const QColor &color) const else img.fill(1); } else { - img = QImage(m_width, m_height, + img = QImage(w, h, m_hasAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); @@ -310,7 +314,7 @@ QImage QGLPixmapData::toImage() const QGLShareContextScope ctx(qt_gl_share_widget()->context()); extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); glBindTexture(GL_TEXTURE_2D, m_textureId); - return qt_gl_read_texture(QSize(m_width, m_height), true, true); + return qt_gl_read_texture(QSize(w, h), true, true); } struct TextureBuffer @@ -342,9 +346,9 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const GL_TEXTURE_2D, m_textureId, 0); const int x0 = 0; - const int x1 = m_width; + const int x1 = w; const int y0 = 0; - const int y1 = m_height; + const int y1 = h; glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); @@ -424,15 +428,15 @@ QPaintEngine* QGLPixmapData::paintEngine() const textureBufferStack << createTextureBuffer(size()); } else { QSize sz = textureBufferStack.at(currentTextureBuffer).fbo->size(); - if (sz.width() < m_width || sz.height() < m_height) { - if (sz.width() < m_width) - sz.setWidth(qMax(m_width, qRound(sz.width() * 1.5))); - if (sz.height() < m_height) - sz.setHeight(qMax(m_height, qRound(sz.height() * 1.5))); + if (sz.width() < w || sz.height() < h) { + if (sz.width() < w) + sz.setWidth(qMax(w, qRound(sz.width() * 1.5))); + if (sz.height() < h) + sz.setHeight(qMax(h, qRound(sz.height() * 1.5))); // wasting too much space? - if (sz.width() * sz.height() > m_width * m_height * 2.5) - sz = QSize(m_width, m_height); + if (sz.width() * sz.height() > w * h * 2.5) + sz = QSize(w, h); delete textureBufferStack.at(currentTextureBuffer).fbo; textureBufferStack[currentTextureBuffer] = @@ -470,7 +474,7 @@ GLuint QGLPixmapData::bind(bool copyBack) const } else { if (m_hasFillColor) { m_dirty = true; - m_source = QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); + m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied); m_source.fill(PREMUL(m_fillColor.rgba())); m_hasFillColor = false; } @@ -493,22 +497,22 @@ extern int qt_defaultDpiY(); int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const { - if (m_width == 0) + if (w == 0) return 0; switch (metric) { case QPaintDevice::PdmWidth: - return m_width; + return w; case QPaintDevice::PdmHeight: - return m_height; + return h; case QPaintDevice::PdmNumColors: return 0; case QPaintDevice::PdmDepth: - return pixelType() == QPixmapData::PixmapType ? 32 : 1; + return d; case QPaintDevice::PdmWidthMM: - return qRound(m_width * 25.4 / qt_defaultDpiX()); + return qRound(w * 25.4 / qt_defaultDpiX()); case QPaintDevice::PdmHeightMM: - return qRound(m_height * 25.4 / qt_defaultDpiY()); + return qRound(h * 25.4 / qt_defaultDpiY()); case QPaintDevice::PdmDpiX: case QPaintDevice::PdmPhysicalDpiX: return qt_defaultDpiX(); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 605b25b..a6aa22d 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -94,9 +94,7 @@ public: 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; } + QSize size() const { return QSize(w, h); } QGLFramebufferObject *fbo() const; @@ -117,9 +115,6 @@ private: QImage fillImage(const QColor &color) const; - int m_width; - int m_height; - mutable QGLFramebufferObject *m_renderFbo; mutable GLuint m_textureId; mutable QPaintEngine *m_engine; |