summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2009-09-07 10:18:46 +1000
committerRhys Weatherley <rhys.weatherley@nokia.com>2009-09-07 10:18:46 +1000
commit6d908473ec1a8c72f4bbb9d772e801024c3a62a0 (patch)
tree235c45a19bbc22d0885ad2eb9b6978731e78569d
parent203158b2444c9eb98714292d057c0c87a037ce3b (diff)
Performance: Convert QGLFormat to use implicit sharing
QGLFormat was being deep-copied many times per frame because of code like this: if (context()->format().doubleBuffer()) { ... This change modifies QGLFormat to use implicit sharing to reduce the overhead of the above type of checks. Reviewed-by: Sarah Smith
-rw-r--r--src/opengl/qgl.cpp38
-rw-r--r--src/opengl/qgl.h4
-rw-r--r--src/opengl/qgl_p.h21
3 files changed, 56 insertions, 7 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index ef0744742d..aa67677855 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -349,13 +349,26 @@ QGLFormat::QGLFormat(QGL::FormatOptions options, int plane)
}
/*!
+ \internal
+*/
+void QGLFormat::detach()
+{
+ if (d->ref != 1) {
+ QGLFormatPrivate *newd = new QGLFormatPrivate(d);
+ if (!d->ref.deref())
+ delete d;
+ d = newd;
+ }
+}
+
+/*!
Constructs a copy of \a other.
*/
QGLFormat::QGLFormat(const QGLFormat &other)
{
- d = new QGLFormatPrivate;
- *d = *other.d;
+ d = other.d;
+ d->ref.ref();
}
/*!
@@ -364,7 +377,12 @@ QGLFormat::QGLFormat(const QGLFormat &other)
QGLFormat &QGLFormat::operator=(const QGLFormat &other)
{
- *d = *other.d;
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = other.d;
+ }
return *this;
}
@@ -373,7 +391,8 @@ QGLFormat &QGLFormat::operator=(const QGLFormat &other)
*/
QGLFormat::~QGLFormat()
{
- delete d;
+ if (!d->ref.deref())
+ delete d;
}
/*!
@@ -649,6 +668,7 @@ int QGLFormat::samples() const
*/
void QGLFormat::setSamples(int numSamples)
{
+ detach();
if (numSamples < 0) {
qWarning("QGLFormat::setSamples: Cannot have negative number of samples per pixel %d", numSamples);
return;
@@ -676,6 +696,7 @@ void QGLFormat::setSamples(int numSamples)
*/
void QGLFormat::setSwapInterval(int interval)
{
+ detach();
d->swapInterval = interval;
}
@@ -743,6 +764,7 @@ int QGLFormat::plane() const
*/
void QGLFormat::setPlane(int plane)
{
+ detach();
d->pln = plane;
}
@@ -754,6 +776,7 @@ void QGLFormat::setPlane(int plane)
void QGLFormat::setOption(QGL::FormatOptions opt)
{
+ detach();
if (opt & 0xffff)
d->opts |= opt;
else
@@ -783,6 +806,7 @@ bool QGLFormat::testOption(QGL::FormatOptions opt) const
*/
void QGLFormat::setDepthBufferSize(int size)
{
+ detach();
if (size < 0) {
qWarning("QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size %d", size);
return;
@@ -809,6 +833,7 @@ int QGLFormat::depthBufferSize() const
*/
void QGLFormat::setRedBufferSize(int size)
{
+ detach();
if (size < 0) {
qWarning("QGLFormat::setRedBufferSize: Cannot set negative red buffer size %d", size);
return;
@@ -837,6 +862,7 @@ int QGLFormat::redBufferSize() const
*/
void QGLFormat::setGreenBufferSize(int size)
{
+ detach();
if (size < 0) {
qWarning("QGLFormat::setGreenBufferSize: Cannot set negative green buffer size %d", size);
return;
@@ -865,6 +891,7 @@ int QGLFormat::greenBufferSize() const
*/
void QGLFormat::setBlueBufferSize(int size)
{
+ detach();
if (size < 0) {
qWarning("QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size %d", size);
return;
@@ -892,6 +919,7 @@ int QGLFormat::blueBufferSize() const
*/
void QGLFormat::setAlphaBufferSize(int size)
{
+ detach();
if (size < 0) {
qWarning("QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size %d", size);
return;
@@ -918,6 +946,7 @@ int QGLFormat::alphaBufferSize() const
*/
void QGLFormat::setAccumBufferSize(int size)
{
+ detach();
if (size < 0) {
qWarning("QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size %d", size);
return;
@@ -942,6 +971,7 @@ int QGLFormat::accumBufferSize() const
*/
void QGLFormat::setStencilBufferSize(int size)
{
+ detach();
if (size < 0) {
qWarning("QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size %d", size);
return;
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 89f167677f..0d724691de 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -255,6 +255,8 @@ public:
private:
QGLFormatPrivate *d;
+ void detach();
+
friend Q_OPENGL_EXPORT bool operator==(const QGLFormat&, const QGLFormat&);
friend Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&);
};
@@ -277,7 +279,6 @@ public:
bool isSharing() const;
void reset();
- // ### Qt 5: make format() return a const ref instead
QGLFormat format() const;
QGLFormat requestedFormat() const;
void setFormat(const QGLFormat& format);
@@ -443,7 +444,6 @@ public:
bool doubleBuffer() const;
void swapBuffers();
- // ### Qt 5: make format() return a const ref instead
QGLFormat format() const;
void setFormat(const QGLFormat& format);
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 72ec35e162..d4b75979a3 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -59,6 +59,7 @@
#include "QtCore/qthread.h"
#include "QtCore/qthreadstorage.h"
#include "QtCore/qhash.h"
+#include "QtCore/qatomic.h"
#include "private/qwidget_p.h"
#include "qcache.h"
@@ -127,7 +128,9 @@ QT_END_INCLUDE_NAMESPACE
class QGLFormatPrivate
{
public:
- QGLFormatPrivate() {
+ QGLFormatPrivate()
+ : ref(1)
+ {
opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering | QGL::StencilBuffer;
#if defined(QT_OPENGL_ES_2)
opts |= QGL::SampleBuffers;
@@ -137,6 +140,22 @@ public:
numSamples = -1;
swapInterval = -1;
}
+ QGLFormatPrivate(const QGLFormatPrivate *other)
+ : ref(1),
+ opts(other->opts),
+ pln(other->pln),
+ depthSize(other->depthSize),
+ accumSize(other->accumSize),
+ stencilSize(other->stencilSize),
+ redSize(other->redSize),
+ greenSize(other->greenSize),
+ blueSize(other->blueSize),
+ alphaSize(other->alphaSize),
+ numSamples(other->numSamples),
+ swapInterval(other->swapInterval)
+ {
+ }
+ QAtomicInt ref;
QGL::FormatOptions opts;
int pln;
int depthSize;