4#include <private/qquickshadereffect_p_p.h>
5#include <private/qsgcontextplugin_p.h>
6#include <private/qsgrhisupport_p.h>
7#include <private/qquickwindow_p.h>
549 d->inDestructor =
true;
568 return d->fragmentShader();
574 d->setFragmentShader(fileUrl);
593 return d->vertexShader();
599 d->setVertexShader(fileUrl);
614 return d->blending();
663 return d->cullMode();
669 return d->setCullMode(
face);
696 return d->supportsAtlasTextures();
702 d->setSupportsAtlasTextures(supports);
768 d->handleGeometryChanged(newGeometry, oldGeometry);
775 return d->handleUpdatePaintNode(oldNode, updatePaintNodeData);
781 d->maybeUpdateShaders();
788 d->handleItemChange(change,
value);
804 return d->updateUniformValue(
name,
value, node);
817 return idx | (shaderType << 16);
822 return mappedId & 0xFFFF;
827 return mappedId >> 16;
831 : m_meshResolution(1, 1)
835 , m_supportsAtlasTextures(
false)
837 , m_fragNeedsUpdate(true)
838 , m_vertNeedsUpdate(true)
840 qRegisterMetaType<QSGGuiThreadShaderEffectManager::ShaderInfo::Type>(
"ShaderInfo::Type");
841 for (
int i = 0;
i < NShader; ++
i)
842 m_inProgress[
i] =
nullptr;
847 for (
int i = 0;
i < NShader; ++
i) {
848 disconnectSignals(Shader(
i));
849 clearMappers(Shader(
i));
858 if (m_fragShader == fileUrl)
861 m_fragShader = fileUrl;
863 m_fragNeedsUpdate =
true;
864 if (
q->isComponentComplete())
867 emit q->fragmentShaderChanged();
873 if (m_vertShader == fileUrl)
876 m_vertShader = fileUrl;
878 m_vertNeedsUpdate =
true;
879 if (
q->isComponentComplete())
882 emit q->vertexShaderChanged();
893 emit q->blendingChanged();
906 if (newMesh && newMesh == m_mesh)
924 int w =
res.at(0).toInt(&
ok);
926 int h =
res.at(1).toInt(&
ok);
928 m_meshResolution =
QSize(
w,
h);
932 qWarning(
"ShaderEffect: mesh property must be a size or an object deriving from QQuickShaderEffectMesh");
940 emit q->meshChanged();
946 if (m_cullMode ==
face)
951 emit q->cullModeChanged();
957 if (m_supportsAtlasTextures == supports)
960 m_supportsAtlasTextures = supports;
962 emit q->supportsAtlasTexturesChanged();
993 for (
int i = 0;
i < NShader; ++
i) {
994 const auto mappedId = findMappedShaderVariableId(propertyName, Shader(
i));
1011 if (
q->width() <= 0 ||
q->height() <= 0) {
1017 if (m_inProgress[
Vertex] || m_inProgress[Fragment])
1065 geometry =
mesh->updateGeometry(geometry, 2, 0, srcRect,
rect);
1075 for (
int i = 0;
i < NShader; ++
i) {
1076 m_dirtyConstants[
i].
clear();
1077 m_dirtyTextures[
i].
clear();
1086 if (m_vertNeedsUpdate)
1087 m_vertNeedsUpdate = !updateShader(
Vertex, m_vertShader);
1088 if (m_fragNeedsUpdate)
1089 m_fragNeedsUpdate = !updateShader(Fragment, m_fragShader);
1090 if (m_vertNeedsUpdate || m_fragNeedsUpdate) {
1097 if (!
q->window() || !
q->window()->isSceneGraphInitialized())
1106 const auto mappedId = findMappedShaderVariableId(
name);
1117 QSet<int> dirtyConstants[NShader];
1118 dirtyConstants[
type].insert(idx);
1146 for (
int shaderType = 0; shaderType < NShader; ++shaderType) {
1147 for (
const auto &vd : std::as_const(m_shaders[shaderType].varData)) {
1185void QQuickShaderEffectPrivate::disconnectSignals(Shader shaderType)
1188 for (
auto *
mapper : m_mappers[shaderType]) {
1193 for (
const auto &vd :
std::as_const(m_shaders[shaderType].varData)) {
1200 if (
it != m_destroyedConnections.
constEnd()) {
1202 m_destroyedConnections.
erase(
it);
1209void QQuickShaderEffectPrivate::clearMappers(QQuickShaderEffectPrivate::Shader shaderType)
1211 for (
auto *
mapper :
std::as_const(m_mappers[shaderType])) {
1213 mapper->destroyIfLastRef();
1215 m_mappers[shaderType].clear();
1222 if (propertyIndex == -1) {
1225 value = itemMetaObject->property(propertyIndex).read(
item);
1235 shaderInfoCache()->clear();
1238bool QQuickShaderEffectPrivate::updateShader(Shader shaderType,
const QUrl &fileUrl)
1245 const bool texturesSeparate = mgr->hasSeparateSamplerAndTextureObjects();
1247 disconnectSignals(shaderType);
1250 m_shaders[shaderType].
varData.clear();
1256 if (
it != shaderInfoCache()->
cend()) {
1272 mgr->prepareShaderCode(typeHint, loadUrl, m_inProgress[shaderType]);
1278 if (shaderType == Fragment) {
1293 updateShaderVars(shaderType);
1307 if (
result != m_inProgress[shaderType]) {
1314 m_inProgress[shaderType] =
nullptr;
1317 qWarning(
"ShaderEffect: shader preparation failed for %s\n%s\n",
1324 shaderInfoCache()->insert(loadUrl, m_shaders[shaderType].shaderInfo);
1325 updateShaderVars(shaderType);
1330void QQuickShaderEffectPrivate::updateShaderVars(Shader shaderType)
1337 const bool texturesSeparate = mgr->hasSeparateSamplerAndTextureObjects();
1340 m_shaders[shaderType].
varData.resize(varCount);
1343 clearMappers(shaderType);
1347 if (!m_itemMetaObject)
1348 m_itemMetaObject =
q->metaObject();
1352 for (
int i = 0;
i < varCount; ++
i) {
1353 const auto &
v(m_shaders[shaderType].shaderInfo.variables.at(
i));
1355 const bool isSpecial =
v.name.startsWith(
"qt_");
1357 if (
v.name ==
"qt_Opacity")
1359 else if (
v.name ==
"qt_Matrix")
1361 else if (
v.name.startsWith(
"qt_SubRect_"))
1370 if (texturesSeparate) {
1387 pd = propCache->property(
QLatin1String(
v.name),
nullptr,
nullptr);
1396 qWarning(
"QQuickShaderEffect: property '%s' does not have notification method!",
v.name.constData());
1402 m_mappers[shaderType].append(
mapper);
1404 Q_ASSERT(
q->metaObject() == m_itemMetaObject);
1409 <<
"(" << propIdx <<
", signal index" << pd->
notifyIndex()
1410 <<
") of item" <<
q;
1415 if (!
q->property(
v.name.constData()).isValid())
1416 qWarning(
"ShaderEffect: '%s' does not have a matching property",
v.name.constData());
1420 vd.propertyIndex = propIdx;
1441std::optional<int> QQuickShaderEffectPrivate::findMappedShaderVariableId(
const QByteArray &
name)
const
1443 for (
int shaderType = 0; shaderType < NShader; ++shaderType) {
1445 for (
int idx = 0; idx < vars.size(); ++idx) {
1454std::optional<int> QQuickShaderEffectPrivate::findMappedShaderVariableId(
const QByteArray &
name, Shader shaderType)
const
1457 for (
int idx = 0; idx < vars.size(); ++idx) {
1465bool QQuickShaderEffectPrivate::sourceIsUnique(
QQuickItem *
source, Shader typeToSkip,
int indexToSkip)
const
1467 for (
int shaderType = 0; shaderType < NShader; ++shaderType) {
1468 for (
int idx = 0; idx < m_shaders[shaderType].
varData.size(); ++idx) {
1469 if (shaderType != typeToSkip || idx != indexToSkip) {
1470 const auto &vd(m_shaders[shaderType].varData[idx]);
1484 const auto &
v(m_shaders[
type].shaderInfo.variables[idx]);
1485 auto &vd(m_shaders[
type].varData[idx]);
1500 if (
it != m_destroyedConnections.
constEnd()) {
1502 m_destroyedConnections.
erase(
it);
1532 for (
int shaderType = 0; shaderType < NShader; ++shaderType) {
1533 for (
auto &vd : m_shaders[shaderType].
varData) {
1535 if (qvariant_cast<QObject *>(vd.value) ==
object)
1551 if (m_supportsAtlasTextures)
1557#include "moc_qquickshadereffect_p.cpp"
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
const_iterator constFind(const Key &key) const noexcept
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
iterator erase(const_iterator it)
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
qsizetype size() const noexcept
static QMetaObject::Connection connectImpl(const QObject *sender, int signal_index, const QObject *receiver, void **slot, QtPrivate::QSlotObjectBase *slotObj, int type, const int *types, const QMetaObject *senderMetaObject)
static bool disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot)
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
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
The QQmlContext class defines a context within a QML engine.
static QQmlPropertyCache::ConstPtr ensurePropertyCache(QObject *object)
void setResolution(const QSize &res)
\qmlproperty size QtQuick::GridMesh::resolution
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
bool event(QEvent *) override
\reimp
void setFlag(Flag flag, bool enabled=true)
Enables the specified flag for this item if enabled is true; if enabled is false, the flag is disable...
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
void componentComplete() override
\reimp Derived classes should call the base class method before adding their own actions to perform a...
virtual void itemChange(ItemChange, const ItemChangeData &)
Called when change occurs for this item.
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
void maybeUpdateShaders()
void updatePolish() override
QQuickShaderEffectPrivate()
void setVertexShader(const QUrl &fileUrl)
void propertyChanged(int mappedId)
void shaderCodePrepared(bool ok, QSGGuiThreadShaderEffectManager::ShaderInfo::Type typeHint, const QUrl &loadUrl, QSGGuiThreadShaderEffectManager::ShaderInfo *result)
void markGeometryDirtyAndUpdate()
~QQuickShaderEffectPrivate()
void setBlending(bool enable)
void handleEvent(QEvent *)
QSGNode * handleUpdatePaintNode(QSGNode *, QQuickItem::UpdatePaintNodeData *)
void setMesh(const QVariant &mesh)
void setSupportsAtlasTextures(bool supports)
bool updateUniformValue(const QByteArray &name, const QVariant &value, QSGShaderEffectNode *node)
QQuickShaderEffect::Status status() const
void setFragmentShader(const QUrl &fileUrl)
void setCullMode(QQuickShaderEffect::CullMode face)
void handleGeometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
void sourceDestroyed(QObject *object)
void markGeometryDirtyAndUpdateIfSupportsAtlas()
void handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
void setBlending(bool enable)
void setFragmentShader(const QUrl &fileUrl)
void componentComplete() override
\reimp Derived classes should call the base class method before adding their own actions to perform a...
void setCullMode(CullMode face)
void setVertexShader(const QUrl &fileUrl)
bool event(QEvent *e) override
\reimp
void setMesh(const QVariant &mesh)
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
~QQuickShaderEffect() override
bool supportsAtlasTextures
QQuickShaderEffect(QQuickItem *parent=nullptr)
bool updateUniformValue(const QByteArray &name, const QVariant &value)
void setSupportsAtlasTextures(bool supports)
QSGNode * updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override
Called on the render thread when it is time to sync the state of the item with the scene graph.
void itemChange(ItemChange change, const ItemChangeData &value) override
Called when change occurs for this item.
bool isComponentComplete() const
static QQuickWindowPrivate * get(QQuickWindow *c)
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
const QSGGeometry * geometry() const
Returns this node's geometry.
void setGeometry(QSGGeometry *geometry)
Sets the geometry of this node to geometry.
virtual QSGShaderEffectNode * createShaderEffectNode(QSGRenderContext *renderContext)
Creates a new shader effect node.
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
void shaderCodePrepared(bool ok, ShaderInfo::Type typeHint, const QUrl &src, ShaderInfo *result)
void logAndStatusChanged()
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
void setFlag(Flag, bool=true)
Sets the flag f on this node if enabled is true; otherwise clears the flag.
QSGContext * sceneGraphContext() const
virtual QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures)=0
virtual void syncMaterial(SyncData *syncData)=0
const_iterator constFind(const T &value) const
iterator insert(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QThread * currentThread()
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
QSize toSize() const
Returns the variant as a QSize if the variant has userType() \l QMetaType::QSize; otherwise returns a...
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
bool canConvert(QMetaType targetType) const
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
std::function< void()> PropChangedFunc
void setSignalIndex(int idx)
EffectSlotMapper(PropChangedFunc func)
QSet< QString >::iterator it
const PluginKeyMapConstIterator cend
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLdouble GLdouble GLdouble GLdouble q
QQmlEngine * qmlEngine(const QObject *obj)
QQmlContext * qmlContext(const QObject *obj)
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
constexpr int mappedIdToShaderType(const int mappedId)
QHash< QUrl, QSGGuiThreadShaderEffectManager::ShaderInfo > QQuickShaderInfoCache
constexpr int mappedIdToIndex(const int mappedId)
static QVariant getValueFromProperty(QObject *item, const QMetaObject *itemMetaObject, const QByteArray &name, int propertyIndex)
void qtquick_shadereffect_purge_gui_thread_shader_cache()
constexpr int indexToMappedId(const int shaderType, const int idx)
#define qPrintable(string)
QLatin1StringView QLatin1String
QVector< Variable > variables
QVector< VariableData > varData
QSGGuiThreadShaderEffectManager::ShaderInfo shaderInfo
const QSet< int > * dirtyTextures
const ShaderData * shader
const QSet< int > * dirtyConstants
void * materialTypeCacheKey
\qmltype MapCircle \instantiates QDeclarativeCircleMapItem \inqmlmodule QtLocation