QtWebPageSGNode.cpp [plain text]
#include "config.h"
#include "QtWebPageSGNode.h"
#include "WebLayerTreeRenderer.h"
#include <QtGui/QPolygonF>
#include <QtQuick/QSGSimpleRectNode>
#include <private/qsgrendernode_p.h>
using namespace WebCore;
namespace WebKit {
class ContentsSGNode : public QSGRenderNode {
public:
ContentsSGNode(PassRefPtr<WebLayerTreeRenderer> renderer)
: m_renderer(renderer)
{
layerTreeRenderer()->setActive(true);
}
virtual StateFlags changedStates()
{
return StateFlags(StencilState) | ColorState | BlendState;
}
virtual void render(const RenderState& state)
{
QMatrix4x4 renderMatrix = matrix() ? *matrix() : QMatrix4x4();
const QMatrix4x4* projection = state.projectionMatrix;
bool mirrored = projection && (*projection)(0, 0) * (*projection)(1, 1) - (*projection)(0, 1) * (*projection)(1, 0) > 0;
layerTreeRenderer()->paintToCurrentGLContext(renderMatrix, inheritedOpacity(), clipRect(), mirrored ? TextureMapper::PaintingMirrored : 0);
}
~ContentsSGNode()
{
layerTreeRenderer()->purgeGLResources();
}
WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); }
private:
QRectF clipRect() const
{
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();
const QSGGeometry::Point2D* geometryPoints = geometry->vertexDataAsPoint2D();
if (geometry->vertexCount() < 3)
continue;
QPolygonF polygon;
for (int i = 0; i < geometry->vertexCount(); i++)
polygon.append(clipMatrix.map(QPointF(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;
};
QtWebPageSGNode::QtWebPageSGNode()
: m_contentsNode(0)
, m_backgroundNode(new QSGSimpleRectNode)
{
appendChildNode(m_backgroundNode);
}
void QtWebPageSGNode::setBackground(const QRectF& rect, const QColor& color)
{
m_backgroundNode->setRect(rect);
m_backgroundNode->setColor(color);
}
void QtWebPageSGNode::setScale(float scale)
{
QMatrix4x4 matrix;
matrix.scale(scale);
setMatrix(matrix);
}
void QtWebPageSGNode::setRenderer(PassRefPtr<WebLayerTreeRenderer> renderer)
{
if (m_contentsNode && m_contentsNode->layerTreeRenderer() == renderer)
return;
delete m_contentsNode;
m_contentsNode = new ContentsSGNode(renderer);
appendChildNode(m_contentsNode);
}
}