qgis_render_cache_v3.diff

Version 3 of my caching implementation - Tim Sutton, 2009-10-05 06:11 AM

Download (14.5 KB)

View differences:

src/app/qgsoptions.cpp (working copy)
149 149

  
150 150
  //set the state of the checkboxes
151 151
  chkAntiAliasing->setChecked( settings.value( "/qgis/enable_anti_aliasing", false ).toBool() );
152
  chkUseRenderCaching->setChecked( settings.value( "/qgis/enable_render_caching", false ).toBool() );
152 153

  
153 154
  // Slightly awkard here at the settings value is true to use QImage,
154 155
  // but the checkbox is true to use QPixmap
......
365 366
  settings.setValue( "/qgis/addPostgisDC", cbxAddPostgisDC->isChecked() );
366 367
  settings.setValue( "/qgis/new_layers_visible", chkAddedVisibility->isChecked() );
367 368
  settings.setValue( "/qgis/enable_anti_aliasing", chkAntiAliasing->isChecked() );
369
  settings.setValue( "/qgis/enable_render_caching", chkUseRenderCaching->isChecked() );
368 370
  settings.setValue( "/qgis/use_qimage_to_render", !( chkUseQPixmap->isChecked() ) );
369 371
  settings.setValue( "qgis/capitaliseLayerName", capitaliseCheckBox->isChecked() );
370 372
  settings.setValue( "qgis/askToSaveProjectChanges", chbAskToSaveProjectChanges->isChecked() );
......
530 532
  // used (we we can. but it then doesn't do anti-aliasing, and this
531 533
  // will confuse people).
532 534
  if ( chkAntiAliasing->isChecked() )
535
  {
533 536
    chkUseQPixmap->setChecked( false );
537
  }
534 538

  
535 539
}
536 540

  
......
540 544
  // used (we we can. but it then doesn't do anti-aliasing, and this
541 545
  // will confuse people).
542 546
  if ( chkUseQPixmap->isChecked() )
547
  {
543 548
    chkAntiAliasing->setChecked( false );
549
  }
544 550

  
545 551
}
546 552

  
src/app/qgsvectorlayerproperties.cpp (working copy)
673 673
  // update symbology
674 674
  emit refreshLegend( layer->getLayerID(), false );
675 675

  
676
  if ( layer->cachePixmap() )
677
  {
678
    //no need to delete the old one, maplayer will do it if needed
679
    layer->setCachePixmap( 0 );
680
  }
676 681
  layer->triggerRepaint();
677 682
  // notify the project we've made a change
678 683
  QgsProject::instance()->dirty( true );
src/core/qgsmaprenderer.h (working copy)
199 199

  
200 200
    //! current extent to be drawn
201 201
    QgsRectangle mExtent;
202
    //
203
    /** Last extent to we drew so we know if we can 
204
        used layer render caching or not. Note there are no
205
        accessors for this as it is intended to internal
206
        use only.
207
        @note added in QGIS 1.4 */
208
    QgsRectangle mLastExtent;
202 209

  
203 210
    //! indicates whether it's map image for overview
204 211
    bool mOverview;
src/core/qgsmaplayer.cpp (working copy)
75 75
  mMinScale = 0;
76 76
  mMaxScale = 100000000;
77 77
  mScaleBasedVisibility = false;
78
  mpCachePixmap = 0;
78 79
}
79 80

  
80 81

  
......
82 83
QgsMapLayer::~QgsMapLayer()
83 84
{
84 85
  delete mCRS;
86
  if ( mpCachePixmap ) 
87
  { 
88
    delete mpCachePixmap; 
89
  }  
85 90
}
86 91

  
87 92
QgsMapLayer::LayerType QgsMapLayer::type() const
......
729 734
{
730 735
  return &mUndoStack;
731 736
}
737

  
738
void QgsMapLayer::setCachePixmap( QPixmap * thepPixmap ) 
739
{ 
740
  QgsDebugMsg( "cache Pixmap set!" );
741
  if ( mpCachePixmap ) 
742
  { 
743
    delete mpCachePixmap; 
744
  }  
745
  mpCachePixmap = thepPixmap; 
746
}
src/core/qgsmaprenderer.cpp (working copy)
80 80

  
81 81
bool QgsMapRenderer::setExtent( const QgsRectangle& extent )
82 82
{
83
  //remember the previous extent
84
  mLastExtent = mExtent;
83 85

  
84 86
  // Don't allow zooms where the current extent is so small that it
85 87
  // can't be accurately represented using a double (which is what
......
207 209

  
208 210
void QgsMapRenderer::render( QPainter* painter )
209 211
{
212
  //flag to see if the render context has changed 
213
  //since the last time we rendered. If it hasnt changed we can
214
  //take some shortcuts with rendering
215
  bool mySameAsLastFlag = true;
216

  
210 217
  QgsDebugMsg( "========== Rendering ==========" );
211 218

  
212 219
  if ( mExtent.isEmpty() )
......
216 223
  }
217 224

  
218 225
  if ( mDrawing )
226
  {
219 227
    return;
228
  }
220 229

  
221 230
  QPaintDevice* thePaintDevice = painter->device();
222 231
  if ( !thePaintDevice )
......
251 260
    scaleFactor = sceneDpi / 25.4;
252 261
  }
253 262
  double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi;
254
  mRenderContext.setScaleFactor( scaleFactor );
255
  mRenderContext.setRasterScaleFactor( rasterScaleFactor );
256
  mRenderContext.setRendererScale( mScale );
263
  if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor )
264
  {
265
    mRenderContext.setRasterScaleFactor( rasterScaleFactor );
266
    mySameAsLastFlag = false;
267
  }
268
  if ( mRenderContext.scaleFactor() != scaleFactor )
269
  {
270
    mRenderContext.setScaleFactor( scaleFactor );
271
    mySameAsLastFlag = false;
272
  }
273
  if ( mRenderContext.rendererScale() != mScale )
274
  {
275
    //add map scale to render context
276
    mRenderContext.setRendererScale( mScale );
277
    mySameAsLastFlag = false;
278
  }
279
  if ( mLastExtent != mExtent )
280
  {
281
    mLastExtent = mExtent;
282
    mySameAsLastFlag = false;
283
  }
257 284

  
258 285
  bool placeOverlays = false;
259 286
  QgsOverlayObjectPositionManager* overlayManager = overlayManagerFromSettings();
......
263 290
    placeOverlays = true;
264 291
  }
265 292

  
266
  //add map scale to render context
267
  mRenderContext.setRendererScale( mScale );
268

  
269 293
  // render all layers in the stack, starting at the base
270 294
  QListIterator<QString> li( mLayerSet );
271 295
  li.toBack();
......
279 303
      break;
280 304
    }
281 305

  
306
    // Store the painter in case we need to swap it out for the 
307
    // cache painter
308
    QPainter * mypContextPainter = mRenderContext.painter();
309

  
282 310
    QString layerId = li.previous();
283 311

  
284 312
    QgsDebugMsg( "Rendering at layer item " + layerId );
......
377 405
        }
378 406
      }
379 407

  
408
      QSettings mySettings;
409
      if ( mySettings.value ( "/qgis/enable_render_caching", false ).toBool() )
410
      {
411
        if ( ( !mySameAsLastFlag || ml->cachePixmap() == 0 ) && !split ) //render caching does not yet cater for split extents
412
        {
413
          QPixmap * mypPixmap = new QPixmap( mRenderContext.painter()->device()->width(), 
414
              mRenderContext.painter()->device()->height() ); 
415
          mypPixmap->fill( QColor( 0,0,0,0 ) );
416
          ml->setCachePixmap( mypPixmap ); //no need to delete the oldone, maplayer does it for you
417
          QPainter * mypPainter = new QPainter( ml->cachePixmap() );
418
          if ( mySettings.value( "/qgis/enable_anti_aliasing", false ).toBool() )
419
          {
420
            mypPainter->setRenderHint( QPainter::Antialiasing );
421
          }
422
          mRenderContext.setPainter( mypPainter  );
423
        }
424
        else if ( mySameAsLastFlag && !split )
425
        {
426
          //always ensure the layers cache pixmap is initialised...
427
          if ( ! ml->cachePixmap() )
428
          {
429
            QPixmap * mypPixmap = new QPixmap( mRenderContext.painter()->device()->width(), 
430
                mRenderContext.painter()->device()->height() ); 
431
            mypPixmap->fill( QColor( 0,0,0,0 ) );
432
            ml->setCachePixmap( mypPixmap );
433
          }
434
          //draw from cached image
435
          mypContextPainter->drawPixmap( 0,0, *(ml->cachePixmap()) );
436
          disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
437
          //short circuit as there is nothing else to do...
438
          continue;
439
        }
440
      }
441

  
380 442
      if ( !ml->draw( mRenderContext ) )
381 443
      {
382 444
        emit drawError( ml );
......
397 459
        mRenderContext.painter()->restore();
398 460
      }
399 461

  
462
      //clean up from caching
463
      if ( mySettings.value ( "/qgis/enable_render_caching", false ).toBool() )
464
      {
465
        if ( !mySameAsLastFlag && !split )
466
        {
467
          //draw from cached image that we created further up
468
          mypContextPainter->drawPixmap( 0,0, *(ml->cachePixmap()) );
469
          // reinstate the painter as it was swapped out for caching
470
          delete mRenderContext.painter();
471
          mRenderContext.setPainter( mypContextPainter  );
472
        }
473
      }
400 474
      disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
401 475
    }
402
    else
476
    else // layer not visible
403 477
    {
478
      //clear the cache pixmap if we changed resolution / extent
479
      QSettings mySettings;
480
      if ( mySettings.value ( "/qgis/enable_render_caching", false ).toBool() )
481
      {
482
        if ( !mySameAsLastFlag )
483
        {
484
          delete ml->cachePixmap();
485
          ml->setCachePixmap( 0 );
486
        }
487
      }
404 488
      QgsDebugMsg( "Layer not rendered because it is not within the defined "
405
                   "visibility scale range" );
489
          "visibility scale range" );
406 490
    }
407 491

  
408 492
  } // while (li.hasPrevious())
src/core/qgsmaplayer.h (working copy)
24 24

  
25 25
#include <QObject>
26 26
#include <QUndoStack>
27
#include <QPixmap>
27 28

  
28 29
#include "qgsrectangle.h"
29 30

  
......
263 264
    /** Return pointer to layer's undo stack */
264 265
    QUndoStack* undoStack();
265 266

  
267
    /** Get the QPixmap used for caching render operations
268
     * @note This method was added in QGIS 1.4 **/
269
    QPixmap * cachePixmap() { return mpCachePixmap; }
270
    /** Set the QPixmap used for caching render operations 
271
     * @note This method was added in QGIS 1.4 **/
272
    void setCachePixmap( QPixmap * thepPixmap ); 
273

  
266 274
  public slots:
267 275

  
268 276
    /** Event handler for when a coordinate transform fails due to bad vertex error */
......
360 368
    /** A flag that tells us whether to use the above vars to restrict layer visibility */
361 369
    bool mScaleBasedVisibility;
362 370

  
371
    /** Collection of undoable operations for this layer. **/
363 372
    QUndoStack mUndoStack;
364 373

  
374
    /**QPixmap for caching of rendering operations
375
     * @note This property was added in QGIS 1.4 **/
376
    QPixmap * mpCachePixmap;
377

  
365 378
};
366 379

  
367 380
#endif
src/ui/qgsoptionsbase.ui (working copy)
13 13
   <string>Options</string>
14 14
  </property>
15 15
  <property name="windowIcon" >
16
   <iconset>
17
    <normaloff/>
18
   </iconset>
16
   <iconset/>
19 17
  </property>
20 18
  <property name="sizeGripEnabled" >
21 19
   <bool>true</bool>
......
195 193
           </widget>
196 194
          </item>
197 195
          <item row="1" column="0" colspan="2" >
198
           <spacer name="verticalSpacer">
199
            <property name="orientation">
196
           <spacer>
197
            <property name="orientation" >
200 198
             <enum>Qt::Vertical</enum>
201 199
            </property>
202
            <property name="sizeType">
200
            <property name="sizeType" >
203 201
             <enum>QSizePolicy::Fixed</enum>
204 202
            </property>
205
            <property name="sizeHint" stdset="0">
203
            <property name="sizeHint" >
206 204
             <size>
207 205
              <width>20</width>
208 206
              <height>10</height>
209 207
             </size>
210 208
            </property>
211 209
           </spacer>
212
          </item>          
210
          </item>
213 211
          <item row="2" column="0" colspan="2" >
214 212
           <widget class="QCheckBox" name="capitaliseCheckBox" >
215 213
            <property name="text" >
......
321 319
            </property>
322 320
           </widget>
323 321
          </item>
322
          <item row="3" column="0" colspan="2" >
323
           <widget class="QCheckBox" name="chkUseRenderCaching" >
324
            <property name="text" >
325
             <string>Use render caching where possible to speed up redraws</string>
326
            </property>
327
           </widget>
328
          </item>
324 329
         </layout>
325 330
        </widget>
326 331
       </item>
......
369 374
         </property>
370 375
         <property name="sizeHint" >
371 376
          <size>
372
           <width>20</width>
373
           <height>40</height>
377
           <width>614</width>
378
           <height>111</height>
374 379
          </size>
375 380
         </property>
376 381
        </spacer>
......
1308 1313
  </customwidget>
1309 1314
 </customwidgets>
1310 1315
 <tabstops>
1316
  <tabstop>tabWidget</tabstop>
1311 1317
  <tabstop>chbAskToSaveProjectChanges</tabstop>
1312 1318
  <tabstop>chbWarnOldProjectVersion</tabstop>
1313 1319
  <tabstop>pbnSelectionColour</tabstop>
1314 1320
  <tabstop>pbnCanvasColor</tabstop>
1315 1321
  <tabstop>cmbTheme</tabstop>
1316 1322
  <tabstop>capitaliseCheckBox</tabstop>
1323
  <tabstop>cbxLegendClassifiers</tabstop>
1317 1324
  <tabstop>cbxHideSplash</tabstop>
1325
  <tabstop>cbxIdentifyResultsDocked</tabstop>
1326
  <tabstop>cbxAttributeTableDocked</tabstop>
1327
  <tabstop>cbxAddPostgisDC</tabstop>
1318 1328
  <tabstop>chkAddedVisibility</tabstop>
1319 1329
  <tabstop>spinBoxUpdateThreshold</tabstop>
1330
  <tabstop>chkUseRenderCaching</tabstop>
1320 1331
  <tabstop>chkAntiAliasing</tabstop>
1321 1332
  <tabstop>chkUseQPixmap</tabstop>
1333
  <tabstop>cmbIdentifyMode</tabstop>
1322 1334
  <tabstop>spinBoxIdentifyValue</tabstop>
1323 1335
  <tabstop>cmbEllipsoid</tabstop>
1324 1336
  <tabstop>pbnMeasureColour</tabstop>
1337
  <tabstop>radMeters</tabstop>
1338
  <tabstop>radFeet</tabstop>
1325 1339
  <tabstop>cmbWheelAction</tabstop>
1326 1340
  <tabstop>spinZoomFactor</tabstop>
1341
  <tabstop>mOverlayAlgorithmComboBox</tabstop>
1327 1342
  <tabstop>mLineWidthSpinBox</tabstop>
1328 1343
  <tabstop>mLineColourToolButton</tabstop>
1329 1344
  <tabstop>mDefaultSnapModeComboBox</tabstop>
1330 1345
  <tabstop>mDefaultSnappingToleranceSpinBox</tabstop>
1331 1346
  <tabstop>mSearchRadiusVertexEditSpinBox</tabstop>
1347
  <tabstop>mDefaultSnappingToleranceComboBox</tabstop>
1348
  <tabstop>mSearchRadiusVertexEditComboBox</tabstop>
1349
  <tabstop>mMarkersOnlyForSelectedCheckBox</tabstop>
1332 1350
  <tabstop>mMarkerStyleComboBox</tabstop>
1351
  <tabstop>mMarkerSizeSpinBox</tabstop>
1352
  <tabstop>chkDisableAttributeValuesDlg</tabstop>
1333 1353
  <tabstop>radPromptForProjection</tabstop>
1334 1354
  <tabstop>radUseProjectProjection</tabstop>
1335 1355
  <tabstop>radUseGlobalProjection</tabstop>
......
1337 1357
  <tabstop>pbnSelectProjection</tabstop>
1338 1358
  <tabstop>grpLocale</tabstop>
1339 1359
  <tabstop>cboLocale</tabstop>
1360
  <tabstop>grpProxy</tabstop>
1361
  <tabstop>leProxyHost</tabstop>
1362
  <tabstop>leProxyPort</tabstop>
1363
  <tabstop>leProxyUser</tabstop>
1364
  <tabstop>leProxyPassword</tabstop>
1365
  <tabstop>mProxyTypeComboBox</tabstop>
1366
  <tabstop>mAddUrlPushButton</tabstop>
1367
  <tabstop>mRemoveUrlPushButton</tabstop>
1368
  <tabstop>mExcludeUrlListWidget</tabstop>
1340 1369
  <tabstop>buttonBox</tabstop>
1341
  <tabstop>tabWidget</tabstop>
1342 1370
 </tabstops>
1343 1371
 <resources/>
1344 1372
 <connections/>