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