Changeset 54541 in webkit
- Timestamp:
- Feb 9, 2010 2:07:58 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r54537 r54541 1 2010-02-09 Noam Rosenthal <noam.rosenthal@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Qt] the above website does not render properly when in compositing mode 6 https://bugs.webkit.org/show_bug.cgi?id=34681 7 8 http://media.24ways.org/2009/15/spinner-alt.html now renders correctly 9 10 * platform/graphics/qt/GraphicsLayerQt.cpp: 11 (WebCore::MaskEffectQt::MaskEffectQt): implement mask as 12 QGraphicsEffect 13 (WebCore::MaskEffectQt::draw): reimp 14 (WebCore::GraphicsLayerQtImpl::GraphicsLayerQtImpl): init the effect 15 (WebCore::GraphicsLayerQtImpl::paint): no need for drawContents 16 (WebCore::GraphicsLayerQtImpl::flushChanges): make sure to update the 17 mask layer, not just the actual children 18 1 19 2010-02-09 Kwang Yul Seo <skyul@company100.net> 2 20 -
trunk/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
r54344 r54541 44 44 45 45 namespace WebCore { 46 47 class MaskEffectQt : public QGraphicsEffect { 48 public: 49 MaskEffectQt(QObject* parent, QGraphicsItem* maskLayer) 50 : QGraphicsEffect(parent) 51 , m_maskLayer(maskLayer) 52 { 53 } 54 55 void draw(QPainter* painter) 56 { 57 // this is a modified clone of QGraphicsOpacityEffect. 58 // It's more efficient to do it this way because 59 // (a) we don't need the QBrush abstraction - we always end up using QGraphicsItem::paint from the mask layer 60 // (b) QGraphicsOpacityEffect detaches the pixmap, which is inefficient on OpenGL. 61 QPixmap maskPixmap(sourceBoundingRect().toAlignedRect().size()); 62 63 // we need to do this so the pixmap would have hasAlpha() 64 maskPixmap.fill(Qt::transparent); 65 QPainter maskPainter(&maskPixmap); 66 QStyleOptionGraphicsItem option; 67 option.exposedRect = option.rect = maskPixmap.rect(); 68 maskPainter.setRenderHints(painter->renderHints(), true); 69 m_maskLayer->paint(&maskPainter, &option, 0); 70 maskPainter.end(); 71 QPoint offset; 72 QPixmap srcPixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, QGraphicsEffect::NoPad); 73 74 // we have to use another intermediate pixmap, to make sure the mask applies only to this item 75 // and doesn't modify pixels already painted into this paint-device 76 QPixmap pixmap(srcPixmap.size()); 77 pixmap.fill(Qt::transparent); 78 79 if (pixmap.isNull()) 80 return; 81 82 QPainter pixmapPainter(&pixmap); 83 pixmapPainter.setRenderHints(painter->renderHints()); 84 pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); 85 // We use drawPixmap rather than detaching, because it's more efficient on OpenGL 86 pixmapPainter.drawPixmap(0, 0, srcPixmap); 87 pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); 88 pixmapPainter.drawPixmap(0, 0, maskPixmap); 89 pixmapPainter.end(); 90 painter->drawPixmap(offset, pixmap); 91 } 92 93 QGraphicsItem* m_maskLayer; 94 }; 46 95 47 96 class GraphicsLayerQtImpl : public QGraphicsObject { … … 89 138 // we manage transforms ourselves because transform-origin acts differently in webkit and in Qt 90 139 void setBaseTransform(const QTransform&); 91 void drawContents(QPainter*, const QRectF&, bool mask = false);92 140 93 141 // let the compositor-API tell us which properties were changed … … 122 170 bool m_transformAnimationRunning; 123 171 bool m_opacityAnimationRunning; 172 QWeakPointer<MaskEffectQt> m_maskEffect; 124 173 125 174 struct ContentData { … … 184 233 , m_layer(newLayer) 185 234 , m_transformAnimationRunning(false) 235 , m_opacityAnimationRunning(false) 186 236 , m_changeMask(NoChanges) 187 237 { … … 278 328 void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 279 329 { 280 if (m_state.maskLayer && m_state.maskLayer->platformLayer()) {281 // FIXME: see if this is better done somewhere else282 GraphicsLayerQtImpl* otherMask = static_cast<GraphicsLayerQtImpl*>(m_state.maskLayer->platformLayer());283 otherMask->flushChanges(true);284 285 // CSS3 mask and QGraphicsOpacityEffect are the same thing! we just need to convert...286 // The conversion is as fast as we can make it - we render the layer once and send it to the QGraphicsOpacityEffect287 if (!graphicsEffect()) {288 QPixmap mask(QSize(m_state.maskLayer->size().width(), m_state.maskLayer->size().height()));289 mask.fill(Qt::transparent);290 {291 QPainter p(&mask);292 p.setRenderHints(painter->renderHints(), true);293 p.setCompositionMode(QPainter::CompositionMode_Source);294 static_cast<GraphicsLayerQtImpl*>(m_state.maskLayer->platformLayer())->drawContents(&p, option->exposedRect, true);295 }296 QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this);297 opacityEffect->setOpacity(1);298 opacityEffect->setOpacityMask(QBrush(mask));299 setGraphicsEffect(opacityEffect);300 }301 }302 drawContents(painter, option->exposedRect);303 }304 305 void GraphicsLayerQtImpl::drawContents(QPainter* painter, const QRectF& exposedRect, bool mask)306 {307 330 if (m_currentContent.backgroundColor.isValid()) 308 painter->fillRect( exposedRect, QColor(m_currentContent.backgroundColor));331 painter->fillRect(option->exposedRect, QColor(m_currentContent.backgroundColor)); 309 332 310 333 switch (m_currentContent.contentType) { 334 case HTMLContentType: 335 if (m_state.drawsContent) { 336 // this is the expensive bit. we try to minimize calls to this area by proper caching 337 GraphicsContext gc(painter); 338 m_layer->paintGraphicsLayerContents(gc, option->exposedRect.toAlignedRect()); 339 } 340 break; 311 341 case PixmapContentType: 312 342 painter->drawPixmap(m_state.contentsRect, m_currentContent.pixmap); … … 314 344 case ColorContentType: 315 345 painter->fillRect(m_state.contentsRect, m_currentContent.contentsBackgroundColor); 316 break;317 default:318 if (m_state.drawsContent) {319 // this is the "expensive" bit. we try to minimize calls to this neck of the woods by proper caching320 GraphicsContext gc(painter);321 m_layer->paintGraphicsLayerContents(gc, exposedRect.toAlignedRect());322 }323 346 break; 324 347 } … … 382 405 // we can't paint here, because we don't know if the mask layer 383 406 // itself is ready... we'll have to wait till this layer tries to paint 407 setFlag(ItemClipsChildrenToShape, m_layer->maskLayer() || m_layer->masksToBounds()); 384 408 setGraphicsEffect(0); 385 if (m_layer->maskLayer()) 386 setFlag(ItemClipsChildrenToShape, true); 387 else 388 setFlag(ItemClipsChildrenToShape, m_layer->masksToBounds()); 389 update(); 409 if (m_layer->maskLayer()) { 410 if (GraphicsLayerQtImpl* mask = qobject_cast<GraphicsLayerQtImpl*>(m_layer->maskLayer()->platformLayer()->toGraphicsObject())) { 411 mask->m_maskEffect = new MaskEffectQt(this, mask); 412 mask->setCacheMode(NoCache); 413 setGraphicsEffect(mask->m_maskEffect.data()); 414 } 415 } 390 416 } 391 417 … … 408 434 } 409 435 410 if (m_changeMask & (ContentChange | DrawsContentChange )) {436 if (m_changeMask & (ContentChange | DrawsContentChange | MaskLayerChange)) { 411 437 switch (m_pendingContent.contentType) { 412 438 case PixmapContentType: … … 420 446 case ColorContentType: 421 447 // no point in caching a solid-color rectangle 422 setCacheMode( QGraphicsItem::NoCache);448 setCacheMode(m_layer->maskLayer() ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache); 423 449 if (m_pendingContent.contentType != m_currentContent.contentType || m_pendingContent.contentsBackgroundColor != m_currentContent.contentsBackgroundColor) 424 450 update(); … … 435 461 if (!m_state.drawsContent && m_layer->drawsContent()) 436 462 update(); 437 if (m_layer->drawsContent() ) {463 if (m_layer->drawsContent() && !m_maskEffect) { 438 464 const QGraphicsItem::CacheMode mewCacheMode = isTransformAnimationRunning() ? ItemCoordinateCache : DeviceCoordinateCache; 439 465 … … 474 500 prepareGeometryChange(); 475 501 476 if (m_changeMask & DisplayChange) 502 if (m_maskEffect) 503 m_maskEffect.data()->update(); 504 else if (m_changeMask & DisplayChange) 477 505 update(m_pendingContent.regionToUpdate.boundingRect()); 478 506 … … 510 538 return; 511 539 512 const QList<QGraphicsItem*> children = childItems(); 540 QList<QGraphicsItem*> children = childItems(); 541 if (m_state.maskLayer) 542 children.append(m_state.maskLayer->platformLayer()); 513 543 514 544 for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it) {
Note: See TracChangeset
for help on using the changeset viewer.