summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com>2009-06-17 09:36:40 (GMT)
committerAndreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com>2009-06-17 09:44:48 (GMT)
commitfa8030a935acaacee570eee320e7510a4cfdc853 (patch)
tree51d48d56c94739aa569bb60f5ef6998da35ff110
parent24580f35a58390b4177aef8edef1192dc05f8ac2 (diff)
downloadQt-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
-rw-r--r--src/gui/image/qpixmap.cpp2
-rw-r--r--src/gui/image/qpixmap.h6
-rw-r--r--src/gui/image/qpixmap_mac.cpp5
-rw-r--r--src/gui/image/qpixmap_mac_p.h1
-rw-r--r--src/gui/image/qpixmap_raster.cpp14
-rw-r--r--src/gui/image/qpixmap_x11.cpp10
-rw-r--r--src/gui/image/qpixmap_x11_p.h2
-rw-r--r--src/gui/image/qpixmapdata.cpp12
-rw-r--r--src/gui/image/qpixmapdata_p.h13
-rw-r--r--src/opengl/qpixmapdata_gl.cpp60
-rw-r--r--src/opengl/qpixmapdata_gl_p.h7
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp8
12 files changed, 88 insertions, 52 deletions
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 6da291c..56c3a29 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -552,7 +552,7 @@ bool QPixmap::isQBitmap() const
*/
bool QPixmap::isNull() const
{
- return data->width() == 0;
+ return data->isNull();
}
/*!
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index e4faebd..d1e2ecb 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -79,11 +79,11 @@ public:
QPixmap &operator=(const QPixmap &);
operator QVariant() const;
- bool isNull() const;
+ bool isNull() const; // ### Qt 5: make inline
int devType() const;
- int width() const;
- int height() const;
+ int width() const; // ### Qt 5: make inline
+ int height() const; // ### Qt 5: make inline
QSize size() const;
QRect rect() const;
int depth() const;
diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp
index ca9d497..b40694a 100644
--- a/src/gui/image/qpixmap_mac.cpp
+++ b/src/gui/image/qpixmap_mac.cpp
@@ -168,7 +168,7 @@ static inline QRgb qt_conv16ToRgb(ushort c) {
QSet<QMacPixmapData*> QMacPixmapData::validDataPointers;
QMacPixmapData::QMacPixmapData(PixelType type)
- : QPixmapData(type, MacClass), w(0), h(0), d(0), has_alpha(0), has_mask(0),
+ : QPixmapData(type, MacClass), has_alpha(0), has_mask(0),
uninit(true), pixels(0), pixelsToFree(0), bytesPerRow(0),
cg_data(0), cg_dataBeingReleased(0), cg_mask(0),
#ifndef QT_MAC_NO_QUICKDRAW
@@ -188,11 +188,13 @@ void QMacPixmapData::resize(int width, int height)
w = width;
h = height;
+ is_null = (w <= 0 || h <= 0);
d = (pixelType() == BitmapType ? 1 : 32);
bool make_null = w <= 0 || h <= 0; // create null pixmap
if (make_null || d == 0) {
w = 0;
h = 0;
+ is_null = true;
d = 0;
if (!make_null)
qWarning("Qt: QPixmap: Invalid pixmap parameters");
@@ -231,6 +233,7 @@ void QMacPixmapData::fromImage(const QImage &img,
w = img.width();
h = img.height();
+ is_null = (w <= 0 || h <= 0);
d = (pixelType() == BitmapType ? 1 : img.depth());
QImage image = img;
diff --git a/src/gui/image/qpixmap_mac_p.h b/src/gui/image/qpixmap_mac_p.h
index 66797ed..a3ff0d3 100644
--- a/src/gui/image/qpixmap_mac_p.h
+++ b/src/gui/image/qpixmap_mac_p.h
@@ -83,7 +83,6 @@ public:
QPaintEngine* paintEngine() const;
private:
- int w, h, d;
uint has_alpha : 1, has_mask : 1, uninit : 1;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 2c57ede..9cc896b 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -85,6 +85,10 @@ void QRasterPixmapData::resize(int width, int height)
#endif
image = QImage(width, height, format);
+ w = width;
+ h = height;
+ d = image.depth();
+ is_null = (w <= 0 || h <= 0);
if (pixelType() == BitmapType && !image.isNull()) {
image.setNumColors(2);
@@ -168,6 +172,10 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage,
}
}
#endif
+ w = image.d->width;
+ h = image.d->height;
+ d = image.d->depth;
+ is_null = (w <= 0 || h <= 0);
setSerialNumber(image.serialNumber());
}
@@ -329,9 +337,9 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
// override the image dpi with the screen dpi when rendering to a pixmap
switch (metric) {
case QPaintDevice::PdmWidth:
- return d->width;
+ return w;
case QPaintDevice::PdmHeight:
- return d->height;
+ return h;
case QPaintDevice::PdmWidthMM:
return qRound(d->width * 25.4 / qt_defaultDpiX());
case QPaintDevice::PdmHeightMM:
@@ -339,7 +347,7 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
case QPaintDevice::PdmNumColors:
return d->colortable.size();
case QPaintDevice::PdmDepth:
- return d->depth;
+ return this->d;
case QPaintDevice::PdmDpiX: // fall-through
case QPaintDevice::PdmPhysicalDpiX:
return qt_defaultDpiX();
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index b7fe92a..86cf515 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -312,7 +312,7 @@ static int qt_pixmap_serial = 0;
int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0;
QX11PixmapData::QX11PixmapData(PixelType type)
- : QPixmapData(type, X11Class), hd(0), w(0), h(0), d(0),
+ : QPixmapData(type, X11Class), hd(0),
uninit(true), read_only(false), x11_mask(0), picture(0), mask_picture(0), hd2(0),
share_mode(QPixmap::ImplicitlyShared), pengine(0)
{
@@ -324,6 +324,7 @@ void QX11PixmapData::resize(int width, int height)
w = width;
h = height;
+ is_null = (w <= 0 || h <= 0);
if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
QX11InfoData* xd = xinfo.getX11Data(true);
@@ -347,6 +348,7 @@ void QX11PixmapData::resize(int width, int height)
if (make_null || d == 0) {
w = 0;
h = 0;
+ is_null = true;
hd = 0;
picture = 0;
d = 0;
@@ -375,6 +377,7 @@ void QX11PixmapData::fromImage(const QImage &img,
w = img.width();
h = img.height();
d = img.depth();
+ is_null = (w <= 0 || h <= 0);
if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
QX11InfoData* xd = xinfo.getX11Data(true);
@@ -395,6 +398,7 @@ void QX11PixmapData::fromImage(const QImage &img,
if (uint(w) >= 32768 || uint(h) >= 32768) {
w = h = 0;
+ is_null = true;
return;
}
@@ -1109,6 +1113,7 @@ void QX11PixmapData::bitmapFromImage(const QImage &image)
w = img.width();
h = img.height();
d = 1;
+ is_null = (w <= 0 || h <= 0);
int bpl = (w + 7) / 8;
int ibpl = img.bytesPerLine();
if (bpl != ibpl) {
@@ -1876,6 +1881,7 @@ QPixmap QX11PixmapData::transformed(const QTransform &transform,
x11Data->d = d;
x11Data->w = w;
x11Data->h = h;
+ x11Data->is_null = (w <= 0 || h <= 0);
x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
RootWindow(X11->display, xinfo.screen()),
w, h, d);
@@ -2132,6 +2138,7 @@ void QX11PixmapData::copy(const QPixmapData *data, const QRect &rect)
d = x11Data->d;
w = rect.width();
h = rect.height();
+ is_null = (w <= 0 || h <= 0);
hd = (Qt::HANDLE)XCreatePixmap(X11->display,
RootWindow(X11->display, x11Data->xinfo.screen()),
w, h, d);
@@ -2250,6 +2257,7 @@ QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
data->uninit = false;
data->w = width;
data->h = height;
+ data->is_null = (width <= 0 || height <= 0);
data->d = depth;
data->hd = pixmap;
diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h
index addcc7c..3de9a0f 100644
--- a/src/gui/image/qpixmap_x11_p.h
+++ b/src/gui/image/qpixmap_x11_p.h
@@ -108,8 +108,6 @@ private:
Qt::HANDLE hd;
- int w, h;
- short d;
uint uninit : 1;
uint read_only : 1;
diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp
index 094d7e4..b50d664 100644
--- a/src/gui/image/qpixmapdata.cpp
+++ b/src/gui/image/qpixmapdata.cpp
@@ -49,9 +49,17 @@ const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80 };
QPixmapData::QPixmapData(PixelType pixelType, int objectId)
- : ref(0), detach_no(0), type(pixelType), id(objectId), ser_no(0), is_cached(false)
+ : w(0),
+ h(0),
+ d(0),
+ is_null(true),
+ ref(0),
+ detach_no(0),
+ type(pixelType),
+ id(objectId),
+ ser_no(0),
+ is_cached(false)
{
-
}
QPixmapData::~QPixmapData()
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 4c49dd2..29dafaf 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -99,13 +99,18 @@ public:
virtual QImage* buffer();
- int width() const { return metric(QPaintDevice::PdmWidth); }
- int height() const { return metric(QPaintDevice::PdmHeight); }
- int numColors() const { return metric(QPaintDevice::PdmNumColors); }
- int depth() const { return metric(QPaintDevice::PdmDepth); }
+ inline int width() const { return w; }
+ inline int height() const { return h; }
+ inline int numColors() const { return metric(QPaintDevice::PdmNumColors); }
+ inline int depth() const { return d; }
+ inline bool isNull() const { return is_null; }
protected:
void setSerialNumber(int serNo);
+ int w;
+ int h;
+ int d;
+ bool is_null;
private:
friend class QPixmap;
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;
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index c2048d8..c239248 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -82,6 +82,10 @@ void QDirectFBPixmapData::resize(int width, int height)
return;
}
+ w = width;
+ h = height;
+ is_null = (w <= 0 || h <= 0);
+ d = metric(QPaintDevice::PdmDepth);
setSerialNumber(++global_ser_no);
}
@@ -191,6 +195,10 @@ void QDirectFBPixmapData::fromImage(const QImage &i,
invalidate();
return;
}
+ w = metric(QPaintDevice::PdmWidth);
+ h = metric(QPaintDevice::PdmHeight);
+ is_null = (w <= 0 || h <= 0);
+ d = metric(QPaintDevice::PdmDepth);
setSerialNumber(++global_ser_no);
}