[Qt][WK2] Move non-api classes to WebKit namespace at WebKit2/UiProcess/qt
[WebKit-https.git] / Source / WebKit2 / UIProcess / qt / QtWebPageSGNode.cpp
1 /*
2  * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this program; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "config.h"
22 #include "QtWebPageSGNode.h"
23
24 #include "WebLayerTreeRenderer.h"
25 #include <QtGui/QPolygonF>
26 #include <QtQuick/QSGSimpleRectNode>
27 #include <private/qsgrendernode_p.h>
28
29 using namespace WebCore;
30
31 namespace WebKit {
32
33 class ContentsSGNode : public QSGRenderNode {
34 public:
35     ContentsSGNode(PassRefPtr<WebLayerTreeRenderer> renderer)
36         : m_renderer(renderer)
37     {
38         layerTreeRenderer()->setActive(true);
39     }
40
41     virtual StateFlags changedStates()
42     {
43         return StateFlags(StencilState) | ColorState | BlendState;
44     }
45
46     virtual void render(const RenderState& state)
47     {
48         QMatrix4x4 renderMatrix = matrix() ? *matrix() : QMatrix4x4();
49
50         // When rendering to an intermediate surface, Qt will
51         // mirror the projection matrix to fit on the destination coordinate system.
52         const QMatrix4x4* projection = state.projectionMatrix;
53         bool mirrored = projection && (*projection)(0, 0) * (*projection)(1, 1) - (*projection)(0, 1) * (*projection)(1, 0) > 0;
54
55         // FIXME: Support non-rectangular clippings.
56         layerTreeRenderer()->paintToCurrentGLContext(renderMatrix, inheritedOpacity(), clipRect(), mirrored ? TextureMapper::PaintingMirrored : 0);
57     }
58
59     ~ContentsSGNode()
60     {
61         layerTreeRenderer()->purgeGLResources();
62     }
63
64     WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); }
65
66 private:
67     QRectF clipRect() const
68     {
69         // Start with an invalid rect.
70         QRectF resultRect(0, 0, -1, -1);
71
72         for (const QSGClipNode* clip = clipList(); clip; clip = clip->clipList()) {
73             QMatrix4x4 clipMatrix;
74             if (clip->matrix())
75                 clipMatrix = *clip->matrix();
76             QRectF currentClip;
77
78             if (clip->isRectangular())
79                 currentClip = clipMatrix.mapRect(clip->clipRect());
80             else {
81                 const QSGGeometry* geometry = clip->geometry();
82                 // Assume here that clipNode has only coordinate data.
83                 const QSGGeometry::Point2D* geometryPoints = geometry->vertexDataAsPoint2D();
84
85                 // Clip region should be at least triangle to make valid clip.
86                 if (geometry->vertexCount() < 3)
87                     continue;
88
89                 QPolygonF polygon;
90
91                 for (int i = 0; i < geometry->vertexCount(); i++)
92                     polygon.append(clipMatrix.map(QPointF(geometryPoints[i].x, geometryPoints[i].y)));
93                 currentClip = polygon.boundingRect();
94             }
95
96             if (currentClip.isEmpty())
97                 continue;
98
99             if (resultRect.isValid())
100                 resultRect &= currentClip;
101             else
102                 resultRect = currentClip;
103         }
104
105         return resultRect;
106     }
107
108     RefPtr<WebLayerTreeRenderer> m_renderer;
109 };
110
111 QtWebPageSGNode::QtWebPageSGNode()
112     : m_contentsNode(0)
113     , m_backgroundNode(new QSGSimpleRectNode)
114 {
115     appendChildNode(m_backgroundNode);
116 }
117
118 void QtWebPageSGNode::setBackground(const QRectF& rect, const QColor& color)
119 {
120     m_backgroundNode->setRect(rect);
121     m_backgroundNode->setColor(color);
122 }
123
124 void QtWebPageSGNode::setScale(float scale)
125 {
126     QMatrix4x4 matrix;
127     matrix.scale(scale);
128     setMatrix(matrix);
129 }
130
131 void QtWebPageSGNode::setRenderer(PassRefPtr<WebLayerTreeRenderer> renderer)
132 {
133     if (m_contentsNode && m_contentsNode->layerTreeRenderer() == renderer)
134         return;
135
136     delete m_contentsNode;
137     m_contentsNode = new ContentsSGNode(renderer);
138     appendChildNode(m_contentsNode);
139 }
140
141 } // namespace WebKit