|
Lines 41-46
a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec1
|
| 41 |
#include <QtGui/qpixmapcache.h> |
41 |
#include <QtGui/qpixmapcache.h> |
| 42 |
#include <QtGui/qstyleoption.h> |
42 |
#include <QtGui/qstyleoption.h> |
| 43 |
|
43 |
|
|
|
44 |
|
| 45 |
#define QT_DEBUG_RECACHE 0 |
| 46 |
#define QT_DEBUG_CACHEDUMP 0 |
| 47 |
|
| 44 |
namespace WebCore { |
48 |
namespace WebCore { |
| 45 |
|
49 |
|
| 46 |
#ifndef QT_NO_GRAPHICSEFFECT |
50 |
#ifndef QT_NO_GRAPHICSEFFECT |
|
Lines 225-231
public:
a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec2
|
| 225 |
int m_changeMask; |
229 |
int m_changeMask; |
| 226 |
|
230 |
|
| 227 |
QSizeF m_size; |
231 |
QSizeF m_size; |
| 228 |
QPixmapCache::Key m_backingStoreKey; |
232 |
struct { |
|
|
233 |
QPixmapCache::Key key; |
| 234 |
QSizeF size; |
| 235 |
} m_backingStore; |
| 229 |
#ifndef QT_NO_ANIMATION |
236 |
#ifndef QT_NO_ANIMATION |
| 230 |
QList<QWeakPointer<QAbstractAnimation> > m_animations; |
237 |
QList<QWeakPointer<QAbstractAnimation> > m_animations; |
| 231 |
#endif |
238 |
#endif |
|
Lines 339-374
const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const
a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec3
|
| 339 |
|
346 |
|
| 340 |
QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) |
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 |
return QPixmap(); |
350 |
return QPixmap(); |
| 344 |
|
351 |
|
| 345 |
QRegion region = regionToUpdate; |
|
|
| 346 |
QPixmap pixmap; |
352 |
QPixmap pixmap; |
|
|
353 |
QRegion region = regionToUpdate; |
| 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 |
} |
| 347 |
|
359 |
|
| 348 |
// We might be drawing into an existing cache. |
360 |
{ |
| 349 |
if (!QPixmapCache::find(m_backingStoreKey, &pixmap)) |
361 |
bool erased = false; |
| 350 |
region = QRegion(QRect(0, 0, m_size.width(), m_size.height())); |
|
|
| 351 |
|
362 |
|
| 352 |
if (m_size != pixmap.size()) { |
363 |
// If the pixmap is not in the cache or the view has grown since last cached. |
| 353 |
pixmap = QPixmap(m_size.toSize()); |
364 |
if (pixmap.isNull() || m_size != m_backingStore.size) { |
| 354 |
if (!m_layer->contentsOpaque()) |
365 |
#if QT_DEBUG_RECACHE |
| 355 |
pixmap.fill(Qt::transparent); |
366 |
if (pixmap.isNull()) |
| 356 |
m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), m_size.toSize())); |
367 |
qDebug() << "CacheMiss" << this << m_size; |
| 357 |
} |
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); |
| 358 |
|
426 |
|
| 359 |
QPainter painter(&pixmap); |
427 |
if (!erased) { // Erase the area in cache that we're drawing into. |
| 360 |
GraphicsContext gc(&painter); |
428 |
painter.setCompositionMode(QPainter::CompositionMode_Clear); |
|
|
429 |
painter.fillRect(region.boundingRect(), Qt::transparent); |
| 361 |
|
430 |
|
| 362 |
// Clear the area in cache that we're drawing into |
431 |
#if QT_DEBUG_CACHEDUMP |
| 363 |
painter.setCompositionMode(QPainter::CompositionMode_Clear); |
432 |
qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size; |
| 364 |
painter.fillRect(region.boundingRect(), Qt::transparent); |
433 |
pixmap.save(QString().sprintf("/tmp/%05d_B.png", recacheCount), "PNG"); |
|
|
434 |
#endif |
| 435 |
} |
| 365 |
|
436 |
|
| 366 |
// Render the actual contents into the cache |
437 |
// Render the actual contents into the cache. |
| 367 |
painter.setCompositionMode(QPainter::CompositionMode_SourceOver); |
438 |
painter.setCompositionMode(QPainter::CompositionMode_SourceOver); |
| 368 |
m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); |
439 |
m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); |
| 369 |
painter.end(); |
440 |
painter.end(); |
| 370 |
|
441 |
|
| 371 |
m_backingStoreKey = QPixmapCache::insert(pixmap); |
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 |
return pixmap; |
452 |
return pixmap; |
| 373 |
} |
453 |
} |
| 374 |
|
454 |
|
|
Lines 487-494
void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte
a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec4
|
| 487 |
if (m_state.drawsContent) { |
567 |
if (m_state.drawsContent) { |
| 488 |
QPixmap backingStore; |
568 |
QPixmap backingStore; |
| 489 |
// We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full). |
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_backingStoreKey, &backingStore) || backingStore.size() != m_size.toSize()) |
570 |
if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize()) |
| 491 |
backingStore = recache(QRegion(m_state.contentsRect)); |
571 |
backingStore = recache(QRegion(m_state.contentsRect)); |
|
|
572 |
const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height()); |
| 492 |
painter->drawPixmap(0, 0, backingStore); |
573 |
painter->drawPixmap(0, 0, backingStore); |
| 493 |
} |
574 |
} |
| 494 |
break; |
575 |
break; |
|
Lines 674-684
void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec5
|
| 674 |
else |
755 |
else |
| 675 |
#endif |
756 |
#endif |
| 676 |
if (m_changeMask & DisplayChange) { |
757 |
if (m_changeMask & DisplayChange) { |
|
|
758 |
#ifndef QT_GRAPHICS_LAYER_NO_RECACHE_ON_DISPLAY_CHANGE |
| 677 |
// Recache now: all the content is ready and we don't want to wait until the paint event. |
759 |
// Recache now: all the content is ready and we don't want to wait until the paint event. |
| 678 |
// We only need to do this for HTML content, there's no point in caching directly composited |
760 |
// We only need to do this for HTML content, there's no point in caching directly composited |
| 679 |
// content like images or solid rectangles. |
761 |
// content like images or solid rectangles. |
| 680 |
if (m_pendingContent.contentType == HTMLContentType) |
762 |
if (m_pendingContent.contentType == HTMLContentType) |
| 681 |
recache(m_pendingContent.regionToUpdate); |
763 |
recache(m_pendingContent.regionToUpdate); |
|
|
764 |
#endif |
| 682 |
update(m_pendingContent.regionToUpdate.boundingRect()); |
765 |
update(m_pendingContent.regionToUpdate.boundingRect()); |
| 683 |
m_pendingContent.regionToUpdate = QRegion(); |
766 |
m_pendingContent.regionToUpdate = QRegion(); |
| 684 |
} |
767 |
} |