9#include <private/qsgplaintexture_p.h>
13#include <QFileSelector>
14#include <QMutexLocker>
43 for (
int i = 0;
i <
shader.shaderInfo.variables.size(); ++
i) {
52 if (shaderEffectDebug) {
55 <<
"offset" <<
var.offset <<
"value" <<
c.
value;
58 <<
"offset" <<
var.offset <<
"special" <<
c.specialType;
63 c.value =
var.name.mid(11);
69 for (
int idx : *dirtyIndices) {
70 const int offset =
shader.shaderInfo.variables.at(idx).offset;
73 if (shaderEffectDebug) {
84 for (
int i = 0;
i <
shader.shaderInfo.variables.size(); ++
i) {
92 Q_ASSERT(existingBindPoint < 0 || existingBindPoint ==
var.bindPoint);
100 for (
int idx : *dirtyIndices) {
106 Q_ASSERT(existingBindPoint < 0 || existingBindPoint ==
var.bindPoint);
122 if (
c.value.userType() == QMetaType::QByteArray) {
125 qWarning(
"ShaderEffect: qt_SubRect_%s refers to unknown source texture",
name.constData());
137 qDebug() <<
"Failed to generate program data";
149 debug <<
"size" <<
c.size;
151 debug <<
"special" <<
c.specialType;
153 debug <<
"value" <<
c.value;
263 c.getRgbF(&
r, &
g, &
b, &
a);
270 const size_t valueBytes =
sizeof(T) * valueCount;
271 const size_t fieldBytes = fieldSizeBytes;
272 if (valueBytes <= fieldBytes) {
274 if (valueBytes < fieldBytes)
275 memset(
dst + valueBytes, 0, fieldBytes - valueBytes);
286 bool changed =
false;
294 if (
state.isOpacityDirty()) {
295 const float f =
state.opacity();
296 fillUniformBlockMember<float>(
dst, &
f, 1,
c.size);
300 if (
state.isMatrixDirty()) {
302 fillUniformBlockMember<float>(
dst,
m.constData(), 16,
c.size);
307 QRectF subRect(0, 0, 1, 1);
308 const int binding =
c.value.toInt();
312 subRect =
t->normalizedTextureSubRect();
315 const float f[4] = { float(subRect.
x()), float(subRect.
y()),
317 fillUniformBlockMember<float>(
dst,
f, 4,
c.size);
320 switch (
int(
c.value.userType())) {
321 case QMetaType::QColor: {
323 const float f[4] = { float(
v.redF()), float(
v.greenF()), float(
v.blueF()), float(
v.alphaF()) };
324 fillUniformBlockMember<float>(
dst,
f, 4,
c.size);
327 case QMetaType::Float: {
328 const float f = qvariant_cast<float>(
c.value);
329 fillUniformBlockMember<float>(
dst, &
f, 1,
c.size);
332 case QMetaType::Double: {
333 const float f = float(qvariant_cast<double>(
c.value));
334 fillUniformBlockMember<float>(
dst, &
f, 1,
c.size);
337 case QMetaType::Int: {
339 fillUniformBlockMember<qint32>(
dst, &
i, 1,
c.size);
342 case QMetaType::Bool: {
344 fillUniformBlockMember<qint32>(
dst, &
b, 1,
c.size);
347 case QMetaType::QTransform: {
348 const QTransform v = qvariant_cast<QTransform>(
c.value);
349 const float m[3][3] = {
350 { float(
v.m11()), float(
v.m12()), float(
v.m13()) },
351 { float(
v.m21()), float(
v.m22()), float(
v.m23()) },
352 { float(
v.m31()), float(
v.m32()), float(
v.m33()) }
355 memset(
dst, 0,
c.size);
356 const size_t bytesPerColumn = 4 *
sizeof(float);
357 if (
c.size >= bytesPerColumn)
358 fillUniformBlockMember<float>(
dst,
m[0], 3, 3 *
sizeof(
float));
359 if (
c.size >= 2 * bytesPerColumn)
360 fillUniformBlockMember<float>(
dst + bytesPerColumn,
m[1], 3, 3 *
sizeof(
float));
361 if (
c.size >= 3 * bytesPerColumn)
362 fillUniformBlockMember<float>(
dst + 2 * bytesPerColumn,
m[2], 3, 3 *
sizeof(
float));
365 case QMetaType::QSize:
366 case QMetaType::QSizeF: {
368 const float f[2] = { float(
v.width()), float(
v.height()) };
369 fillUniformBlockMember<float>(
dst,
f, 2,
c.size);
372 case QMetaType::QPoint:
373 case QMetaType::QPointF: {
375 const float f[2] = { float(
v.x()), float(
v.y()) };
376 fillUniformBlockMember<float>(
dst,
f, 2,
c.size);
379 case QMetaType::QRect:
380 case QMetaType::QRectF: {
382 const float f[4] = { float(
v.x()), float(
v.y()), float(
v.width()), float(
v.height()) };
383 fillUniformBlockMember<float>(
dst,
f, 4,
c.size);
386 case QMetaType::QVector2D: {
387 const QVector2D v = qvariant_cast<QVector2D>(
c.value);
388 const float f[2] = { float(
v.x()), float(
v.y()) };
389 fillUniformBlockMember<float>(
dst,
f, 2,
c.size);
392 case QMetaType::QVector3D: {
393 const QVector3D v = qvariant_cast<QVector3D>(
c.value);
394 const float f[3] = { float(
v.x()), float(
v.y()), float(
v.z()) };
395 fillUniformBlockMember<float>(
dst,
f, 3,
c.size);
398 case QMetaType::QVector4D: {
399 const QVector4D v = qvariant_cast<QVector4D>(
c.value);
400 const float f[4] = { float(
v.x()), float(
v.y()), float(
v.z()), float(
v.w()) };
401 fillUniformBlockMember<float>(
dst,
f, 4,
c.size);
404 case QMetaType::QQuaternion: {
406 const float f[4] = { float(
v.x()), float(
v.y()), float(
v.z()), float(
v.scalar()) };
407 fillUniformBlockMember<float>(
dst,
f, 4,
c.size);
410 case QMetaType::QMatrix4x4: {
411 const QMatrix4x4 m = qvariant_cast<QMatrix4x4>(
c.value);
412 fillUniformBlockMember<float>(
dst,
m.constData(), 16,
c.size);
436 t->commitTextureOperations(
state.rhi(),
state.resourceUpdateBatch());
479 ps->
cullMode = GraphicsPipelineState::CullFront;
482 ps->
cullMode = GraphicsPipelineState::CullBack;
506 if (tp && tp->texture() && tp->texture()->isAtlasTexture())
541 return diff < 0 ? -1 : 1;
576 SLOT(handleTextureChange()));
585 const int binding =
it.key();
589 qWarning(
"Sampler at binding %d exceeds the available ShaderEffect binding slots; ignored",
594 if (newProvider != activeProvider) {
595 if (activeProvider) {
597 SLOT(handleTextureChange()));
603 "QSGRhiShaderEffectMaterial::updateTextureProviders",
604 "Texture provider must belong to the rendering thread");
610 qWarning(
"ShaderEffect: Texture t%d is not assigned a valid texture provider (%s).",
613 activeProvider = newProvider;
628 QRectF srcRect(0, 0, 1, 1);
629 bool geometryUsesTextureSubRect =
false;
630 if (supportsAtlasTextures) {
644 geometryUsesTextureSubRect =
true;
660 qWarning() <<
"Failed to find shader" << filename;
668 static QShader defaultVertexShader;
669 static QShader defaultFragmentShader;
691 if (!defaultVertexShader.
isValid())
700 if (!defaultFragmentShader.
isValid())
724 v.size = 16 *
sizeof(float);
745 v.offset = 16 *
sizeof(float);
746 v.size =
sizeof(float);
802void QSGRhiShaderEffectNode::handleTextureChange()
808void QSGRhiShaderEffectNode::handleTextureProviderDestroyed(
QObject *
object)
844 if (!m_fileSelector) {
851 qWarning(
"ShaderEffect: Failed to deserialize QShader from %s. "
852 "Either the filename is incorrect, or it is not a valid .qsb file. "
853 "In Qt 6 shaders must be preprocessed using the Qt Shader Tools infrastructure. "
854 "The vertexShader and fragmentShader properties are now URLs that are expected to point to .qsb files generated by the qsb tool. "
855 "See https://doc.qt.io/qt-6/qtshadertools-index.html for more information.",
869 qWarning(
"rhi shader effect only supports files (qrc or local) at the moment");
874bool QSGRhiGuiThreadShaderEffectManager::reflect(ShaderInfo *
result)
876 switch (
result->rhiShader.stage()) {
878 result->type = ShaderInfo::TypeVertex;
881 result->type = ShaderInfo::TypeFragment;
884 result->type = ShaderInfo::TypeOther;
885 qWarning(
"Unsupported shader stage (%d)",
result->rhiShader.stage());
890 result->constantDataSize = 0;
892 int ubufBinding = -1;
894 const int ubufCount = ubufs.
size();
895 for (
int i = 0;
i < ubufCount; ++
i) {
897 if (ubufBinding == -1 && ubuf.binding >= 0) {
898 ubufBinding = ubuf.binding;
899 result->constantDataSize = ubuf.size;
901 ShaderInfo::Variable
v;
902 v.type = ShaderInfo::Constant;
903 v.name = member.name;
904 v.offset = member.offset;
905 v.size = member.size;
909 qWarning(
"Uniform block %s (binding %d) ignored", ubuf.blockName.constData(),
915 const int samplerCount = combinedImageSamplers.
size();
916 for (
int i = 0;
i < samplerCount; ++
i) {
918 ShaderInfo::Variable
v;
919 v.type = ShaderInfo::Sampler;
920 v.name = combinedImageSampler.name;
921 v.bindPoint = combinedImageSampler.binding;
930#include "moc_qsgrhishadereffectnode_p.cpp"
The QColor class provides colors based on RGB, HSV or CMYK values.
QColor toRgb() const noexcept
Create and returns an RGB QColor based on this color.
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Static convenience function that returns a QColor constructed from the RGB color values,...
void setExtraSelectors(const QStringList &list)
Sets the list of extra selectors which have been added programmatically to this instance.
QString select(const QString &filePath) const
This function returns the selected version of the path, based on the conditions at runtime.
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
void reserve(qsizetype size)
Ensures that the QHash's internal hash table has space to store at least size items without having to...
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
T value(const Key &key) const noexcept
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
@ Format_ARGB32_Premultiplied
qsizetype size() const noexcept
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
QThread * thread() const
Returns the thread in which the object lives.
\inmodule QtCore\reentrant
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to QFile.
The QQuaternion class represents a quaternion consisting of a vector and scalar.
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
\inmodule QtCore\reentrant
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
The QSGDynamicTexture class serves as a baseclass for dynamically changing textures,...
void setMaterial(QSGMaterial *material)
Sets the material of this geometry node to material.
void shaderCodePrepared(bool ok, ShaderInfo::Type typeHint, const QUrl &src, ShaderInfo *result)
void logAndStatusChanged()
Encapsulates the current rendering state during a call to QSGMaterialShader::updateUniformData() and ...
The QSGMaterialShader class represents a graphics API independent shader program.
void setShader(Stage stage, const QShader &shader)
Sets the shader for the specified stage.
void setFlag(Flags flags, bool on=true)
Sets the flags on this material shader if on is true; otherwise clears the specified flags.
@ UpdatesGraphicsPipelineState
The QSGMaterial class encapsulates rendering state for a shader program.
QSGMaterial::Flags flags() const
Returns the material's flags.
void setFlag(Flags flags, bool on=true)
Sets the flags flags on this material if on is true; otherwise clears the attribute.
void markDirty(DirtyState bits)
Notifies all connected renderers that the node has dirty bits.
void setFlag(Flag, bool=true)
Sets the flag f on this node if enabled is true; otherwise clears the flag.
void setImage(const QImage &image)
void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override
Call this function to enqueue image upload operations to resourceUpdates, in case there are any pendi...
RenderMode
\value RenderMode2D Normal 2D rendering \value RenderMode2DNoDepthBuffer Normal 2D rendering with dep...
QString log() const override
void prepareShaderCode(ShaderInfo::Type typeHint, const QUrl &src, ShaderInfo *result) override
Status status() const override
bool hasSeparateSamplerAndTextureObjects() const override
void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
QSGRhiShaderEffectMaterialShader(const QSGRhiShaderEffectMaterial *material)
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
bool updateGraphicsPipelineState(RenderState &state, GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to enable the material to provide a custom set of graphics...
QSGRhiShaderLinker m_linker
QVector< QSGTextureProvider * > m_textureProviders
bool m_hasCustomFragmentShader
static const int MAX_BINDINGS
QSGMaterialType * m_materialType
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
~QSGRhiShaderEffectMaterial()
QSGRhiShaderEffectMaterial(QSGRhiShaderEffectNode *node)
bool usesSubRectUniform(int binding) const
int compare(const QSGMaterial *other) const override
Compares this material to other and returns 0 if they are equal; -1 if this material should sort befo...
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
QSGRhiShaderEffectNode * m_node
void * m_materialTypeCacheKey
QSGPlainTexture * m_dummyTexture
QSGShaderEffectNode::CullMode m_cullMode
void updateTextureProviders(bool layoutChange)
bool m_geometryUsesTextureSubRect
bool m_hasCustomVertexShader
void preprocess() override
Override this function to do processing on the node before it is rendered.
static void garbageCollectMaterialTypeCache(void *materialTypeCacheKey)
QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures) override
QSGRhiShaderEffectNode(QSGDefaultRenderContext *rc)
void syncMaterial(SyncData *syncData) override
static void resetMaterialTypeCache(void *materialTypeCacheKey)
void feedSamplers(const QSGShaderEffectNode::ShaderData &shader, const QSet< int > *dirtyIndices=nullptr)
QHash< QByteArray, int > m_samplerNameMap
void reset(const QShader &vs, const QShader &fs)
QHash< uint, Constant > m_constants
void linkTextureSubRects()
QSet< int > m_subRectBindings
QHash< int, QVariant > m_samplers
uint m_constantBufferSize
void feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet< int > *dirtyIndices=nullptr)
The QSGTextureProvider class encapsulates texture based entities in QML.
virtual QSGTexture * texture() const =0
Returns a pointer to the texture object.
virtual void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
Call this function to enqueue image upload operations to resourceUpdates, in case there are any pendi...
virtual QRectF normalizedTextureSubRect() const
Returns the rectangle inside textureSize() that this texture represents in normalized coordinates.
void setHorizontalWrapMode(WrapMode hwrap)
Sets the horizontal wrap mode to hwrap.
virtual QSGTexture * removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates=nullptr) const
This function returns a copy of the current texture which is removed from its atlas.
void setFiltering(Filtering filter)
Sets the sampling mode to filter.
virtual qint64 comparisonKey() const =0
Returns a key suitable for comparing textures.
void setVerticalWrapMode(WrapMode vwrap)
Sets the vertical wrap mode to vwrap.
iterator insert(const T &value)
static QShader fromSerialized(const QByteArray &data)
Creates a new QShader instance from the given data.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QThread * currentThread()
The QVector2D class represents a vector or vertex in 2D space.
The QVector3D class represents a vector or vertex in 3D space.
The QVector4D class represents a vector or vertex in 4D space.
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLintptr offset
GLsizei GLsizei GLchar * source
QCborArray members(const QCborMap *classDef, QLatin1StringView key, QTypeRevision maxMajorVersion, Postprocess &&process)
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
#define Q_ASSERT_X(cond, x, msg)
static void fillUniformBlockMember(char *dst, const T *value, int valueCount, int fieldSizeBytes)
static QShader loadShaderFromFile(const QString &filename)
size_t qHash(const QSGRhiShaderMaterialTypeCache::Key &key, size_t seed=0)
static QMutex shaderMaterialTypeCacheMutex
static QColor qsg_premultiply_color(const QColor &c)
static QHash< void *, QSGRhiShaderMaterialTypeCache > shaderMaterialTypeCache
static bool hasAtlasTexture(const QVector< QSGTextureProvider * > &textureProviders)
QDebug operator<<(QDebug debug, const QSGRhiShaderLinker::Constant &c)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
QVector< Variable > variables
Describes state changes that the material wants to apply to the currently active graphics pipeline st...
The QSGMaterialType class is used as a unique type token in combination with QSGMaterial.
bool operator==(const Key &other) const
Key(const QShader &vs, const QShader &fs)
QHash< Key, MaterialType > m_types
void unref(const QShader &vs, const QShader &fs)
QSGMaterialType * ref(const QShader &vs, const QShader &fs)
QVector< QSGMaterialType * > m_graveyard
QVector< VariableData > varData
QSGGuiThreadShaderEffectManager::ShaderInfo shaderInfo
const QSet< int > * dirtyTextures
const ShaderData * shader
const QSet< int > * dirtyConstants
void * materialTypeCacheKey
\variable QShaderDescription::InOutVariable::name