rhi: Optimize the default null QShader
To please qmlbench. 441->463 in delegates_shadereffect.qml Change-Id: I66bbfd7747df958963a4ebf588a1461edc5dce59 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
parent
9b3de58d2d
commit
b61e9846d3
@ -209,7 +209,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
Constructs a new, empty (and thus invalid) QShader instance.
|
Constructs a new, empty (and thus invalid) QShader instance.
|
||||||
*/
|
*/
|
||||||
QShader::QShader()
|
QShader::QShader()
|
||||||
: d(new QShaderPrivate)
|
: d(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +218,10 @@ QShader::QShader()
|
|||||||
*/
|
*/
|
||||||
void QShader::detach()
|
void QShader::detach()
|
||||||
{
|
{
|
||||||
qAtomicDetach(d);
|
if (d)
|
||||||
|
qAtomicDetach(d);
|
||||||
|
else
|
||||||
|
d = new QShaderPrivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -227,7 +230,8 @@ void QShader::detach()
|
|||||||
QShader::QShader(const QShader &other)
|
QShader::QShader(const QShader &other)
|
||||||
: d(other.d)
|
: d(other.d)
|
||||||
{
|
{
|
||||||
d->ref.ref();
|
if (d)
|
||||||
|
d->ref.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -235,7 +239,12 @@ QShader::QShader(const QShader &other)
|
|||||||
*/
|
*/
|
||||||
QShader &QShader::operator=(const QShader &other)
|
QShader &QShader::operator=(const QShader &other)
|
||||||
{
|
{
|
||||||
qAtomicAssign(d, other.d);
|
if (d) {
|
||||||
|
qAtomicAssign(d, other.d);
|
||||||
|
} else if (other.d) {
|
||||||
|
other.d->ref.ref();
|
||||||
|
d = other.d;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +253,7 @@ QShader &QShader::operator=(const QShader &other)
|
|||||||
*/
|
*/
|
||||||
QShader::~QShader()
|
QShader::~QShader()
|
||||||
{
|
{
|
||||||
if (!d->ref.deref())
|
if (d && !d->ref.deref())
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +262,7 @@ QShader::~QShader()
|
|||||||
*/
|
*/
|
||||||
bool QShader::isValid() const
|
bool QShader::isValid() const
|
||||||
{
|
{
|
||||||
return !d->shaders.isEmpty();
|
return d ? !d->shaders.isEmpty() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -261,7 +270,7 @@ bool QShader::isValid() const
|
|||||||
*/
|
*/
|
||||||
QShader::Stage QShader::stage() const
|
QShader::Stage QShader::stage() const
|
||||||
{
|
{
|
||||||
return d->stage;
|
return d ? d->stage : QShader::VertexStage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -269,7 +278,7 @@ QShader::Stage QShader::stage() const
|
|||||||
*/
|
*/
|
||||||
void QShader::setStage(Stage stage)
|
void QShader::setStage(Stage stage)
|
||||||
{
|
{
|
||||||
if (stage != d->stage) {
|
if (!d || stage != d->stage) {
|
||||||
detach();
|
detach();
|
||||||
d->stage = stage;
|
d->stage = stage;
|
||||||
}
|
}
|
||||||
@ -280,7 +289,7 @@ void QShader::setStage(Stage stage)
|
|||||||
*/
|
*/
|
||||||
QShaderDescription QShader::description() const
|
QShaderDescription QShader::description() const
|
||||||
{
|
{
|
||||||
return d->desc;
|
return d ? d->desc : QShaderDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -297,7 +306,7 @@ void QShader::setDescription(const QShaderDescription &desc)
|
|||||||
*/
|
*/
|
||||||
QList<QShaderKey> QShader::availableShaders() const
|
QList<QShaderKey> QShader::availableShaders() const
|
||||||
{
|
{
|
||||||
return d->shaders.keys().toVector();
|
return d ? d->shaders.keys().toVector() : QList<QShaderKey>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -305,7 +314,7 @@ QList<QShaderKey> QShader::availableShaders() const
|
|||||||
*/
|
*/
|
||||||
QShaderCode QShader::shader(const QShaderKey &key) const
|
QShaderCode QShader::shader(const QShaderKey &key) const
|
||||||
{
|
{
|
||||||
return d->shaders.value(key);
|
return d ? d->shaders.value(key) : QShaderCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -313,7 +322,7 @@ QShaderCode QShader::shader(const QShaderKey &key) const
|
|||||||
*/
|
*/
|
||||||
void QShader::setShader(const QShaderKey &key, const QShaderCode &shader)
|
void QShader::setShader(const QShaderKey &key, const QShaderCode &shader)
|
||||||
{
|
{
|
||||||
if (d->shaders.value(key) == shader)
|
if (d && d->shaders.value(key) == shader)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
detach();
|
||||||
@ -326,6 +335,9 @@ void QShader::setShader(const QShaderKey &key, const QShaderCode &shader)
|
|||||||
*/
|
*/
|
||||||
void QShader::removeShader(const QShaderKey &key)
|
void QShader::removeShader(const QShaderKey &key)
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
auto it = d->shaders.find(key);
|
auto it = d->shaders.find(key);
|
||||||
if (it == d->shaders.end())
|
if (it == d->shaders.end())
|
||||||
return;
|
return;
|
||||||
@ -350,6 +362,9 @@ static void writeShaderKey(QDataStream *ds, const QShaderKey &k)
|
|||||||
*/
|
*/
|
||||||
QByteArray QShader::serialized() const
|
QByteArray QShader::serialized() const
|
||||||
{
|
{
|
||||||
|
static QShaderPrivate sd;
|
||||||
|
QShaderPrivate *dd = d ? d : &sd;
|
||||||
|
|
||||||
QBuffer buf;
|
QBuffer buf;
|
||||||
QDataStream ds(&buf);
|
QDataStream ds(&buf);
|
||||||
ds.setVersion(QDataStream::Qt_5_10);
|
ds.setVersion(QDataStream::Qt_5_10);
|
||||||
@ -357,18 +372,18 @@ QByteArray QShader::serialized() const
|
|||||||
return QByteArray();
|
return QByteArray();
|
||||||
|
|
||||||
ds << QShaderPrivate::QSB_VERSION;
|
ds << QShaderPrivate::QSB_VERSION;
|
||||||
ds << int(d->stage);
|
ds << int(dd->stage);
|
||||||
d->desc.serialize(&ds);
|
dd->desc.serialize(&ds);
|
||||||
ds << int(d->shaders.count());
|
ds << int(dd->shaders.count());
|
||||||
for (auto it = d->shaders.cbegin(), itEnd = d->shaders.cend(); it != itEnd; ++it) {
|
for (auto it = dd->shaders.cbegin(), itEnd = dd->shaders.cend(); it != itEnd; ++it) {
|
||||||
const QShaderKey &k(it.key());
|
const QShaderKey &k(it.key());
|
||||||
writeShaderKey(&ds, k);
|
writeShaderKey(&ds, k);
|
||||||
const QShaderCode &shader(d->shaders.value(k));
|
const QShaderCode &shader(dd->shaders.value(k));
|
||||||
ds << shader.shader();
|
ds << shader.shader();
|
||||||
ds << shader.entryPoint();
|
ds << shader.entryPoint();
|
||||||
}
|
}
|
||||||
ds << int(d->bindings.count());
|
ds << int(dd->bindings.count());
|
||||||
for (auto it = d->bindings.cbegin(), itEnd = d->bindings.cend(); it != itEnd; ++it) {
|
for (auto it = dd->bindings.cbegin(), itEnd = dd->bindings.cend(); it != itEnd; ++it) {
|
||||||
const QShaderKey &k(it.key());
|
const QShaderKey &k(it.key());
|
||||||
writeShaderKey(&ds, k);
|
writeShaderKey(&ds, k);
|
||||||
const NativeResourceBindingMap &map(it.value());
|
const NativeResourceBindingMap &map(it.value());
|
||||||
@ -379,8 +394,8 @@ QByteArray QShader::serialized() const
|
|||||||
ds << mapIt.value().second;
|
ds << mapIt.value().second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ds << int(d->combinedImageMap.count());
|
ds << int(dd->combinedImageMap.count());
|
||||||
for (auto it = d->combinedImageMap.cbegin(), itEnd = d->combinedImageMap.cend(); it != itEnd; ++it) {
|
for (auto it = dd->combinedImageMap.cbegin(), itEnd = dd->combinedImageMap.cend(); it != itEnd; ++it) {
|
||||||
const QShaderKey &k(it.key());
|
const QShaderKey &k(it.key());
|
||||||
writeShaderKey(&ds, k);
|
writeShaderKey(&ds, k);
|
||||||
const SeparateToCombinedImageSamplerMappingList &list(it.value());
|
const SeparateToCombinedImageSamplerMappingList &list(it.value());
|
||||||
@ -391,8 +406,8 @@ QByteArray QShader::serialized() const
|
|||||||
ds << listIt->samplerBinding;
|
ds << listIt->samplerBinding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ds << int(d->nativeShaderInfoMap.count());
|
ds << int(dd->nativeShaderInfoMap.count());
|
||||||
for (auto it = d->nativeShaderInfoMap.cbegin(), itEnd = d->nativeShaderInfoMap.cend(); it != itEnd; ++it) {
|
for (auto it = dd->nativeShaderInfoMap.cbegin(), itEnd = dd->nativeShaderInfoMap.cend(); it != itEnd; ++it) {
|
||||||
const QShaderKey &k(it.key());
|
const QShaderKey &k(it.key());
|
||||||
writeShaderKey(&ds, k);
|
writeShaderKey(&ds, k);
|
||||||
ds << it->flags;
|
ds << it->flags;
|
||||||
@ -438,6 +453,7 @@ QShader QShader::fromSerialized(const QByteArray &data)
|
|||||||
return QShader();
|
return QShader();
|
||||||
|
|
||||||
QShader bs;
|
QShader bs;
|
||||||
|
bs.detach(); // to get d created
|
||||||
QShaderPrivate *d = QShaderPrivate::get(&bs);
|
QShaderPrivate *d = QShaderPrivate::get(&bs);
|
||||||
Q_ASSERT(d->ref.loadRelaxed() == 1); // must be detached
|
Q_ASSERT(d->ref.loadRelaxed() == 1); // must be detached
|
||||||
int intVal;
|
int intVal;
|
||||||
@ -573,6 +589,9 @@ QShaderKey::QShaderKey(QShader::Source s,
|
|||||||
*/
|
*/
|
||||||
bool operator==(const QShader &lhs, const QShader &rhs) noexcept
|
bool operator==(const QShader &lhs, const QShader &rhs) noexcept
|
||||||
{
|
{
|
||||||
|
if (!lhs.d || !rhs.d)
|
||||||
|
return lhs.d == rhs.d;
|
||||||
|
|
||||||
return lhs.d->stage == rhs.d->stage
|
return lhs.d->stage == rhs.d->stage
|
||||||
&& lhs.d->shaders == rhs.d->shaders
|
&& lhs.d->shaders == rhs.d->shaders
|
||||||
&& lhs.d->bindings == rhs.d->bindings;
|
&& lhs.d->bindings == rhs.d->bindings;
|
||||||
@ -595,11 +614,13 @@ bool operator==(const QShader &lhs, const QShader &rhs) noexcept
|
|||||||
*/
|
*/
|
||||||
size_t qHash(const QShader &s, size_t seed) noexcept
|
size_t qHash(const QShader &s, size_t seed) noexcept
|
||||||
{
|
{
|
||||||
QtPrivate::QHashCombine hash;
|
if (s.d) {
|
||||||
seed = hash(seed, s.stage());
|
QtPrivate::QHashCombine hash;
|
||||||
if (!s.d->shaders.isEmpty()) {
|
seed = hash(seed, s.stage());
|
||||||
seed = hash(seed, s.d->shaders.firstKey());
|
if (!s.d->shaders.isEmpty()) {
|
||||||
seed = hash(seed, s.d->shaders.first());
|
seed = hash(seed, s.d->shaders.firstKey());
|
||||||
|
seed = hash(seed, s.d->shaders.first());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
@ -741,11 +762,15 @@ QDebug operator<<(QDebug dbg, const QShader &bs)
|
|||||||
const QShaderPrivate *d = bs.d;
|
const QShaderPrivate *d = bs.d;
|
||||||
QDebugStateSaver saver(dbg);
|
QDebugStateSaver saver(dbg);
|
||||||
|
|
||||||
dbg.nospace() << "QShader("
|
if (d) {
|
||||||
<< "stage=" << d->stage
|
dbg.nospace() << "QShader("
|
||||||
<< " shaders=" << d->shaders.keys()
|
<< "stage=" << d->stage
|
||||||
<< " desc.isValid=" << d->desc.isValid()
|
<< " shaders=" << d->shaders.keys()
|
||||||
<< ')';
|
<< " desc.isValid=" << d->desc.isValid()
|
||||||
|
<< ')';
|
||||||
|
} else {
|
||||||
|
dbg.nospace() << "QShader()";
|
||||||
|
}
|
||||||
|
|
||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
@ -809,6 +834,9 @@ QDebug operator<<(QDebug dbg, const QShaderVersion &v)
|
|||||||
*/
|
*/
|
||||||
QShader::NativeResourceBindingMap QShader::nativeResourceBindingMap(const QShaderKey &key) const
|
QShader::NativeResourceBindingMap QShader::nativeResourceBindingMap(const QShaderKey &key) const
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return {};
|
||||||
|
|
||||||
auto it = d->bindings.constFind(key);
|
auto it = d->bindings.constFind(key);
|
||||||
if (it == d->bindings.cend())
|
if (it == d->bindings.cend())
|
||||||
return {};
|
return {};
|
||||||
@ -832,6 +860,9 @@ void QShader::setResourceBindingMap(const QShaderKey &key, const NativeResourceB
|
|||||||
*/
|
*/
|
||||||
void QShader::removeResourceBindingMap(const QShaderKey &key)
|
void QShader::removeResourceBindingMap(const QShaderKey &key)
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
auto it = d->bindings.find(key);
|
auto it = d->bindings.find(key);
|
||||||
if (it == d->bindings.end())
|
if (it == d->bindings.end())
|
||||||
return;
|
return;
|
||||||
@ -866,6 +897,9 @@ void QShader::removeResourceBindingMap(const QShaderKey &key)
|
|||||||
*/
|
*/
|
||||||
QShader::SeparateToCombinedImageSamplerMappingList QShader::separateToCombinedImageSamplerMappingList(const QShaderKey &key) const
|
QShader::SeparateToCombinedImageSamplerMappingList QShader::separateToCombinedImageSamplerMappingList(const QShaderKey &key) const
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return {};
|
||||||
|
|
||||||
auto it = d->combinedImageMap.constFind(key);
|
auto it = d->combinedImageMap.constFind(key);
|
||||||
if (it == d->combinedImageMap.cend())
|
if (it == d->combinedImageMap.cend())
|
||||||
return {};
|
return {};
|
||||||
@ -890,6 +924,9 @@ void QShader::setSeparateToCombinedImageSamplerMappingList(const QShaderKey &key
|
|||||||
*/
|
*/
|
||||||
void QShader::removeSeparateToCombinedImageSamplerMappingList(const QShaderKey &key)
|
void QShader::removeSeparateToCombinedImageSamplerMappingList(const QShaderKey &key)
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
auto it = d->combinedImageMap.find(key);
|
auto it = d->combinedImageMap.find(key);
|
||||||
if (it == d->combinedImageMap.end())
|
if (it == d->combinedImageMap.end())
|
||||||
return;
|
return;
|
||||||
@ -925,6 +962,9 @@ void QShader::removeSeparateToCombinedImageSamplerMappingList(const QShaderKey &
|
|||||||
*/
|
*/
|
||||||
QShader::NativeShaderInfo QShader::nativeShaderInfo(const QShaderKey &key) const
|
QShader::NativeShaderInfo QShader::nativeShaderInfo(const QShaderKey &key) const
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return {};
|
||||||
|
|
||||||
auto it = d->nativeShaderInfoMap.constFind(key);
|
auto it = d->nativeShaderInfoMap.constFind(key);
|
||||||
if (it == d->nativeShaderInfoMap.cend())
|
if (it == d->nativeShaderInfoMap.cend())
|
||||||
return {};
|
return {};
|
||||||
@ -948,6 +988,9 @@ void QShader::setNativeShaderInfo(const QShaderKey &key, const NativeShaderInfo
|
|||||||
*/
|
*/
|
||||||
void QShader::removeNativeShaderInfo(const QShaderKey &key)
|
void QShader::removeNativeShaderInfo(const QShaderKey &key)
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
auto it = d->nativeShaderInfoMap.find(key);
|
auto it = d->nativeShaderInfoMap.find(key);
|
||||||
if (it == d->nativeShaderInfoMap.end())
|
if (it == d->nativeShaderInfoMap.end())
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user