File indexing completed on 2024-12-22 04:12:46

0001 /*
0002  * SPDX-FileCopyrightText: 2016 Julian Thijssen <julianthijssen@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "canvas/kis_display_filter.h"
0008 
0009 #include <QOpenGLShaderProgram>
0010 #include <QByteArray>
0011 #include <QString>
0012 
0013 #include <unordered_map>
0014 #include <string>
0015 #include <stdexcept>
0016 
0017 #include <map>
0018 
0019 /**
0020  * An enum for storing all uniform names used in shaders
0021  */
0022 enum Uniform { ModelViewProjection, TextureMatrix, ViewportScale,
0023                TexelSize, Texture0, Texture1, FixedLodLevel, FragmentColor };
0024 
0025 /**
0026  * A wrapper class over Qt's QOpenGLShaderProgram to
0027  * provide access to uniform locations without
0028  * having to store them as constants next to the shader.
0029  */
0030 class KisShaderProgram : public QOpenGLShaderProgram {
0031 public:
0032     /**
0033      * Stores the mapping of uniform enums to actual shader uniform names.
0034      * The actual shader names are necessary for calls to uniformLocation.
0035      */
0036     static std::map<Uniform, const char *> names;
0037 
0038     /**
0039      * Stores uniform location in cache if it is called for the first time
0040      * and retrieves the location from the map on subsequent calls.
0041      */
0042     int location(Uniform uniform) {
0043         std::map<Uniform, int>::const_iterator it = locationMap.find(uniform);
0044         if (it != locationMap.end()) {
0045             return it->second;
0046         } else {
0047             int location = uniformLocation(names[uniform]);
0048             locationMap[uniform] = location;
0049             return location;
0050         }
0051     }
0052 private:
0053     std::map<Uniform, int> locationMap;
0054 };
0055 
0056 /**
0057  * A wrapper class over C++ Runtime Error, specifically to record
0058  * failures in shader compilation. Only thrown in KisOpenGLShaderLoader.
0059  */
0060 class ShaderLoaderException : public std::runtime_error {
0061 public:
0062     ShaderLoaderException(QString error) : std::runtime_error(error.toStdString()) { }
0063 };
0064 
0065 /**
0066  * A utility class for loading various shaders we use in Krita. It provides
0067  * specific methods for shaders that pick the correct vertex and fragment files
0068  * depending on the availability of OpenGL3. Additionally, it provides a generic
0069  * shader loading method to prevent duplication.
0070  */
0071 class KisOpenGLShaderLoader {
0072 public:
0073     KisShaderProgram *loadDisplayShader(QSharedPointer<KisDisplayFilter> displayFilter, bool useHiQualityFiltering);
0074     KisShaderProgram *loadCheckerShader();
0075     KisShaderProgram *loadSolidColorShader();
0076 
0077 private:
0078     KisShaderProgram *loadShader(QString vertPath, QString fragPath, QByteArray vertHeader, QByteArray fragHeader);
0079 };