File indexing completed on 2024-05-05 03:56:28

0001 /*
0002  *  SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "shadowedtexturenode.h"
0008 
0009 #include "shadowedbordertexturematerial.h"
0010 
0011 template<typename T>
0012 inline void preprocessTexture(QSGMaterial *material, QSGTextureProvider *provider)
0013 {
0014     auto m = static_cast<T *>(material);
0015     // Since we handle texture coordinates differently in the shader, we
0016     // need to remove the texture from the atlas for now.
0017     if (provider->texture()->isAtlasTexture()) {
0018         // Blegh, I have no idea why "removedFromAtlas" doesn't just return
0019         // the texture when it's not an atlas.
0020         m->textureSource = provider->texture()->removedFromAtlas();
0021     } else {
0022         m->textureSource = provider->texture();
0023     }
0024     if (QSGDynamicTexture *dynamic_texture = qobject_cast<QSGDynamicTexture *>(m->textureSource)) {
0025         dynamic_texture->updateTexture();
0026     }
0027 }
0028 
0029 ShadowedTextureNode::ShadowedTextureNode()
0030     : ShadowedRectangleNode()
0031 {
0032     setFlag(QSGNode::UsePreprocess);
0033 }
0034 
0035 ShadowedTextureNode::~ShadowedTextureNode()
0036 {
0037     QObject::disconnect(m_textureChangeConnectionHandle);
0038 }
0039 
0040 void ShadowedTextureNode::setTextureSource(QSGTextureProvider *source)
0041 {
0042     if (m_textureSource == source) {
0043         return;
0044     }
0045 
0046     if (m_textureSource) {
0047         m_textureSource->disconnect();
0048     }
0049 
0050     m_textureSource = source;
0051     m_textureChangeConnectionHandle = QObject::connect(m_textureSource.data(), &QSGTextureProvider::textureChanged, [this] {
0052         markDirty(QSGNode::DirtyMaterial);
0053     });
0054     markDirty(QSGNode::DirtyMaterial);
0055 }
0056 
0057 void ShadowedTextureNode::preprocess()
0058 {
0059     if (m_textureSource && m_material && m_textureSource->texture()) {
0060         if (m_material->type() == borderlessMaterialType()) {
0061             preprocessTexture<ShadowedTextureMaterial>(m_material, m_textureSource);
0062         } else {
0063             preprocessTexture<ShadowedBorderTextureMaterial>(m_material, m_textureSource);
0064         }
0065     }
0066 }
0067 
0068 ShadowedRectangleMaterial *ShadowedTextureNode::createBorderlessMaterial()
0069 {
0070     return new ShadowedTextureMaterial{};
0071 }
0072 
0073 ShadowedBorderRectangleMaterial *ShadowedTextureNode::createBorderMaterial()
0074 {
0075     return new ShadowedBorderTextureMaterial{};
0076 }
0077 
0078 QSGMaterialType *ShadowedTextureNode::borderlessMaterialType()
0079 {
0080     return &ShadowedTextureMaterial::staticType;
0081 }
0082 
0083 QSGMaterialType *ShadowedTextureNode::borderMaterialType()
0084 {
0085     return &ShadowedBorderTextureMaterial::staticType;
0086 }