1 #include "xorg_composite.h"
2
3 #include "xorg_renderer.h"
4 #include "xorg_exa_tgsi.h"
5
6 #include "cso_cache/cso_context.h"
7 #include "util/u_format.h"
8 #include "util/u_sampler.h"
9
10
11 /*XXX also in Xrender.h but the including it here breaks compilition */
12 #define XFixedToDouble(f) (((double) (f)) / 65536.)
13
14 struct xorg_composite_blend {
15 int op : 8;
16
17 unsigned alpha_dst : 4;
18 unsigned alpha_src : 4;
19
20 unsigned rgb_src : 8; /**< PIPE_BLENDFACTOR_x */
21 unsigned rgb_dst : 8; /**< PIPE_BLENDFACTOR_x */
22 };
23
24 #define BLEND_OP_OVER 3
25 static const struct xorg_composite_blend xorg_blends[] = {
26 { PictOpClear,
27 0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO},
28 { PictOpSrc,
29 0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO},
30 { PictOpDst,
31 0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE},
32 { PictOpOver,
33 0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
34 { PictOpOverReverse,
35 1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE},
36 { PictOpIn,
37 1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
38 { PictOpInReverse,
39 0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA},
40 { PictOpOut,
41 1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
42 { PictOpOutReverse,
43 0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
44 { PictOpAtop,
45 1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
46 { PictOpAtopReverse,
47 1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA},
48 { PictOpXor,
49 1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
50 { PictOpAdd,
51 0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
52 };
53
54
55 static INLINE void
pixel_to_float4(Pixel pixel,float * color,enum pipe_format format)56 pixel_to_float4(Pixel pixel, float *color, enum pipe_format format)
57 {
58 const struct util_format_description *format_desc;
59 uint8_t packed[4];
60
61 format_desc = util_format_description(format);
62 packed[0] = pixel;
63 packed[1] = pixel >> 8;
64 packed[2] = pixel >> 16;
65 packed[3] = pixel >> 24;
66 format_desc->unpack_rgba_float(color, 0, packed, 0, 1, 1);
67 }
68
69 static boolean
blend_for_op(struct xorg_composite_blend * blend,int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture)70 blend_for_op(struct xorg_composite_blend *blend,
71 int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
72 PicturePtr pDstPicture)
73 {
74 const int num_blends =
75 sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
76 int i;
77 boolean supported = FALSE;
78
79 /* our default in case something goes wrong */
80 *blend = xorg_blends[BLEND_OP_OVER];
81
82 for (i = 0; i < num_blends; ++i) {
83 if (xorg_blends[i].op == op) {
84 *blend = xorg_blends[i];
85 supported = TRUE;
86 }
87 }
88
89 /* If there's no dst alpha channel, adjust the blend op so that we'll treat
90 * it as always 1. */
91 if (pDstPicture &&
92 PICT_FORMAT_A(pDstPicture->format) == 0 && blend->alpha_dst) {
93 if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
94 blend->rgb_src = PIPE_BLENDFACTOR_ONE;
95 else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
96 blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
97 }
98
99 /* If the source alpha is being used, then we should only be in a case where
100 * the source blend factor is 0, and the source blend value is the mask
101 * channels multiplied by the source picture's alpha. */
102 if (pMaskPicture && pMaskPicture->componentAlpha &&
103 PICT_FORMAT_RGB(pMaskPicture->format) && blend->alpha_src) {
104 if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
105 blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
106 } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
107 blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
108 }
109 }
110
111 return supported;
112 }
113
114 static INLINE int
render_repeat_to_gallium(int mode)115 render_repeat_to_gallium(int mode)
116 {
117 switch(mode) {
118 case RepeatNone:
119 return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
120 case RepeatNormal:
121 return PIPE_TEX_WRAP_REPEAT;
122 case RepeatReflect:
123 return PIPE_TEX_WRAP_MIRROR_REPEAT;
124 case RepeatPad:
125 return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
126 default:
127 debug_printf("Unsupported repeat mode\n");
128 }
129 return PIPE_TEX_WRAP_REPEAT;
130 }
131
132 static INLINE boolean
render_filter_to_gallium(int xrender_filter,int * out_filter)133 render_filter_to_gallium(int xrender_filter, int *out_filter)
134 {
135
136 switch (xrender_filter) {
137 case PictFilterNearest:
138 *out_filter = PIPE_TEX_FILTER_NEAREST;
139 break;
140 case PictFilterBilinear:
141 *out_filter = PIPE_TEX_FILTER_LINEAR;
142 break;
143 case PictFilterFast:
144 *out_filter = PIPE_TEX_FILTER_NEAREST;
145 break;
146 case PictFilterGood:
147 *out_filter = PIPE_TEX_FILTER_LINEAR;
148 break;
149 case PictFilterBest:
150 *out_filter = PIPE_TEX_FILTER_LINEAR;
151 break;
152 case PictFilterConvolution:
153 *out_filter = PIPE_TEX_FILTER_NEAREST;
154 return FALSE;
155 default:
156 debug_printf("Unknown xrender filter\n");
157 *out_filter = PIPE_TEX_FILTER_NEAREST;
158 return FALSE;
159 }
160
161 return TRUE;
162 }
163
is_filter_accelerated(PicturePtr pic)164 static boolean is_filter_accelerated(PicturePtr pic)
165 {
166 int filter;
167 if (pic && !render_filter_to_gallium(pic->filter, &filter))
168 return FALSE;
169 return TRUE;
170 }
171
xorg_composite_accelerated(int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture)172 boolean xorg_composite_accelerated(int op,
173 PicturePtr pSrcPicture,
174 PicturePtr pMaskPicture,
175 PicturePtr pDstPicture)
176 {
177 ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
178 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
179 modesettingPtr ms = modesettingPTR(pScrn);
180 struct xorg_composite_blend blend;
181
182 if (!is_filter_accelerated(pSrcPicture) ||
183 !is_filter_accelerated(pMaskPicture)) {
184 XORG_FALLBACK("Unsupported Xrender filter");
185 }
186
187 if (pSrcPicture->pSourcePict) {
188 if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
189 XORG_FALLBACK("Gradients not enabled (haven't been well tested)");
190 }
191
192 if (blend_for_op(&blend, op,
193 pSrcPicture, pMaskPicture, pDstPicture)) {
194 /* Check for component alpha */
195 if (pMaskPicture && pMaskPicture->componentAlpha &&
196 PICT_FORMAT_RGB(pMaskPicture->format)) {
197 if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
198 XORG_FALLBACK("Component alpha not supported with source "
199 "alpha and source value blending. (op=%d)",
200 op);
201 }
202 }
203
204 return TRUE;
205 }
206 XORG_FALLBACK("Unsupported composition operation = %d", op);
207 }
208
209 static void
bind_blend_state(struct exa_context * exa,int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture)210 bind_blend_state(struct exa_context *exa, int op,
211 PicturePtr pSrcPicture,
212 PicturePtr pMaskPicture,
213 PicturePtr pDstPicture)
214 {
215 struct xorg_composite_blend blend_opt;
216 struct pipe_blend_state blend;
217
218 blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
219
220 memset(&blend, 0, sizeof(struct pipe_blend_state));
221 blend.rt[0].blend_enable = 1;
222 blend.rt[0].colormask = PIPE_MASK_RGBA;
223
224 blend.rt[0].rgb_src_factor = blend_opt.rgb_src;
225 blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
226 blend.rt[0].rgb_dst_factor = blend_opt.rgb_dst;
227 blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
228
229 cso_set_blend(exa->renderer->cso, &blend);
230 }
231
232 static unsigned
picture_format_fixups(struct exa_pixmap_priv * pSrc,PicturePtr pSrcPicture,boolean mask,PicturePtr pDstPicture)233 picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
234 PicturePtr pDstPicture)
235 {
236 boolean set_alpha = FALSE;
237 boolean swizzle = FALSE;
238 unsigned ret = 0;
239
240 if (pSrc && pSrc->picture_format == pSrcPicture->format) {
241 if (pSrc->picture_format == PICT_a8) {
242 if (mask)
243 return FS_MASK_LUMINANCE;
244 else if (pDstPicture->format != PICT_a8) {
245 /* if both dst and src are luminance then
246 * we don't want to swizzle the alpha (X) of the
247 * source into W component of the dst because
248 * it will break our destination */
249 return FS_SRC_LUMINANCE;
250 }
251 }
252 return 0;
253 }
254
255 if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) {
256 assert(!"can not handle formats");
257 return 0;
258 }
259
260 /* pSrc->picture_format == PICT_a8r8g8b8 */
261 switch (pSrcPicture->format) {
262 case PICT_x8b8g8r8:
263 case PICT_b8g8r8:
264 set_alpha = TRUE; /* fall trough */
265 case PICT_a8b8g8r8:
266 swizzle = TRUE;
267 break;
268 case PICT_x8r8g8b8:
269 case PICT_r8g8b8:
270 set_alpha = TRUE; /* fall through */
271 case PICT_a8r8g8b8:
272 break;
273 #ifdef PICT_TYPE_BGRA
274 case PICT_b8g8r8a8:
275 case PICT_b8g8r8x8:
276 case PICT_a2r10g10b10:
277 case PICT_x2r10g10b10:
278 case PICT_a2b10g10r10:
279 case PICT_x2b10g10r10:
280 #endif
281 default:
282 assert(!"can not handle formats");
283 return 0;
284 }
285
286 if (set_alpha)
287 ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
288 if (swizzle)
289 ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
290
291 return ret;
292 }
293
294 static void
bind_shaders(struct exa_context * exa,int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture,struct exa_pixmap_priv * pSrc,struct exa_pixmap_priv * pMask)295 bind_shaders(struct exa_context *exa, int op,
296 PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
297 struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
298 {
299 unsigned vs_traits = 0, fs_traits = 0;
300 struct xorg_shader shader;
301
302 exa->has_solid_color = FALSE;
303
304 if (pSrcPicture) {
305 if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
306 fs_traits |= FS_SRC_REPEAT_NONE;
307
308 if (pSrcPicture->pSourcePict) {
309 if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
310 fs_traits |= FS_SOLID_FILL;
311 vs_traits |= VS_SOLID_FILL;
312 debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
313 pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
314 exa->solid_color, PIPE_FORMAT_B8G8R8A8_UNORM);
315 exa->has_solid_color = TRUE;
316 } else {
317 debug_assert("!gradients not supported");
318 }
319 } else {
320 fs_traits |= FS_COMPOSITE;
321 vs_traits |= VS_COMPOSITE;
322 }
323
324 fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
325 }
326
327 if (pMaskPicture) {
328 vs_traits |= VS_MASK;
329 fs_traits |= FS_MASK;
330 if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
331 fs_traits |= FS_MASK_REPEAT_NONE;
332 if (pMaskPicture->componentAlpha) {
333 struct xorg_composite_blend blend;
334 blend_for_op(&blend, op,
335 pSrcPicture, pMaskPicture, NULL);
336 if (blend.alpha_src) {
337 fs_traits |= FS_CA_SRCALPHA;
338 } else
339 fs_traits |= FS_CA_FULL;
340 }
341
342 fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
343 }
344
345 shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
346 cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
347 cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
348 }
349
350 static void
bind_samplers(struct exa_context * exa,int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture,struct exa_pixmap_priv * pSrc,struct exa_pixmap_priv * pMask,struct exa_pixmap_priv * pDst)351 bind_samplers(struct exa_context *exa, int op,
352 PicturePtr pSrcPicture, PicturePtr pMaskPicture,
353 PicturePtr pDstPicture,
354 struct exa_pixmap_priv *pSrc,
355 struct exa_pixmap_priv *pMask,
356 struct exa_pixmap_priv *pDst)
357 {
358 struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
359 struct pipe_sampler_state src_sampler, mask_sampler;
360 struct pipe_sampler_view view_templ;
361 struct pipe_sampler_view *src_view;
362 struct pipe_context *pipe = exa->pipe;
363
364 exa->num_bound_samplers = 0;
365
366 memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
367 memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
368
369 if (pSrcPicture && pSrc) {
370 if (exa->has_solid_color) {
371 debug_assert(!"solid color with textures");
372 samplers[0] = NULL;
373 pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
374 } else {
375 unsigned src_wrap = render_repeat_to_gallium(
376 pSrcPicture->repeatType);
377 int filter;
378
379 render_filter_to_gallium(pSrcPicture->filter, &filter);
380
381 src_sampler.wrap_s = src_wrap;
382 src_sampler.wrap_t = src_wrap;
383 src_sampler.min_img_filter = filter;
384 src_sampler.mag_img_filter = filter;
385 src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
386 src_sampler.normalized_coords = 1;
387 samplers[0] = &src_sampler;
388 exa->num_bound_samplers = 1;
389 u_sampler_view_default_template(&view_templ,
390 pSrc->tex,
391 pSrc->tex->format);
392 src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
393 pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
394 exa->bound_sampler_views[0] = src_view;
395 }
396 }
397
398 if (pMaskPicture && pMask) {
399 unsigned mask_wrap = render_repeat_to_gallium(
400 pMaskPicture->repeatType);
401 int filter;
402
403 render_filter_to_gallium(pMaskPicture->filter, &filter);
404
405 mask_sampler.wrap_s = mask_wrap;
406 mask_sampler.wrap_t = mask_wrap;
407 mask_sampler.min_img_filter = filter;
408 mask_sampler.mag_img_filter = filter;
409 src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
410 mask_sampler.normalized_coords = 1;
411 samplers[1] = &mask_sampler;
412 exa->num_bound_samplers = 2;
413 u_sampler_view_default_template(&view_templ,
414 pMask->tex,
415 pMask->tex->format);
416 src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
417 pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
418 exa->bound_sampler_views[1] = src_view;
419 }
420
421 cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
422 exa->num_bound_samplers,
423 (const struct pipe_sampler_state **)samplers);
424 cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
425 exa->num_bound_samplers,
426 exa->bound_sampler_views);
427 }
428
429
430
matrix_from_pict_transform(PictTransform * trans,float * matrix)431 static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
432 {
433 if (!trans)
434 return FALSE;
435
436 matrix[0] = XFixedToDouble(trans->matrix[0][0]);
437 matrix[3] = XFixedToDouble(trans->matrix[0][1]);
438 matrix[6] = XFixedToDouble(trans->matrix[0][2]);
439
440 matrix[1] = XFixedToDouble(trans->matrix[1][0]);
441 matrix[4] = XFixedToDouble(trans->matrix[1][1]);
442 matrix[7] = XFixedToDouble(trans->matrix[1][2]);
443
444 matrix[2] = XFixedToDouble(trans->matrix[2][0]);
445 matrix[5] = XFixedToDouble(trans->matrix[2][1]);
446 matrix[8] = XFixedToDouble(trans->matrix[2][2]);
447
448 return TRUE;
449 }
450
451 static void
setup_transforms(struct exa_context * exa,PicturePtr pSrcPicture,PicturePtr pMaskPicture)452 setup_transforms(struct exa_context *exa,
453 PicturePtr pSrcPicture, PicturePtr pMaskPicture)
454 {
455 PictTransform *src_t = NULL;
456 PictTransform *mask_t = NULL;
457
458 if (pSrcPicture)
459 src_t = pSrcPicture->transform;
460 if (pMaskPicture)
461 mask_t = pMaskPicture->transform;
462
463 exa->transform.has_src =
464 matrix_from_pict_transform(src_t, exa->transform.src);
465 exa->transform.has_mask =
466 matrix_from_pict_transform(mask_t, exa->transform.mask);
467 }
468
xorg_composite_bind_state(struct exa_context * exa,int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture,struct exa_pixmap_priv * pSrc,struct exa_pixmap_priv * pMask,struct exa_pixmap_priv * pDst)469 boolean xorg_composite_bind_state(struct exa_context *exa,
470 int op,
471 PicturePtr pSrcPicture,
472 PicturePtr pMaskPicture,
473 PicturePtr pDstPicture,
474 struct exa_pixmap_priv *pSrc,
475 struct exa_pixmap_priv *pMask,
476 struct exa_pixmap_priv *pDst)
477 {
478 struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pDst);
479
480 renderer_bind_destination(exa->renderer, dst_surf,
481 pDst->width,
482 pDst->height);
483
484 bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
485 bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
486 bind_samplers(exa, op, pSrcPicture, pMaskPicture,
487 pDstPicture, pSrc, pMask, pDst);
488
489 setup_transforms(exa, pSrcPicture, pMaskPicture);
490
491 if (exa->num_bound_samplers == 0 ) { /* solid fill */
492 renderer_begin_solid(exa->renderer);
493 } else {
494 renderer_begin_textures(exa->renderer,
495 exa->num_bound_samplers);
496 }
497
498
499 pipe_surface_reference(&dst_surf, NULL);
500 return TRUE;
501 }
502
xorg_composite(struct exa_context * exa,struct exa_pixmap_priv * dst,int srcX,int srcY,int maskX,int maskY,int dstX,int dstY,int width,int height)503 void xorg_composite(struct exa_context *exa,
504 struct exa_pixmap_priv *dst,
505 int srcX, int srcY, int maskX, int maskY,
506 int dstX, int dstY, int width, int height)
507 {
508 if (exa->num_bound_samplers == 0 ) { /* solid fill */
509 renderer_solid(exa->renderer,
510 dstX, dstY, dstX + width, dstY + height,
511 exa->solid_color);
512 } else {
513 int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
514 float *src_matrix = NULL;
515 float *mask_matrix = NULL;
516
517 if (exa->transform.has_src)
518 src_matrix = exa->transform.src;
519 if (exa->transform.has_mask)
520 mask_matrix = exa->transform.mask;
521
522 renderer_texture(exa->renderer,
523 pos, width, height,
524 exa->bound_sampler_views,
525 exa->num_bound_samplers,
526 src_matrix, mask_matrix);
527 }
528 }
529
xorg_solid_bind_state(struct exa_context * exa,struct exa_pixmap_priv * pixmap,Pixel fg)530 boolean xorg_solid_bind_state(struct exa_context *exa,
531 struct exa_pixmap_priv *pixmap,
532 Pixel fg)
533 {
534 struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
535 unsigned vs_traits, fs_traits;
536 struct xorg_shader shader;
537
538 pixel_to_float4(fg, exa->solid_color, pixmap->tex->format);
539 exa->has_solid_color = TRUE;
540
541 #if 0
542 debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
543 (fg >> 24) & 0xff, (fg >> 16) & 0xff,
544 (fg >> 8) & 0xff, (fg >> 0) & 0xff,
545 exa->solid_color[0], exa->solid_color[1],
546 exa->solid_color[2], exa->solid_color[3]);
547 #endif
548
549 vs_traits = VS_SOLID_FILL;
550 fs_traits = FS_SOLID_FILL;
551
552 renderer_bind_destination(exa->renderer, dst_surf,
553 pixmap->width, pixmap->height);
554 bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
555 cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
556 cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
557
558 shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
559 cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
560 cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
561
562 renderer_begin_solid(exa->renderer);
563
564 pipe_surface_reference(&dst_surf, NULL);
565 return TRUE;
566 }
567
xorg_solid(struct exa_context * exa,struct exa_pixmap_priv * pixmap,int x0,int y0,int x1,int y1)568 void xorg_solid(struct exa_context *exa,
569 struct exa_pixmap_priv *pixmap,
570 int x0, int y0, int x1, int y1)
571 {
572 renderer_solid(exa->renderer,
573 x0, y0, x1, y1, exa->solid_color);
574 }
575
576 void
xorg_composite_done(struct exa_context * exa)577 xorg_composite_done(struct exa_context *exa)
578 {
579 renderer_draw_flush(exa->renderer);
580
581 exa->transform.has_src = FALSE;
582 exa->transform.has_mask = FALSE;
583 exa->has_solid_color = FALSE;
584 exa->num_bound_samplers = 0;
585 }
586