Add test expectation for one more test having color space issues after r156793.
[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 <QtGui/QPolygonF>
25 #include <QtQuick/QQuickItem>
26 #include <QtQuick/QQuickWindow>
27 #include <QtQuick/QSGSimpleRectNode>
28 #include <WebCore/CoordinatedGraphicsScene.h>
29 #include <WebCore/TransformationMatrix.h>
30 #include <private/qsgrendernode_p.h>
31
32 using namespace WebCore;
33
34 namespace WebKit {
35
36 class ContentsSGNode : public QSGRenderNode {
37 public:
38     ContentsSGNode(PassRefPtr<CoordinatedGraphicsScene> scene)
39         : m_scene(scene)
40     {
41         coordinatedGraphicsScene()->setActive(true);
42     }
43
44     virtual StateFlags changedStates()
45     {
46         return StateFlags(StencilState) | ColorState | BlendState;
47     }
48
49     virtual void render(const RenderState& state)
50     {
51         TransformationMatrix renderMatrix;
52         if (pageNode()->devicePixelRatio() != 1.0) {
53             renderMatrix.scale(pageNode()->devicePixelRatio());
54             if (matrix())
55                 renderMatrix.multiply(*matrix());
56         } else if (matrix())
57             renderMatrix = *matrix();
58
59         // When rendering to an intermediate surface, Qt will
60         // mirror the projection matrix to fit on the destination coordinate system.
61         const QMatrix4x4* projection = state.projectionMatrix;
62         bool mirrored = projection && (*projection)(0, 0) * (*projection)(1, 1) - (*projection)(0, 1) * (*projection)(1, 0) > 0;
63
64         // FIXME: Support non-rectangular clippings.
65         coordinatedGraphicsScene()->paintToCurrentGLContext(renderMatrix, inheritedOpacity(), clipRect(), mirrored ? TextureMapper::PaintingMirrored : 0);
66     }
67
68     ~ContentsSGNode()
69     {
70         coordinatedGraphicsScene()->purgeGLResources();
71     }
72
73     const QtWebPageSGNode* pageNode() const
74     {
75         const QtWebPageSGNode* parent = static_cast<QtWebPageSGNode*>(this->parent());
76         ASSERT(parent);
77         return parent;
78     }
79
80     WebCore::CoordinatedGraphicsScene* coordinatedGraphicsScene() const { return m_scene.get(); }
81
82 private:
83     QRectF clipRect() const
84     {
85         // Start with an invalid rect.
86         QRectF resultRect(0, 0, -1, -1);
87
88         for (const QSGClipNode* clip = clipList(); clip; clip = clip->clipList()) {
89             QMatrix4x4 clipMatrix;
90             if (pageNode()->devicePixelRatio() != 1.0) {
91                 clipMatrix.scale(pageNode()->devicePixelRatio());
92                 if (clip->matrix())
93                     clipMatrix *= (*clip->matrix());
94             } else if (clip->matrix())
95                 clipMatrix = *clip->matrix();
96
97             QRectF currentClip;
98
99             if (clip->isRectangular())
100                 currentClip = clipMatrix.mapRect(clip->clipRect());
101             else {
102                 const QSGGeometry* geometry = clip->geometry();
103                 // Assume here that clipNode has only coordinate data.
104                 const QSGGeometry::Point2D* geometryPoints = geometry->vertexDataAsPoint2D();
105
106                 // Clip region should be at least triangle to make valid clip.
107                 if (geometry->vertexCount() < 3)
108                     continue;
109
110                 QPolygonF polygon;
111
112                 for (int i = 0; i < geometry->vertexCount(); i++)
113                     polygon.append(clipMatrix.map(QPointF(geometryPoints[i].x, geometryPoints[i].y)));
114                 currentClip = polygon.boundingRect();
115             }
116
117             if (currentClip.isEmpty())
118                 continue;
119
120             if (resultRect.isValid())
121                 resultRect &= currentClip;
122             else
123                 resultRect = currentClip;
124         }
125
126         return resultRect;
127     }
128
129     RefPtr<WebCore::CoordinatedGraphicsScene> m_scene;
130 };
131
132 QtWebPageSGNode::QtWebPageSGNode()
133     : m_contentsNode(0)
134     , m_backgroundNode(new QSGSimpleRectNode)
135     , m_devicePixelRatio(1)
136 {
137     appendChildNode(m_backgroundNode);
138 }
139
140 void QtWebPageSGNode::setBackground(const QRectF& rect, const QColor& color)
141 {
142     m_backgroundNode->setRect(rect);
143     m_backgroundNode->setColor(color);
144 }
145
146 void QtWebPageSGNode::setScale(float scale)
147 {
148     QMatrix4x4 matrix;
149     matrix.scale(scale);
150     setMatrix(matrix);
151 }
152
153 void QtWebPageSGNode::setCoordinatedGraphicsScene(PassRefPtr<WebCore::CoordinatedGraphicsScene> scene)
154 {
155     if (m_contentsNode && m_contentsNode->coordinatedGraphicsScene() == scene)
156         return;
157
158     delete m_contentsNode;
159     m_contentsNode = new ContentsSGNode(scene);
160     // This sets the parent node of the content to QtWebPageSGNode.
161     appendChildNode(m_contentsNode);
162 }
163
164 } // namespace WebKit