Changeset 61880 in webkit
- Timestamp:
- Jun 25, 2010 12:31:08 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r61877 r61880 1 2010-06-25 Sam Magnuson <smagnuson@netflix.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Qt] When any geometry change happens to a node it will resize the 6 backing cache 7 https://bugs.webkit.org/show_bug.cgi?id=40378 8 9 Continue to grow the cache, but never toss it. When the pixmap 10 cache gets too big it will be lost and created at the right size 11 next time. 12 13 No new tests: this is an optimization. 14 15 * platform/graphics/qt/GraphicsLayerQt.cpp: 16 (WebCore::GraphicsLayerQtImpl::recache): 17 (WebCore::GraphicsLayerQtImpl::paint): 18 (WebCore::GraphicsLayerQtImpl::flushChanges): 19 1 20 2010-06-25 Andreas Kling <andreas.kling@nokia.com> 2 21 -
trunk/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
r61086 r61880 42 42 #include <QtGui/qstyleoption.h> 43 43 44 45 #define QT_DEBUG_RECACHE 0 46 #define QT_DEBUG_CACHEDUMP 0 47 44 48 namespace WebCore { 45 49 … … 226 230 227 231 QSizeF m_size; 228 QPixmapCache::Key m_backingStoreKey; 232 struct { 233 QPixmapCache::Key key; 234 QSizeF size; 235 } m_backingStore; 229 236 #ifndef QT_NO_ANIMATION 230 237 QList<QWeakPointer<QAbstractAnimation> > m_animations; … … 340 347 QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) 341 348 { 342 if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid())349 if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid()) 343 350 return QPixmap(); 344 351 352 QPixmap pixmap; 345 353 QRegion region = regionToUpdate; 346 QPixmap pixmap; 347 348 // We might be drawing into an existing cache. 349 if (!QPixmapCache::find(m_backingStoreKey, &pixmap)) 350 region = QRegion(QRect(0, 0, m_size.width(), m_size.height())); 351 352 if (m_size != pixmap.size()) { 353 pixmap = QPixmap(m_size.toSize()); 354 if (!m_layer->contentsOpaque()) 355 pixmap.fill(Qt::transparent); 356 m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), m_size.toSize())); 357 } 358 359 QPainter painter(&pixmap); 360 GraphicsContext gc(&painter); 361 362 // Clear the area in cache that we're drawing into 363 painter.setCompositionMode(QPainter::CompositionMode_Clear); 364 painter.fillRect(region.boundingRect(), Qt::transparent); 365 366 // Render the actual contents into the cache 367 painter.setCompositionMode(QPainter::CompositionMode_SourceOver); 368 m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); 369 painter.end(); 370 371 m_backingStoreKey = QPixmapCache::insert(pixmap); 354 if (QPixmapCache::find(m_backingStore.key, &pixmap)) { 355 if (region.isEmpty()) 356 return pixmap; 357 QPixmapCache::remove(m_backingStore.key); // Remove the reference to the pixmap in the cache to avoid a detach. 358 } 359 360 { 361 bool erased = false; 362 363 // If the pixmap is not in the cache or the view has grown since last cached. 364 if (pixmap.isNull() || m_size != m_backingStore.size) { 365 #if QT_DEBUG_RECACHE 366 if (pixmap.isNull()) 367 qDebug() << "CacheMiss" << this << m_size; 368 #endif 369 bool fill = true; 370 QRegion newRegion; 371 QPixmap oldPixmap = pixmap; 372 373 // If the pixmap is two small to hold the view contents we enlarge, otherwise just use the old (large) pixmap. 374 if (pixmap.width() < m_size.width() || pixmap.height() < m_size.height()) { 375 #if QT_DEBUG_RECACHE 376 qDebug() << "CacheGrow" << this << m_size; 377 #endif 378 pixmap = QPixmap(m_size.toSize()); 379 pixmap.fill(Qt::transparent); 380 newRegion = QRegion(0, 0, m_size.width(), m_size.height()); 381 } 382 383 #if 1 384 // Blit the contents of oldPixmap back into the cached pixmap as we are just adding new pixels. 385 if (!oldPixmap.isNull()) { 386 const QRegion cleanRegion = (QRegion(0, 0, m_size.width(), m_size.height()) 387 & QRegion(0, 0, m_backingStore.size.width(), m_backingStore.size.height())) - regionToUpdate; 388 if (!cleanRegion.isEmpty()) { 389 #if QT_DEBUG_RECACHE 390 qDebug() << "CacheBlit" << this << cleanRegion; 391 #endif 392 const QRect cleanBounds(cleanRegion.boundingRect()); 393 QPainter painter(&pixmap); 394 painter.setCompositionMode(QPainter::CompositionMode_Source); 395 painter.drawPixmap(cleanBounds.topLeft(), oldPixmap, cleanBounds); 396 newRegion -= cleanRegion; 397 fill = false; // We cannot just fill the pixmap. 398 } 399 oldPixmap = QPixmap(); 400 } 401 #endif 402 region += newRegion; 403 if (fill && !region.isEmpty()) { // Clear the entire pixmap with the background. 404 #if QT_DEBUG_RECACHE 405 qDebug() << "CacheErase" << this << m_size << background; 406 #endif 407 erased = true; 408 pixmap.fill(Qt::transparent); 409 } 410 } 411 region &= QRegion(0, 0, m_size.width(), m_size.height()); 412 413 // If we have something to draw its time to erase it and render the contents. 414 if (!region.isEmpty()) { 415 #if QT_DEBUG_CACHEDUMP 416 static int recacheCount = 0; 417 ++recacheCount; 418 qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size; 419 pixmap.save(QString().sprintf("/tmp/%05d_A.png", recacheCount), "PNG"); 420 #endif 421 422 QPainter painter(&pixmap); 423 GraphicsContext gc(&painter); 424 425 painter.setClipRegion(region); 426 427 if (!erased) { // Erase the area in cache that we're drawing into. 428 painter.setCompositionMode(QPainter::CompositionMode_Clear); 429 painter.fillRect(region.boundingRect(), Qt::transparent); 430 431 #if QT_DEBUG_CACHEDUMP 432 qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size; 433 pixmap.save(QString().sprintf("/tmp/%05d_B.png", recacheCount), "PNG"); 434 #endif 435 } 436 437 // Render the actual contents into the cache. 438 painter.setCompositionMode(QPainter::CompositionMode_SourceOver); 439 m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); 440 painter.end(); 441 442 #if QT_DEBUG_CACHEDUMP 443 qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size; 444 pixmap.save(QString().sprintf("/tmp/%05d_C.png", recacheCount), "PNG"); 445 #endif 446 } 447 m_backingStore.size = m_size; // Store the used size of the pixmap. 448 } 449 450 // Finally insert into the cache and allow a reference there. 451 m_backingStore.key = QPixmapCache::insert(pixmap); 372 452 return pixmap; 373 453 } … … 488 568 QPixmap backingStore; 489 569 // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full). 490 if (!QPixmapCache::find(m_backingStore Key, &backingStore) || backingStore.size() != m_size.toSize())570 if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize()) 491 571 backingStore = recache(QRegion(m_state.contentsRect)); 572 const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height()); 492 573 painter->drawPixmap(0, 0, backingStore); 493 574 } … … 675 756 #endif 676 757 if (m_changeMask & DisplayChange) { 758 #ifndef QT_GRAPHICS_LAYER_NO_RECACHE_ON_DISPLAY_CHANGE 677 759 // Recache now: all the content is ready and we don't want to wait until the paint event. 678 760 // We only need to do this for HTML content, there's no point in caching directly composited … … 680 762 if (m_pendingContent.contentType == HTMLContentType) 681 763 recache(m_pendingContent.regionToUpdate); 764 #endif 682 765 update(m_pendingContent.regionToUpdate.boundingRect()); 683 766 m_pendingContent.regionToUpdate = QRegion();
Note: See TracChangeset
for help on using the changeset viewer.