Changeset 54906 in webkit


Ignore:
Timestamp:
Feb 17, 2010, 12:08:08 PM (16 years ago)
Author:
eric@webkit.org
Message:

2010-02-17 Noam Rosenthal <noam.rosenthal@nokia.com>

Reviewed by Ariya Hidayat.

[Qt] GraphicsLayer: support perspective and 3D transforms
https://bugs.webkit.org/show_bug.cgi?id=34960

  • WebKit.pri: added appropriate define: ENABLED_3D_RENDERING

2010-02-17 Noam Rosenthal <noam.rosenthal@nokia.com>

Reviewed by Ariya Hidayat.

[Qt] GraphicsLayer: support perspective and 3D transforms
https://bugs.webkit.org/show_bug.cgi?id=34960

New tests: http://webkit.org/blog-files/3d-transforms/perspective-by-example.html

  • platform/graphics/qt/GraphicsLayerQt.cpp: (WebCore::GraphicsLayerQtImpl::updateTransform): (WebCore::GraphicsLayerQtImpl::setBaseTransform): (WebCore::GraphicsLayerQtImpl::computeTransform): (WebCore::GraphicsLayerQtImpl::flushChanges): (WebCore::TransformAnimationQt::~TransformAnimationQt):
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r54878 r54906  
     12010-02-17  Noam Rosenthal  <noam.rosenthal@nokia.com>
     2
     3        Reviewed by Ariya Hidayat.
     4
     5        [Qt] GraphicsLayer: support perspective and 3D transforms
     6        https://bugs.webkit.org/show_bug.cgi?id=34960
     7
     8        * WebKit.pri: added appropriate define: ENABLED_3D_RENDERING
     9
    1102010-02-15  Philippe Normand  <pnormand@igalia.com>
    211
  • trunk/WebCore/ChangeLog

    r54905 r54906  
     12010-02-17  Noam Rosenthal  <noam.rosenthal@nokia.com>
     2
     3        Reviewed by Ariya Hidayat.
     4
     5        [Qt] GraphicsLayer: support perspective and 3D transforms
     6        https://bugs.webkit.org/show_bug.cgi?id=34960
     7
     8        New tests: http://webkit.org/blog-files/3d-transforms/perspective-by-example.html
     9
     10        * platform/graphics/qt/GraphicsLayerQt.cpp:
     11        (WebCore::GraphicsLayerQtImpl::updateTransform):
     12        (WebCore::GraphicsLayerQtImpl::setBaseTransform):
     13        (WebCore::GraphicsLayerQtImpl::computeTransform):
     14        (WebCore::GraphicsLayerQtImpl::flushChanges):
     15        (WebCore::TransformAnimationQt::~TransformAnimationQt):
     16
    1172010-02-17  Peter Kasting  <pkasting@google.com>
    218
  • trunk/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp

    r54644 r54906  
    137137
    138138    // we manage transforms ourselves because transform-origin acts differently in webkit and in Qt
    139     void setBaseTransform(const QTransform&);
     139    void setBaseTransform(const TransformationMatrix&);
     140    QTransform computeTransform(const TransformationMatrix& baseTransform) const;
     141    void updateTransform();
    140142
    141143    // let the compositor-API tell us which properties were changed
     
    146148    // (meaning the sync would happen together with the next draw)
    147149    // or ChromeClientQt::scheduleCompositingLayerSync (meaning the sync will happen ASAP)
    148     void flushChanges(bool recursive = true);
     150    void flushChanges(bool recursive = true, bool forceTransformUpdate = false);
    149151
    150152    // optimization: when we have an animation running on an element with no contents, that has child-elements with contents,
     
    167169    GraphicsLayerQt* m_layer;
    168170
    169     QTransform m_baseTransform;
     171    TransformationMatrix m_baseTransform;
    170172    bool m_transformAnimationRunning;
    171173    bool m_opacityAnimationRunning;
     
    281283}
    282284
    283 void GraphicsLayerQtImpl::setBaseTransform(const QTransform& transform)
     285void GraphicsLayerQtImpl::updateTransform()
     286{
     287    setBaseTransform(isTransformAnimationRunning() ? m_baseTransform : m_layer->transform());
     288}
     289
     290void GraphicsLayerQtImpl::setBaseTransform(const TransformationMatrix& baseTransform)
     291{
     292    m_baseTransform = baseTransform;
     293    setTransform(computeTransform(baseTransform));
     294}
     295
     296QTransform GraphicsLayerQtImpl::computeTransform(const TransformationMatrix& baseTransform) const
    284297{
    285298    if (!m_layer)
    286         return;
     299        return baseTransform;
     300
     301    TransformationMatrix computedTransform;
     302
     303    // The origin for childrenTransform is always the center of the ancestor which contains the childrenTransform.
     304    // this has to do with how WebCore implements -webkit-perspective and -webkit-perspective-origin, which are the CSS
     305    // attribute that call setChildrenTransform
     306    QPointF offset = -pos() - boundingRect().bottomRight() / 2;
     307    const GraphicsLayerQtImpl* ancestor = this;
     308    while ((ancestor = qobject_cast<GraphicsLayerQtImpl*>(ancestor->parentObject()))) {
     309        if (!ancestor->m_state.childrenTransform.isIdentity()) {
     310            offset += ancestor->boundingRect().bottomRight() / 2;
     311            computedTransform
     312                .translate(offset.x(), offset.y())
     313                .multLeft(ancestor->m_state.childrenTransform)
     314                .translate(-offset.x(), -offset.y());
     315            break;
     316        }
     317        offset -= ancestor->pos();
     318    }
     319
     320    computedTransform.multLeft(baseTransform);
     321
    287322    // webkit has relative-to-size originPoint, graphics-view has a pixel originPoint, here we convert
    288323    // we have to manage this ourselves because QGraphicsView's transformOrigin is incompatible
    289     const qreal x = m_layer->anchorPoint().x() * m_layer->size().width();
    290     const qreal y = m_layer->anchorPoint().y() * m_layer->size().height();
    291     setTransform(QTransform::fromTranslate(x, y));
    292     setTransform(transform, true);
    293     translate(-x, -y);
    294     m_baseTransform = transform;
     324    const qreal originX = m_state.anchorPoint.x() * m_size.width();
     325    const qreal originY = m_state.anchorPoint.y() * m_size.height();
     326    computedTransform = TransformationMatrix()
     327                            .translate(originX, originY)
     328                            .multiply(computedTransform)
     329                            .translate(-originX, -originY);
     330
     331    // now we project to 2D
     332    return QTransform(computedTransform);
    295333}
    296334
     
    358396}
    359397
    360 void GraphicsLayerQtImpl::flushChanges(bool recursive)
     398void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform)
    361399{
    362400    // this is the bulk of the work. understanding what the compositor is trying to achieve,
     
    426464    }
    427465
    428     if (m_changeMask & (TransformChange | AnchorPointChange | SizeChange)) {
    429         // since we convert a percentage-based origin-point to a pixel-based one,
    430         // the anchor-point, transform and size from WebCore all affect the one
    431         // that we give Qt
    432         if (m_state.transform != m_layer->transform() || m_state.anchorPoint != m_layer->anchorPoint() || m_state.size != m_layer->size())
    433             setBaseTransform(m_layer->transform());
     466    // FIXME: this is a hack, due to a probable QGraphicsScene bug when rapidly modifying the perspective
     467    // but without this line we get graphic artifacts
     468    if ((m_changeMask & ChildrenTransformChange) && m_state.childrenTransform != m_layer->childrenTransform())
     469        scene()->update();
     470
     471    if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange)) {
     472        // due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
     473        // all these elements affect the transforms of all the descendants.
     474        forceUpdateTransform = true;
    434475    }
    435476
     
    440481            setFlag(ItemHasNoContents, false);
    441482
    442             // we only use ItemUsesExtendedStyleOption for HTML content - pixmap can be handled better with regular clipping
    443             setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, false);
    444483            break;
    445484
     
    525564    m_state.contentsOpaque = m_layer->contentsOpaque();
    526565    m_state.backfaceVisibility = m_layer->backfaceVisibility();
     566    m_state.childrenTransform = m_layer->childrenTransform();
    527567    m_currentContent.pixmap = m_pendingContent.pixmap;
    528568    m_currentContent.contentType = m_pendingContent.contentType;
     
    535575
    536576afterLayerChanges:
     577    if (forceUpdateTransform)
     578        updateTransform();
     579
    537580    if (!recursive)
    538581        return;   
     
    545588        if (QGraphicsItem* item = *it)
    546589            if (GraphicsLayerQtImpl* layer = qobject_cast<GraphicsLayerQtImpl*>(item->toGraphicsObject()))
    547                 layer->flushChanges(true);
     590                layer->flushChanges(true, forceUpdateTransform);
    548591    }
    549592}
     
    10141057        // when the animation dies, the transform has to go back to default
    10151058        if (m_layer)
    1016             m_layer.data()->setBaseTransform(m_layer.data()->m_layer->transform());
     1059            m_layer.data()->updateTransform();
    10171060    }
    10181061
  • trunk/WebKit.pri

    r54715 r54906  
    5151}
    5252greaterThan(QT_MINOR_VERSION, 5):DEFINES += WTF_USE_ACCELERATED_COMPOSITING
     53greaterThan(QT_MINOR_VERSION, 5):DEFINES += ENABLE_3D_RENDERING=1
    5354
    5455!mac:!unix|symbian {
Note: See TracChangeset for help on using the changeset viewer.