|
21 | 21 |
|
22 | 22 | #include <drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx>
|
23 | 23 | #include <drawinglayer/geometry/viewinformation2d.hxx>
|
24 |
| - |
25 |
| -namespace |
26 |
| -{ |
27 |
| -class LocalCallbackTimer : public salhelper::Timer |
28 |
| -{ |
29 |
| -protected: |
30 |
| - drawinglayer::primitive2d::BufferedDecompositionGroupPrimitive2D* pCustomer; |
31 |
| - |
32 |
| -public: |
33 |
| - explicit LocalCallbackTimer( |
34 |
| - drawinglayer::primitive2d::BufferedDecompositionGroupPrimitive2D& rCustomer) |
35 |
| - : pCustomer(&rCustomer) |
36 |
| - { |
37 |
| - } |
38 |
| - |
39 |
| - void clearCallback() { pCustomer = nullptr; } |
40 |
| - |
41 |
| -protected: |
42 |
| - virtual void SAL_CALL onShot() override; |
43 |
| -}; |
44 |
| - |
45 |
| -void SAL_CALL LocalCallbackTimer::onShot() |
46 |
| -{ |
47 |
| - if (nullptr != pCustomer) |
48 |
| - flushBufferedDecomposition(*pCustomer); |
49 |
| -} |
50 |
| -} |
| 24 | +#include <drawinglayer/primitive2d/BufferedDecompositionFlusher.hxx> |
51 | 25 |
|
52 | 26 | namespace drawinglayer::primitive2d
|
53 | 27 | {
|
54 |
| -void flushBufferedDecomposition(BufferedDecompositionGroupPrimitive2D& rTarget) |
55 |
| -{ |
56 |
| - rTarget.acquire(); |
57 |
| - rTarget.setBuffered2DDecomposition(Primitive2DContainer()); |
58 |
| - rTarget.release(); |
59 |
| -} |
60 |
| - |
61 | 28 | bool BufferedDecompositionGroupPrimitive2D::hasBuffered2DDecomposition() const
|
62 | 29 | {
|
63 |
| - if (0 != maCallbackSeconds) |
64 |
| - { |
65 |
| - std::lock_guard Guard(maCallbackLock); |
| 30 | + if (!mbFlushOnTimer) |
66 | 31 | return !maBuffered2DDecomposition.empty();
|
67 |
| - } |
68 | 32 | else
|
69 | 33 | {
|
| 34 | + std::lock_guard Guard(maCallbackLock); |
70 | 35 | return !maBuffered2DDecomposition.empty();
|
71 | 36 | }
|
72 | 37 | }
|
73 | 38 |
|
74 | 39 | void BufferedDecompositionGroupPrimitive2D::setBuffered2DDecomposition(Primitive2DContainer&& rNew)
|
75 | 40 | {
|
76 |
| - if (0 == maCallbackSeconds) |
| 41 | + if (!mbFlushOnTimer) |
77 | 42 | {
|
78 | 43 | // no flush used, just set
|
79 | 44 | maBuffered2DDecomposition = std::move(rNew);
|
80 |
| - return; |
81 | 45 | }
|
82 |
| - |
83 |
| - if (maCallbackTimer.is()) |
84 |
| - { |
85 |
| - if (rNew.empty()) |
86 |
| - { |
87 |
| - // stop timer |
88 |
| - maCallbackTimer->stop(); |
89 |
| - } |
90 |
| - else |
91 |
| - { |
92 |
| - // decomposition changed, touch |
93 |
| - maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0)); |
94 |
| - if (!maCallbackTimer->isTicking()) |
95 |
| - maCallbackTimer->start(); |
96 |
| - } |
97 |
| - } |
98 |
| - else if (!rNew.empty()) |
| 46 | + else |
99 | 47 | {
|
100 |
| - // decomposition defined/set/changed, init & start timer |
101 |
| - maCallbackTimer.set(new LocalCallbackTimer(*this)); |
102 |
| - maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0)); |
103 |
| - maCallbackTimer->start(); |
104 |
| - } |
| 48 | + // decomposition changed, touch |
| 49 | + maLastAccess = std::chrono::steady_clock::now(); |
| 50 | + BufferedDecompositionFlusher::update(this); |
105 | 51 |
|
106 |
| - // tdf#158913 need to secure change when flush/multithreading is in use |
107 |
| - std::lock_guard Guard(maCallbackLock); |
108 |
| - maBuffered2DDecomposition = std::move(rNew); |
| 52 | + // tdf#158913 need to secure change when flush/multithreading is in use |
| 53 | + std::lock_guard Guard(maCallbackLock); |
| 54 | + maBuffered2DDecomposition = std::move(rNew); |
| 55 | + } |
109 | 56 | }
|
110 | 57 |
|
111 | 58 | BufferedDecompositionGroupPrimitive2D::BufferedDecompositionGroupPrimitive2D(
|
112 | 59 | Primitive2DContainer&& aChildren)
|
113 | 60 | : GroupPrimitive2D(std::move(aChildren))
|
114 |
| - , maCallbackTimer() |
115 | 61 | , maCallbackLock()
|
116 |
| - , maCallbackSeconds(0) |
| 62 | + , mbFlushOnTimer(false) |
117 | 63 | {
|
118 | 64 | }
|
119 | 65 |
|
120 |
| -BufferedDecompositionGroupPrimitive2D::~BufferedDecompositionGroupPrimitive2D() |
121 |
| -{ |
122 |
| - if (maCallbackTimer.is()) |
123 |
| - { |
124 |
| - // no more decomposition, end callback |
125 |
| - static_cast<LocalCallbackTimer*>(maCallbackTimer.get())->clearCallback(); |
126 |
| - maCallbackTimer->stop(); |
127 |
| - } |
128 |
| -} |
| 66 | +BufferedDecompositionGroupPrimitive2D::~BufferedDecompositionGroupPrimitive2D() {} |
129 | 67 |
|
130 | 68 | void BufferedDecompositionGroupPrimitive2D::get2DDecomposition(
|
131 | 69 | Primitive2DDecompositionVisitor& rVisitor,
|
132 | 70 | const geometry::ViewInformation2D& rViewInformation) const
|
133 | 71 | {
|
134 |
| - if (!hasBuffered2DDecomposition()) |
135 |
| - { |
136 |
| - Primitive2DContainer aNewSequence; |
137 |
| - create2DDecomposition(aNewSequence, rViewInformation); |
138 |
| - const_cast<BufferedDecompositionGroupPrimitive2D*>(this)->setBuffered2DDecomposition( |
139 |
| - std::move(aNewSequence)); |
140 |
| - } |
141 |
| - |
142 |
| - if (0 == maCallbackSeconds) |
| 72 | + if (!mbFlushOnTimer) |
143 | 73 | {
|
144 | 74 | // no flush/multithreading is in use, just call
|
| 75 | + if (maBuffered2DDecomposition.empty()) |
| 76 | + create2DDecomposition(maBuffered2DDecomposition, rViewInformation); |
145 | 77 | rVisitor.visit(maBuffered2DDecomposition);
|
146 |
| - return; |
147 | 78 | }
|
148 |
| - |
149 |
| - // decomposition was used, touch/restart time |
150 |
| - if (maCallbackTimer) |
151 |
| - maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0)); |
152 |
| - |
153 |
| - // tdf#158913 need to secure 'visit' when flush/multithreading is in use, |
154 |
| - // so that the local non-ref-Counted instance of the decomposition gets not |
155 |
| - // manipulated (e.g. deleted) |
156 |
| - std::lock_guard Guard(maCallbackLock); |
157 |
| - rVisitor.visit(maBuffered2DDecomposition); |
| 79 | + else |
| 80 | + { |
| 81 | + // tdf#158913 need to secure 'visit' when flush/multithreading is in use, |
| 82 | + // so that the local non-ref-Counted instance of the decomposition gets not |
| 83 | + // manipulated (e.g. deleted) |
| 84 | + Primitive2DContainer xTmp; |
| 85 | + { |
| 86 | + // only hold the lock for long enough to get a valid reference |
| 87 | + std::lock_guard Guard(maCallbackLock); |
| 88 | + maLastAccess = std::chrono::steady_clock::now(); |
| 89 | + if (maBuffered2DDecomposition.empty()) |
| 90 | + { |
| 91 | + create2DDecomposition(maBuffered2DDecomposition, rViewInformation); |
| 92 | + BufferedDecompositionFlusher::update(this); |
| 93 | + } |
| 94 | + xTmp = maBuffered2DDecomposition; |
| 95 | + } |
| 96 | + rVisitor.visit(xTmp); |
| 97 | + } |
158 | 98 | }
|
159 | 99 |
|
160 | 100 | } // end of namespace drawinglayer::primitive2d
|
|
0 commit comments