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 #include "../api-build_p.h"
8 #if BL_TARGET_ARCH_X86 && !defined(BL_BUILD_NO_JIT)
9 
10 #include "../pipegen/fetchpart_p.h"
11 #include "../pipegen/pipecompiler_p.h"
12 
13 namespace BLPipeGen {
14 
15 // ============================================================================
16 // [BLPipeGen::FetchPart - Construction / Destruction]
17 // ============================================================================
18 
FetchPart(PipeCompiler * pc,uint32_t fetchType,uint32_t fetchPayload,uint32_t format)19 FetchPart::FetchPart(PipeCompiler* pc, uint32_t fetchType, uint32_t fetchPayload, uint32_t format) noexcept
20   : PipePart(pc, kTypeFetch),
21     _fetchType(fetchType),
22     _fetchPayload(fetchPayload),
23     _format(uint8_t(format)),
24     _bpp(uint8_t(blFormatInfo[format].depth / 8u)),
25     _maxPixels(1),
26     _pixelType(Pixel::kTypeNone), // Initialized by FetchPart::init().
27     _pixelGranularity(0),         // Initialized by FetchPart::init().
28     _alphaFetch(false),           // Initialized by FetchPart::init().
29     _alphaOffset(0),              // Initialized by FetchPart::init().
30     _isRectFill(false),           // Initialized by FetchPart::init().
31     _isComplexFetch(false),
32     _hasRGB((blFormatInfo[format].flags & BL_FORMAT_FLAG_RGB) != 0),
33     _hasAlpha((blFormatInfo[format].flags & BL_FORMAT_FLAG_ALPHA) != 0) {}
34 
35 // ============================================================================
36 // [BLPipeGen::FetchPart - Init / Fini]
37 // ============================================================================
38 
init(x86::Gp & x,x86::Gp & y,uint32_t pixelType,uint32_t pixelGranularity)39 void FetchPart::init(x86::Gp& x, x86::Gp& y, uint32_t pixelType, uint32_t pixelGranularity) noexcept {
40   _isRectFill = x.isValid();
41   _pixelType = uint8_t(pixelType);
42   _pixelGranularity = uint8_t(pixelGranularity);
43 
44   // Initialize alpha fetch information. The fetch would be A8 if either the
45   // requested pixel is alpha-only or the source pixel format is alpha-only
46   // (or both).
47   _alphaFetch = _pixelType == Pixel::kTypeAlpha || _format == BL_FORMAT_A8;
48   _alphaOffset = blFormatInfo[_format].aShift / 8;
49 
50   _initPart(x, y);
51   _initGlobalHook(cc->cursor());
52 }
53 
fini()54 void FetchPart::fini() noexcept {
55   _finiPart();
56   _finiGlobalHook();
57 
58   _isRectFill = false;
59   _pixelType = Pixel::kTypeNone;
60   _pixelGranularity = 0;
61 }
62 
_initPart(x86::Gp & x,x86::Gp & y)63 void FetchPart::_initPart(x86::Gp& x, x86::Gp& y) noexcept {
64   BL_UNUSED(x);
65   BL_UNUSED(y);
66 }
67 
_finiPart()68 void FetchPart::_finiPart() noexcept {}
69 
70 // ============================================================================
71 // [BLPipeGen::FetchPart - Advance]
72 // ============================================================================
73 
74 // By default these do nothing, only used by `SolidFetch()` this way.
advanceY()75 void FetchPart::advanceY() noexcept {
76   // Nothing by default.
77 }
78 
startAtX(x86::Gp & x)79 void FetchPart::startAtX(x86::Gp& x) noexcept {
80   // Nothing by default.
81   BL_UNUSED(x);
82 }
83 
advanceX(x86::Gp & x,x86::Gp & diff)84 void FetchPart::advanceX(x86::Gp& x, x86::Gp& diff) noexcept {
85   // Nothing by default.
86   BL_UNUSED(x);
87   BL_UNUSED(diff);
88 }
89 
90 // ============================================================================
91 // [BLPipeGen::FetchPart - Fetch]
92 // ============================================================================
93 
prefetch1()94 void FetchPart::prefetch1() noexcept {
95   // Nothing by default.
96 }
97 
enterN()98 void FetchPart::enterN() noexcept {
99   // Nothing by default.
100 }
101 
leaveN()102 void FetchPart::leaveN() noexcept {
103   // Nothing by default.
104 }
105 
prefetchN()106 void FetchPart::prefetchN() noexcept {
107   // Nothing by default.
108 }
109 
postfetchN()110 void FetchPart::postfetchN() noexcept {
111   // Nothing by default.
112 }
113 
fetch8(Pixel & p,uint32_t flags)114 void FetchPart::fetch8(Pixel& p, uint32_t flags) noexcept {
115   // Fallback to `fetch4()` by default.
116   p.setCount(8);
117 
118   Pixel x(p.type());
119   Pixel y(p.type());
120 
121   fetch4(x, flags);
122   fetch4(y, flags);
123 
124   // Each invocation of fetch should provide a stable output.
125   BL_ASSERT(x.isImmutable() == y.isImmutable());
126 
127   if (p.isRGBA()) {
128     if (flags & Pixel::kPC) {
129       p.pc.init(x.pc[0], y.pc[0]);
130       pc->rename(p.pc, "pc");
131     }
132 
133     if (flags & Pixel::kUC) {
134       p.uc.init(x.uc[0], x.uc[1], y.uc[0], y.uc[1]);
135       pc->rename(p.uc, "uc");
136     }
137 
138     if (flags & Pixel::kUA) {
139       p.ua.init(x.ua[0], x.ua[1], y.ua[0], y.ua[1]);
140       pc->rename(p.uc, "ua");
141     }
142 
143     if (flags & Pixel::kUIA) {
144       p.uia.init(x.uia[0], x.uia[1], y.uia[0], y.uia[1]);
145       pc->rename(p.uc, "uia");
146     }
147 
148     p.setImmutable(x.isImmutable());
149   }
150   else if (p.isAlpha()) {
151     if (flags & Pixel::kPA) {
152       p.pa.init(x.pa[0]);
153       pc->rename(p.pa, "pa");
154       pc->vunpackli32(x.pa[0], x.pa[0], y.pa[0]);
155     }
156 
157     if (flags & Pixel::kUA) {
158       p.ua.init(x.ua[0]);
159       pc->rename(p.ua, "ua");
160       pc->vunpackli64(x.ua[0], x.ua[0], y.ua[0]);
161     }
162 
163     if (flags & Pixel::kUIA) {
164       p.uia.init(x.uia[0]);
165       pc->rename(p.uia, "uia");
166       pc->vunpackli64(x.uia[0], x.uia[0], y.uia[0]);
167     }
168 
169     p.setImmutable(x.isImmutable());
170   }
171 }
172 
173 } // {BLPipeGen}
174 
175 #endif
176