qgis_rendercachepatch_v7_23Oct2009.diff

Added missing sip / python bindings - Tim Sutton, 2009-10-23 03:30 PM

Download (19.8 KB)

View differences:

python/core/qgsmaplayer.sip (working copy)
252 252
    /** Return pointer to layer's undo stack */
253 253
    QUndoStack* undoStack();
254 254

  
255
    /** Get the QImage used for caching render operations
256
     * @note This method was added in QGIS 1.4 **/
257
    QImage * cacheImage() { return mpCacheImage; }
258
    /** Set the QImage used for caching render operations 
259
     * @note This method was added in QGIS 1.4 **/
260
    void setCacheImage( QImage * thepImage ); 
261

  
255 262
public slots:
256 263

  
257 264
    /** Event handler for when a coordinate transform fails due to bad vertex error */
python/core/qgsmaplayerregistry.sip (working copy)
59 59
 */
60 60
 void removeAllMapLayers();
61 61

  
62
 /* Clears all layer caches, resetting them to zero and 
63
 * freeing up any memory they may have been using. Layer
64
 * caches are used to speed up rendering in certain situations
65
 * see ticket #1974 for more details.
66
 * @note this method was added in QGIS 1.4
67
 */
68
 void clearAllLayerCaches();
69

  
62 70
signals:
63 71

  
64 72
    /** emitted when a layer is removed from the registry
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)
658 658
  // update symbology
659 659
  emit refreshLegend( layer->getLayerID(), false );
660 660

  
661
  if ( layer->cacheImage() )
662
  {
663
    //no need to delete the old one, maplayer will do it if needed
664
    layer->setCacheImage( 0 );
665
  }
661 666
  layer->triggerRepaint();
662 667
  // notify the project we've made a change
663 668
  QgsProject::instance()->dirty( true );
src/app/qgisapp.cpp (working copy)
4476 4476

  
4477 4477
void QgisApp::refreshMapCanvas()
4478 4478
{
4479
  //clear all caches first
4480
  QgsMapLayerRegistry::instance()->clearAllLayerCaches();
4481
  //then refresh
4479 4482
  mMapCanvas->refresh();
4480 4483
}
4481 4484

  
src/core/qgsvectorlayer.cpp (working copy)
2768 2768
bool QgsVectorLayer::commitChanges()
2769 2769
{
2770 2770
  bool success = true;
2771
  
2772
  //clear the cache image so markers dont appear anymore on next draw
2773
  setCacheImage( 0 );
2771 2774

  
2772 2775
  mCommitErrors.clear();
2773 2776

  
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
  mpCacheImage = 0;
78 79
}
79 80

  
80 81

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

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

  
738
void QgsMapLayer::setCacheImage( QImage * thepImage ) 
739
{ 
740
  QgsDebugMsg( "cache Image set!" );
741
  if ( mpCacheImage ) 
742
  { 
743
    delete mpCacheImage; 
744
  }  
745
  mpCacheImage = thepImage; 
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

  
285
  // know we know if this render is just a repeat of the last time, we 
286
  // can clear caches if it has changed
287
  if ( !mySameAsLastFlag )
288
  {
289
      //clear the cache pixmap if we changed resolution / extent
290
      QSettings mySettings;
291
      if ( mySettings.value ( "/qgis/enable_render_caching", false ).toBool() )
292
      {
293
        QgsMapLayerRegistry::instance()->clearAllLayerCaches();
294
      }
295
  }
296

  
258 297
  bool placeOverlays = false;
259 298
  QgsOverlayObjectPositionManager* overlayManager = overlayManagerFromSettings();
260 299
  QList<QgsVectorOverlay*> allOverlayList; //list of all overlays, used to draw them after layers have been rendered
......
263 302
    placeOverlays = true;
264 303
  }
265 304

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

  
269 305
  // render all layers in the stack, starting at the base
270 306
  QListIterator<QString> li( mLayerSet );
271 307
  li.toBack();
......
279 315
      break;
280 316
    }
281 317

  
318
    // Store the painter in case we need to swap it out for the 
319
    // cache painter
320
    QPainter * mypContextPainter = mRenderContext.painter();
321

  
282 322
    QString layerId = li.previous();
283 323

  
284 324
    QgsDebugMsg( "Rendering at layer item " + layerId );
......
343 383
      }
344 384

  
345 385

  
346
      if ( scaleRaster )
347
      {
348
        bk_mapToPixel = mRenderContext.mapToPixel();
349
        rasterMapToPixel = mRenderContext.mapToPixel();
350
        rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor );
351
        rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor );
352
        mRenderContext.setMapToPixel( rasterMapToPixel );
353
        mRenderContext.painter()->save();
354
        mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
355
      }
356

  
357 386
      //create overlay objects for features within the view extent
358 387
      if ( ml->type() == QgsMapLayer::VectorLayer && overlayManager )
359 388
      {
......
377 406
        }
378 407
      }
379 408

  
409
      // Force render of layers that are being edited
410
      if ( ml->type() == QgsMapLayer::VectorLayer )
411
      {
412
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
413
        if ( vl->isEditable() )
414
        {
415
          ml->setCacheImage( 0 );
416
        }
417
      }
418
        
419
      QSettings mySettings;
420
      if ( ! split )//render caching does not yet cater for split extents
421
      {
422
        if ( mySettings.value ( "/qgis/enable_render_caching", false ).toBool() )
423
        {
424
          if ( !mySameAsLastFlag || ml->cacheImage() == 0 ) 
425
          {
426
            QgsDebugMsg( "\n\n\nCaching enabled but layer redraw forced by extent change or empty cache\n\n\n" );
427
            QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(), 
428
                mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 ); 
429
            mypImage->fill( 0 );
430
            ml->setCacheImage( mypImage ); //no need to delete the oldone, maplayer does it for you
431
            QPainter * mypPainter = new QPainter( ml->cacheImage() );
432
            if ( mySettings.value( "/qgis/enable_anti_aliasing", false ).toBool() )
433
            {
434
              mypPainter->setRenderHint( QPainter::Antialiasing );
435
            }
436
            mRenderContext.setPainter( mypPainter  );
437
          }
438
          else if ( mySameAsLastFlag )
439
          {
440
            //draw from cached image
441
            QgsDebugMsg( "\n\n\nCaching enabled --- drawing layer from cached image\n\n\n" );
442
            mypContextPainter->drawImage( 0,0, *(ml->cacheImage()) );
443
            disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
444
            //short circuit as there is nothing else to do...
445
            continue;
446
          }
447
        }
448
      }
449

  
450
      if ( scaleRaster )
451
      {
452
        bk_mapToPixel = mRenderContext.mapToPixel();
453
        rasterMapToPixel = mRenderContext.mapToPixel();
454
        rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor );
455
        rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor );
456
        mRenderContext.setMapToPixel( rasterMapToPixel );
457
        mRenderContext.painter()->save();
458
        mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
459
      }
460

  
461

  
380 462
      if ( !ml->draw( mRenderContext ) )
381 463
      {
382 464
        emit drawError( ml );
383 465
      }
384

  
466
      else
467
      {
468
            QgsDebugMsg( "\n\n\nLayer rendered without issues\n\n\n" );
469
      }
385 470
      if ( split )
386 471
      {
387 472
        mRenderContext.setExtent( r2 );
......
397 482
        mRenderContext.painter()->restore();
398 483
      }
399 484

  
485
      if ( mySettings.value ( "/qgis/enable_render_caching", false ).toBool() )
486
      {
487
        if ( !split )
488
        {
489
          // composite the cached image into our view and then clean up from caching
490
          // by reinstating the painter as it was swapped out for caching renders
491
          delete mRenderContext.painter();
492
          mRenderContext.setPainter( mypContextPainter  );
493
          //draw from cached image that we created further up
494
          mypContextPainter->drawImage( 0,0, *(ml->cacheImage()) );
495
        }
496
      }
400 497
      disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
401 498
    }
402
    else
499
    else // layer not visible due to scale
403 500
    {
404 501
      QgsDebugMsg( "Layer not rendered because it is not within the defined "
405
                   "visibility scale range" );
502
          "visibility scale range" );
406 503
    }
407 504

  
408 505
  } // while (li.hasPrevious())
src/core/qgsmaplayerregistry.cpp (working copy)
118 118

  
119 119
} // QgsMapLayerRegistry::removeAllMapLayers()
120 120

  
121
//Added in QGIS 1.4
122
void QgsMapLayerRegistry::clearAllLayerCaches()
123
{
124
  QMap<QString, QgsMapLayer *>::iterator it;
125
  for ( it = mMapLayers.begin(); it != mMapLayers.end() ; ++it )
126
  {
127
    //the map layer will take care of deleting the QImage
128
    it.value()->setCacheImage( 0 );
129
  }
130
} // QgsMapLayerRegistry::clearAllLayerCaches()
121 131

  
122 132
QMap<QString, QgsMapLayer*> & QgsMapLayerRegistry::mapLayers()
123 133
{
src/core/qgsmaplayerregistry.h (working copy)
82 82
    */
83 83
    void removeAllMapLayers();
84 84

  
85
    /* Clears all layer caches, resetting them to zero and 
86
     * freeing up any memory they may have been using. Layer
87
     * caches are used to speed up rendering in certain situations
88
     * see ticket #1974 for more details.
89
     * @note this method was added in QGIS 1.4
90
     */
91
     void clearAllLayerCaches();
85 92
  signals:
86 93

  
87 94
    /** emitted when a layer is removed from the registry
src/core/qgsmaplayer.h (working copy)
24 24

  
25 25
#include <QObject>
26 26
#include <QUndoStack>
27
#include <QImage>
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 QImage used for caching render operations
268
     * @note This method was added in QGIS 1.4 **/
269
    QImage * cacheImage() { return mpCacheImage; }
270
    /** Set the QImage used for caching render operations 
271
     * @note This method was added in QGIS 1.4 **/
272
    void setCacheImage( QImage * thepImage ); 
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
    /**QImage for caching of rendering operations
375
     * @note This property was added in QGIS 1.4 **/
376
    QImage * mpCacheImage;
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/>