Mercurial > hg > svgui
comparison view/View.cpp @ 1490:c83504eb2649
Attempt a mechanism for the View to time-align a layer on display using an aligning version of the ViewProxy
author | Chris Cannam |
---|---|
date | Fri, 02 Aug 2019 16:44:32 +0100 |
parents | c3cc36c014b8 |
children | a2fbcfeb2572 |
comparison
equal
deleted
inserted
replaced
1489:b402121d8f5f | 1490:c83504eb2649 |
---|---|
69 m_cacheCentreFrame(0), | 69 m_cacheCentreFrame(0), |
70 m_cacheZoomLevel(ZoomLevel::FramesPerPixel, 1024), | 70 m_cacheZoomLevel(ZoomLevel::FramesPerPixel, 1024), |
71 m_selectionCached(false), | 71 m_selectionCached(false), |
72 m_deleting(false), | 72 m_deleting(false), |
73 m_haveSelectedLayer(false), | 73 m_haveSelectedLayer(false), |
74 m_useAligningProxy(false), | |
74 m_manager(nullptr), | 75 m_manager(nullptr), |
75 m_propertyContainer(new ViewPropertyContainer(this)) | 76 m_propertyContainer(new ViewPropertyContainer(this)) |
76 { | 77 { |
77 // cerr << "View::View(" << this << ")" << endl; | 78 // cerr << "View::View(" << this << ")" << endl; |
78 } | 79 } |
1347 } | 1348 } |
1348 | 1349 |
1349 ModelId | 1350 ModelId |
1350 View::getAligningModel() const | 1351 View::getAligningModel() const |
1351 { | 1352 { |
1353 ModelId aligning, reference; | |
1354 getAligningAndReferenceModels(aligning, reference); | |
1355 return aligning; | |
1356 } | |
1357 | |
1358 void | |
1359 View::getAligningAndReferenceModels(ModelId &aligning, | |
1360 ModelId &reference) const | |
1361 { | |
1352 if (!m_manager || | 1362 if (!m_manager || |
1353 !m_manager->getAlignMode() || | 1363 !m_manager->getAlignMode() || |
1354 m_manager->getPlaybackModel().isNone()) { | 1364 m_manager->getPlaybackModel().isNone()) { |
1355 return {}; | 1365 return; |
1356 } | 1366 } |
1357 | 1367 |
1358 ModelId anyModel; | 1368 ModelId anyModel; |
1359 ModelId alignedModel; | |
1360 ModelId goodModel; | |
1361 | 1369 |
1362 for (auto layer: m_layerStack) { | 1370 for (auto layer: m_layerStack) { |
1363 | 1371 |
1364 if (!layer) continue; | 1372 if (!layer) continue; |
1365 if (dynamic_cast<TimeRulerLayer *>(layer)) continue; | 1373 if (dynamic_cast<TimeRulerLayer *>(layer)) continue; |
1369 if (!model) continue; | 1377 if (!model) continue; |
1370 | 1378 |
1371 anyModel = thisId; | 1379 anyModel = thisId; |
1372 | 1380 |
1373 if (!model->getAlignmentReference().isNone()) { | 1381 if (!model->getAlignmentReference().isNone()) { |
1374 alignedModel = thisId; | 1382 |
1375 if (layer->isLayerOpaque() || | 1383 if (layer->isLayerOpaque() || |
1376 std::dynamic_pointer_cast | 1384 std::dynamic_pointer_cast |
1377 <RangeSummarisableTimeValueModel>(model)) { | 1385 <RangeSummarisableTimeValueModel>(model)) { |
1378 goodModel = thisId; | 1386 |
1379 } | 1387 aligning = thisId; |
1380 } | 1388 reference = model->getAlignmentReference(); |
1381 } | 1389 return; |
1382 | 1390 |
1383 if (!goodModel.isNone()) return goodModel; | 1391 } else if (aligning.isNone()) { |
1384 else if (!alignedModel.isNone()) return alignedModel; | 1392 |
1385 else return anyModel; | 1393 aligning = thisId; |
1394 reference = model->getAlignmentReference(); | |
1395 } | |
1396 } | |
1397 } | |
1398 | |
1399 if (aligning.isNone()) { | |
1400 aligning = anyModel; | |
1401 reference = {}; | |
1402 } | |
1386 } | 1403 } |
1387 | 1404 |
1388 sv_frame_t | 1405 sv_frame_t |
1389 View::alignFromReference(sv_frame_t f) const | 1406 View::alignFromReference(sv_frame_t f) const |
1390 { | 1407 { |
2130 // shouldUseCache is also false, then the scrollables can't | 2147 // shouldUseCache is also false, then the scrollables can't |
2131 // appear because they will only be on the cache | 2148 // appear because they will only be on the cache |
2132 throw std::logic_error("ERROR: shouldRepaintCache is true, but shouldUseCache is false: this can't lead to the correct result"); | 2149 throw std::logic_error("ERROR: shouldRepaintCache is true, but shouldUseCache is false: this can't lead to the correct result"); |
2133 } | 2150 } |
2134 | 2151 |
2152 // Create the ViewProxy for geometry provision, using the | |
2153 // device-pixel ratio for pixel-doubled hi-dpi rendering as | |
2154 // appropriate. | |
2155 | |
2156 ViewProxy proxy(this, dpratio); | |
2157 | |
2158 // Some layers may need an aligning proxy. If a layer's model has | |
2159 // a source model that is the reference model for the aligning | |
2160 // model, and the layer is tagged as to be aligned, then we use an | |
2161 // aligning proxy. | |
2162 | |
2163 ModelId alignmentModelId; | |
2164 ModelId alignmentReferenceId; | |
2165 auto aligningModel = ModelById::get(getAligningModel()); | |
2166 if (aligningModel) { | |
2167 alignmentModelId = aligningModel->getAlignment(); | |
2168 alignmentReferenceId = aligningModel->getAlignmentReference(); | |
2169 SVCERR << "alignmentModelId = " << alignmentModelId << " (reference = " << alignmentReferenceId << ")" << endl; | |
2170 } else { | |
2171 SVCERR << "no aligningModel" << endl; | |
2172 } | |
2173 ViewProxy aligningProxy(this, dpratio, alignmentModelId); | |
2174 | |
2135 // Scrollable (cacheable) items first. If we are repainting the | 2175 // Scrollable (cacheable) items first. If we are repainting the |
2136 // cache, then we paint these to the cache; otherwise straight to | 2176 // cache, then we paint these to the cache; otherwise straight to |
2137 // the buffer. | 2177 // the buffer. |
2138 | |
2139 ViewProxy proxy(this, dpratio); | |
2140 QRect areaToPaint; | 2178 QRect areaToPaint; |
2141 QPainter paint; | 2179 QPainter paint; |
2142 | 2180 |
2143 if (shouldRepaintCache) { | 2181 if (shouldRepaintCache) { |
2144 paint.begin(m_cache); | 2182 paint.begin(m_cache); |
2162 i != scrollables.end(); ++i) { | 2200 i != scrollables.end(); ++i) { |
2163 | 2201 |
2164 paint.setRenderHint(QPainter::Antialiasing, false); | 2202 paint.setRenderHint(QPainter::Antialiasing, false); |
2165 paint.save(); | 2203 paint.save(); |
2166 | 2204 |
2205 Layer *layer = *i; | |
2206 | |
2207 bool useAligningProxy = false; | |
2208 if (m_useAligningProxy) { | |
2209 if (layer->getModel() == alignmentReferenceId || | |
2210 layer->getSourceModel() == alignmentReferenceId) { | |
2211 useAligningProxy = true; | |
2212 } | |
2213 } | |
2214 | |
2167 #ifdef DEBUG_VIEW_WIDGET_PAINT | 2215 #ifdef DEBUG_VIEW_WIDGET_PAINT |
2168 cerr << "Painting scrollable layer " << *i << " using proxy with shouldRepaintCache = " << shouldRepaintCache << ", dpratio = " << dpratio << ", areaToPaint = " << areaToPaint.x() << "," << areaToPaint.y() << " " << areaToPaint.width() << "x" << areaToPaint.height() << endl; | 2216 cerr << "Painting scrollable layer " << layer << " (model " << layer->getModel() << ", source model " << layer->getSourceModel() << ") with shouldRepaintCache = " << shouldRepaintCache << ", useAligningProxy = " << useAligningProxy << ", dpratio = " << dpratio << ", areaToPaint = " << areaToPaint.x() << "," << areaToPaint.y() << " " << areaToPaint.width() << "x" << areaToPaint.height() << endl; |
2169 #endif | 2217 #endif |
2170 | 2218 |
2171 (*i)->paint(&proxy, paint, areaToPaint); | 2219 layer->paint(useAligningProxy ? &aligningProxy : &proxy, |
2220 paint, areaToPaint); | |
2172 | 2221 |
2173 paint.restore(); | 2222 paint.restore(); |
2174 } | 2223 } |
2175 | 2224 |
2176 paint.end(); | 2225 paint.end(); |
2202 paint.setPen(getForeground()); | 2251 paint.setPen(getForeground()); |
2203 paint.setBrush(Qt::NoBrush); | 2252 paint.setBrush(Qt::NoBrush); |
2204 | 2253 |
2205 for (LayerList::iterator i = nonScrollables.begin(); | 2254 for (LayerList::iterator i = nonScrollables.begin(); |
2206 i != nonScrollables.end(); ++i) { | 2255 i != nonScrollables.end(); ++i) { |
2207 | 2256 |
2208 // Profiler profiler2("View::paintEvent non-cacheable"); | 2257 Layer *layer = *i; |
2258 | |
2259 bool useAligningProxy = false; | |
2260 if (m_useAligningProxy) { | |
2261 if (layer->getModel() == alignmentReferenceId || | |
2262 layer->getSourceModel() == alignmentReferenceId) { | |
2263 useAligningProxy = true; | |
2264 } | |
2265 } | |
2266 | |
2209 #ifdef DEBUG_VIEW_WIDGET_PAINT | 2267 #ifdef DEBUG_VIEW_WIDGET_PAINT |
2210 cerr << "Painting non-scrollable layer " << *i << " without proxy with shouldRepaintCache = " << shouldRepaintCache << ", dpratio = " << dpratio << ", requestedPaintArea = " << requestedPaintArea.x() << "," << requestedPaintArea.y() << " " << requestedPaintArea.width() << "x" << requestedPaintArea.height() << endl; | 2268 cerr << "Painting non-scrollable layer " << layer << " (model " << layer->getModel() << ", source model " << layer->getSourceModel() << ") with shouldRepaintCache = " << shouldRepaintCache << ", useAligningProxy = " << useAligningProxy << ", dpratio = " << dpratio << ", requestedPaintArea = " << requestedPaintArea.x() << "," << requestedPaintArea.y() << " " << requestedPaintArea.width() << "x" << requestedPaintArea.height() << endl; |
2211 #endif | 2269 #endif |
2212 (*i)->paint(&proxy, paint, requestedPaintArea); | 2270 |
2271 layer->paint(useAligningProxy ? &aligningProxy : &proxy, | |
2272 paint, requestedPaintArea); | |
2213 } | 2273 } |
2214 | 2274 |
2215 paint.end(); | 2275 paint.end(); |
2216 | 2276 |
2217 // Now paint to widget from buffer: target rects from here on, | 2277 // Now paint to widget from buffer: target rects from here on, |