1 /**************************************************************************
3 * Copyright 2009 VMware, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
32 #include "pipe/p_compiler.h"
33 #include "util/u_inlines.h"
35 #include "util/u_memory.h"
36 #include "util/u_math.h"
37 #include "util/u_sampler.h"
39 #include "cso_cache/cso_context.h"
42 struct vg_object base
;
52 VGColorRampSpreadMode spread
;
53 VGuint color_data
[1024];
62 struct pipe_sampler_view
*sampler_view
;
63 struct pipe_sampler_state sampler
;
69 VGboolean color_ramps_premultiplied
;
73 struct pipe_sampler_view
*sampler_view
;
74 VGTilingMode tiling_mode
;
75 struct pipe_sampler_state sampler
;
78 /* XXX next 3 all unneded? */
79 struct pipe_resource
*cbuf
;
80 struct pipe_shader_state fs_state
;
84 static INLINE VGuint
mix_pixels(VGuint p1
, VGuint a
, VGuint p2
, VGuint b
)
86 VGuint t
= (p1
& 0xff00ff) * a
+ (p2
& 0xff00ff) * b
;
87 t
>>= 8; t
&= 0xff00ff;
89 p1
= ((p1
>> 8) & 0xff00ff) * a
+ ((p2
>> 8) & 0xff00ff) * b
;
90 p1
&= 0xff00ff00; p1
|= t
;
95 static INLINE VGuint
float4_to_argb(const VGfloat
*clr
)
97 return float_to_ubyte(clr
[3]) << 24 |
98 float_to_ubyte(clr
[0]) << 16 |
99 float_to_ubyte(clr
[1]) << 8 |
100 float_to_ubyte(clr
[2]) << 0;
103 static INLINE
void create_gradient_data(const VGfloat
*ramp_stops
,
110 VGfloat fpos
= 0, incr
= 1.f
/ size
;
113 while (fpos
< ramp_stops
[0]) {
114 data
[pos
] = float4_to_argb(ramp_stops
+ 1);
119 for (i
= 0; i
< num
- 1; ++i
) {
121 VGint rnext
= 5 * (i
+ 1);
122 VGfloat delta
= 1.f
/(ramp_stops
[rnext
] - ramp_stops
[rcur
]);
123 while (fpos
< ramp_stops
[rnext
] && pos
< size
) {
124 VGint dist
= 256 * ((fpos
- ramp_stops
[rcur
]) * delta
);
125 VGint idist
= 256 - dist
;
126 VGuint current_color
= float4_to_argb(ramp_stops
+ rcur
+ 1);
127 VGuint next_color
= float4_to_argb(ramp_stops
+ rnext
+ 1);
128 data
[pos
] = mix_pixels(current_color
, idist
,
135 last_color
= float4_to_argb(ramp_stops
+ ((num
- 1) * 5 + 1));
137 data
[pos
] = last_color
;
140 data
[size
-1] = last_color
;
143 static INLINE
struct pipe_resource
*create_gradient_texture(struct vg_paint
*p
)
145 struct pipe_context
*pipe
= p
->base
.ctx
->pipe
;
146 struct pipe_screen
*screen
= pipe
->screen
;
147 struct pipe_resource
*tex
= 0;
148 struct pipe_resource templ
;
150 memset(&templ
, 0, sizeof(templ
));
151 templ
.target
= PIPE_TEXTURE_1D
;
152 templ
.format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
153 templ
.last_level
= 0;
157 templ
.array_size
= 1;
158 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
;
160 tex
= screen
->resource_create(screen
, &templ
);
162 { /* upload color_data */
163 struct pipe_transfer
*transfer
=
164 pipe_get_transfer(p
->base
.ctx
->pipe
, tex
, 0, 0,
165 PIPE_TRANSFER_WRITE
, 0, 0, 1024, 1);
166 void *map
= pipe
->transfer_map(pipe
, transfer
);
167 memcpy(map
, p
->gradient
.color_data
, sizeof(VGint
)*1024);
168 pipe
->transfer_unmap(pipe
, transfer
);
169 pipe
->transfer_destroy(pipe
, transfer
);
175 static INLINE
struct pipe_sampler_view
*create_gradient_sampler_view(struct vg_paint
*p
)
177 struct pipe_context
*pipe
= p
->base
.ctx
->pipe
;
178 struct pipe_resource
*texture
;
179 struct pipe_sampler_view view_templ
;
180 struct pipe_sampler_view
*view
;
182 texture
= create_gradient_texture(p
);
187 u_sampler_view_default_template(&view_templ
, texture
, texture
->format
);
188 view
= pipe
->create_sampler_view(pipe
, texture
, &view_templ
);
189 /* want the texture to go away if the view is freed */
190 pipe_resource_reference(&texture
, NULL
);
195 struct vg_paint
* paint_create(struct vg_context
*ctx
)
197 struct vg_paint
*paint
= CALLOC_STRUCT(vg_paint
);
198 const VGfloat default_color
[] = {0.0f
, 0.0f
, 0.0f
, 1.0f
};
199 const VGfloat def_ling
[] = {0.0f
, 0.0f
, 1.0f
, 0.0f
};
200 const VGfloat def_radg
[] = {0.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
};
201 vg_init_object(&paint
->base
, ctx
, VG_OBJECT_PAINT
);
202 vg_context_add_object(ctx
, VG_OBJECT_PAINT
, paint
);
204 paint
->type
= VG_PAINT_TYPE_COLOR
;
205 memcpy(paint
->solid
.color
, default_color
,
206 4 * sizeof(VGfloat
));
207 paint
->gradient
.spread
= VG_COLOR_RAMP_SPREAD_PAD
;
208 memcpy(paint
->gradient
.linear
.coords
, def_ling
,
209 4 * sizeof(VGfloat
));
210 memcpy(paint
->gradient
.radial
.vals
, def_radg
,
211 5 * sizeof(VGfloat
));
213 paint
->gradient
.sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
214 paint
->gradient
.sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
215 paint
->gradient
.sampler
.min_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
216 paint
->gradient
.sampler
.mag_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
217 paint
->gradient
.sampler
.normalized_coords
= 1;
219 memcpy(&paint
->pattern
.sampler
,
220 &paint
->gradient
.sampler
,
221 sizeof(struct pipe_sampler_state
));
226 void paint_destroy(struct vg_paint
*paint
)
228 struct vg_context
*ctx
= paint
->base
.ctx
;
229 pipe_sampler_view_reference(&paint
->gradient
.sampler_view
, NULL
);
230 if (paint
->pattern
.sampler_view
)
231 pipe_sampler_view_reference(&paint
->pattern
.sampler_view
, NULL
);
233 vg_context_remove_object(ctx
, VG_OBJECT_PAINT
, paint
);
235 free(paint
->gradient
.ramp_stopsi
);
236 free(paint
->gradient
.ramp_stops
);
240 void paint_set_color(struct vg_paint
*paint
,
241 const VGfloat
*color
)
243 paint
->solid
.color
[0] = color
[0];
244 paint
->solid
.color
[1] = color
[1];
245 paint
->solid
.color
[2] = color
[2];
246 paint
->solid
.color
[3] = color
[3];
248 paint
->solid
.colori
[0] = FLT_TO_INT(color
[0]);
249 paint
->solid
.colori
[1] = FLT_TO_INT(color
[1]);
250 paint
->solid
.colori
[2] = FLT_TO_INT(color
[2]);
251 paint
->solid
.colori
[3] = FLT_TO_INT(color
[3]);
254 static INLINE
void paint_color_buffer(struct vg_paint
*paint
, void *buffer
)
256 VGfloat
*map
= (VGfloat
*)buffer
;
257 memcpy(buffer
, paint
->solid
.color
, 4 * sizeof(VGfloat
));
264 static INLINE
void paint_linear_gradient_buffer(struct vg_paint
*paint
,
265 const struct matrix
*inv
,
268 VGfloat
*map
= (VGfloat
*)buffer
;
271 map
[0] = paint
->gradient
.linear
.coords
[2] - paint
->gradient
.linear
.coords
[0];
272 map
[1] = paint
->gradient
.linear
.coords
[3] - paint
->gradient
.linear
.coords
[1];
273 dd
= (map
[0] * map
[0] + map
[1] * map
[1]);
275 map
[2] = (dd
> 0.0f
) ? 1.f
/ dd
: 0.f
;
284 matrix_load_identity(&mat
);
285 /* VEGA_LINEAR_GRADIENT_SHADER expects the first point to be at (0, 0) */
286 matrix_translate(&mat
, -paint
->gradient
.linear
.coords
[0], -paint
->gradient
.linear
.coords
[1]);
287 matrix_mult(&mat
, inv
);
289 map
[8] = mat
.m
[0]; map
[9] = mat
.m
[3]; map
[10] = mat
.m
[6]; map
[11] = 0.f
;
290 map
[12] = mat
.m
[1]; map
[13] = mat
.m
[4]; map
[14] = mat
.m
[7]; map
[15] = 0.f
;
291 map
[16] = mat
.m
[2]; map
[17] = mat
.m
[5]; map
[18] = mat
.m
[8]; map
[19] = 0.f
;
294 debug_printf("Coords (%f, %f, %f, %f)\n",
295 map
[0], map
[1], map
[2], map
[3]);
300 static INLINE
void paint_radial_gradient_buffer(struct vg_paint
*paint
,
301 const struct matrix
*inv
,
304 const VGfloat
*center
= &paint
->gradient
.radial
.vals
[0];
305 const VGfloat
*focal
= &paint
->gradient
.radial
.vals
[2];
306 VGfloat rr
= paint
->gradient
.radial
.vals
[4];
307 VGfloat
*map
= (VGfloat
*)buffer
;
308 VGfloat dd
, new_focal
[2];
312 map
[0] = center
[0] - focal
[0];
313 map
[1] = center
[1] - focal
[1];
314 dd
= map
[0] * map
[0] + map
[1] * map
[1];
316 /* focal point must lie inside the circle */
317 if (0.998f
* rr
< dd
) {
320 scale
= (dd
> 0.0f
) ? sqrt(0.998f
* rr
/ dd
) : 0.0f
;
324 new_focal
[0] = center
[0] - map
[0];
325 new_focal
[1] = center
[1] - map
[1];
326 dd
= map
[0] * map
[0] + map
[1] * map
[1];
330 map
[2] = (rr
> dd
) ? rr
- dd
: 1.0f
;
340 matrix_load_identity(&mat
);
341 matrix_translate(&mat
, -focal
[0], -focal
[1]);
342 matrix_mult(&mat
, inv
);
344 map
[8] = mat
.m
[0]; map
[9] = mat
.m
[3]; map
[10] = mat
.m
[6]; map
[11] = 0.f
;
345 map
[12] = mat
.m
[1]; map
[13] = mat
.m
[4]; map
[14] = mat
.m
[7]; map
[15] = 0.f
;
346 map
[16] = mat
.m
[2]; map
[17] = mat
.m
[5]; map
[18] = mat
.m
[8]; map
[19] = 0.f
;
350 debug_printf("Coords (%f, %f, %f, %f)\n",
351 map
[0], map
[1], map
[2], map
[3]);
356 static INLINE
void paint_pattern_buffer(struct vg_paint
*paint
,
357 const struct matrix
*inv
,
360 VGfloat
*map
= (VGfloat
*)buffer
;
361 memcpy(map
, paint
->solid
.color
, 4 * sizeof(VGfloat
));
365 map
[6] = paint
->pattern
.sampler_view
->texture
->width0
;
366 map
[7] = paint
->pattern
.sampler_view
->texture
->height0
;
370 memcpy(&mat
, inv
, sizeof(*inv
));
372 map
[8] = mat
.m
[0]; map
[9] = mat
.m
[3]; map
[10] = mat
.m
[6]; map
[11] = 0.f
;
373 map
[12] = mat
.m
[1]; map
[13] = mat
.m
[4]; map
[14] = mat
.m
[7]; map
[15] = 0.f
;
374 map
[16] = mat
.m
[2]; map
[17] = mat
.m
[5]; map
[18] = mat
.m
[8]; map
[19] = 0.f
;
378 void paint_set_type(struct vg_paint
*paint
, VGPaintType type
)
383 void paint_set_ramp_stops(struct vg_paint
*paint
, const VGfloat
*stops
,
386 const VGfloat default_stops
[] = {0.0f
, 0.0f
, 0.0f
, 0.0f
, 1.0f
,
387 1.0f
, 1.0f
, 1.0f
, 1.0f
, 1.0f
};
389 const VGint num_stops
= num
/ 5;
392 paint
->gradient
.num_stops
= num
;
394 free(paint
->gradient
.ramp_stops
);
395 paint
->gradient
.ramp_stops
= malloc(sizeof(VGfloat
)*num
);
396 memcpy(paint
->gradient
.ramp_stops
, stops
, sizeof(VGfloat
)*num
);
400 /* stops must be in increasing order. the last stop is 1.0. if the
401 * first one is bigger than 1 then the whole sequence is invalid*/
403 stops
= default_stops
;
406 last_coord
= stops
[0];
407 for (i
= 1; i
< num_stops
; ++i
) {
409 VGfloat coord
= stops
[idx
];
410 if (!floatsEqual(last_coord
, coord
) && coord
< last_coord
) {
411 stops
= default_stops
;
418 create_gradient_data(stops
, num
/ 5, paint
->gradient
.color_data
,
421 if (paint
->gradient
.sampler_view
) {
422 pipe_sampler_view_reference(&paint
->gradient
.sampler_view
, NULL
);
423 paint
->gradient
.sampler_view
= NULL
;
426 paint
->gradient
.sampler_view
= create_gradient_sampler_view(paint
);
429 void paint_set_colori(struct vg_paint
*p
,
432 p
->solid
.color
[0] = ((rgba
>> 24) & 0xff) / 255.f
;
433 p
->solid
.color
[1] = ((rgba
>> 16) & 0xff) / 255.f
;
434 p
->solid
.color
[2] = ((rgba
>> 8) & 0xff) / 255.f
;
435 p
->solid
.color
[3] = ((rgba
>> 0) & 0xff) / 255.f
;
438 VGuint
paint_colori(struct vg_paint
*p
)
440 #define F2B(f) (float_to_ubyte(f))
442 return ((F2B(p
->solid
.color
[0]) << 24) |
443 (F2B(p
->solid
.color
[1]) << 16) |
444 (F2B(p
->solid
.color
[2]) << 8) |
445 (F2B(p
->solid
.color
[3]) << 0));
449 void paint_set_linear_gradient(struct vg_paint
*paint
,
450 const VGfloat
*coords
)
452 memcpy(paint
->gradient
.linear
.coords
, coords
, sizeof(VGfloat
) * 4);
455 void paint_set_spread_mode(struct vg_paint
*paint
,
458 paint
->gradient
.spread
= mode
;
460 case VG_COLOR_RAMP_SPREAD_PAD
:
461 paint
->gradient
.sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
463 case VG_COLOR_RAMP_SPREAD_REPEAT
:
464 paint
->gradient
.sampler
.wrap_s
= PIPE_TEX_WRAP_REPEAT
;
466 case VG_COLOR_RAMP_SPREAD_REFLECT
:
467 paint
->gradient
.sampler
.wrap_s
= PIPE_TEX_WRAP_MIRROR_REPEAT
;
472 VGColorRampSpreadMode
paint_spread_mode(struct vg_paint
*paint
)
474 return paint
->gradient
.spread
;
477 void paint_set_radial_gradient(struct vg_paint
*paint
,
478 const VGfloat
*values
)
480 memcpy(paint
->gradient
.radial
.vals
, values
, sizeof(VGfloat
) * 5);
483 void paint_set_pattern(struct vg_paint
*paint
,
484 struct vg_image
*img
)
486 if (paint
->pattern
.sampler_view
)
487 pipe_sampler_view_reference(&paint
->pattern
.sampler_view
, NULL
);
489 paint
->pattern
.sampler_view
= NULL
;
490 pipe_sampler_view_reference(&paint
->pattern
.sampler_view
,
494 void paint_set_pattern_tiling(struct vg_paint
*paint
,
497 paint
->pattern
.tiling_mode
= mode
;
501 paint
->pattern
.sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_BORDER
;
502 paint
->pattern
.sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_BORDER
;
505 paint
->pattern
.sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
506 paint
->pattern
.sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
509 paint
->pattern
.sampler
.wrap_s
= PIPE_TEX_WRAP_REPEAT
;
510 paint
->pattern
.sampler
.wrap_t
= PIPE_TEX_WRAP_REPEAT
;
512 case VG_TILE_REFLECT
:
513 paint
->pattern
.sampler
.wrap_s
= PIPE_TEX_WRAP_MIRROR_REPEAT
;
514 paint
->pattern
.sampler
.wrap_t
= PIPE_TEX_WRAP_MIRROR_REPEAT
;
517 debug_assert("!Unknown tiling mode");
521 void paint_get_color(struct vg_paint
*paint
,
524 color
[0] = paint
->solid
.color
[0];
525 color
[1] = paint
->solid
.color
[1];
526 color
[2] = paint
->solid
.color
[2];
527 color
[3] = paint
->solid
.color
[3];
530 void paint_ramp_stops(struct vg_paint
*paint
, VGfloat
*stops
,
533 memcpy(stops
, paint
->gradient
.ramp_stops
, sizeof(VGfloat
)*num
);
536 void paint_linear_gradient(struct vg_paint
*paint
,
539 memcpy(coords
, paint
->gradient
.linear
.coords
, sizeof(VGfloat
)*4);
542 void paint_radial_gradient(struct vg_paint
*paint
,
545 memcpy(coords
, paint
->gradient
.radial
.vals
, sizeof(VGfloat
)*5);
548 int paint_num_ramp_stops(struct vg_paint
*paint
)
550 return paint
->gradient
.num_stops
;
553 VGPaintType
paint_type(struct vg_paint
*paint
)
558 void paint_set_coloriv(struct vg_paint
*paint
,
561 paint
->solid
.color
[0] = color
[0];
562 paint
->solid
.color
[1] = color
[1];
563 paint
->solid
.color
[2] = color
[2];
564 paint
->solid
.color
[3] = color
[3];
566 paint
->solid
.colori
[0] = color
[0];
567 paint
->solid
.colori
[1] = color
[1];
568 paint
->solid
.colori
[2] = color
[2];
569 paint
->solid
.colori
[3] = color
[3];
572 void paint_get_coloriv(struct vg_paint
*paint
,
575 color
[0] = paint
->solid
.colori
[0];
576 color
[1] = paint
->solid
.colori
[1];
577 color
[2] = paint
->solid
.colori
[2];
578 color
[3] = paint
->solid
.colori
[3];
581 void paint_set_color_ramp_premultiplied(struct vg_paint
*paint
,
584 paint
->gradient
.color_ramps_premultiplied
= set
;
587 VGboolean
paint_color_ramp_premultiplied(struct vg_paint
*paint
)
589 return paint
->gradient
.color_ramps_premultiplied
;
592 void paint_set_ramp_stopsi(struct vg_paint
*paint
, const VGint
*stops
,
596 free(paint
->gradient
.ramp_stopsi
);
597 paint
->gradient
.ramp_stopsi
= malloc(sizeof(VGint
)*num
);
598 memcpy(paint
->gradient
.ramp_stopsi
, stops
, sizeof(VGint
)*num
);
602 void paint_ramp_stopsi(struct vg_paint
*paint
, VGint
*stops
,
605 memcpy(stops
, paint
->gradient
.ramp_stopsi
, sizeof(VGint
)*num
);
608 void paint_set_linear_gradienti(struct vg_paint
*paint
,
611 memcpy(paint
->gradient
.linear
.coordsi
, coords
, sizeof(VGint
) * 4);
614 void paint_linear_gradienti(struct vg_paint
*paint
,
617 memcpy(coords
, paint
->gradient
.linear
.coordsi
, sizeof(VGint
)*4);
620 void paint_set_radial_gradienti(struct vg_paint
*paint
,
623 memcpy(paint
->gradient
.radial
.valsi
, values
, sizeof(VGint
) * 5);
626 void paint_radial_gradienti(struct vg_paint
*paint
,
629 memcpy(coords
, paint
->gradient
.radial
.valsi
, sizeof(VGint
)*5);
632 VGTilingMode
paint_pattern_tiling(struct vg_paint
*paint
)
634 return paint
->pattern
.tiling_mode
;
637 VGint
paint_bind_samplers(struct vg_paint
*paint
, struct pipe_sampler_state
**samplers
,
638 struct pipe_sampler_view
**sampler_views
)
640 struct vg_context
*ctx
= vg_current_context();
642 switch(paint
->type
) {
643 case VG_PAINT_TYPE_LINEAR_GRADIENT
:
644 case VG_PAINT_TYPE_RADIAL_GRADIENT
: {
645 if (paint
->gradient
.sampler_view
) {
646 paint
->gradient
.sampler
.min_img_filter
= image_sampler_filter(ctx
);
647 paint
->gradient
.sampler
.mag_img_filter
= image_sampler_filter(ctx
);
648 samplers
[0] = &paint
->gradient
.sampler
;
649 sampler_views
[0] = paint
->gradient
.sampler_view
;
654 case VG_PAINT_TYPE_PATTERN
: {
655 memcpy(paint
->pattern
.sampler
.border_color
,
656 ctx
->state
.vg
.tile_fill_color
,
657 sizeof(VGfloat
) * 4);
658 paint
->pattern
.sampler
.min_img_filter
= image_sampler_filter(ctx
);
659 paint
->pattern
.sampler
.mag_img_filter
= image_sampler_filter(ctx
);
660 samplers
[0] = &paint
->pattern
.sampler
;
661 sampler_views
[0] = paint
->pattern
.sampler_view
;
671 void paint_resolve_type(struct vg_paint
*paint
)
673 if (paint
->type
== VG_PAINT_TYPE_PATTERN
&&
674 !paint
->pattern
.sampler_view
) {
675 paint
->type
= VG_PAINT_TYPE_COLOR
;
679 VGboolean
paint_is_degenerate(struct vg_paint
*paint
)
685 switch (paint
->type
) {
686 case VG_PAINT_TYPE_LINEAR_GRADIENT
:
687 vals
= paint
->gradient
.linear
.coords
;
688 /* two points are coincident */
689 degen
= (floatsEqual(vals
[0], vals
[2]) &&
690 floatsEqual(vals
[1], vals
[3]));
692 case VG_PAINT_TYPE_RADIAL_GRADIENT
:
693 vals
= paint
->gradient
.radial
.vals
;
695 degen
= (vals
[4] <= 0.0f
);
697 case VG_PAINT_TYPE_COLOR
:
698 case VG_PAINT_TYPE_PATTERN
:
707 VGint
paint_constant_buffer_size(struct vg_paint
*paint
)
709 switch(paint
->type
) {
710 case VG_PAINT_TYPE_COLOR
:
711 return 8 * sizeof(VGfloat
);/*4 color + 4 constants (0.f,1.f,2.f,4.f)*/
713 case VG_PAINT_TYPE_LINEAR_GRADIENT
:
714 return 20 * sizeof(VGfloat
);
716 case VG_PAINT_TYPE_RADIAL_GRADIENT
:
717 return 20 * sizeof(VGfloat
);
719 case VG_PAINT_TYPE_PATTERN
:
720 return 20 * sizeof(VGfloat
);
723 debug_printf("Uknown paint type: %d\n", paint
->type
);
729 void paint_fill_constant_buffer(struct vg_paint
*paint
,
730 const struct matrix
*mat
,
733 switch(paint
->type
) {
734 case VG_PAINT_TYPE_COLOR
:
735 paint_color_buffer(paint
, buffer
);
737 case VG_PAINT_TYPE_LINEAR_GRADIENT
:
738 paint_linear_gradient_buffer(paint
, mat
, buffer
);
740 case VG_PAINT_TYPE_RADIAL_GRADIENT
:
741 paint_radial_gradient_buffer(paint
, mat
, buffer
);
743 case VG_PAINT_TYPE_PATTERN
:
744 paint_pattern_buffer(paint
, mat
, buffer
);
752 VGboolean
paint_is_opaque(struct vg_paint
*paint
)
754 /* TODO add other paint types and make sure PAINT_DIRTY gets set */
755 return (paint
->type
== VG_PAINT_TYPE_COLOR
&&
756 floatsEqual(paint
->solid
.color
[3], 1.0f
));