summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2020-06-01 11:54:45 +0200
committerMarc Mutz <marc.mutz@kdab.com>2021-07-16 14:06:57 +0200
commit49df693145bbd94afd0b65a57c5b93d7773ff886 (patch)
treeacf735094aef96752a695c29cc9b2b355e22a9cd /src/gui
parented9effb62dd2f0d0a283ed783ba1e7c90e33e9d3 (diff)
QPainter: replace manual memory management [5/5]: d_ptrs
Replace a manually-managed pointer + size with QVarLengthArray, allowing use of pre-allocated space. Change-Id: Ife3abea0b3b0f2577bb76c348513d52d46f79641 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/painting/qpainter.cpp23
-rw-r--r--src/gui/painting/qpainter_p.h7
2 files changed, 10 insertions, 20 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 82a96960a8..31f8e40381 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -267,20 +267,8 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
// Save the current state of the shared painter and assign
// the current d_ptr to the shared painter's d_ptr.
sp->save();
- if (!sp->d_ptr->d_ptrs) {
- // Allocate space for 4 d-pointers (enough for up to 4 sub-sequent
- // redirections within the same paintEvent(), which should be enough
- // in 99% of all cases). E.g: A renders B which renders C which renders D.
- sp->d_ptr->d_ptrs_size = 4;
- sp->d_ptr->d_ptrs = (QPainterPrivate **)malloc(4 * sizeof(QPainterPrivate *));
- Q_CHECK_PTR(sp->d_ptr->d_ptrs);
- } else if (sp->d_ptr->refcount - 1 == sp->d_ptr->d_ptrs_size) {
- // However, to support corner cases we grow the array dynamically if needed.
- sp->d_ptr->d_ptrs_size <<= 1;
- const int newSize = sp->d_ptr->d_ptrs_size * sizeof(QPainterPrivate *);
- sp->d_ptr->d_ptrs = q_check_ptr((QPainterPrivate **)realloc(sp->d_ptr->d_ptrs, newSize));
- }
- sp->d_ptr->d_ptrs[++sp->d_ptr->refcount - 2] = q->d_ptr.data();
+ ++sp->d_ptr->refcount;
+ sp->d_ptr->d_ptrs.push_back(q->d_ptr.data());
q->d_ptr.take();
q->d_ptr.reset(sp->d_ptr.data());
@@ -325,7 +313,9 @@ void QPainterPrivate::detachPainterPrivate(QPainter *q)
Q_ASSERT(refcount > 1);
Q_ASSERT(q);
- QPainterPrivate *original = d_ptrs[--refcount - 1];
+ --refcount;
+ QPainterPrivate *original = d_ptrs.back();
+ d_ptrs.pop_back();
if (inDestructor) {
inDestructor = false;
if (original)
@@ -334,7 +324,6 @@ void QPainterPrivate::detachPainterPrivate(QPainter *q)
original = new QPainterPrivate(q);
}
- d_ptrs[refcount - 1] = nullptr;
q->restore();
q->d_ptr.take();
q->d_ptr.reset(original);
@@ -1515,8 +1504,6 @@ QPainter::~QPainter()
Q_ASSERT(d_ptr->inDestructor);
d_ptr->inDestructor = false;
Q_ASSERT(d_ptr->refcount == 1);
- if (d_ptr->d_ptrs)
- free(d_ptr->d_ptrs);
}
}
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 09de84f2b2..7f5fe1a6c5 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -198,7 +198,11 @@ public:
~QPainterPrivate();
QPainter *q_ptr;
- QPainterPrivate **d_ptrs = nullptr;
+ // Allocate space for 4 d-pointers (enough for up to 4 sub-sequent
+ // redirections within the same paintEvent(), which should be enough
+ // in 99% of all cases). E.g: A renders B which renders C which renders D.
+ static constexpr qsizetype NDPtrs = 4;
+ QVarLengthArray<QPainterPrivate*, NDPtrs> d_ptrs;
std::unique_ptr<QPainterState> state;
template <typename T, std::size_t N = 8>
@@ -212,7 +216,6 @@ public:
QTransform invMatrix;
uint txinv:1;
uint inDestructor : 1;
- uint d_ptrs_size = 0;
uint refcount = 1;
enum DrawOperation { StrokeDraw = 0x1,