1 // [Blend2D] 2 // 2D Vector Graphics Powered by a JIT Compiler. 3 // 4 // [License] 5 // Zlib - See LICENSE.md file in the package. 6 7 #ifndef BLEND2D_PIPEGEN_FETCHPART_P_H 8 #define BLEND2D_PIPEGEN_FETCHPART_P_H 9 10 #include "../pipegen/pipepart_p.h" 11 12 //! \cond INTERNAL 13 //! \addtogroup blend2d_internal_pipegen 14 //! \{ 15 16 namespace BLPipeGen { 17 18 // ============================================================================ 19 // [BLPipeGen::FetchPart] 20 // ============================================================================ 21 22 //! Pipeline fetch part. 23 class FetchPart : public PipePart { 24 public: 25 BL_NONCOPYABLE(FetchPart) 26 27 enum : uint32_t { 28 kUnlimitedMaxPixels = 64 29 }; 30 31 //! Fetch type. 32 uint32_t _fetchType; 33 //! Fetch extra (different meaning for each fetch type). 34 uint32_t _fetchPayload; 35 36 //! Source pixel format, see `BLFormat`. 37 uint8_t _format; 38 //! Source bytes-per-pixel (only required by pattern fetcher). 39 uint8_t _bpp; 40 //! Maximum pixel step that the fetcher can fetch at a time (0=unlimited). 41 uint8_t _maxPixels; 42 //! Pixel type. 43 uint8_t _pixelType; 44 //! Pixel granularity passed to init(). 45 uint8_t _pixelGranularity; 46 47 //! True if the fetching should happen in alpha mode (no RGB). 48 uint8_t _alphaFetch; 49 //! Alpha channel [memory] offset, only used when `_alphaFetch` is true 50 uint8_t _alphaOffset; 51 52 //! Fetcher is in a rectangle fill mode, set and cleared by `init...()`. 53 bool _isRectFill; 54 //! If the fetch-type is complex (used to limit the maximum number of pixels). 55 bool _isComplexFetch; 56 57 //! If the fetched pixels contain RGB channels. 58 bool _hasRGB; 59 //! If the fetched pixels contain alpha channel. 60 bool _hasAlpha; 61 62 FetchPart(PipeCompiler* pc, uint32_t fetchType, uint32_t fetchPayload, uint32_t format) noexcept; 63 64 //! Returns the fetch type. fetchType()65 BL_INLINE uint32_t fetchType() const noexcept { return _fetchType; } 66 67 //! Tests whether the fetch-type equals `ft`. isFetchType(uint32_t ft)68 BL_INLINE bool isFetchType(uint32_t ft) const noexcept { return _fetchType == ft; } 69 //! Tests whether the fetch-type is between `first..last`, inclusive. isFetchType(uint32_t first,uint32_t last)70 BL_INLINE bool isFetchType(uint32_t first, uint32_t last) const noexcept { return _fetchType >= first && _fetchType <= last; } 71 72 //! Tests whether the fetch-type is solid. isSolid()73 BL_INLINE bool isSolid() const noexcept { return isFetchType(BL_PIPE_FETCH_TYPE_SOLID); } 74 75 //! Tests whether the fetch-type is gradient. isGradient()76 BL_INLINE bool isGradient() const noexcept { return isFetchType(BL_PIPE_FETCH_TYPE_GRADIENT_ANY_FIRST, BL_PIPE_FETCH_TYPE_GRADIENT_ANY_LAST); } 77 //! Tests whether the fetch-type is linear gradient. isLinearGradient()78 BL_INLINE bool isLinearGradient() const noexcept { return isFetchType(BL_PIPE_FETCH_TYPE_GRADIENT_LINEAR_FIRST, BL_PIPE_FETCH_TYPE_GRADIENT_LINEAR_LAST); } 79 //! Tests whether the fetch-type is radial gradient. isRadialGradient()80 BL_INLINE bool isRadialGradient() const noexcept { return isFetchType(BL_PIPE_FETCH_TYPE_GRADIENT_RADIAL_FIRST, BL_PIPE_FETCH_TYPE_GRADIENT_RADIAL_LAST); } 81 //! Tests whether the fetch-type is conical gradient. isConicalGradient()82 BL_INLINE bool isConicalGradient() const noexcept { return isFetchType(BL_PIPE_FETCH_TYPE_GRADIENT_CONICAL_FIRST, BL_PIPE_FETCH_TYPE_GRADIENT_CONICAL_LAST); } 83 84 //! Tests whether the fetch-type is pattern. isPattern()85 BL_INLINE bool isPattern() const noexcept { return isFetchType(BL_PIPE_FETCH_TYPE_PATTERN_ANY_FIRST, BL_PIPE_FETCH_TYPE_PATTERN_ANY_LAST); } 86 //! Tests whether the fetch is the destination (special type). isPixelPtr()87 BL_INLINE bool isPixelPtr() const noexcept { return isFetchType(BL_PIPE_FETCH_TYPE_PIXEL_PTR); } 88 89 //! Returns source pixel format. format()90 BL_INLINE uint32_t format() const noexcept { return _format; } 91 //! Returns source pixel format information. formatInfo()92 BL_INLINE BLFormatInfo formatInfo() const noexcept { return blFormatInfo[_format]; } 93 94 //! Returns source bytes-per-pixel (only used when `isPattern()` is true). bpp()95 BL_INLINE uint32_t bpp() const noexcept { return _bpp; } 96 97 //! Returns the maximum pixels the fetch part can fetch at a time. maxPixels()98 BL_INLINE uint32_t maxPixels() const noexcept { return _maxPixels; } 99 100 //! Tests whether the fetched pixels contain RGB channels. hasRGB()101 BL_INLINE bool hasRGB() const noexcept { return _hasRGB; } 102 //! Tests whether the fetched pixels contain Alpha channel. hasAlpha()103 BL_INLINE bool hasAlpha() const noexcept { return _hasAlpha; } 104 105 //! Tests whether the fetching should happen in alpha-only mode. isAlphaFetch()106 BL_INLINE bool isAlphaFetch() const noexcept { return _alphaFetch != 0; } 107 //! Returns a byte offset of alpha channel (if provided), used when fetching alpha from memory. alphaOffset()108 BL_INLINE uint32_t alphaOffset() const noexcept { return _alphaOffset; } 109 110 //! Tests whether the fetch is currently initialized for a rectangular fill. isRectFill()111 BL_INLINE bool isRectFill() const noexcept { return _isRectFill; } 112 //! Returns the pixel granularity passed to `FetchPath::init()`. pixelGranularity()113 BL_INLINE uint32_t pixelGranularity() const noexcept { return _pixelGranularity; } 114 isComplexFetch()115 BL_INLINE bool isComplexFetch() const noexcept { return _isComplexFetch; } setComplexFetch(bool value)116 BL_INLINE void setComplexFetch(bool value) noexcept { _isComplexFetch = value; } 117 118 void init(x86::Gp& x, x86::Gp& y, uint32_t pixelType, uint32_t pixelGranularity) noexcept; 119 void fini() noexcept; 120 121 virtual void _initPart(x86::Gp& x, x86::Gp& y) noexcept; 122 virtual void _finiPart() noexcept; 123 124 //! Advances the current y coordinate by one pixel. 125 virtual void advanceY() noexcept; 126 127 //! Initializes the current horizontal cursor of the current scanline to `x`. 128 //! 129 //! \note This initializer is generally called once per scanline to setup the 130 //! current position by initializing it to `x`. The position is then advanced 131 //! automatically by pixel fetchers and by `advanceX()`, which is used when 132 //! there is a gap in the scanline that has to be skipped. 133 virtual void startAtX(x86::Gp& x) noexcept; 134 135 //! Advances the current x coordinate by `diff` pixels. The final x position 136 //! after advance will be `x`. The fetcher can decide whether to use `x`, 137 //! `diff`, or both. 138 virtual void advanceX(x86::Gp& x, x86::Gp& diff) noexcept; 139 140 //! Called before `fetch1()`. 141 virtual void prefetch1() noexcept; 142 143 //! Fetches 1 RGBA pixel to `p` and advances by 1. 144 virtual void fetch1(Pixel& p, uint32_t flags) noexcept = 0; 145 146 //! Called as a prolog before fetching multiple fixels at once. This must be 147 //! called before any loop that would call `fetch4()` or `fetch8()` unless the 148 //! fetcher is in a vector mode because of `pixelGranularity`. 149 virtual void enterN() noexcept; 150 151 //! Called as an epilog after fetching multiple fixels at once. This must be 152 //! called after a loop that uses `fetch4()` or `fetch8()` unless the fetcher 153 //! is in a vector mode because of `pixelGranularity`. 154 virtual void leaveN() noexcept; 155 156 //! Called before a loop that calls `fetch4()` or `fetch8()`. In some cases 157 //! there will be some instructions placed between `prefetch` and `fetch`, 158 //! which means that if the fetcher requires an expensive operation that has 159 //! greater latency then it would be better to place that code into the prefetch 160 //! area. 161 virtual void prefetchN() noexcept; 162 163 //! Cancels the effect of `prefetchN()` and also automatic prefetch that happens 164 //! inside `fetch4()` or `fetch8()`. Must be called after a loop that calls 165 //! `fetch4()`, `fetch8()`, or immediately after `prefetchN()` if no loop has 166 //! been entered. 167 virtual void postfetchN() noexcept; 168 169 //! Fetches 4 pixels to `p` and advances by 4. 170 virtual void fetch4(Pixel& p, uint32_t flags) noexcept = 0; 171 172 //! Fetches 8 pixels to `p` and advances by 8. 173 //! 174 //! \note The default implementation uses `fetch4()` twice. 175 virtual void fetch8(Pixel& p, uint32_t flags) noexcept; 176 }; 177 178 } // {BLPipeGen} 179 180 //! \} 181 //! \endcond 182 183 #endif // BLEND2D_PIPEGEN_FETCHPART_P_H 184