1 #ifndef __RIPIXELPIPE_H |
|
2 #define __RIPIXELPIPE_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 Paint and PixelPipe classes. |
|
34 * \note |
|
35 *//*-------------------------------------------------------------------*/ |
|
36 |
|
37 #ifndef __RIMATH_H |
|
38 #include "riMath.h" |
|
39 #endif |
|
40 |
|
41 #ifndef __RIIMAGE_H |
|
42 #include "riImage.h" |
|
43 #endif |
|
44 |
|
45 //======================================================================= |
|
46 |
|
47 namespace OpenVGRI |
|
48 { |
|
49 |
|
50 struct Span; |
|
51 class PPCompiler; |
|
52 class PixelPipe; |
|
53 |
|
54 /*-------------------------------------------------------------------*//*! |
|
55 * \brief Storage and operations for VGPaint. |
|
56 * \param |
|
57 * \return |
|
58 * \note |
|
59 *//*-------------------------------------------------------------------*/ |
|
60 |
|
61 class Paint |
|
62 { |
|
63 public: |
|
64 enum { GRADIENT_LUT_BITS = 8 }; |
|
65 enum { GRADIENT_LUT_COUNT = 1 << GRADIENT_LUT_BITS }; |
|
66 enum { GRADIENT_LUT_MASK = (1<<GRADIENT_LUT_BITS)-1 }; |
|
67 |
|
68 struct GradientStop |
|
69 { |
|
70 GradientStop() : offset(0.0f), color(0.0f, 0.0f, 0.0f, 0.0f, Color::sRGBA) {} |
|
71 RIfloat offset; |
|
72 Color color; |
|
73 }; |
|
74 |
|
75 public: |
|
76 Paint(); |
|
77 ~Paint(); |
|
78 void addReference() { m_referenceCount++; } |
|
79 int removeReference() { m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; } |
|
80 void setColor(const Color& color) {m_paintColor = color; m_paintColor.clamp(); m_paintColor.premultiply(); } |
|
81 void setGradientStops(Array<GradientStop>& inputStops, Array<GradientStop>& stops); |
|
82 void generateLUT(PixelPipe& pipe, VGImageFormat targetFormat); |
|
83 const IntegerColor* getGradientLUT() const { return m_gradientLUT; } |
|
84 void setLinearGradient(const Vector2& p0, const Vector2& p1); |
|
85 void setRadialGradient(const Vector2& c, const Vector2& f, VGfloat r); |
|
86 bool linearDegenerate() const; |
|
87 bool radialDegenerate() const; |
|
88 Color getSolidColor() const; |
|
89 |
|
90 Color integrateColorRamp(RIfloat gmin, RIfloat gmax) const; // \todo Private after modifications. |
|
91 |
|
92 public: |
|
93 VGPaintType m_paintType; |
|
94 Color m_paintColor; |
|
95 Color m_inputPaintColor; |
|
96 VGColorRampSpreadMode m_colorRampSpreadMode; |
|
97 Array<GradientStop> m_colorRampStops; |
|
98 Array<GradientStop> m_inputColorRampStops; |
|
99 VGboolean m_colorRampPremultiplied; |
|
100 Vector2 m_inputLinearGradientPoint0; |
|
101 Vector2 m_inputLinearGradientPoint1; |
|
102 Vector2 m_inputRadialGradientCenter; |
|
103 Vector2 m_inputRadialGradientFocalPoint; |
|
104 RIfloat m_inputRadialGradientRadius; |
|
105 Vector2 m_linearGradientPoint0; |
|
106 Vector2 m_linearGradientPoint1; |
|
107 Vector2 m_radialGradientCenter; |
|
108 Vector2 m_radialGradientFocalPoint; |
|
109 RIfloat m_radialGradientRadius; |
|
110 VGTilingMode m_patternTilingMode; |
|
111 Image* m_pattern; |
|
112 private: |
|
113 Paint(const Paint&); //!< Not allowed. |
|
114 const Paint& operator=(const Paint&); //!< Not allowed. |
|
115 |
|
116 int m_referenceCount; |
|
117 IntegerColor m_gradientLUT[GRADIENT_LUT_COUNT]; |
|
118 VGImageFormat m_lutFormat; |
|
119 bool m_gradientStopsChanged; |
|
120 bool m_gradientDegenerate; |
|
121 }; |
|
122 |
|
123 /*-------------------------------------------------------------------*//*! |
|
124 * \brief Encapsulates all information needed for painting a pixel. |
|
125 * \param |
|
126 * \return |
|
127 * \note |
|
128 *//*-------------------------------------------------------------------*/ |
|
129 |
|
130 #define RGRAD_FLOATS |
|
131 #if defined(RGRAD_FLOATS) |
|
132 typedef RIfloat RGScalar; |
|
133 #else |
|
134 typedef double RGScalar; |
|
135 #endif |
|
136 |
|
137 class PixelPipe |
|
138 { |
|
139 public: |
|
140 enum SamplerType |
|
141 { |
|
142 SAMPLER_TYPE_NEAREST = 0, |
|
143 SAMPLER_TYPE_LINEAR = 1, |
|
144 SAMPLER_TYPE_SIZE |
|
145 }; |
|
146 |
|
147 enum TilingMode |
|
148 { |
|
149 TILING_MODE_PAD = 0, |
|
150 TILING_MODE_REPEAT = 1, |
|
151 TILING_MODE_REFLECT = 2, |
|
152 TILING_MODE_FILL = 3, |
|
153 TILING_MODE_SIZE |
|
154 }; |
|
155 |
|
156 // Span per-pixel variants: |
|
157 struct PPVariants |
|
158 { |
|
159 void* dst; |
|
160 void* src; |
|
161 void* maskPtr; |
|
162 int coverage; |
|
163 |
|
164 RIuint32 dstX; |
|
165 |
|
166 RIint32 sx; |
|
167 RIint32 sy; |
|
168 |
|
169 RGScalar rx; |
|
170 RGScalar ry; |
|
171 |
|
172 // \todo Image sampling coordinates will be in fixed point if transform is affine, |
|
173 // in floating point if not. |
|
174 RGScalar ix; |
|
175 RGScalar iy; |
|
176 |
|
177 RIint32 iImageX; |
|
178 RIint32 iImageY; |
|
179 RIfloat fImageX; |
|
180 RIfloat fImageY; |
|
181 RIfloat fImageW; |
|
182 }; |
|
183 |
|
184 // Uniform state per-pixel |
|
185 // \todo Organize into sub-structures? |
|
186 struct PPUniforms |
|
187 { |
|
188 // \todo Do not store pointers to classes, only atoms! It should make the |
|
189 // dynamic compilation a lot easier. |
|
190 void* srcPtr; |
|
191 RIint32 srcStride; |
|
192 void* dstPtr; |
|
193 RIint32 dstStride; |
|
194 void* maskPtr; |
|
195 int maskStride; |
|
196 void* imagePtr; |
|
197 int imageStride; |
|
198 void* patternPtr; |
|
199 int patternStride; |
|
200 const IntegerColor* gradientLookup; |
|
201 const RIint32* colorTransformValues; |
|
202 |
|
203 // Linear gradient |
|
204 RIint32 dgdx; |
|
205 RIint32 dgdy; |
|
206 RIint32 lgc; |
|
207 |
|
208 // Radial gradient |
|
209 RGScalar rsqrp; |
|
210 RGScalar rfxp; |
|
211 RGScalar rfyp; |
|
212 RGScalar rx0; |
|
213 RGScalar ry0; |
|
214 RGScalar rdxdx; |
|
215 RGScalar rdxdy; |
|
216 RGScalar rdydx; |
|
217 RGScalar rdydy; |
|
218 |
|
219 // Pattern. Note that pattern and image may be used at the same time. |
|
220 RIint32 paint_width; |
|
221 RIint32 paint_height; |
|
222 RIint32 paint_x0; |
|
223 RIint32 paint_y0; |
|
224 RIint32 paint_dxdx; |
|
225 RIint32 paint_dxdy; |
|
226 RIint32 paint_dydx; |
|
227 RIint32 paint_dydy; |
|
228 |
|
229 // Image |
|
230 RIint32 image_iWidth; |
|
231 RIint32 image_iHeight; |
|
232 RIint32 image_ix0; |
|
233 RIint32 image_iy0; |
|
234 RIint32 image_idxdx; |
|
235 RIint32 image_idxdy; |
|
236 RIint32 image_idydx; |
|
237 RIint32 image_idydy; |
|
238 |
|
239 |
|
240 RIfloat image_fWidth; |
|
241 RIfloat image_fHeight; |
|
242 RIfloat image_fx0; |
|
243 RIfloat image_fy0; |
|
244 RIfloat image_fw0; |
|
245 RIfloat image_fdxdx; |
|
246 RIfloat image_fdxdy; |
|
247 RIfloat image_fdydx; |
|
248 RIfloat image_fdydy; |
|
249 RIfloat image_fdwdx; |
|
250 RIfloat image_fdwdy; |
|
251 |
|
252 IntegerColor tileFillColor; |
|
253 IntegerColor solidColor; |
|
254 RIuint32 packedSolidColor; |
|
255 }; |
|
256 |
|
257 enum ImageGradientType { |
|
258 GRADIENT_TYPE_INTEGER = 0, |
|
259 GRADIENT_TYPE_FIXED = 1, |
|
260 GRADIENT_TYPE_FLOAT = 2, |
|
261 GRADIENT_TYPE_SIZE |
|
262 }; |
|
263 |
|
264 // Signature state contains all the information necessary to compile |
|
265 // a pixel-pipeline. Note that some of these are actually derived. |
|
266 // \note REMEMBER TO UPDATE THE COMPILER. For now, there is now |
|
267 // automatic mechanism to propagate changes to that component! |
|
268 struct SignatureState |
|
269 { |
|
270 VGBlendMode blendMode; |
|
271 VGImageMode imageMode; |
|
272 VGPaintType paintType; |
|
273 VGMaskOperation maskOperation; |
|
274 TilingMode paintTilingMode; |
|
275 SamplerType paintSampler; |
|
276 SamplerType imageSampler; |
|
277 |
|
278 ImageGradientType imageGradientType; |
|
279 |
|
280 Color::Descriptor dstDesc; |
|
281 Color::Descriptor maskDesc; |
|
282 Color::Descriptor imageDesc; |
|
283 Color::Descriptor patternDesc; |
|
284 |
|
285 bool hasMasking; |
|
286 bool hasImage; |
|
287 bool hasColorTransform; |
|
288 bool isRenderToMask; |
|
289 bool fillColorTransparent; |
|
290 // When using external data for rendering an image: This is the only case |
|
291 // where the data can be invalid in the pixel-pipe. |
|
292 bool unsafeImageInput; |
|
293 |
|
294 }; |
|
295 |
|
296 public: |
|
297 PixelPipe(); //throws bad_alloc |
|
298 ~PixelPipe(); |
|
299 |
|
300 void pixelPipe(int x, int y, RIuint32 coverage) const; //rasterizer calls this function for each pixel |
|
301 void fillSolidSpan(int startX, int y, int nPixels) const; |
|
302 void setDrawable(Drawable* drawable); |
|
303 void setBlendMode(VGBlendMode blendMode); |
|
304 RI_INLINE VGBlendMode getBlendMode() const { return m_blendMode; } |
|
305 void setRenderToMask(bool renderToMask) { m_renderToMask = renderToMask; } |
|
306 void setMaskOperation(VGMaskOperation maskOperation) { m_maskOperation = maskOperation; } |
|
307 void setMask(bool masking); |
|
308 void setImage(Image* image, VGImageMode imageMode); //image = NULL disables drawImage functionality |
|
309 void setSurfaceToPaintMatrix(const Matrix3x3& surfaceToPaintMatrix); |
|
310 void setSurfaceToImageMatrix(const Matrix3x3& surfaceToImageMatrix); |
|
311 void setImageQuality(VGImageQuality imageQuality); |
|
312 void setTileFillColor(const Color& c); |
|
313 void setPaint(Paint* paint); |
|
314 void setColorTransform(bool enable, RIfloat values[8]); |
|
315 bool hasColorTransform() const { return m_colorTransform; } |
|
316 RI_INLINE const SignatureState& getSignatureState() const { return m_signatureState; } |
|
317 |
|
318 // Functions that determine parts of derived state. |
|
319 void prepareSpanUniforms(bool aa); |
|
320 |
|
321 RI_INLINE VGPaintType getPaintType() const; |
|
322 RI_INLINE bool isMasking() const; |
|
323 void fillSpans(PPVariants& variants, const Span* spans, int nSpans) const; |
|
324 |
|
325 void colorTransform(Color& c) const; |
|
326 void setColorTransformChanged(bool changed) { m_colorTransformChanged = changed; } // make paint friend and this private! |
|
327 bool colorTransformChanged() const { return m_colorTransformChanged; } |
|
328 RI_INLINE VGImageMode getImageMode() const { return m_imageMode; } |
|
329 |
|
330 RI_INLINE static bool isImageOnly(const SignatureState& state); |
|
331 |
|
332 private: |
|
333 |
|
334 const Image* getRenderTargetImage() const; |
|
335 VGImageFormat getPreferredLUTFormat() const; |
|
336 |
|
337 void prepareSolidFill(); |
|
338 void prepareCoverageFill(); |
|
339 void prepareLinearGradient(); |
|
340 void prepareRadialGradient(); |
|
341 void preparePattern(); |
|
342 void prepareImage(bool aa); |
|
343 void prepareSignatureState(); |
|
344 void prepareRenderToMask(); |
|
345 void linearGradient(RIfloat& g, RIfloat& rho, RIfloat x, RIfloat y) const; |
|
346 void radialGradient(RIfloat& g, RIfloat& rho, RIfloat x, RIfloat y) const; |
|
347 Color colorRamp(RIfloat gradient, RIfloat rho) const; |
|
348 Color blend(const Color& s, RIfloat ar, RIfloat ag, RIfloat ab, const Color& d, VGBlendMode blendMode) const; |
|
349 |
|
350 PixelPipe(const PixelPipe&); //!< Not allowed. |
|
351 const PixelPipe& operator=(const PixelPipe&); //!< Not allowed. |
|
352 |
|
353 Drawable* m_drawable; |
|
354 bool m_masking; |
|
355 Image* m_image; |
|
356 // \todo LUT within the paint class broke constness of paint. |
|
357 Paint* m_paint; |
|
358 Paint m_defaultPaint; |
|
359 VGBlendMode m_blendMode; |
|
360 VGImageMode m_imageMode; |
|
361 VGImageQuality m_imageQuality; |
|
362 Color m_tileFillColor; |
|
363 bool m_colorTransform; |
|
364 RIfloat m_colorTransformValues[8]; |
|
365 RIint32 m_iColorTransformValues[8]; |
|
366 Matrix3x3 m_surfaceToPaintMatrix; |
|
367 Matrix3x3 m_surfaceToImageMatrix; |
|
368 Matrix3x3 m_paintToSurfaceMatrix; |
|
369 VGMaskOperation m_maskOperation; |
|
370 bool m_renderToMask; |
|
371 bool m_colorTransformChanged; |
|
372 |
|
373 public: |
|
374 |
|
375 enum { COLOR_TRANSFORM_BITS = 8 }; |
|
376 enum { COLOR_TRANSFORM_ONE = (1<<COLOR_TRANSFORM_BITS) }; |
|
377 enum { COLOR_TRANSFORM_MASK = (COLOR_TRANSFORM_ONE - 1) }; |
|
378 enum { GRADIENT_BITS = 16 }; |
|
379 enum { GRADIENT_MASK = (1<<GRADIENT_BITS)-1 }; |
|
380 enum { SAMPLE_BITS = 8 }; |
|
381 enum { SAMPLE_MASK = (1<<SAMPLE_BITS)-1 }; |
|
382 |
|
383 private: |
|
384 |
|
385 |
|
386 SignatureState m_signatureState; |
|
387 SignatureState m_derivedState; |
|
388 |
|
389 PPUniforms m_spanUniforms; |
|
390 }; |
|
391 |
|
392 RI_INLINE VGPaintType PixelPipe::getPaintType() const |
|
393 { |
|
394 if (m_paint->m_paintType == VG_PAINT_TYPE_COLOR) |
|
395 return VG_PAINT_TYPE_COLOR; |
|
396 |
|
397 if (m_paint->m_paintType == VG_PAINT_TYPE_PATTERN && !m_paint->m_pattern) |
|
398 return VG_PAINT_TYPE_COLOR; |
|
399 |
|
400 if (m_paint->m_paintType == VG_PAINT_TYPE_LINEAR_GRADIENT && m_paint->linearDegenerate()) |
|
401 return VG_PAINT_TYPE_COLOR; |
|
402 |
|
403 if (m_paint->m_paintType == VG_PAINT_TYPE_RADIAL_GRADIENT && m_paint->radialDegenerate()) |
|
404 return VG_PAINT_TYPE_COLOR; |
|
405 |
|
406 return m_paint->m_paintType; |
|
407 } |
|
408 |
|
409 RI_INLINE bool PixelPipe::isMasking() const |
|
410 { |
|
411 return m_masking; |
|
412 } |
|
413 |
|
414 RI_INLINE /*static*/ bool PixelPipe::isImageOnly(const SignatureState& state) |
|
415 { |
|
416 if (state.hasImage) |
|
417 return (state.imageMode == VG_DRAW_IMAGE_NORMAL) ? true : false; |
|
418 else |
|
419 return false; |
|
420 } |
|
421 |
|
422 //======================================================================= |
|
423 |
|
424 } //namespace OpenVGRI |
|
425 |
|
426 //======================================================================= |
|
427 |
|
428 #endif /* __RIPIXELPIPE_H */ |
|