1 #ifndef __RIRASTERIZER_H |
|
2 #define __RIRASTERIZER_H |
|
3 |
|
4 /*------------------------------------------------------------------------ |
|
5 * |
|
6 * OpenVG 1.1 Reference Implementation |
|
7 * ----------------------------------- |
|
8 * |
|
9 * Copyright (c) 2007 The Khronos Group Inc. |
|
10 * Portions copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
11 * |
|
12 * Permission is hereby granted, free of charge, to any person obtaining a |
|
13 * copy of this software and /or associated documentation files |
|
14 * (the "Materials "), to deal in the Materials without restriction, |
|
15 * including without limitation the rights to use, copy, modify, merge, |
|
16 * publish, distribute, sublicense, and/or sell copies of the Materials, |
|
17 * and to permit persons to whom the Materials are furnished to do so, |
|
18 * subject to the following conditions: |
|
19 * |
|
20 * The above copyright notice and this permission notice shall be included |
|
21 * in all copies or substantial portions of the Materials. |
|
22 * |
|
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
27 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
28 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR |
|
29 * THE USE OR OTHER DEALINGS IN THE MATERIALS. |
|
30 * |
|
31 *//** |
|
32 * \file |
|
33 * \brief Rasterizer class. |
|
34 * \note |
|
35 *//*-------------------------------------------------------------------*/ |
|
36 |
|
37 #ifndef __RIMATH_H |
|
38 #include "riMath.h" |
|
39 #endif |
|
40 |
|
41 #ifndef __RIARRAY_H |
|
42 #include "riArray.h" |
|
43 #endif |
|
44 |
|
45 #ifndef __RIPIXELPIPE_H |
|
46 #include "riPixelPipe.h" |
|
47 #endif |
|
48 |
|
49 // TESTING ONLY!! |
|
50 #include "sfDynamicPixelPipe.h" |
|
51 |
|
52 #if defined(RI_DEBUG) |
|
53 # include <stdio.h> |
|
54 #endif |
|
55 // \todo SSE2 probably has everything necessary and matches the minimum platform requirements. |
|
56 // SSE4 is probably too new. SSE3? |
|
57 // \note This will cause the code to not compile on MSVC... |
|
58 #define USE_SSE2 |
|
59 |
|
60 #if defined(USE_SSE2) |
|
61 // \todo only the last include is needed: QT creator does not find types if others not included. |
|
62 # include <mmintrin.h> |
|
63 # include <xmmintrin.h> |
|
64 # include <emmintrin.h> |
|
65 #endif |
|
66 |
|
67 //======================================================================= |
|
68 |
|
69 namespace OpenVGRI |
|
70 { |
|
71 |
|
72 /*-------------------------------------------------------------------*//*! |
|
73 * \brief Scalar and vector data types used by the rasterizer. |
|
74 * \param |
|
75 * \return |
|
76 * \note |
|
77 *//*-------------------------------------------------------------------*/ |
|
78 |
|
79 typedef RIfloat RScalar; //change this if you want to have different precision for rasterizer scalars and RIfloat |
|
80 |
|
81 struct RVector2 |
|
82 { |
|
83 RI_INLINE RVector2() { } |
|
84 RI_INLINE RVector2(const Vector2& v) { x = v.x; y = v.y; } |
|
85 RI_INLINE RVector2(RIfloat vx, RIfloat vy) { x = vx; y = vy; } |
|
86 RI_INLINE void set(RIfloat vx, RIfloat vy) { x = vx; y = vy; } |
|
87 RScalar x; |
|
88 RScalar y; |
|
89 }; |
|
90 |
|
91 struct IVector2 |
|
92 { |
|
93 RI_INLINE IVector2() {} |
|
94 RI_INLINE IVector2(const IVector2& v) { x = v.x; y = v.y; } |
|
95 RI_INLINE IVector2(const Vector2& v) { x = (int)v.x; y = (int) v.y; } |
|
96 RI_INLINE IVector2(int vx, int vy) { x = vx; y = vy; } |
|
97 RI_INLINE void set(int vx, int vy) { x = vx; y = vy; } |
|
98 int x; |
|
99 int y; |
|
100 }; |
|
101 |
|
102 struct Span |
|
103 { |
|
104 RIuint16 x0; |
|
105 RIuint16 y; |
|
106 RIuint16 len; |
|
107 RIuint8 coverage; |
|
108 RIuint8 pad; // align to 8 bytes. \temp Use qualifiers instead? |
|
109 }; |
|
110 |
|
111 /*-------------------------------------------------------------------*//*! |
|
112 * \brief Converts a set of edges to coverage values for each pixel and |
|
113 * calls PixelPipe::pixelPipe for painting a pixel. |
|
114 * \param |
|
115 * \return |
|
116 * \note |
|
117 *//*-------------------------------------------------------------------*/ |
|
118 |
|
119 class Rasterizer |
|
120 { |
|
121 public: |
|
122 Rasterizer(); //throws bad_alloc |
|
123 ~Rasterizer(); |
|
124 |
|
125 void setup(int vpx, int vpy, int vpwidth, int vpheight, VGFillRule fillRule, const PixelPipe* pixelPipe); |
|
126 void setScissor(const Array<Rectangle>& scissors); //throws bad_alloc |
|
127 void setScissoring(bool enabled); |
|
128 |
|
129 void clear(); |
|
130 void addEdge(const Vector2& v0, const Vector2& v1); //throws bad_alloc |
|
131 |
|
132 RI_INLINE void setAntiAliasing(bool enable) { m_aa = enable; } |
|
133 void fill(); //throws bad_alloc |
|
134 |
|
135 void getBBox(int& sx, int& sy, int& ex, int& ey) const { sx = m_covMinx; sy = m_covMiny; ex = m_covMaxx; ey = m_covMaxy; } |
|
136 |
|
137 public: |
|
138 enum { SAMPLE_BITS = 3 }; |
|
139 enum { Y_BITS = SAMPLE_BITS }; |
|
140 enum { MAX_COVERAGE = 1<<SAMPLE_BITS }; |
|
141 |
|
142 // temp!: |
|
143 RIuint32 *m_covBuffer; |
|
144 size_t m_covBufferSz; |
|
145 |
|
146 private: |
|
147 Rasterizer(const Rasterizer&); //!< Not allowed. |
|
148 const Rasterizer& operator=(const Rasterizer&); //!< Not allowed. |
|
149 |
|
150 public: |
|
151 struct ScissorEdge |
|
152 { |
|
153 ScissorEdge() {} |
|
154 bool operator<(const ScissorEdge& e) const { return x < e.x; } |
|
155 int x; |
|
156 int miny; |
|
157 int maxy; |
|
158 int direction; //1 start, -1 end |
|
159 }; |
|
160 |
|
161 struct Edge |
|
162 { |
|
163 Edge() {} |
|
164 bool operator<(const Edge& e) const { return v0.y < e.v0.y; } |
|
165 #if defined(RI_DEBUG) |
|
166 bool operator<=(const Edge& e) const {return v0.y <= e.v0.y; } |
|
167 #endif |
|
168 IVector2 v0; |
|
169 IVector2 v1; |
|
170 int direction; |
|
171 }; |
|
172 |
|
173 struct ActiveEdge |
|
174 { |
|
175 typedef RIint16 XCoord; |
|
176 typedef RIint16 YCoord; |
|
177 |
|
178 ActiveEdge() {} |
|
179 //bool operator<(const ActiveEdge& e) const { return minx < e.minx; } |
|
180 bool operator<(const ActiveEdge& e) const |
|
181 { |
|
182 if (minx < e.minx) |
|
183 return true; |
|
184 if (minx == e.minx) |
|
185 return maxx < e.maxx; |
|
186 return false; |
|
187 } |
|
188 #if defined(RI_DEBUG) |
|
189 bool operator<=(const ActiveEdge& e) const { return minx <= e.minx; } |
|
190 #endif |
|
191 // Fixed-point edge coordinates. |
|
192 RIuint32 next; // \todo Pointer? |
|
193 int direction; //-1 down, 1 up |
|
194 int xRef; |
|
195 int slope; |
|
196 XCoord minx; // for the current scanline |
|
197 XCoord maxx; // for the current scanline |
|
198 YCoord yStart; // for the edge |
|
199 YCoord yEnd; // for the edge |
|
200 }; |
|
201 |
|
202 enum { SF_SAMPLES = 8 }; |
|
203 enum { RASTERIZER_BITS = 14 }; |
|
204 enum { RASTERIZER_MASK = ((1<<RASTERIZER_BITS)-1) }; |
|
205 enum { Y_MASK = ((1<<Y_BITS)-1) }; |
|
206 enum { X_BITS = 7 }; |
|
207 enum { XMASK = ((1<<X_BITS)-1) }; |
|
208 enum { LEFT_DISCARD = -0x100000 }; |
|
209 enum { LEFT_DISCARD_SHORT = -32768 }; |
|
210 |
|
211 struct Windings |
|
212 { |
|
213 #if !defined(USE_SSE2) |
|
214 Windings() {wq = 0;} |
|
215 // \todo Use SSE counters or packed counters! |
|
216 // \todo 8 samples -> 64 bits == 2 32-bit uints |
|
217 union |
|
218 { |
|
219 RIint8 winding[SF_SAMPLES]; |
|
220 RIuint32 wd[SF_SAMPLES/4]; |
|
221 unsigned long long wq; |
|
222 }; |
|
223 #else |
|
224 Windings() { sseWinding = _mm_setzero_si128(); } |
|
225 __m128i sseWinding; |
|
226 #endif |
|
227 }; |
|
228 |
|
229 private: |
|
230 void pushEdge(const Edge& edge); |
|
231 void clipAndAddEdge(Edge& edge); |
|
232 void addBBox(const IVector2& v); |
|
233 RI_INLINE void pushSpan(int x, int y, int len, int coverage); |
|
234 RI_INLINE void commitSpans(); |
|
235 |
|
236 //RI_INLINE void calculateAEWinding(const ActiveEdge& currAe, Windings& pixel, Windings& scanline, int intY, int pixelX); |
|
237 |
|
238 Array<ActiveEdge> m_edgePool; |
|
239 Array<RIuint32> m_edges; |
|
240 Array<ScissorEdge> m_scissorEdges; |
|
241 Array<ActiveEdge> m_aet; |
|
242 Array<ScissorEdge> m_scissorAet; |
|
243 bool m_scissor; |
|
244 |
|
245 bool m_aa; |
|
246 |
|
247 IVector2 m_edgeMin; |
|
248 IVector2 m_edgeMax; |
|
249 int m_covMinx; |
|
250 int m_covMiny; |
|
251 int m_covMaxx; |
|
252 int m_covMaxy; |
|
253 int m_vpx; |
|
254 int m_vpy; |
|
255 int m_vpwidth; |
|
256 int m_vpheight; |
|
257 int m_vpMinx; |
|
258 int m_vpMiny; |
|
259 int m_vpMaxx; |
|
260 int m_vpMaxy; |
|
261 VGFillRule m_fillRule; |
|
262 RIuint32 m_fillRuleMask; |
|
263 |
|
264 const PixelPipe* m_pixelPipe; |
|
265 PixelPipe::PPVariants m_ppVariants; |
|
266 |
|
267 enum { N_CACHED_SPANS = 64 }; |
|
268 Span m_spanCache[N_CACHED_SPANS]; |
|
269 int m_nSpans; |
|
270 |
|
271 }; |
|
272 |
|
273 //======================================================================= |
|
274 |
|
275 } //namespace OpenVGRI |
|
276 |
|
277 //======================================================================= |
|
278 |
|
279 #endif /* __RIRASTERIZER_H */ |
|