File indexing completed on 2024-06-23 04:27:47

0001 /*
0002  *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_DAB_CACHE_BASE_H
0008 #define __KIS_DAB_CACHE_BASE_H
0009 
0010 #include "kritapaintop_export.h"
0011 #include "kis_brush.h"
0012 
0013 #include "KisDabCacheUtils.h"
0014 
0015 class KisColorSource;
0016 class KisSharpnessOption;
0017 class KisTextureOption;
0018 class KisMirrorOption;
0019 class KisPrecisionOption;
0020 struct MirrorProperties;
0021 
0022 
0023 /**
0024  * @brief The KisDabCacheBase class provides caching for dabs into the brush paintop
0025  *
0026  *  This class adds caching of the dabs to the paintop system of Krita.
0027  *  Such cache makes the execution of the benchmarks up to 2 times faster.
0028  *  Subjectively, the real painting becomes much faster, especially with
0029  *  huge brushes. Artists report up to 20% speed gain while painting.
0030  *
0031  *  Of course, such caching makes the painting a bit less precise: we need
0032  *  to tolerate subpixel differences to allow the cache to work. Sometimes
0033  *  small difference in the size of a dab can also be acceptable. That is
0034  *  why I introduced levels of precision. They are graded from 1 to 5: from
0035  *  the fastest and less precise to the slowest, but with the best quality.
0036  *  You can see the slider in the paintop settings dialog. The ToolTip text
0037  *  explains which features of the brush are sacrificed on each precision
0038  *  level.
0039  *
0040  *  The texturing and mirroring problems are solved.
0041  */
0042 class PAINTOP_EXPORT KisDabCacheBase
0043 {
0044 public:
0045     KisDabCacheBase();
0046     ~KisDabCacheBase();
0047 
0048     void setMirrorPostprocessing(KisMirrorOption *option);
0049     void setPrecisionOption(KisPrecisionOption *option);
0050 
0051     /**
0052      * Disables handling of the subPixelX and subPixelY values, this
0053      * is needed at least for the Color Smudge paint op, which reads
0054      * aligned areas from image, so additional offsets generated by
0055      * the subpixel precision should be avoided
0056      */
0057     void disableSubpixelPrecision();
0058 
0059     /**
0060      * Return true if the dab needs postprocessing by special options
0061      * like 'texture' or 'sharpness'
0062      */
0063     bool needSeparateOriginal(KisTextureOption *textureOption,
0064                               KisSharpnessOption *sharpnessOption) const;
0065 
0066 protected:
0067     /**
0068      * Fetches all the necessary information for dab generation and
0069      * tells if the caller must should reuse the preciously returned dab. *
0070      * Please note that KisDabCacheBase has an internal state, that keeps the
0071      * parameters of the previously generated (on a cache-miss) dab. This function
0072      * automatically updates this state when 'shouldUseCache == false'. Therefore, the
0073      * caller *must* generate the dab if and only if when 'shouldUseCache == false'.
0074      * Otherwise the internal state will become inconsistent.
0075      *
0076      * @param hasDabInCache shows if the caller has something in its cache
0077      * @param resources rendering resources available for this dab
0078      * @param request the request information
0079      * @param di (OUT) calculated dab generation information
0080      * @param shouldUseCache (OUT) shows whether the caller *must* use cache or not
0081      */
0082     void fetchDabGenerationInfo(bool hasDabInCache,
0083                                 KisDabCacheUtils::DabRenderingResources *resources,
0084                                 const KisDabCacheUtils::DabRequestInfo &request,
0085                                 /* out */
0086                                 KisDabCacheUtils::DabGenerationInfo *di,
0087                                 bool *shouldUseCache);
0088 
0089 private:
0090     struct SavedDabParameters;
0091     struct DabPosition;
0092 private:
0093     inline SavedDabParameters getDabParameters(KisBrushSP brush, const KoColor& color,
0094                                                KisDabShape const&,
0095                                                const KisPaintInformation& info,
0096                                                double subPixelX, double subPixelY,
0097                                                qreal softnessFactor,
0098                                                qreal lightnessStrength,
0099                                                MirrorProperties mirrorProperties);
0100 
0101     inline KisDabCacheBase::DabPosition
0102     calculateDabRect(KisBrushSP brush, const QPointF &cursorPoint,
0103                      KisDabShape,
0104                      const KisPaintInformation& info,
0105                      const MirrorProperties &mirrorProperties, KisSharpnessOption *sharpnessOption);
0106 
0107 private:
0108     struct Private;
0109     Private * const m_d;
0110 };
0111 
0112 #endif /* __KIS_DAB_CACHE_BASE_H */