Title: [101683] trunk/Source/WebKit2
Revision
101683
Author
[email protected]
Date
2011-12-01 10:02:20 -0800 (Thu, 01 Dec 2011)

Log Message

[Qt] [WK2] QQuickWebView covers QML elements that should be rendered on top.
https://bugs.webkit.org/show_bug.cgi?id=73338

Patch by Viatcheslav Ostapenko <[email protected]> on 2011-12-01
Reviewed by Noam Rosenthal.

Move painting of QQuickWebPage content from canvas afterrendering() to
QSGGeometryNode/QSGMaterial based paint node. Implementation uses QSGMaterialShader
updateState() method to draw TextureMapper graphics layers.
This is considered to be temporary until QSGNode::UserNodeType will be available.

* UIProcess/API/qt/qquickwebpage.cpp:
(QQuickWebPage::QQuickWebPage):
(QQuickWebPagePrivate::QQuickWebPagePrivate):
(PageProxyMaterialShader::attributeNames):
(PageProxyMaterialShader::vertexShader):
(PageProxyMaterialShader::fragmentShader):
(PageProxyMaterial::PageProxyMaterial):
(PageProxyMaterial::type):
(PageProxyMaterial::createShader):
(PageProxyNode::PageProxyNode):
(PageProxyNode::~PageProxyNode):
(PageProxyMaterialShader::updateState):
(QQuickWebPage::updatePaintNode):
(QQuickWebPagePrivate::resetPaintNode):
(QQuickWebPagePrivate::~QQuickWebPagePrivate):
* UIProcess/API/qt/qquickwebpage_p.h:
* UIProcess/API/qt/qquickwebpage_p_p.h:
* UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp:
(tst_QQuickWebView::showWebView):
* UIProcess/qt/LayerTreeHostProxyQt.cpp:
(WebKit::LayerTreeHostProxy::didRenderFrame):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (101682 => 101683)


--- trunk/Source/WebKit2/ChangeLog	2011-12-01 17:57:32 UTC (rev 101682)
+++ trunk/Source/WebKit2/ChangeLog	2011-12-01 18:02:20 UTC (rev 101683)
@@ -1,3 +1,37 @@
+2011-12-01  Viatcheslav Ostapenko  <[email protected]>
+
+        [Qt] [WK2] QQuickWebView covers QML elements that should be rendered on top.
+        https://bugs.webkit.org/show_bug.cgi?id=73338
+
+        Reviewed by Noam Rosenthal.
+
+        Move painting of QQuickWebPage content from canvas afterrendering() to
+        QSGGeometryNode/QSGMaterial based paint node. Implementation uses QSGMaterialShader
+        updateState() method to draw TextureMapper graphics layers.
+        This is considered to be temporary until QSGNode::UserNodeType will be available.
+
+        * UIProcess/API/qt/qquickwebpage.cpp:
+        (QQuickWebPage::QQuickWebPage):
+        (QQuickWebPagePrivate::QQuickWebPagePrivate):
+        (PageProxyMaterialShader::attributeNames):
+        (PageProxyMaterialShader::vertexShader):
+        (PageProxyMaterialShader::fragmentShader):
+        (PageProxyMaterial::PageProxyMaterial):
+        (PageProxyMaterial::type):
+        (PageProxyMaterial::createShader):
+        (PageProxyNode::PageProxyNode):
+        (PageProxyNode::~PageProxyNode):
+        (PageProxyMaterialShader::updateState):
+        (QQuickWebPage::updatePaintNode):
+        (QQuickWebPagePrivate::resetPaintNode):
+        (QQuickWebPagePrivate::~QQuickWebPagePrivate):
+        * UIProcess/API/qt/qquickwebpage_p.h:
+        * UIProcess/API/qt/qquickwebpage_p_p.h:
+        * UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp:
+        (tst_QQuickWebView::showWebView):
+        * UIProcess/qt/LayerTreeHostProxyQt.cpp:
+        (WebKit::LayerTreeHostProxy::didRenderFrame):
+
 2011-12-01  Nayan Kumar K  <[email protected]>
 
         [WK2][GTK] Change default-font-size and default-monospace-font-size

Modified: trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp (101682 => 101683)


--- trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp	2011-12-01 17:57:32 UTC (rev 101682)
+++ trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp	2011-12-01 18:02:20 UTC (rev 101683)
@@ -27,7 +27,9 @@
 #include "qquickwebpage_p_p.h"
 #include "qquickwebview_p.h"
 #include <QtCore/QUrl>
+#include <QtDeclarative/QSGGeometryNode>
 #include <QtDeclarative/QQuickCanvas>
+#include <QtDeclarative/QSGMaterial>
 
 QQuickWebPage::QQuickWebPage(QQuickItem* parent)
     : QQuickItem(parent)
@@ -38,7 +40,6 @@
     // We do the transform from the top left so the viewport can assume the position 0, 0
     // is always where rendering starts.
     setTransformOrigin(TopLeft);
-    d->initializeSceneGraphConnections();
 }
 
 QQuickWebPage::~QQuickWebPage()
@@ -158,31 +159,15 @@
     this->event(event);
 }
 
-void QQuickWebPage::itemChange(ItemChange change, const ItemChangeData& data)
-{
-    if (change == ItemSceneChange)
-        d->initializeSceneGraphConnections();
-    QQuickItem::itemChange(change, data);
-}
-
 QQuickWebPagePrivate::QQuickWebPagePrivate(QQuickWebPage* view)
     : q(view)
     , pageProxy(0)
     , sgUpdateQueue(view)
     , paintingIsInitialized(false)
+    , m_paintNode(0)
 {
 }
 
-void QQuickWebPagePrivate::initializeSceneGraphConnections()
-{
-    if (paintingIsInitialized)
-        return;
-    if (!q->canvas())
-        return;
-    paintingIsInitialized = true;
-    QObject::connect(q->canvas(), SIGNAL(afterRendering()), q, SLOT(_q_onAfterSceneRender()), Qt::DirectConnection);
-}
-
 void QQuickWebPagePrivate::setPageProxy(QtWebPageProxy* pageProxy)
 {
     ASSERT(!this->pageProxy);
@@ -233,10 +218,107 @@
     ASSERT(!glGetError());
 }
 
-void QQuickWebPagePrivate::_q_onAfterSceneRender()
+struct PageProxyMaterial;
+struct PageProxyNode;
+
+// FIXME: temporary until Qt Scenegraph will support custom painting.
+struct PageProxyMaterialShader : public QSGMaterialShader {
+    virtual void updateState(const RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial);
+    virtual char const* const* attributeNames() const
+    {
+        static char const* const attr[] = { 0 };
+        return attr;
+    }
+
+    // vertexShader and fragmentShader are no-op shaders.
+    // All real painting is gone by TextureMapper through LayerTreeHostProxy.
+    virtual const char* vertexShader() const
+    {
+        return "void main() { gl_Position = gl_Vertex; }";
+    }
+
+    virtual const char* fragmentShader() const
+    {
+        return "void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); }";
+    }
+};
+
+struct PageProxyMaterial : public QSGMaterial {
+    PageProxyMaterial(PageProxyNode* node) : m_node(node) { }
+
+    QSGMaterialType* type() const
+    {
+        static QSGMaterialType type;
+        return &type;
+    }
+
+    QSGMaterialShader* createShader() const
+    {
+        return new PageProxyMaterialShader;
+    }
+
+    PageProxyNode* m_node;
+};
+
+struct PageProxyNode : public QSGGeometryNode {
+    PageProxyNode(QQuickWebPagePrivate* page) :
+        m_pagePrivate(page)
+      , m_material(this)
+      , m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
+    {
+        setGeometry(&m_geometry);
+        setMaterial(&m_material);
+    }
+
+    ~PageProxyNode()
+    {
+        if (m_pagePrivate)
+            m_pagePrivate->resetPaintNode();
+    }
+
+    QQuickWebPagePrivate* m_pagePrivate;
+    PageProxyMaterial m_material;
+    QSGGeometry m_geometry;
+};
+
+void PageProxyMaterialShader::updateState(const RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial)
 {
-    // TODO: Allow painting before the scene or in the middle of the scene with an FBO.
-    paintToCurrentGLContext();
+    if (!newMaterial)
+        return;
+
+    PageProxyNode* node = static_cast<PageProxyMaterial*>(newMaterial)->m_node;
+    // FIXME: Normally we wouldn't paint inside QSGMaterialShader::updateState,
+    // but this is a temporary hack until custom paint nodes are available.
+    if (node->m_pagePrivate)
+        node->m_pagePrivate->paintToCurrentGLContext();
 }
 
+QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*)
+{
+    if (!(flags() & ItemHasContents)) {
+        if (oldNode)
+            delete oldNode;
+        return 0;
+    }
+
+    PageProxyNode* proxyNode = static_cast<PageProxyNode*>(oldNode);
+    if (!proxyNode) {
+        proxyNode = new PageProxyNode(d);
+        d->m_paintNode = proxyNode;
+    }
+
+    return proxyNode;
+}
+
+void QQuickWebPagePrivate::resetPaintNode()
+{
+    m_paintNode = 0;
+}
+
+QQuickWebPagePrivate::~QQuickWebPagePrivate()
+{
+    if (m_paintNode)
+        static_cast<PageProxyNode*>(m_paintNode)->m_pagePrivate = 0;
+}
+
 #include "moc_qquickwebpage_p.cpp"

Modified: trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h (101682 => 101683)


--- trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h	2011-12-01 17:57:32 UTC (rev 101682)
+++ trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h	2011-12-01 18:02:20 UTC (rev 101683)
@@ -65,11 +65,9 @@
     virtual void touchEvent(QTouchEvent*);
     virtual bool event(QEvent*);
     virtual void geometryChanged(const QRectF&, const QRectF&);
-    virtual void itemChange(ItemChange, const ItemChangeData&);
+    virtual QSGNode* updatePaintNode(QSGNode*, UpdatePaintNodeData*);
 
 private:
-    Q_PRIVATE_SLOT(d, void _q_onAfterSceneRender());
-
     QQuickWebPagePrivate* d;
     friend class QQuickWebView;
     friend class QQuickWebViewPrivate;

Modified: trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h (101682 => 101683)


--- trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h	2011-12-01 17:57:32 UTC (rev 101682)
+++ trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h	2011-12-01 18:02:20 UTC (rev 101683)
@@ -36,18 +36,18 @@
 class QQuickWebPagePrivate {
 public:
     QQuickWebPagePrivate(QQuickWebPage* view);
+    ~QQuickWebPagePrivate();
 
     void setPageProxy(QtWebPageProxy*);
 
-    void initializeSceneGraphConnections();
-
-    void _q_onAfterSceneRender();
     void paintToCurrentGLContext();
+    void resetPaintNode();
 
     QQuickWebPage* const q;
     QtWebPageProxy* pageProxy;
     WebKit::QtSGUpdateQueue sgUpdateQueue;
     bool paintingIsInitialized;
+    QSGNode* m_paintNode;
 };
 
 #endif // qquickwebpage_p_p_h

Modified: trunk/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp (101682 => 101683)


--- trunk/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp	2011-12-01 17:57:32 UTC (rev 101682)
+++ trunk/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp	2011-12-01 18:02:20 UTC (rev 101683)
@@ -49,6 +49,7 @@
     void scrollRequest();
 
     void show();
+    void showWebView();
 
 private:
     inline QQuickWebView* webView() const;
@@ -239,6 +240,21 @@
     m_window->hide();
 }
 
+void tst_QQuickWebView::showWebView()
+{
+    webView()->setSize(QSizeF(300, 400));
+
+    webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html")));
+    QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded())));
+
+    m_window->show();
+    // This should not crash.
+    webView()->setVisible(true);
+    QTest::qWait(200);
+    webView()->setVisible(false);
+    QTest::qWait(200);
+}
+
 void tst_QQuickWebView::scrollRequest()
 {
     webView()->setSize(QSizeF(300, 400));

Modified: trunk/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp (101682 => 101683)


--- trunk/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp	2011-12-01 17:57:32 UTC (rev 101682)
+++ trunk/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp	2011-12-01 18:02:20 UTC (rev 101683)
@@ -587,6 +587,7 @@
 {
     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::RenderNextFrame(), m_drawingAreaProxy->page()->pageID());
     pushUpdateToQueue(FlushLayerChangesMessage::create());
+    updateViewport();
 }
 
 void LayerTreeHostProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to