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