[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756
eric at webkit.org
eric at webkit.org
Fri Feb 26 22:15:45 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit c04d572135df158deff0fb8b62fef5de32193f42
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Feb 9 10:07:58 2010 +0000
2010-02-09 Noam Rosenthal <noam.rosenthal at nokia.com>
Reviewed by Kenneth Rohde Christiansen.
[Qt] the above website does not render properly when in compositing mode
https://bugs.webkit.org/show_bug.cgi?id=34681
http://media.24ways.org/2009/15/spinner-alt.html now renders correctly
* platform/graphics/qt/GraphicsLayerQt.cpp:
(WebCore::MaskEffectQt::MaskEffectQt): implement mask as
QGraphicsEffect
(WebCore::MaskEffectQt::draw): reimp
(WebCore::GraphicsLayerQtImpl::GraphicsLayerQtImpl): init the effect
(WebCore::GraphicsLayerQtImpl::paint): no need for drawContents
(WebCore::GraphicsLayerQtImpl::flushChanges): make sure to update the
mask layer, not just the actual children
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54541 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e0796c3..bee4192 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,21 @@
+2010-02-09 Noam Rosenthal <noam.rosenthal at nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] the above website does not render properly when in compositing mode
+ https://bugs.webkit.org/show_bug.cgi?id=34681
+
+ http://media.24ways.org/2009/15/spinner-alt.html now renders correctly
+
+ * platform/graphics/qt/GraphicsLayerQt.cpp:
+ (WebCore::MaskEffectQt::MaskEffectQt): implement mask as
+ QGraphicsEffect
+ (WebCore::MaskEffectQt::draw): reimp
+ (WebCore::GraphicsLayerQtImpl::GraphicsLayerQtImpl): init the effect
+ (WebCore::GraphicsLayerQtImpl::paint): no need for drawContents
+ (WebCore::GraphicsLayerQtImpl::flushChanges): make sure to update the
+ mask layer, not just the actual children
+
2010-02-09 Kwang Yul Seo <skyul at company100.net>
Reviewed by Laszlo Gombos.
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index 70743d8..3a0d1ba 100644
--- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -44,6 +44,55 @@
namespace WebCore {
+class MaskEffectQt : public QGraphicsEffect {
+public:
+ MaskEffectQt(QObject* parent, QGraphicsItem* maskLayer)
+ : QGraphicsEffect(parent)
+ , m_maskLayer(maskLayer)
+ {
+ }
+
+ void draw(QPainter* painter)
+ {
+ // this is a modified clone of QGraphicsOpacityEffect.
+ // It's more efficient to do it this way because
+ // (a) we don't need the QBrush abstraction - we always end up using QGraphicsItem::paint from the mask layer
+ // (b) QGraphicsOpacityEffect detaches the pixmap, which is inefficient on OpenGL.
+ QPixmap maskPixmap(sourceBoundingRect().toAlignedRect().size());
+
+ // we need to do this so the pixmap would have hasAlpha()
+ maskPixmap.fill(Qt::transparent);
+ QPainter maskPainter(&maskPixmap);
+ QStyleOptionGraphicsItem option;
+ option.exposedRect = option.rect = maskPixmap.rect();
+ maskPainter.setRenderHints(painter->renderHints(), true);
+ m_maskLayer->paint(&maskPainter, &option, 0);
+ maskPainter.end();
+ QPoint offset;
+ QPixmap srcPixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, QGraphicsEffect::NoPad);
+
+ // we have to use another intermediate pixmap, to make sure the mask applies only to this item
+ // and doesn't modify pixels already painted into this paint-device
+ QPixmap pixmap(srcPixmap.size());
+ pixmap.fill(Qt::transparent);
+
+ if (pixmap.isNull())
+ return;
+
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
+ // We use drawPixmap rather than detaching, because it's more efficient on OpenGL
+ pixmapPainter.drawPixmap(0, 0, srcPixmap);
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ pixmapPainter.drawPixmap(0, 0, maskPixmap);
+ pixmapPainter.end();
+ painter->drawPixmap(offset, pixmap);
+ }
+
+ QGraphicsItem* m_maskLayer;
+};
+
class GraphicsLayerQtImpl : public QGraphicsObject {
Q_OBJECT
@@ -88,7 +137,6 @@ public:
// we manage transforms ourselves because transform-origin acts differently in webkit and in Qt
void setBaseTransform(const QTransform&);
- void drawContents(QPainter*, const QRectF&, bool mask = false);
// let the compositor-API tell us which properties were changed
void notifyChange(ChangeMask);
@@ -121,6 +169,7 @@ public:
QTransform m_baseTransform;
bool m_transformAnimationRunning;
bool m_opacityAnimationRunning;
+ QWeakPointer<MaskEffectQt> m_maskEffect;
struct ContentData {
QPixmap pixmap;
@@ -183,6 +232,7 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
: QGraphicsObject(0)
, m_layer(newLayer)
, m_transformAnimationRunning(false)
+ , m_opacityAnimationRunning(false)
, m_changeMask(NoChanges)
{
// we use graphics-view for compositing, not for interactivity
@@ -277,50 +327,23 @@ QRectF GraphicsLayerQtImpl::boundingRect() const
void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
- if (m_state.maskLayer && m_state.maskLayer->platformLayer()) {
- // FIXME: see if this is better done somewhere else
- GraphicsLayerQtImpl* otherMask = static_cast<GraphicsLayerQtImpl*>(m_state.maskLayer->platformLayer());
- otherMask->flushChanges(true);
-
- // CSS3 mask and QGraphicsOpacityEffect are the same thing! we just need to convert...
- // The conversion is as fast as we can make it - we render the layer once and send it to the QGraphicsOpacityEffect
- if (!graphicsEffect()) {
- QPixmap mask(QSize(m_state.maskLayer->size().width(), m_state.maskLayer->size().height()));
- mask.fill(Qt::transparent);
- {
- QPainter p(&mask);
- p.setRenderHints(painter->renderHints(), true);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- static_cast<GraphicsLayerQtImpl*>(m_state.maskLayer->platformLayer())->drawContents(&p, option->exposedRect, true);
- }
- QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this);
- opacityEffect->setOpacity(1);
- opacityEffect->setOpacityMask(QBrush(mask));
- setGraphicsEffect(opacityEffect);
- }
- }
- drawContents(painter, option->exposedRect);
-}
-
-void GraphicsLayerQtImpl::drawContents(QPainter* painter, const QRectF& exposedRect, bool mask)
-{
if (m_currentContent.backgroundColor.isValid())
- painter->fillRect(exposedRect, QColor(m_currentContent.backgroundColor));
+ painter->fillRect(option->exposedRect, QColor(m_currentContent.backgroundColor));
switch (m_currentContent.contentType) {
+ case HTMLContentType:
+ if (m_state.drawsContent) {
+ // this is the expensive bit. we try to minimize calls to this area by proper caching
+ GraphicsContext gc(painter);
+ m_layer->paintGraphicsLayerContents(gc, option->exposedRect.toAlignedRect());
+ }
+ break;
case PixmapContentType:
painter->drawPixmap(m_state.contentsRect, m_currentContent.pixmap);
break;
case ColorContentType:
painter->fillRect(m_state.contentsRect, m_currentContent.contentsBackgroundColor);
break;
- default:
- if (m_state.drawsContent) {
- // this is the "expensive" bit. we try to minimize calls to this neck of the woods by proper caching
- GraphicsContext gc(painter);
- m_layer->paintGraphicsLayerContents(gc, exposedRect.toAlignedRect());
- }
- break;
}
}
@@ -381,12 +404,15 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive)
if (m_changeMask & MaskLayerChange) {
// we can't paint here, because we don't know if the mask layer
// itself is ready... we'll have to wait till this layer tries to paint
+ setFlag(ItemClipsChildrenToShape, m_layer->maskLayer() || m_layer->masksToBounds());
setGraphicsEffect(0);
- if (m_layer->maskLayer())
- setFlag(ItemClipsChildrenToShape, true);
- else
- setFlag(ItemClipsChildrenToShape, m_layer->masksToBounds());
- update();
+ if (m_layer->maskLayer()) {
+ if (GraphicsLayerQtImpl* mask = qobject_cast<GraphicsLayerQtImpl*>(m_layer->maskLayer()->platformLayer()->toGraphicsObject())) {
+ mask->m_maskEffect = new MaskEffectQt(this, mask);
+ mask->setCacheMode(NoCache);
+ setGraphicsEffect(mask->m_maskEffect.data());
+ }
+ }
}
if ((m_changeMask & PositionChange) && (m_layer->position() != m_state.pos))
@@ -407,7 +433,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive)
setBaseTransform(m_layer->transform());
}
- if (m_changeMask & (ContentChange | DrawsContentChange)) {
+ if (m_changeMask & (ContentChange | DrawsContentChange | MaskLayerChange)) {
switch (m_pendingContent.contentType) {
case PixmapContentType:
update();
@@ -419,7 +445,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive)
case ColorContentType:
// no point in caching a solid-color rectangle
- setCacheMode(QGraphicsItem::NoCache);
+ setCacheMode(m_layer->maskLayer() ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);
if (m_pendingContent.contentType != m_currentContent.contentType || m_pendingContent.contentsBackgroundColor != m_currentContent.contentsBackgroundColor)
update();
m_state.drawsContent = false;
@@ -434,7 +460,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive)
update();
if (!m_state.drawsContent && m_layer->drawsContent())
update();
- if (m_layer->drawsContent()) {
+ if (m_layer->drawsContent() && !m_maskEffect) {
const QGraphicsItem::CacheMode mewCacheMode = isTransformAnimationRunning() ? ItemCoordinateCache : DeviceCoordinateCache;
// optimization: QGraphicsItem doesn't always perform this test
@@ -473,7 +499,9 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive)
if ((m_changeMask & ContentsOpaqueChange) && m_state.contentsOpaque != m_layer->contentsOpaque())
prepareGeometryChange();
- if (m_changeMask & DisplayChange)
+ if (m_maskEffect)
+ m_maskEffect.data()->update();
+ else if (m_changeMask & DisplayChange)
update(m_pendingContent.regionToUpdate.boundingRect());
if ((m_changeMask & BackgroundColorChange) && (m_pendingContent.backgroundColor != m_currentContent.backgroundColor))
@@ -509,7 +537,9 @@ afterLayerChanges:
if (!recursive)
return;
- const QList<QGraphicsItem*> children = childItems();
+ QList<QGraphicsItem*> children = childItems();
+ if (m_state.maskLayer)
+ children.append(m_state.maskLayer->platformLayer());
for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it) {
if (QGraphicsItem* item = *it)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list