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/compoppart_p.h"
11 #include "../pipegen/fetchsolidpart_p.h"
12 #include "../pipegen/pipecompiler_p.h"
13
14 namespace BLPipeGen {
15
16 #define REL_SOLID(FIELD) BL_OFFSET_OF(BLPipeFetchData::Solid, FIELD)
17
18 // ============================================================================
19 // [BLPipeGen::FetchSolidPart - Construction / Destruction]
20 // ============================================================================
21
FetchSolidPart(PipeCompiler * pc,uint32_t fetchType,uint32_t fetchPayload,uint32_t format)22 FetchSolidPart::FetchSolidPart(PipeCompiler* pc, uint32_t fetchType, uint32_t fetchPayload, uint32_t format) noexcept
23 : FetchPart(pc, fetchType, fetchPayload, format) {
24
25 _maxPixels = kUnlimitedMaxPixels;
26 _maxSimdWidthSupported = 16;
27
28 _pixel.reset();
29 _pixel.setCount(1);
30 }
31
32 // ============================================================================
33 // [BLPipeGen::FetchSolidPart - Init / Fini]
34 // ============================================================================
35
_initPart(x86::Gp & x,x86::Gp & y)36 void FetchSolidPart::_initPart(x86::Gp& x, x86::Gp& y) noexcept {
37 if (_pixel.type() != _pixelType) {
38 _pixel.setType(_pixelType);
39 }
40 else {
41 // The type should never change after it's been assigned.
42 BL_ASSERT(_pixel.type() == _pixelType);
43 }
44
45 BL_UNUSED(x);
46 BL_UNUSED(y);
47 }
48
_finiPart()49 void FetchSolidPart::_finiPart() noexcept {}
50
51 // ============================================================================
52 // [BLPipeGen::FetchSolidPart - InitSolidFlags]
53 // ============================================================================
54
initSolidFlags(uint32_t flags)55 void FetchSolidPart::initSolidFlags(uint32_t flags) noexcept {
56 ScopedInjector injector(cc, &_globalHook);
57 Pixel& s = _pixel;
58
59 switch (s.type()) {
60 case Pixel::kTypeRGBA:
61 if ((flags & (Pixel::kPC | Pixel::kUC | Pixel::kUA | Pixel::kUIA)) && s.pc.empty()) {
62 s.pc.init(cc->newXmm("pixel.pc"));
63 x86::Vec& pix = s.pc[0];
64 pc->vbroadcast_u32(pix, x86::ptr_32(pc->_fetchData));
65 }
66 break;
67
68 case Pixel::kTypeAlpha:
69 if ((flags & (Pixel::kSA | Pixel::kPA | Pixel::kUA | Pixel::kUIA)) && !s.sa.isValid()) {
70 s.sa = cc->newUInt32("pixel.sa");
71 pc->load8(s.sa, x86::ptr_8(pc->_fetchData, 3));
72 }
73
74 if (flags & (Pixel::kPA | Pixel::kUA | Pixel::kUIA) && s.ua.empty()) {
75 s.ua.init(cc->newXmm("pixel.ua"));
76 pc->vbroadcast_u16(s.ua[0], s.sa);
77 }
78 break;
79 }
80
81 pc->xSatisfySolid(s, flags);
82 }
83
84 // ============================================================================
85 // [BLPipeGen::FetchSolidPart - Fetch]
86 // ============================================================================
87
fetch1(Pixel & p,uint32_t flags)88 void FetchSolidPart::fetch1(Pixel& p, uint32_t flags) noexcept {
89 BL_ASSERT(_pixel.type() == p.type());
90
91 p.setCount(1);
92 if (p.isRGBA()) {
93 if (flags & Pixel::kAny) {
94 initSolidFlags(flags & Pixel::kAny);
95 Pixel& s = _pixel;
96
97 if (flags & Pixel::kImmutable) {
98 if (flags & Pixel::kPC ) { p.pc.init(s.pc); }
99 if (flags & Pixel::kUC ) { p.uc.init(s.uc); }
100 if (flags & Pixel::kUA ) { p.ua.init(s.ua); }
101 if (flags & Pixel::kUIA) { p.uia.init(s.uia); }
102 }
103 else {
104 if (flags & Pixel::kPC) {
105 p.pc.init(cc->newXmm("p.pc0"));
106 pc->vmov(p.pc[0], s.pc[0]);
107 }
108
109 if (flags & Pixel::kUC) {
110 p.uc.init(cc->newXmm("p.uc0"));
111 pc->vmov(p.uc[0], s.uc[0]);
112 }
113
114 if (flags & Pixel::kUA) {
115 p.ua.init(cc->newXmm("p.ua0"));
116 pc->vmov(p.ua[0], s.ua[0]);
117 }
118
119 if (flags & Pixel::kUIA) {
120 p.uia.init(cc->newXmm("p.uia0"));
121 pc->vmov(p.uia[0], s.uia[0]);
122 }
123 }
124 }
125 }
126 else if (p.isAlpha()) {
127 if (flags & Pixel::kSA) {
128 initSolidFlags(Pixel::kSA);
129 Pixel& s = _pixel;
130
131 if (flags & Pixel::kImmutable) {
132 if (flags & Pixel::kSA ) { p.sa = s.sa; }
133 }
134 else {
135 if (flags & Pixel::kSA) {
136 p.sa = cc->newUInt32("p.sa");
137 cc->mov(p.sa, s.sa);
138 }
139 }
140 }
141 }
142
143 pc->xSatisfyPixel(p, flags);
144 }
145
fetch4(Pixel & p,uint32_t flags)146 void FetchSolidPart::fetch4(Pixel& p, uint32_t flags) noexcept {
147 BL_ASSERT(_pixel.type() == p.type());
148
149 p.setCount(4);
150 if (p.isRGBA()) {
151 initSolidFlags(flags & (Pixel::kPC | Pixel::kUC | Pixel::kUA | Pixel::kUIA));
152 Pixel& s = _pixel;
153
154 uint32_t pCount = 1;
155 uint32_t uCount = 2;
156
157 if (flags & Pixel::kImmutable) {
158 if (flags & Pixel::kPC) { p.pc.init(s.pc); }
159 if (flags & Pixel::kUC) { p.uc.init(s.uc); }
160 if (flags & Pixel::kUA) { p.ua.init(s.ua); }
161 if (flags & Pixel::kUIA) { p.uia.init(s.uia); }
162 }
163 else {
164 if (flags & Pixel::kPC) {
165 pc->newXmmArray(p.pc, pCount, "p.pc");
166 pc->vmov(p.pc, s.pc[0]);
167 }
168
169 if (flags & Pixel::kUC) {
170 pc->newXmmArray(p.uc, uCount, "p.uc");
171 pc->vmov(p.uc, s.uc[0]);
172 }
173
174 if (flags & Pixel::kUA) {
175 pc->newXmmArray(p.ua, uCount, "p.ua");
176 pc->vmov(p.ua, s.ua[0]);
177 }
178
179 if (flags & Pixel::kUIA) {
180 pc->newXmmArray(p.uia, uCount, "p.uia");
181 pc->vmov(p.uia, s.uia[0]);
182 }
183 }
184 }
185 else if (p.isAlpha()) {
186 initSolidFlags(flags & (Pixel::kPA | Pixel::kUA | Pixel::kUIA));
187 Pixel& s = _pixel;
188
189 uint32_t pCount = 1;
190 uint32_t uCount = 1;
191
192 if (flags & Pixel::kImmutable) {
193 if (flags & Pixel::kPA) { p.pa.init(s.pa); }
194 if (flags & Pixel::kUA) { p.ua.init(s.ua); }
195 if (flags & Pixel::kUIA) { p.uia.init(s.uia); }
196 }
197 else {
198 if (flags & Pixel::kPA) {
199 pc->newXmmArray(p.pa, pCount, "p.pa");
200 pc->vmov(p.pa[0], s.pa[0]);
201 }
202
203 if (flags & Pixel::kUA) {
204 pc->newXmmArray(p.ua, uCount, "p.ua");
205 pc->vmov(p.ua, s.ua[0]);
206 }
207
208 if (flags & Pixel::kUIA) {
209 pc->newXmmArray(p.uia, uCount, "p.uia");
210 pc->vmov(p.uia, s.uia[0]);
211 }
212 }
213 }
214
215 pc->xSatisfyPixel(p, flags);
216 }
217
218 } // {BLPipeGen}
219
220 #endif
221