Changeset 54284 in webkit
- Timestamp:
- Feb 3, 2010 10:02:01 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r54282 r54284 1 2010-02-03 Andras Becsi <abecsi@webkit.org> 2 3 Unreviewed build fix. 4 5 [Qt] Roll-out r54281 because it broke the build on the Qt Release bot. 6 7 * platform/graphics/qt/GraphicsLayerQt.cpp: 8 (WebCore::GraphicsLayerQtImpl::State::State): 9 (WebCore::GraphicsLayerQtImpl::GraphicsLayerQtImpl): 10 (WebCore::GraphicsLayerQtImpl::setBaseTransform): 11 (WebCore::GraphicsLayerQtImpl::drawContents): 12 (WebCore::GraphicsLayerQtImpl::notifyChange): 13 (WebCore::GraphicsLayerQtImpl::flushChanges): 14 (WebCore::GraphicsLayerQt::setNeedsDisplayInRect): 15 (WebCore::applyTimingFunction): 16 (WebCore::webkitAnimationToQtAnimationValue): 17 (WebCore::AnimationQtBase::updateState): 18 (WebCore::AnimationQt::updateCurrentTime): 19 (WebCore::TransformAnimationQt::TransformAnimationQt): 20 (WebCore::TransformAnimationQt::~TransformAnimationQt): 21 (WebCore::TransformAnimationQt::applyFrame): 22 (WebCore::TransformAnimationQt::updateState): 23 (WebCore::OpacityAnimationQt::updateState): 24 (WebCore::GraphicsLayerQt::pauseAnimation): 25 1 26 2010-02-02 Bryan Yeung <bryeung@google.com> 2 27 … … 17 42 * dom/Element.cpp: 18 43 (WebCore::Element::baseURI): 19 20 2010-02-03 No'am Rosenthal <noam.rosenthal@nokia.com>21 22 Reviewed by Laszlo Gombos.23 24 [Qt] Tuning and optimizations to GraphicsLayerQt. Reduce unnecessary25 recaching, remove QTimer::singleShot and QPixmap::scaled, more26 accurate strategy of handling transform operation blends. Rotating a27 bordered-table, for example, now runs at 50FPS instead of 40FPS on Maemo5.28 29 https://bugs.webkit.org/show_bug.cgi?id=3406230 31 This is tested by https://bugs.webkit.org/show_bug.cgi?id=34450, fps measurements.32 33 * platform/graphics/qt/GraphicsLayerQt.cpp:34 (WebCore::GraphicsLayerQtImpl::flushChanges): Fine-tune caching35 (WebCore::TransformAnimationQt::TransformAnimationQt): transform bugs36 (WebCore::OpacityAnimationQt::updateState): style change37 44 38 45 2010-02-02 Joel Stanley <joel@jms.id.au> -
trunk/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
r54281 r54284 100 100 void flushChanges(bool recursive = true); 101 101 102 // optimization: when we have an animation running on an element with no contents, that has child-elements with contents,103 // ALL of them have to have ItemCoordinateCache and not DeviceCoordinateCache104 void adjustCachingRecursively(bool animationIsRunning);105 106 // optimization: returns true if this or an ancestor has a transform animation running.107 // this enables us to use ItemCoordinatesCache while the animation is running, otherwise we have to recache for every frame108 bool isTransformAnimationRunning() const;109 110 102 public slots: 111 103 // we need to notify the client (aka the layer compositor) when the animation actually starts 112 104 void notifyAnimationStarted(); 113 105 114 signals:115 // optimization: we don't want to use QTimer::singleShot116 void notifyAnimationStartedAsync();117 118 106 public: 119 107 GraphicsLayerQt* m_layer; 120 108 121 QTransform m_baseTransfo rm;109 QTransform m_baseTransfom; 122 110 bool m_transformAnimationRunning; 123 111 bool m_opacityAnimationRunning; … … 170 158 bool distributeOpacity: 1; 171 159 bool align: 2; 172 State(): maskLayer(0), opacity(1 .f), preserves3D(false), masksToBounds(false),160 State(): maskLayer(0), opacity(1), preserves3D(false), masksToBounds(false), 173 161 drawsContent(false), contentsOpaque(false), backfaceVisibility(false), 174 162 distributeOpacity(false) … … 176 164 } 177 165 } m_state; 178 179 friend class AnimationQtBase;180 166 }; 181 167 … … 186 172 , m_changeMask(NoChanges) 187 173 { 174 // better to calculate the exposed rect in QGraphicsView than over-render in WebCore 175 // FIXME: test different approaches 176 setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true); 177 188 178 // we use graphics-view for compositing, not for interactivity 189 179 setAcceptedMouseButtons(Qt::NoButton); … … 192 182 // we'll set the cache when we know what's going on 193 183 setCacheMode(NoCache); 194 195 connect(this, SIGNAL(notifyAnimationStartedAsync()), this, SLOT(notifyAnimationStarted()), Qt::QueuedConnection);196 184 } 197 185 … … 216 204 } 217 205 218 void GraphicsLayerQtImpl::adjustCachingRecursively(bool animationIsRunning)219 {220 // optimization: we make sure all our children have ItemCoordinateCache -221 // otherwise we end up re-rendering them during the animation222 const QList<QGraphicsItem*> children = childItems();223 224 for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it) {225 if (QGraphicsItem* item = *it)226 if (GraphicsLayerQtImpl* layer = qobject_cast<GraphicsLayerQtImpl*>(item->toGraphicsObject())) {227 if (layer->m_layer->drawsContent() && layer->m_currentContent.contentType == HTMLContentType)228 layer->setCacheMode(animationIsRunning ? QGraphicsItem::ItemCoordinateCache : QGraphicsItem::DeviceCoordinateCache);229 }230 }231 }232 233 206 void GraphicsLayerQtImpl::setBaseTransform(const QTransform& transform) 234 207 { 235 208 if (!m_layer) 236 209 return; 237 // webkit has relative-to-size originPoint, graphics-view has a pixel originPoint, here we convert 238 // we have to manage this ourselves because QGraphicsView's transformOrigin is incompatible 239 const qreal x = m_layer->anchorPoint().x() * m_layer->size().width(); 240 const qreal y = m_layer->anchorPoint().y() * m_layer->size().height(); 241 setTransform(QTransform::fromTranslate(x, y)); 210 // webkit has relative-to-size originPoint, graphics-view has a pixel originPoint 211 // here we convert 212 QPointF originTranslate( 213 m_layer->anchorPoint().x() * m_layer->size().width(), m_layer->anchorPoint().y() * m_layer->size().height()); 214 215 resetTransform(); 216 217 // we have to manage this ourselves because QGraphicsView's transformOrigin is incomplete 218 translate(originTranslate.x(), originTranslate.y()); 242 219 setTransform(transform, true); 243 translate(-x, -y); 244 m_baseTransform = transform; 245 } 246 247 bool GraphicsLayerQtImpl::isTransformAnimationRunning() const 248 { 249 if (m_transformAnimationRunning) 250 return true; 251 if (GraphicsLayerQtImpl* parent = qobject_cast<GraphicsLayerQtImpl*>(parentObject())) 252 return parent->isTransformAnimationRunning(); 253 return false; 220 translate(-originTranslate.x(), -originTranslate.y()); 221 m_baseTransfom = transform; 254 222 } 255 223 … … 303 271 } 304 272 305 void GraphicsLayerQtImpl::drawContents(QPainter* painter, const QRectF& exposedRect, bool mask) 306 { 273 void GraphicsLayerQtImpl::drawContents(QPainter* painter, const QRectF& r, bool mask) 274 { 275 QRect rect = r.toAlignedRect(); 276 277 if (m_currentContent.contentType != HTMLContentType && !m_state.contentsRect.isEmpty()) 278 rect = rect.intersected(m_state.contentsRect); 279 307 280 if (m_currentContent.backgroundColor.isValid()) 308 painter->fillRect(exposedRect, QColor(m_currentContent.backgroundColor)); 309 310 switch (m_currentContent.contentType) { 311 case PixmapContentType: 312 painter->drawPixmap(m_state.contentsRect, m_currentContent.pixmap); 313 break; 314 case ColorContentType: 315 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 caching 320 GraphicsContext gc(painter); 321 m_layer->paintGraphicsLayerContents(gc, exposedRect.toAlignedRect()); 322 } 323 break; 281 painter->fillRect(r, QColor(m_currentContent.backgroundColor)); 282 283 if (!rect.isEmpty()) { 284 switch (m_currentContent.contentType) { 285 case PixmapContentType: 286 // we have to scale the image to the contentsRect 287 // FIXME: a better way would probably be drawPixmap with a src/target rect 288 painter->drawPixmap(rect.topLeft(), m_currentContent.pixmap.scaled(m_state.contentsRect.size()), r); 289 break; 290 case ColorContentType: 291 painter->fillRect(rect, m_currentContent.contentsBackgroundColor); 292 break; 293 default: 294 if (m_state.drawsContent) { 295 // this is the "expensive" bit. we try to minimize calls to this 296 // neck of the woods by proper caching 297 GraphicsContext gc(painter); 298 m_layer->paintGraphicsLayerContents(gc, rect); 299 } 300 break; 301 } 324 302 } 325 303 } … … 327 305 void GraphicsLayerQtImpl::notifyChange(ChangeMask changeMask) 328 306 { 329 Q_ASSERT(this); 307 if (!this) 308 return; 330 309 331 310 m_changeMask |= changeMask; … … 364 343 const QSet<QGraphicsItem*> childrenToAdd = newChildren - currentChildren; 365 344 const QSet<QGraphicsItem*> childrenToRemove = currentChildren - newChildren; 366 367 for (QSet<QGraphicsItem*>::const_iterator it = childrenToAdd.begin(); it != childrenToAdd.end(); ++it) 345 for (QSet<QGraphicsItem*>::const_iterator it = childrenToAdd.begin(); it != childrenToAdd.end(); ++it) { 368 346 if (QGraphicsItem* w = *it) 369 347 w->setParentItem(this); 370 371 for (QSet<QGraphicsItem*>::const_iterator it = childrenToRemove.begin(); it != childrenToRemove.end(); ++it) 348 } 349 for (QSet<QGraphicsItem*>::const_iterator it = childrenToRemove.begin(); it != childrenToRemove.end(); ++it) { 372 350 if (QGraphicsItem* w = *it) 373 351 w->setParentItem(0); 352 } 374 353 375 354 // children are ordered by z-value, let graphics-view know. … … 405 384 // that we give Qt 406 385 if (m_state.transform != m_layer->transform() || m_state.anchorPoint != m_layer->anchorPoint() || m_state.size != m_layer->size()) 407 setBaseTransform( m_layer->transform());386 setBaseTransform(QTransform(m_layer->transform())); 408 387 } 409 388 … … 411 390 switch (m_pendingContent.contentType) { 412 391 case PixmapContentType: 392 // we need cache even for images, because they need to be resized 393 // to the contents rect. maybe this can be optimized though 394 setCacheMode(m_transformAnimationRunning ? ItemCoordinateCache : DeviceCoordinateCache); 413 395 update(); 414 396 setFlag(ItemHasNoContents, false); 415 416 // we only use ItemUsesExtendedStyleOption for HTML content - pixmap can be handled better with regular clipping417 setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, false);418 397 break; 419 398 … … 425 404 m_state.drawsContent = false; 426 405 setFlag(ItemHasNoContents, false); 427 428 // we only use ItemUsesExtendedStyleOption for HTML content - colors don't gain much from that anyway429 setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, false);430 406 break; 431 407 … … 435 411 if (!m_state.drawsContent && m_layer->drawsContent()) 436 412 update(); 437 if (m_layer->drawsContent()) { 438 const QGraphicsItem::CacheMode mewCacheMode = isTransformAnimationRunning() ? ItemCoordinateCache : DeviceCoordinateCache; 439 440 // optimization: QGraphicsItem doesn't always perform this test 441 if (mewCacheMode != cacheMode()) 442 setCacheMode(mewCacheMode); 443 444 // HTML content: we want to use exposedRect so we don't use WebCore rendering if we don't have to 445 setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true); 446 } 413 if (m_layer->drawsContent()) 414 setCacheMode(m_transformAnimationRunning ? ItemCoordinateCache : DeviceCoordinateCache); 447 415 else 448 416 setCacheMode(NoCache); … … 481 449 482 450 // FIXME: the following flags are currently not handled, as they don't have a clear test or are in low priority 483 // GeometryOrientationChange, ContentsOrientationChange, BackfaceVisibilityChange, ChildrenTransformChange , Preserves3DChange451 // GeometryOrientationChange, ContentsOrientationChange, BackfaceVisibilityChange, ChildrenTransformChange 484 452 485 453 m_state.maskLayer = m_layer->maskLayer(); … … 556 524 557 525 // reimp from GraphicsLayer.h 558 void GraphicsLayerQt::setNeedsDisplayInRect(const FloatRect& r ect)559 { 560 m_impl->m_pendingContent.regionToUpdate|= QRectF(r ect).toAlignedRect();526 void GraphicsLayerQt::setNeedsDisplayInRect(const FloatRect& r) 527 { 528 m_impl->m_pendingContent.regionToUpdate|= QRectF(r).toAlignedRect(); 561 529 m_impl->notifyChange(GraphicsLayerQtImpl::DisplayChange); 562 530 } … … 840 808 static inline qreal applyTimingFunction(const TimingFunction& timingFunction, qreal progress, int duration) 841 809 { 842 if (timingFunction.type() == LinearTimingFunction) 843 return progress; 844 if (timingFunction.type() == CubicBezierTimingFunction) { 845 return solveCubicBezierFunction(timingFunction.x1(), 846 timingFunction.y1(), 847 timingFunction.x2(), 848 timingFunction.y2(), 849 double(progress), double(duration) / 1000); 850 } 810 if (timingFunction.type() == LinearTimingFunction) 851 811 return progress; 812 if (timingFunction.type() == CubicBezierTimingFunction) { 813 return solveCubicBezierFunction(timingFunction.x1(), 814 timingFunction.y1(), 815 timingFunction.x2(), 816 timingFunction.y2(), 817 double(progress), double(duration) / 1000); 818 } 819 return progress; 852 820 } 853 821 … … 859 827 return; 860 828 861 if (const TransformOperations* ops = static_cast<const TransformAnimationValue*>(animationValue)->value()) 829 const TransformOperations* ops = static_cast<const TransformAnimationValue*>(animationValue)->value(); 830 831 if (ops) 862 832 transformOperations = *ops; 863 833 } … … 887 857 888 858 // for some reason I have do this asynchronously - or the animation won't work 889 if (newState == Running && oldState == Stopped && m_layer.data())890 m_layer.data()->notifyAnimationStartedAsync();859 if (newState == Running && oldState == Stopped) 860 QTimer::singleShot(0, m_layer.data(), SLOT(notifyAnimationStarted())); 891 861 } 892 862 … … 963 933 // now we have a source keyframe, origin keyframe and a timing function 964 934 // we can now process the progress and apply the frame 965 progress = (!progress || progress == 1 || it.key() == it2.key()) 966 ? progress 967 : applyTimingFunction(timingFunc, (progress - it.key()) / (it2.key() - it.key()), duration() / 1000); 968 applyFrame(fromValue, toValue, progress); 935 qreal normalizedProgress = (it.key() == it2.key()) ? 0 : (progress - it.key()) / (it2.key() - it.key()); 936 normalizedProgress = applyTimingFunction(timingFunc, normalizedProgress, duration() / 1000); 937 applyFrame(fromValue, toValue, normalizedProgress); 969 938 } 970 939 … … 975 944 public: 976 945 TransformAnimationQt(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name) 977 : AnimationQt<TransformOperations>(layer, values, boxSize, anim, name)946 : AnimationQt<TransformOperations>(layer, values, boxSize, anim, name) 978 947 { 979 948 } … … 984 953 // when the animation dies, the transform has to go back to default 985 954 if (m_layer) 986 m_layer.data()->setBaseTransform( m_layer.data()->m_layer->transform());955 m_layer.data()->setBaseTransform(QTransform(m_layer.data()->m_layer->transform())); 987 956 } 988 957 … … 995 964 TransformationMatrix transformMatrix; 996 965 997 // sometimes the animation values from WebCore are misleading and we have to use the actual matrix as source 998 // The Mac implementation simply doesn't try to accelerate those (e.g. 360deg rotation), but we do. 999 if (progress == 1 || !targetOperations.size() || sourceOperations == targetOperations) { 1000 TransformationMatrix sourceMatrix; 1001 sourceOperations.apply(m_boxSize, sourceMatrix); 1002 transformMatrix = m_sourceMatrix; 1003 transformMatrix.blend(sourceMatrix, 1 - progress); 1004 } else if (targetOperations.size() != sourceOperations.size()) { 1005 transformMatrix = m_sourceMatrix; 1006 targetOperations.apply(m_boxSize, transformMatrix); 1007 transformMatrix.blend(m_sourceMatrix, progress); 1008 } else { 1009 for (size_t i = 0; i < targetOperations.size(); ++i) 1010 targetOperations.operations()[i]->blend(sourceOperations.at(i), progress)->apply(transformMatrix, m_boxSize); 1011 } 1012 m_layer.data()->setBaseTransform(transformMatrix); 966 // this looks simple but is really tricky to get right. Use caution. 967 for (size_t i = 0; i < targetOperations.size(); ++i) 968 targetOperations.operations()[i]->blend(sourceOperations.at(i), progress)->apply(transformMatrix, m_boxSize); 969 970 m_layer.data()->setBaseTransform(QTransform(transformMatrix)); 1013 971 } 1014 972 … … 1023 981 // this is a UX choice that should probably be customizable 1024 982 if (newState == QAbstractAnimation::Running) { 1025 m_sourceMatrix = m_layer.data()->transform();1026 983 m_layer.data()->m_transformAnimationRunning = true; 1027 m_layer.data()->adjustCachingRecursively(true); 984 if (m_layer.data()->cacheMode() == QGraphicsItem::DeviceCoordinateCache) 985 m_layer.data()->setCacheMode(QGraphicsItem::ItemCoordinateCache); 1028 986 } else { 1029 987 m_layer.data()->m_transformAnimationRunning = false; 1030 m_layer.data()->adjustCachingRecursively(false); 1031 } 1032 } 1033 1034 TransformationMatrix m_sourceMatrix; 988 if (m_layer.data()->cacheMode() == QGraphicsItem::ItemCoordinateCache) 989 m_layer.data()->setCacheMode(QGraphicsItem::DeviceCoordinateCache); 990 } 991 } 1035 992 }; 1036 993 … … 1050 1007 { 1051 1008 QAbstractAnimation::updateState(newState, oldState); 1052 1053 1009 if (m_layer) 1054 1010 m_layer.data()->m_opacityAnimationRunning = (newState == QAbstractAnimation::Running); … … 1124 1080 { 1125 1081 for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) { 1126 if (!(*it)) 1127 continue; 1128 1129 AnimationQtBase* anim = static_cast<AnimationQtBase*>((*it).data()); 1130 if (anim && anim->m_keyframesName == QString(name)) 1131 QTimer::singleShot(timeOffset * 1000, anim, SLOT(pause())); 1082 if (*it) { 1083 AnimationQtBase* anim = static_cast<AnimationQtBase*>((*it).data()); 1084 if (anim && anim->m_keyframesName == QString(name)) 1085 QTimer::singleShot(timeOffset * 1000, anim, SLOT(pause())); 1086 } 1132 1087 } 1133 1088 } -
trunk/WebKit/qt/Api/qgraphicswebview.cpp
r54281 r54284 28 28 #include "QWebPageClient.h" 29 29 #include <FrameView.h> 30 #include <QtCore/qmetaobject.h>31 30 #include <QtCore/qsharedpointer.h> 32 31 #include <QtCore/qtimer.h> … … 80 79 #if USE(ACCELERATED_COMPOSITING) 81 80 , rootGraphicsLayer(0) 82 , shouldSync( false)81 , shouldSync(true) 83 82 #endif 84 83 { … … 87 86 // this QGraphicsWebView as the scrollbars are needed when there's no compositing 88 87 q->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption); 89 syncMetaMethod = q->metaObject()->method(q->metaObject()->indexOfMethod("syncLayers()"));90 88 #endif 91 89 } … … 133 131 // compositor telling us to do so. We'll get that call from ChromeClientQt 134 132 bool shouldSync; 135 136 // we have to flush quite often, so we use a meta-method instead of QTimer::singleShot for putting the event in the queue137 QMetaMethod syncMetaMethod;138 133 139 134 // we need to put the root graphics layer behind the overlay (which contains the scrollbar) … … 184 179 shouldSync = true; 185 180 if (scheduleSync) 186 syncMetaMethod.invoke(q, Qt::QueuedConnection);181 QTimer::singleShot(0, q, SLOT(syncLayers())); 187 182 } 188 183 … … 230 225 if (overlay) 231 226 overlay->update(QRectF(dirtyRect)); 232 syncLayers();233 227 #endif 234 228 } … … 449 443 #if USE(ACCELERATED_COMPOSITING) 450 444 page()->mainFrame()->render(painter, d->overlay ? QWebFrame::ContentsLayer : QWebFrame::AllLayers, option->exposedRect.toAlignedRect()); 445 d->syncLayers(); 451 446 #else 452 447 page()->mainFrame()->render(painter, QWebFrame::AllLayers, option->exposedRect.toRect()); -
trunk/WebKit/qt/ChangeLog
r54281 r54284 1 2010-02-03 No'am Rosenthal <noam.rosenthal@nokia.com> 2 3 Reviewed by Laszlo Gombos. 4 5 [Qt] Tuning and optimizations to GraphicsLayerQt. Mainly reduced usage 6 of QTimer::singleShot, and moved syncLayers() from paint() to update() 7 https://bugs.webkit.org/show_bug.cgi?id=34062 1 2010-02-03 Andras Becsi <abecsi@webkit.org> 2 3 Unreviewed build fix. 4 5 [Qt] Roll-out r54281 because it broke the build on the Qt Release bot. 8 6 9 7 * Api/qgraphicswebview.cpp: 10 (QGraphicsWebViewPrivate::update): Moved the sync operation to update 11 (QGraphicsWebView::paint): Moved the sync operation to update 8 (QGraphicsWebViewPrivate::QGraphicsWebViewPrivate): 9 (QGraphicsWebViewPrivate::markForSync): 10 (QGraphicsWebViewPrivate::update): 11 (QGraphicsWebView::paint): 12 12 13 13 2010-02-02 Kenneth Rohde Christiansen <kenneth@webkit.org>
Note: See TracChangeset
for help on using the changeset viewer.