Skip to content

Commit e5674c6

Browse files
committed
Cache depth buffer average to improve performance
Previously the average could be computed on every mouse move event. This is a problem, since the loop can be slow, especially on debug builds where nothing gets inlined.
1 parent 0bf42b8 commit e5674c6

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/3d/qgscameracontroller.cpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ void QgsCameraController::readXml( const QDomElement &elem )
240240
setLookingAtPoint( QgsVector3D( x, elev, y ), dist, pitch, yaw );
241241
}
242242

243-
double QgsCameraController::sampleDepthBuffer( const QImage &buffer, int px, int py )
243+
double QgsCameraController::sampleDepthBuffer( int px, int py )
244244
{
245245
double depth = 1;
246246

@@ -249,24 +249,28 @@ double QgsCameraController::sampleDepthBuffer( const QImage &buffer, int px, int
249249
{
250250
for ( int y = py - 3; y <= py + 3; ++y )
251251
{
252-
if ( buffer.valid( x, y ) )
252+
if ( mDepthBufferImage.valid( x, y ) )
253253
{
254-
depth = std::min( depth, Qgs3DUtils::decodeDepth( buffer.pixel( x, y ) ) );
254+
depth = std::min( depth, Qgs3DUtils::decodeDepth( mDepthBufferImage.pixel( x, y ) ) );
255255
}
256256
}
257257
}
258258

259259
if ( depth < 1 )
260260
return depth;
261261

262+
// Cache the computed depth, since averaging over all pixels can be expensive
263+
if ( mDepthBufferNonVoidAverage != -1 )
264+
return mDepthBufferNonVoidAverage;
265+
262266
// Returns the average of depth values that are not 1 (void area)
263267
depth = 0;
264268
int samplesCount = 0;
265-
for ( int x = 0; x < buffer.width(); ++x )
269+
for ( int x = 0; x < mDepthBufferImage.width(); ++x )
266270
{
267-
for ( int y = 0; y < buffer.height(); ++y )
271+
for ( int y = 0; y < mDepthBufferImage.height(); ++y )
268272
{
269-
double d = Qgs3DUtils::decodeDepth( buffer.pixel( x, y ) );
273+
double d = Qgs3DUtils::decodeDepth( mDepthBufferImage.pixel( x, y ) );
270274
if ( d < 1 )
271275
{
272276
depth += d;
@@ -281,6 +285,8 @@ double QgsCameraController::sampleDepthBuffer( const QImage &buffer, int px, int
281285
else
282286
depth /= samplesCount;
283287

288+
mDepthBufferNonVoidAverage = depth;
289+
284290
return depth;
285291
}
286292

@@ -319,7 +325,7 @@ void QgsCameraController::onPositionChanged( Qt3DInput::QMouseEvent *mouse )
319325

320326
bool QgsCameraController::screenPointToWorldPos( QPoint position, Qt3DRender::QCamera *mCameraBefore, double &depth, QVector3D &worldPosition )
321327
{
322-
depth = sampleDepthBuffer( mDepthBufferImage, position.x(), position.y() );
328+
depth = sampleDepthBuffer( position.x(), position.y() );
323329
if ( !std::isfinite( depth ) )
324330
{
325331
QgsDebugMsgLevel( QStringLiteral( "screenPointToWorldPos: depth is NaN or Inf. This should not happen." ), 2 );
@@ -1026,6 +1032,7 @@ void QgsCameraController::depthBufferCaptured( const QImage &depthImage )
10261032
{
10271033
mDepthBufferImage = depthImage;
10281034
mDepthBufferIsReady = true;
1035+
mDepthBufferNonVoidAverage = -1;
10291036

10301037
if ( mCurrentOperation == MouseOperation::ZoomWheel )
10311038
{

src/3d/qgscameracontroller.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ class _3D_EXPORT QgsCameraController : public QObject
326326
* Returns the minimum depth value in the square [px - 3, px + 3] * [py - 3, py + 3]
327327
* If the value is 1, the average depth of all non void pixels is returned instead.
328328
*/
329-
double sampleDepthBuffer( const QImage &buffer, int px, int py );
329+
double sampleDepthBuffer( int px, int py );
330330

331331
#ifndef SIP_RUN
332332
//! Converts screen point to world position
@@ -350,6 +350,9 @@ class _3D_EXPORT QgsCameraController : public QObject
350350

351351
bool mDepthBufferIsReady = false;
352352
QImage mDepthBufferImage;
353+
// -1 when unset
354+
// TODO: Change to std::optional<double>
355+
double mDepthBufferNonVoidAverage;
353356

354357
std::unique_ptr<Qt3DRender::QCamera> mCameraBefore;
355358

0 commit comments

Comments
 (0)