1 /*
2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
3
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 #ifndef VDRAWHELPER_H
24 #define VDRAWHELPER_H
25
26 #include <memory>
27 #include <array>
28 #include "assert.h"
29 #include "vbitmap.h"
30 #include "vbrush.h"
31 #include "vrect.h"
32 #include "vrle.h"
33
34 V_USE_NAMESPACE
35
36 struct VSpanData;
37 struct Operator;
38
39 struct RenderFunc
40 {
41 using Color = void (*)(uint32_t *dest, int length, uint32_t color, uint32_t alpha);
42 using Src = void (*)(uint32_t *dest, int length, const uint32_t *src, uint32_t alpha);
43 enum class Type {
44 Invalid,
45 Color,
46 Src,
47 };
48 RenderFunc() = default;
RenderFuncRenderFunc49 RenderFunc(Type t, Color f):type_(t), color_(f){assert(t == Type::Color);}
RenderFuncRenderFunc50 RenderFunc(Type t, Src f):type_(t), src_(f){ assert(t == Type::Src);}
51
52 Type type_{Type::Invalid};
53 union {
54 Color color_;
55 Src src_;
56 };
57 };
58
59 class RenderFuncTable
60 {
61 public:
62 RenderFuncTable();
color(BlendMode mode)63 RenderFunc::Color color(BlendMode mode) const
64 {
65 return colorTable[uint32_t(mode)].color_;
66 }
src(BlendMode mode)67 RenderFunc::Src src(BlendMode mode) const
68 {
69 return srcTable[uint32_t(mode)].src_;
70 }
71 private:
72 void neon();
73 void sse();
updateColor(BlendMode mode,RenderFunc::Color f)74 void updateColor(BlendMode mode, RenderFunc::Color f)
75 {
76 colorTable[uint32_t(mode)] = {RenderFunc::Type::Color, f};
77 }
updateSrc(BlendMode mode,RenderFunc::Src f)78 void updateSrc(BlendMode mode, RenderFunc::Src f)
79 {
80 srcTable[uint32_t(mode)] = {RenderFunc::Type::Src, f};
81 }
82 private:
83 std::array<RenderFunc, uint32_t(BlendMode::Last)> colorTable;
84 std::array<RenderFunc, uint32_t(BlendMode::Last)> srcTable;
85 };
86
87 typedef void (*SourceFetchProc)(uint32_t *buffer, const Operator *o,
88 const VSpanData *data, int y, int x,
89 int length);
90 typedef void (*ProcessRleSpan)(size_t count, const VRle::Span *spans,
91 void *userData);
92
93 extern void memfill32(uint32_t *dest, uint32_t value, int count);
94
95 struct LinearGradientValues {
96 float dx;
97 float dy;
98 float l;
99 float off;
100 };
101
102 struct RadialGradientValues {
103 float dx;
104 float dy;
105 float dr;
106 float sqrfr;
107 float a;
108 float inv2a;
109 bool extended;
110 };
111
112 struct Operator {
113 BlendMode mode;
114 SourceFetchProc srcFetch;
115 RenderFunc::Color funcSolid;
116 RenderFunc::Src func;
117 union {
118 LinearGradientValues linear;
119 RadialGradientValues radial;
120 };
121 };
122
123 class VRasterBuffer {
124 public:
125 VBitmap::Format prepare(const VBitmap *image);
126 void clear();
127
128 void resetBuffer(int val = 0);
129
scanLine(int y)130 inline uchar *scanLine(int y)
131 {
132 assert(y >= 0);
133 assert(size_t(y) < mHeight);
134 return mBuffer + y * mBytesPerLine;
135 }
pixelRef(int x,int y)136 uint32_t *pixelRef(int x, int y) const
137 {
138 return (uint32_t *)(mBuffer + y * mBytesPerLine + x * mBytesPerPixel);
139 }
140
width()141 size_t width() const { return mWidth; }
height()142 size_t height() const { return mHeight; }
bytesPerLine()143 size_t bytesPerLine() const { return mBytesPerLine; }
bytesPerPixel()144 size_t bytesPerPixel() const { return mBytesPerPixel; }
format()145 VBitmap::Format format() const { return mFormat; }
146
147 private:
148 VBitmap::Format mFormat{VBitmap::Format::ARGB32_Premultiplied};
149 size_t mWidth{0};
150 size_t mHeight{0};
151 size_t mBytesPerLine{0};
152 size_t mBytesPerPixel{0};
153 mutable uchar * mBuffer{nullptr};
154 };
155
156 struct VGradientData {
157 VGradient::Spread mSpread;
158 struct Linear {
159 float x1, y1, x2, y2;
160 };
161 struct Radial {
162 float cx, cy, fx, fy, cradius, fradius;
163 };
164 union {
165 Linear linear;
166 Radial radial;
167 };
168 const uint32_t *mColorTable;
169 bool mColorTableAlpha;
170 };
171
172 struct VTextureData : public VRasterBuffer {
pixelVTextureData173 uint32_t pixel(int x, int y) const { return *pixelRef(x, y); };
alphaVTextureData174 uchar alpha() const { return mAlpha; }
setAlphaVTextureData175 void setAlpha(uchar alpha) { mAlpha = alpha; }
176 void setClip(const VRect &clip);
177 // clip rect
178 int left;
179 int right;
180 int top;
181 int bottom;
182 bool hasAlpha;
183 uchar mAlpha;
184 };
185
186 struct VColorTable {
187 uint32_t buffer32[VGradient::colorTableSize];
188 bool alpha{true};
189 };
190
191 struct VSpanData {
192 enum class Type { None, Solid, LinearGradient, RadialGradient, Texture };
193
194 void updateSpanFunc();
195 void init(VRasterBuffer *image);
196 void setup(const VBrush &brush, BlendMode mode = BlendMode::SrcOver,
197 int alpha = 255);
198 void setupMatrix(const VMatrix &matrix);
199
clipRectVSpanData200 VRect clipRect() const
201 {
202 return VRect(0, 0, mDrawableSize.width(), mDrawableSize.height());
203 }
204
setDrawRegionVSpanData205 void setDrawRegion(const VRect ®ion)
206 {
207 mOffset = VPoint(region.left(), region.top());
208 mDrawableSize = VSize(region.width(), region.height());
209 }
210
bufferVSpanData211 uint *buffer(int x, int y) const
212 {
213 return mRasterBuffer->pixelRef(x + mOffset.x(), y + mOffset.y());
214 }
215 void initTexture(const VBitmap *image, int alpha, const VRect &sourceRect);
textureVSpanData216 const VTextureData &texture() const { return mTexture; }
217
218 BlendMode mBlendMode{BlendMode::SrcOver};
219 VRasterBuffer * mRasterBuffer;
220 ProcessRleSpan mBlendFunc;
221 ProcessRleSpan mUnclippedBlendFunc;
222 VSpanData::Type mType;
223 std::shared_ptr<const VColorTable> mColorTable{nullptr};
224 VPoint mOffset; // offset to the subsurface
225 VSize mDrawableSize; // suburface size
226 uint32_t mSolid;
227 VGradientData mGradient;
228 VTextureData mTexture;
229
230 float m11, m12, m13, m21, m22, m23, m33, dx, dy; // inverse xform matrix
231 bool fast_matrix{true};
232 VMatrix::MatrixType transformType{VMatrix::MatrixType::None};
233 };
234
235 #define BYTE_MUL(c, a) \
236 ((((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) + \
237 (((((c)&0x00ff00ff) * (a)) >> 8) & 0x00ff00ff))
238
vRed(uint32_t c)239 inline constexpr int vRed(uint32_t c)
240 {
241 return ((c >> 16) & 0xff);
242 }
243
vGreen(uint32_t c)244 inline constexpr int vGreen(uint32_t c)
245 {
246 return ((c >> 8) & 0xff);
247 }
248
vBlue(uint32_t c)249 inline constexpr int vBlue(uint32_t c)
250 {
251 return (c & 0xff);
252 }
253
vAlpha(uint32_t c)254 inline constexpr int vAlpha(uint32_t c)
255 {
256 return c >> 24;
257 }
258
interpolate_pixel(uint x,uint a,uint y,uint b)259 static inline uint32_t interpolate_pixel(uint x, uint a, uint y, uint b)
260 {
261 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
262 t >>= 8;
263 t &= 0xff00ff;
264 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
265 x &= 0xff00ff00;
266 x |= t;
267 return x;
268 }
269
270 #endif // QDRAWHELPER_P_H
271