Skip to content

Commit

Permalink
QskBoxClipNode renamed to QskClipNode + more clip options added
Browse files Browse the repository at this point in the history
  • Loading branch information
uwerat committed Nov 20, 2024
1 parent 1e38340 commit 109fc7d
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 145 deletions.
49 changes: 4 additions & 45 deletions designsystems/material3/QskMaterial3SliderSkinlet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "QskMaterial3SliderSkinlet.h"

#include <QskSlider.h>
#include <QskVertex.h>
#include <QskClipNode.h>
#include <QskSGNode.h>

#include <qmath.h>
Expand Down Expand Up @@ -43,45 +43,6 @@ static inline qreal qskTickValue( const QskSlider* slider, int index )
return slider->maximum();
}

namespace
{
class ClipNode : public QSGClipNode
{
public:
ClipNode()
: m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
{
m_geometry.setDrawingMode( QSGGeometry::DrawTriangleStrip );
setGeometry( &m_geometry );
}

void setRegion( const QRectF& boundingRect, const QRectF& rect )
{
if ( ( rect == clipRect() ) && ( m_boundingRect == boundingRect ) )
return;

setIsRectangular( false );
setClipRect( rect );

m_geometry.allocate( 2 * 5 ); // 2 points per line

const auto l = reinterpret_cast< QskVertex::Line* >( m_geometry.vertexData() );
l[0].setLine( boundingRect.topLeft(), rect.topLeft() );
l[1].setLine( boundingRect.topRight(), rect.topRight() );
l[2].setLine( boundingRect.bottomRight(), rect.bottomRight() );
l[3].setLine( boundingRect.bottomLeft(), rect.bottomLeft() );
l[4] = l[0];

m_geometry.markVertexDataDirty();
markDirty( QSGNode::DirtyGeometry );
}

private:
QRectF m_boundingRect;
QSGGeometry m_geometry;
};
}

QskMaterial3SliderSkinlet::QskMaterial3SliderSkinlet( QskSkin* skin )
: Inherited( skin )
{
Expand Down Expand Up @@ -128,12 +89,10 @@ QSGNode* QskMaterial3SliderSkinlet::updateSubNode(
{
const auto slider = static_cast< const QskSlider* >( skinnable );

auto clipNode = QskSGNode::ensureNode< ClipNode >( node );
auto clipNode = QskSGNode::ensureNode< QskClipNode >( node );

clipNode->setRegion(
slider->subControlRect( Q::Panel ),
slider->subControlRect( Q::Handle )
);
clipNode->setRegion( slider->subControlRect( Q::Panel ),
slider->subControlRect( Q::Handle ) );

QskSGNode::setNodeRole( clippedNode, nodeRole );
QskSGNode::setParentNode( clippedNode, clipNode );
Expand Down
4 changes: 2 additions & 2 deletions playground/plots/QskPlotView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <QskSkinlet.h>

#include <QskQuick.h>
#include <QskBoxClipNode.h>
#include <QskClipNode.h>
#include <QskBoxBorderMetrics.h>

#include <qsgnode.h>
Expand Down Expand Up @@ -315,7 +315,7 @@ void QskPlotView::updateNode( QSGNode* node )
if ( m_data->needsClipping() )
{
if ( itemsNode == nullptr || itemsNode->type() != QSGNode::ClipNodeType )
itemsNode = new QskBoxClipNode();
itemsNode = new QskClipNode();
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ list(APPEND HEADERS
nodes/QskArcRenderNode.h
nodes/QskBasicLinesNode.h
nodes/QskBoxNode.h
nodes/QskBoxClipNode.h
nodes/QskBoxRectangleNode.h
nodes/QskBoxRenderer.h
nodes/QskBoxMetrics.h
nodes/QskBoxBasicStroker.h
nodes/QskBoxGradientStroker.h
nodes/QskBoxShadowNode.h
nodes/QskClipNode.h
nodes/QskColorRamp.h
nodes/QskFillNode.h
nodes/QskGraduationNode.h
Expand Down Expand Up @@ -145,13 +145,13 @@ list(APPEND SOURCES
nodes/QskArcRenderNode.cpp
nodes/QskBasicLinesNode.cpp
nodes/QskBoxNode.cpp
nodes/QskBoxClipNode.cpp
nodes/QskBoxRectangleNode.cpp
nodes/QskBoxRenderer.cpp
nodes/QskBoxMetrics.cpp
nodes/QskBoxBasicStroker.cpp
nodes/QskBoxGradientStroker.cpp
nodes/QskBoxShadowNode.cpp
nodes/QskClipNode.cpp
nodes/QskColorRamp.cpp
nodes/QskFillNode.cpp
nodes/QskGraduationNode.cpp
Expand Down
7 changes: 3 additions & 4 deletions src/controls/QskSkinlet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include "QskBoxBorderColors.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxNode.h"
#include "QskBoxClipNode.h"
#include "QskBoxRectangleNode.h"
#include "QskBoxShapeMetrics.h"
#include "QskBoxHints.h"
#include "QskClipNode.h"
#include "QskColorFilter.h"
#include "QskControl.h"
#include "QskFunctions.h"
Expand Down Expand Up @@ -641,15 +641,14 @@ QSGNode* QskSkinlet::updateBoxClipNode( const QskSkinnable* skinnable,
QSGNode* QskSkinlet::updateBoxClipNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl )
{
auto clipNode = QskSGNode::ensureNode< QskBoxClipNode >( node );
auto clipNode = QskSGNode::ensureNode< QskClipNode >( node );

const auto margins = skinnable->marginHint( subControl );

const auto clipRect = rect.marginsRemoved( margins );
if ( clipRect.isEmpty() )
{
clipNode->setIsRectangular( true );
clipNode->setClipRect( clipRect );
clipNode->setRect( clipRect );
}
else
{
Expand Down
85 changes: 0 additions & 85 deletions src/nodes/QskBoxClipNode.cpp

This file was deleted.

151 changes: 151 additions & 0 deletions src/nodes/QskClipNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/

#include "QskClipNode.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxRenderer.h"
#include "QskBoxShapeMetrics.h"
#include "QskFunctions.h"
#include "QskVertex.h"

#include <qquickwindow.h>

static inline QskHashValue qskMetricsHash(
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border )
{
QskHashValue hash = 13000;

hash = shape.hash( hash );
return border.hash( hash );
}

static inline void qskSetBoundingRect( QSGClipNode* node, const QRectF& rect )
{
/*
Depending on isRectangular: the "scene graph renderer can use
scissoring instead of stencil, which is significantly faster."
However the batch renderer ( qsgbatchrenderer.cpp ) is rounding
the clip rectangle to integers and the clip might become too small/large.
So we always have to use stencil clipping - even if it might have a negative
impact on the performance.
When isRectangular is set to false the clipRect is not used from the
renderer and we use the memory for the storing the bounding rectangle.
*/

node->setIsRectangular( false );
node->setClipRect( rect );
}

static inline QskVertex::Line* qskAllocateLines(
QSGGeometry& geometry, int lineCount )
{
geometry.allocate( 2 * lineCount ); // 2 points per line
return reinterpret_cast< QskVertex::Line* >( geometry.vertexData() );
}

QskClipNode::QskClipNode()
: m_hash( 0 )
, m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
{
setGeometry( &m_geometry );
}

QskClipNode::~QskClipNode()
{
}

void QskClipNode::setRect( const QRectF& rect )
{
setRegion( rect, QRectF() );
}

void QskClipNode::setRegion( const QRectF& rect, const QRectF& excludedRect )
{
if ( rect.isEmpty() )
{
/*
what about rectangles having a width/height
of 0 ( f.e lines ) TODO ...
*/
reset();
return;
}

const auto innerRect = excludedRect.isEmpty()
? QRectF() : excludedRect.intersected( rect );

const auto hash = qHashBits( &innerRect, sizeof( innerRect ), 1450 );
if ( ( hash == m_hash ) && ( rect == Inherited::clipRect() ) )
return;

qskSetBoundingRect( this, rect );
m_hash = hash;

m_geometry.setDrawingMode( QSGGeometry::DrawTriangleStrip );

if ( innerRect.isEmpty() )
{
const auto l = qskAllocateLines( m_geometry, 2 );

l[0].setLine( rect.topLeft(), rect.topRight() );
l[1].setLine( rect.bottomLeft(), rect.bottomRight() );
}
else
{
const auto l = qskAllocateLines( m_geometry, 5 );

l[0].setLine( rect.topLeft(), innerRect.topLeft() );
l[1].setLine( rect.topRight(), innerRect.topRight() );
l[2].setLine( rect.bottomRight(), innerRect.bottomRight() );
l[3].setLine( rect.bottomLeft(), innerRect.bottomLeft() );
l[4] = l[0];
}

m_geometry.markVertexDataDirty();
markDirty( QSGNode::DirtyGeometry );
}

void QskClipNode::setBox( const QQuickWindow* window, const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border )
{
if ( rect.isEmpty() )
{
reset();
return;
}

const auto hash = qskMetricsHash( shape, border );
if ( hash == m_hash && rect == boundingRectangle() )
return;

qskSetBoundingRect( this, rect );
m_hash = hash;

QskBoxRenderer renderer( window );
renderer.setFillLines( rect, shape, border, m_geometry );

m_geometry.markVertexDataDirty();
markDirty( QSGNode::DirtyGeometry );
}

void QskClipNode::reset()
{
Inherited::setIsRectangular( true );
Inherited::setClipRect( QRectF() );

if ( m_geometry.vertexData() )
{
m_geometry.allocate( 0 );
m_geometry.markVertexDataDirty();
}

if ( m_hash != 0 )
{
m_hash = 0;
markDirty( QSGNode::DirtyGeometry );
}
}
Loading

0 comments on commit 109fc7d

Please sign in to comment.