paint.c revision f914cd1796845164109c837a111c39ba64852ad4
1/************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. All Rights Reserved. 4 * 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: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 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. 24 * 25 **************************************************************************/ 26 27#include "paint.h" 28 29#include "shaders_cache.h" 30#include "matrix.h" 31#include "image.h" 32#include "st_inlines.h" 33 34#include "pipe/p_compiler.h" 35#include "util/u_inlines.h" 36 37#include "util/u_format.h" 38#include "util/u_memory.h" 39#include "util/u_math.h" 40#include "util/u_sampler.h" 41 42#include "cso_cache/cso_context.h" 43 44struct vg_paint { 45 struct vg_object base; 46 47 VGPaintType type; 48 49 struct { 50 VGfloat color[4]; 51 VGint colori[4]; 52 } solid; 53 54 struct { 55 VGColorRampSpreadMode spread; 56 VGuint color_data[1024]; 57 struct { 58 VGfloat coords[4]; 59 VGint coordsi[4]; 60 } linear; 61 struct { 62 VGfloat vals[5]; 63 VGint valsi[5]; 64 } radial; 65 struct pipe_sampler_view *sampler_view; 66 struct pipe_sampler_state sampler; 67 68 VGfloat *ramp_stops; 69 VGint *ramp_stopsi; 70 VGint num_stops; 71 72 VGboolean color_ramps_premultiplied; 73 } gradient; 74 75 struct { 76 struct pipe_sampler_view *sampler_view; 77 VGTilingMode tiling_mode; 78 struct pipe_sampler_state sampler; 79 } pattern; 80 81 /* XXX next 3 all unneded? */ 82 struct pipe_resource *cbuf; 83 struct pipe_shader_state fs_state; 84 void *fs; 85}; 86 87static INLINE VGuint mix_pixels(VGuint p1, VGuint a, VGuint p2, VGuint b) 88{ 89 VGuint t = (p1 & 0xff00ff) * a + (p2 & 0xff00ff) * b; 90 t >>= 8; t &= 0xff00ff; 91 92 p1 = ((p1 >> 8) & 0xff00ff) * a + ((p2 >> 8) & 0xff00ff) * b; 93 p1 &= 0xff00ff00; p1 |= t; 94 95 return p1; 96} 97 98static INLINE VGuint float4_to_argb(const VGfloat *clr) 99{ 100 return float_to_ubyte(clr[3]) << 24 | 101 float_to_ubyte(clr[0]) << 16 | 102 float_to_ubyte(clr[1]) << 8 | 103 float_to_ubyte(clr[2]) << 0; 104} 105 106static INLINE void create_gradient_data(const VGfloat *ramp_stops, 107 VGint num, 108 VGuint *data, 109 VGint size) 110{ 111 VGint i; 112 VGint pos = 0; 113 VGfloat fpos = 0, incr = 1.f / size; 114 VGuint last_color; 115 116 while (fpos < ramp_stops[0]) { 117 data[pos] = float4_to_argb(ramp_stops + 1); 118 fpos += incr; 119 ++pos; 120 } 121 122 for (i = 0; i < num - 1; ++i) { 123 VGint rcur = 5 * i; 124 VGint rnext = 5 * (i + 1); 125 VGfloat delta = 1.f/(ramp_stops[rnext] - ramp_stops[rcur]); 126 while (fpos < ramp_stops[rnext] && pos < size) { 127 VGint dist = 256 * ((fpos - ramp_stops[rcur]) * delta); 128 VGint idist = 256 - dist; 129 VGuint current_color = float4_to_argb(ramp_stops + rcur + 1); 130 VGuint next_color = float4_to_argb(ramp_stops + rnext + 1); 131 data[pos] = mix_pixels(current_color, idist, 132 next_color, dist); 133 fpos += incr; 134 ++pos; 135 } 136 } 137 138 last_color = float4_to_argb(ramp_stops + ((num - 1) * 5 + 1)); 139 while (pos < size) { 140 data[pos] = last_color; 141 ++pos; 142 } 143 data[size-1] = last_color; 144} 145 146static INLINE struct pipe_resource *create_gradient_texture(struct vg_paint *p) 147{ 148 struct pipe_context *pipe = p->base.ctx->pipe; 149 struct pipe_screen *screen = pipe->screen; 150 struct pipe_resource *tex = 0; 151 struct pipe_resource templ; 152 153 memset(&templ, 0, sizeof(templ)); 154 templ.target = PIPE_TEXTURE_1D; 155 templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; 156 templ.last_level = 0; 157 templ.width0 = 1024; 158 templ.height0 = 1; 159 templ.depth0 = 1; 160 templ.bind = PIPE_BIND_SAMPLER_VIEW; 161 162 tex = screen->resource_create(screen, &templ); 163 164 { /* upload color_data */ 165 struct pipe_transfer *transfer = 166 st_no_flush_get_transfer(p->base.ctx, tex, 0, 0, 0, 167 PIPE_TRANSFER_WRITE, 0, 0, 1024, 1); 168 void *map = pipe->transfer_map(pipe, transfer); 169 memcpy(map, p->gradient.color_data, sizeof(VGint)*1024); 170 pipe->transfer_unmap(pipe, transfer); 171 pipe->transfer_destroy(pipe, transfer); 172 } 173 174 return tex; 175} 176 177static INLINE struct pipe_sampler_view *create_gradient_sampler_view(struct vg_paint *p) 178{ 179 struct pipe_context *pipe = p->base.ctx->pipe; 180 struct pipe_resource *texture; 181 struct pipe_sampler_view view_templ; 182 struct pipe_sampler_view *view; 183 184 texture = create_gradient_texture(p); 185 186 if (!texture) 187 return NULL; 188 189 u_sampler_view_default_template(&view_templ, texture, texture->format); 190 view = pipe->create_sampler_view(pipe, texture, &view_templ); 191 /* want the texture to go away if the view is freed */ 192 pipe_resource_reference(&texture, NULL); 193 194 return view; 195} 196 197struct vg_paint * paint_create(struct vg_context *ctx) 198{ 199 struct vg_paint *paint = CALLOC_STRUCT(vg_paint); 200 const VGfloat default_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; 201 const VGfloat def_ling[] = {0.0f, 0.0f, 1.0f, 0.0f}; 202 const VGfloat def_radg[] = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; 203 vg_init_object(&paint->base, ctx, VG_OBJECT_PAINT); 204 vg_context_add_object(ctx, VG_OBJECT_PAINT, paint); 205 206 paint->type = VG_PAINT_TYPE_COLOR; 207 memcpy(paint->solid.color, default_color, 208 4 * sizeof(VGfloat)); 209 paint->gradient.spread = VG_COLOR_RAMP_SPREAD_PAD; 210 memcpy(paint->gradient.linear.coords, def_ling, 211 4 * sizeof(VGfloat)); 212 memcpy(paint->gradient.radial.vals, def_radg, 213 5 * sizeof(VGfloat)); 214 215 paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 216 paint->gradient.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 217 paint->gradient.sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; 218 paint->gradient.sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; 219 paint->gradient.sampler.normalized_coords = 1; 220 221 memcpy(&paint->pattern.sampler, 222 &paint->gradient.sampler, 223 sizeof(struct pipe_sampler_state)); 224 225 return paint; 226} 227 228void paint_destroy(struct vg_paint *paint) 229{ 230 struct vg_context *ctx = paint->base.ctx; 231 pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL); 232 if (paint->pattern.sampler_view) 233 pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL); 234 if (ctx) 235 vg_context_remove_object(ctx, VG_OBJECT_PAINT, paint); 236 237 free(paint->gradient.ramp_stopsi); 238 free(paint->gradient.ramp_stops); 239 FREE(paint); 240} 241 242void paint_set_color(struct vg_paint *paint, 243 const VGfloat *color) 244{ 245 paint->solid.color[0] = color[0]; 246 paint->solid.color[1] = color[1]; 247 paint->solid.color[2] = color[2]; 248 paint->solid.color[3] = color[3]; 249 250 paint->solid.colori[0] = FLT_TO_INT(color[0]); 251 paint->solid.colori[1] = FLT_TO_INT(color[1]); 252 paint->solid.colori[2] = FLT_TO_INT(color[2]); 253 paint->solid.colori[3] = FLT_TO_INT(color[3]); 254} 255 256static INLINE void paint_color_buffer(struct vg_paint *paint, void *buffer) 257{ 258 VGfloat *map = (VGfloat*)buffer; 259 memcpy(buffer, paint->solid.color, 4 * sizeof(VGfloat)); 260 map[4] = 0.f; 261 map[5] = 1.f; 262 map[6] = 2.f; 263 map[7] = 4.f; 264} 265 266static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *buffer) 267{ 268 struct vg_context *ctx = paint->base.ctx; 269 VGfloat *map = (VGfloat*)buffer; 270 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 map[2] = 1.f / (map[0] * map[0] + map[1] * map[1]); 274 map[3] = 1.f; 275 276 map[4] = 0.f; 277 map[5] = 1.f; 278 map[6] = 2.f; 279 map[7] = 4.f; 280 { 281 struct matrix mat; 282 struct matrix inv; 283 matrix_load_identity(&mat); 284 matrix_translate(&mat, -paint->gradient.linear.coords[0], -paint->gradient.linear.coords[1]); 285 memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix, 286 sizeof(struct matrix)); 287 matrix_invert(&inv); 288 matrix_mult(&inv, &mat); 289 memcpy(&mat, &inv, 290 sizeof(struct matrix)); 291 292 map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f; 293 map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f; 294 map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f; 295 } 296#if 0 297 debug_printf("Coords (%f, %f, %f, %f)\n", 298 map[0], map[1], map[2], map[3]); 299#endif 300} 301 302 303static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *buffer) 304{ 305 VGfloat *radialCoords = paint->gradient.radial.vals; 306 struct vg_context *ctx = paint->base.ctx; 307 308 VGfloat *map = (VGfloat*)buffer; 309 310 map[0] = radialCoords[0] - radialCoords[2]; 311 map[1] = radialCoords[1] - radialCoords[3]; 312 map[2] = -map[0] * map[0] - map[1] * map[1] + 313 radialCoords[4] * radialCoords[4]; 314 map[3] = 1.f; 315 316 map[4] = 0.f; 317 map[5] = 1.f; 318 map[6] = 2.f; 319 map[7] = 4.f; 320 321 { 322 struct matrix mat; 323 struct matrix inv; 324 matrix_load_identity(&mat); 325 matrix_translate(&mat, -radialCoords[2], -radialCoords[3]); 326 memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix, 327 sizeof(struct matrix)); 328 matrix_invert(&inv); 329 matrix_mult(&inv, &mat); 330 memcpy(&mat, &inv, 331 sizeof(struct matrix)); 332 333 map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f; 334 map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f; 335 map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f; 336 } 337 338#if 0 339 debug_printf("Coords (%f, %f, %f, %f)\n", 340 map[0], map[1], map[2], map[3]); 341#endif 342} 343 344 345static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer) 346{ 347 struct vg_context *ctx = paint->base.ctx; 348 349 VGfloat *map = (VGfloat *)buffer; 350 memcpy(map, paint->solid.color, 4 * sizeof(VGfloat)); 351 352 map[4] = 0.f; 353 map[5] = 1.f; 354 map[6] = paint->pattern.sampler_view->texture->width0; 355 map[7] = paint->pattern.sampler_view->texture->height0; 356 { 357 struct matrix mat; 358 memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix, 359 sizeof(struct matrix)); 360 matrix_invert(&mat); 361 { 362 struct matrix pm; 363 memcpy(&pm, &ctx->state.vg.path_user_to_surface_matrix, 364 sizeof(struct matrix)); 365 matrix_invert(&pm); 366 matrix_mult(&pm, &mat); 367 memcpy(&mat, &pm, sizeof(struct matrix)); 368 } 369 370 map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f; 371 map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f; 372 map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f; 373 } 374} 375 376void paint_set_type(struct vg_paint *paint, VGPaintType type) 377{ 378 paint->type = type; 379} 380 381void paint_set_ramp_stops(struct vg_paint *paint, const VGfloat *stops, 382 int num) 383{ 384 const VGfloat default_stops[] = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 385 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; 386 VGint i; 387 const VGint num_stops = num / 5; 388 VGfloat last_coord; 389 390 paint->gradient.num_stops = num; 391 if (num) { 392 free(paint->gradient.ramp_stops); 393 paint->gradient.ramp_stops = malloc(sizeof(VGfloat)*num); 394 memcpy(paint->gradient.ramp_stops, stops, sizeof(VGfloat)*num); 395 } else 396 return; 397 398 /* stops must be in increasing order. the last stop is 1.0. if the 399 * first one is bigger than 1 then the whole sequence is invalid*/ 400 if (stops[0] > 1) { 401 stops = default_stops; 402 num = 10; 403 } 404 last_coord = stops[0]; 405 for (i = 1; i < num_stops; ++i) { 406 VGint idx = 5 * i; 407 VGfloat coord = stops[idx]; 408 if (!floatsEqual(last_coord, coord) && coord < last_coord) { 409 stops = default_stops; 410 num = 10; 411 break; 412 } 413 last_coord = coord; 414 } 415 416 create_gradient_data(stops, num / 5, paint->gradient.color_data, 417 1024); 418 419 if (paint->gradient.sampler_view) { 420 pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL); 421 paint->gradient.sampler_view = NULL; 422 } 423 424 paint->gradient.sampler_view = create_gradient_sampler_view(paint); 425} 426 427void paint_set_colori(struct vg_paint *p, 428 VGuint rgba) 429{ 430 p->solid.color[0] = ((rgba >> 24) & 0xff) / 255.f; 431 p->solid.color[1] = ((rgba >> 16) & 0xff) / 255.f; 432 p->solid.color[2] = ((rgba >> 8) & 0xff) / 255.f; 433 p->solid.color[3] = ((rgba >> 0) & 0xff) / 255.f; 434} 435 436VGuint paint_colori(struct vg_paint *p) 437{ 438#define F2B(f) (float_to_ubyte(f)) 439 440 return ((F2B(p->solid.color[0]) << 24) | 441 (F2B(p->solid.color[1]) << 16) | 442 (F2B(p->solid.color[2]) << 8) | 443 (F2B(p->solid.color[3]) << 0)); 444#undef F2B 445} 446 447void paint_set_linear_gradient(struct vg_paint *paint, 448 const VGfloat *coords) 449{ 450 memcpy(paint->gradient.linear.coords, coords, sizeof(VGfloat) * 4); 451} 452 453void paint_set_spread_mode(struct vg_paint *paint, 454 VGint mode) 455{ 456 paint->gradient.spread = mode; 457 switch(mode) { 458 case VG_COLOR_RAMP_SPREAD_PAD: 459 paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 460 break; 461 case VG_COLOR_RAMP_SPREAD_REPEAT: 462 paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; 463 break; 464 case VG_COLOR_RAMP_SPREAD_REFLECT: 465 paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT; 466 break; 467 } 468} 469 470VGColorRampSpreadMode paint_spread_mode(struct vg_paint *paint) 471{ 472 return paint->gradient.spread; 473} 474 475void paint_set_radial_gradient(struct vg_paint *paint, 476 const VGfloat *values) 477{ 478 memcpy(paint->gradient.radial.vals, values, sizeof(VGfloat) * 5); 479} 480 481void paint_set_pattern(struct vg_paint *paint, 482 struct vg_image *img) 483{ 484 if (paint->pattern.sampler_view) 485 pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL); 486 487 paint->pattern.sampler_view = NULL; 488 pipe_sampler_view_reference(&paint->pattern.sampler_view, 489 img->sampler_view); 490} 491 492void paint_set_pattern_tiling(struct vg_paint *paint, 493 VGTilingMode mode) 494{ 495 paint->pattern.tiling_mode = mode; 496 497 switch(mode) { 498 case VG_TILE_FILL: 499 paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_BORDER; 500 paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_BORDER; 501 break; 502 case VG_TILE_PAD: 503 paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 504 paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 505 break; 506 case VG_TILE_REPEAT: 507 paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; 508 paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; 509 break; 510 case VG_TILE_REFLECT: 511 paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT; 512 paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_MIRROR_REPEAT; 513 break; 514 default: 515 debug_assert("!Unknown tiling mode"); 516 } 517} 518 519void paint_get_color(struct vg_paint *paint, 520 VGfloat *color) 521{ 522 color[0] = paint->solid.color[0]; 523 color[1] = paint->solid.color[1]; 524 color[2] = paint->solid.color[2]; 525 color[3] = paint->solid.color[3]; 526} 527 528void paint_ramp_stops(struct vg_paint *paint, VGfloat *stops, 529 int num) 530{ 531 memcpy(stops, paint->gradient.ramp_stops, sizeof(VGfloat)*num); 532} 533 534void paint_linear_gradient(struct vg_paint *paint, 535 VGfloat *coords) 536{ 537 memcpy(coords, paint->gradient.linear.coords, sizeof(VGfloat)*4); 538} 539 540void paint_radial_gradient(struct vg_paint *paint, 541 VGfloat *coords) 542{ 543 memcpy(coords, paint->gradient.radial.vals, sizeof(VGfloat)*5); 544} 545 546int paint_num_ramp_stops(struct vg_paint *paint) 547{ 548 return paint->gradient.num_stops; 549} 550 551VGPaintType paint_type(struct vg_paint *paint) 552{ 553 return paint->type; 554} 555 556void paint_set_coloriv(struct vg_paint *paint, 557 const VGint *color) 558{ 559 paint->solid.color[0] = color[0]; 560 paint->solid.color[1] = color[1]; 561 paint->solid.color[2] = color[2]; 562 paint->solid.color[3] = color[3]; 563 564 paint->solid.colori[0] = color[0]; 565 paint->solid.colori[1] = color[1]; 566 paint->solid.colori[2] = color[2]; 567 paint->solid.colori[3] = color[3]; 568} 569 570void paint_get_coloriv(struct vg_paint *paint, 571 VGint *color) 572{ 573 color[0] = paint->solid.colori[0]; 574 color[1] = paint->solid.colori[1]; 575 color[2] = paint->solid.colori[2]; 576 color[3] = paint->solid.colori[3]; 577} 578 579void paint_set_color_ramp_premultiplied(struct vg_paint *paint, 580 VGboolean set) 581{ 582 paint->gradient.color_ramps_premultiplied = set; 583} 584 585VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint) 586{ 587 return paint->gradient.color_ramps_premultiplied; 588} 589 590void paint_set_ramp_stopsi(struct vg_paint *paint, const VGint *stops, 591 int num) 592{ 593 if (num) { 594 free(paint->gradient.ramp_stopsi); 595 paint->gradient.ramp_stopsi = malloc(sizeof(VGint)*num); 596 memcpy(paint->gradient.ramp_stopsi, stops, sizeof(VGint)*num); 597 } 598} 599 600void paint_ramp_stopsi(struct vg_paint *paint, VGint *stops, 601 int num) 602{ 603 memcpy(stops, paint->gradient.ramp_stopsi, sizeof(VGint)*num); 604} 605 606void paint_set_linear_gradienti(struct vg_paint *paint, 607 const VGint *coords) 608{ 609 memcpy(paint->gradient.linear.coordsi, coords, sizeof(VGint) * 4); 610} 611 612void paint_linear_gradienti(struct vg_paint *paint, 613 VGint *coords) 614{ 615 memcpy(coords, paint->gradient.linear.coordsi, sizeof(VGint)*4); 616} 617 618void paint_set_radial_gradienti(struct vg_paint *paint, 619 const VGint *values) 620{ 621 memcpy(paint->gradient.radial.valsi, values, sizeof(VGint) * 5); 622} 623 624void paint_radial_gradienti(struct vg_paint *paint, 625 VGint *coords) 626{ 627 memcpy(coords, paint->gradient.radial.valsi, sizeof(VGint)*5); 628} 629 630VGTilingMode paint_pattern_tiling(struct vg_paint *paint) 631{ 632 return paint->pattern.tiling_mode; 633} 634 635VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers, 636 struct pipe_sampler_view **sampler_views) 637{ 638 struct vg_context *ctx = vg_current_context(); 639 640 switch(paint->type) { 641 case VG_PAINT_TYPE_LINEAR_GRADIENT: 642 case VG_PAINT_TYPE_RADIAL_GRADIENT: { 643 if (paint->gradient.sampler_view) { 644 paint->gradient.sampler.min_img_filter = image_sampler_filter(ctx); 645 paint->gradient.sampler.mag_img_filter = image_sampler_filter(ctx); 646 samplers[0] = &paint->gradient.sampler; 647 sampler_views[0] = paint->gradient.sampler_view; 648 return 1; 649 } 650 } 651 break; 652 case VG_PAINT_TYPE_PATTERN: { 653 memcpy(paint->pattern.sampler.border_color, 654 ctx->state.vg.tile_fill_color, 655 sizeof(VGfloat) * 4); 656 paint->pattern.sampler.min_img_filter = image_sampler_filter(ctx); 657 paint->pattern.sampler.mag_img_filter = image_sampler_filter(ctx); 658 samplers[0] = &paint->pattern.sampler; 659 sampler_views[0] = paint->pattern.sampler_view; 660 return 1; 661 } 662 break; 663 default: 664 break; 665 } 666 return 0; 667} 668 669void paint_resolve_type(struct vg_paint *paint) 670{ 671 if (paint->type == VG_PAINT_TYPE_PATTERN && 672 !paint->pattern.sampler_view) { 673 paint->type = VG_PAINT_TYPE_COLOR; 674 } 675} 676 677VGint paint_constant_buffer_size(struct vg_paint *paint) 678{ 679 switch(paint->type) { 680 case VG_PAINT_TYPE_COLOR: 681 return 8 * sizeof(VGfloat);/*4 color + 4 constants (0.f,1.f,2.f,4.f)*/ 682 break; 683 case VG_PAINT_TYPE_LINEAR_GRADIENT: 684 return 20 * sizeof(VGfloat); 685 break; 686 case VG_PAINT_TYPE_RADIAL_GRADIENT: 687 return 20 * sizeof(VGfloat); 688 break; 689 case VG_PAINT_TYPE_PATTERN: 690 return 20 * sizeof(VGfloat); 691 break; 692 default: 693 debug_printf("Uknown paint type: %d\n", paint->type); 694 } 695 696 return 0; 697} 698 699void paint_fill_constant_buffer(struct vg_paint *paint, 700 void *buffer) 701{ 702 switch(paint->type) { 703 case VG_PAINT_TYPE_COLOR: 704 paint_color_buffer(paint, buffer); 705 break; 706 case VG_PAINT_TYPE_LINEAR_GRADIENT: 707 paint_linear_gradient_buffer(paint, buffer); 708 break; 709 case VG_PAINT_TYPE_RADIAL_GRADIENT: 710 paint_radial_gradient_buffer(paint, buffer); 711 break; 712 case VG_PAINT_TYPE_PATTERN: 713 paint_pattern_buffer(paint, buffer); 714 break; 715 716 default: 717 abort(); 718 } 719} 720