diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp | 147 |
1 files changed, 84 insertions, 63 deletions
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp index d164a6b85..9293c972f 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp @@ -24,8 +24,10 @@ #include "LayerTreeHostProxy.h" #include "QtWebPageEventHandler.h" #include "TransformationMatrix.h" +#include "WebLayerTreeRenderer.h" #include "qquickwebpage_p_p.h" #include "qquickwebview_p.h" +#include <QPolygonF> #include <QtQuick/QQuickCanvas> #include <QtQuick/QSGGeometryNode> #include <QtQuick/QSGMaterial> @@ -36,6 +38,7 @@ QQuickWebPage::QQuickWebPage(QQuickWebView* viewportItem) , d(new QQuickWebPagePrivate(this, viewportItem)) { setFlag(ItemHasContents); + setClip(true); // We do the transform from the top left so the viewport can assume the position 0, 0 // is always where rendering starts. @@ -63,18 +66,6 @@ void QQuickWebPagePrivate::initialize(WebKit::WebPageProxy* webPageProxy) eventHandler.reset(new QtWebPageEventHandler(toAPI(webPageProxy), q, viewportItem)); } -static float computeEffectiveOpacity(const QQuickItem* item) -{ - if (!item) - return 1; - - float opacity = item->opacity(); - if (opacity < 0.01) - return 0; - - return opacity * computeEffectiveOpacity(item->parentItem()); -} - void QQuickWebPagePrivate::setDrawingAreaSize(const QSize& size) { DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); @@ -89,69 +80,109 @@ void QQuickWebPagePrivate::paint(QPainter* painter) webPageProxy->drawingArea()->paintLayerTree(painter); } -void QQuickWebPagePrivate::paintToCurrentGLContext() -{ - if (!q->isVisible()) - return; - - QTransform transform = q->itemTransform(0, 0); - transform.scale(contentsScale, contentsScale); - - float opacity = computeEffectiveOpacity(q); - QRectF clipRect = viewportItem->mapRectToScene(viewportItem->boundingRect()); - - if (!clipRect.isValid()) - return; - - DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); - if (!drawingArea) - return; - - drawingArea->paintToCurrentGLContext(transform, opacity, clipRect); -} - struct PageProxyNode : public QSGRenderNode { - PageProxyNode(QQuickWebPagePrivate* page) - : m_pagePrivate(page) + PageProxyNode(PassRefPtr<WebLayerTreeRenderer> renderer) + : m_renderer(renderer) + , m_scale(1) { } virtual StateFlags changedStates() { - return StateFlags(DepthState) | StencilState | ScissorState | ColorState | BlendState - | CullState | ViewportState; + return StateFlags(StencilState) | ColorState | BlendState; } - virtual void render(const RenderState &) + virtual void render(const RenderState&) { - if (m_pagePrivate) - m_pagePrivate->paintToCurrentGLContext(); + QMatrix4x4 renderMatrix = matrix() ? *matrix() : QMatrix4x4(); + + // Have to apply render scale manualy because it is not applied on page item. + // http://trac.webkit.org/changeset/104450 + renderMatrix.scale(m_scale); + + // FIXME: Support non-rectangular clippings. + layerTreeRenderer()->paintToCurrentGLContext(renderMatrix, inheritedOpacity(), clipRect()); } ~PageProxyNode() { - if (m_pagePrivate) - m_pagePrivate->resetPaintNode(); + layerTreeRenderer()->purgeGLResources(); } - QQuickWebPagePrivate* m_pagePrivate; + WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); } + void setScale(float scale) { m_scale = scale; } + +private: + QRectF clipRect() const + { + // Start with an invalid rect. + QRectF resultRect(0, 0, -1, -1); + + for (const QSGClipNode* clip = clipList(); clip; clip = clip->clipList()) { + QMatrix4x4 clipMatrix; + if (clip->matrix()) + clipMatrix = *clip->matrix(); + QRectF currentClip; + + if (clip->isRectangular()) + currentClip = clipMatrix.mapRect(clip->clipRect()); + else { + const QSGGeometry* geometry = clip->geometry(); + // Assume here that clipNode has only coordinate data. + const QSGGeometry::Point2D* geometryPoints = geometry->vertexDataAsPoint2D(); + + // Clip region should be at least triangle to make valid clip. + if (geometry->vertexCount() < 3) + continue; + + QPolygonF polygon; + + for (int i = 0; i < geometry->vertexCount(); i++) + polygon.append(clipMatrix.map(QPoint(geometryPoints[i].x, geometryPoints[i].y))); + currentClip = polygon.boundingRect(); + } + + if (currentClip.isEmpty()) + continue; + + if (resultRect.isValid()) + resultRect &= currentClip; + else + resultRect = currentClip; + } + + return resultRect; + } + + RefPtr<WebLayerTreeRenderer> m_renderer; + float m_scale; }; QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { - if (!(flags() & ItemHasContents)) { - if (oldNode) - delete oldNode; - return 0; - } + if (!d->webPageProxy->drawingArea()) + return oldNode; + + LayerTreeHostProxy* layerTreeHostProxy = d->webPageProxy->drawingArea()->layerTreeHostProxy(); + WebLayerTreeRenderer* renderer = layerTreeHostProxy->layerTreeRenderer(); - PageProxyNode* proxyNode = static_cast<PageProxyNode*>(oldNode); - if (!proxyNode) { - proxyNode = new PageProxyNode(d); - d->m_paintNode = proxyNode; + PageProxyNode* node = static_cast<PageProxyNode*>(oldNode); + + if (node && node->layerTreeRenderer() != renderer) { + // This means that LayerTreeHostProxy was deleted and recreated while old paint node survived. + // This could happen if web process have crashed. In this case we have to recreate paint node. + delete node; + node = 0; } - return proxyNode; + renderer->syncRemoteContent(); + + if (!node) + node = new PageProxyNode(renderer); + + node->setScale(d->contentsScale); + + return node; } QtWebPageEventHandler* QQuickWebPage::eventHandler() const @@ -205,18 +236,8 @@ void QQuickWebPagePrivate::updateSize() viewportItem->updateContentsSize(scaledSize); } -void QQuickWebPagePrivate::resetPaintNode() -{ - m_paintNode = 0; - DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); - if (drawingArea && drawingArea->layerTreeHostProxy()) - drawingArea->layerTreeHostProxy()->purgeGLResources(); -} - QQuickWebPagePrivate::~QQuickWebPagePrivate() { - if (m_paintNode) - static_cast<PageProxyNode*>(m_paintNode)->m_pagePrivate = 0; } #include "moc_qquickwebpage_p.cpp" |