1 #include "xorg_composite.h"
3 #include <cso_cache/cso_context.h>
5 #include <pipe/p_inlines.h>
7 struct xorg_composite_blend
{
10 unsigned rgb_src_factor
:5; /**< PIPE_BLENDFACTOR_x */
11 unsigned rgb_dst_factor
:5; /**< PIPE_BLENDFACTOR_x */
13 unsigned alpha_src_factor
:5; /**< PIPE_BLENDFACTOR_x */
14 unsigned alpha_dst_factor
:5; /**< PIPE_BLENDFACTOR_x */
17 #define BLEND_OP_OVER 3
18 static const struct xorg_composite_blend xorg_blends
[] = {
20 PIPE_BLENDFACTOR_CONST_COLOR
, PIPE_BLENDFACTOR_CONST_ALPHA
,
21 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ZERO
},
24 PIPE_BLENDFACTOR_ONE
, PIPE_BLENDFACTOR_ONE
,
25 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ZERO
},
28 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ZERO
,
29 PIPE_BLENDFACTOR_ONE
, PIPE_BLENDFACTOR_ONE
},
32 PIPE_BLENDFACTOR_SRC_ALPHA
, PIPE_BLENDFACTOR_ONE
,
33 PIPE_BLENDFACTOR_INV_SRC_ALPHA
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
36 PIPE_BLENDFACTOR_SRC_ALPHA
, PIPE_BLENDFACTOR_ONE
,
37 PIPE_BLENDFACTOR_INV_SRC_ALPHA
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
40 struct acceleration_info
{
43 int component_alpha
: 1;
45 static const struct acceleration_info accelerated_ops
[] = {
50 {PictOpOverReverse
, 1, 0},
52 {PictOpInReverse
, 1, 0},
54 {PictOpOutReverse
, 1, 0},
56 {PictOpAtopReverse
, 1, 0},
59 {PictOpSaturate
, 1, 0},
62 static struct xorg_composite_blend
65 const int num_blends
=
66 sizeof(xorg_blends
)/sizeof(struct xorg_composite_blend
);
69 for (i
= 0; i
< num_blends
; ++i
) {
70 if (xorg_blends
[i
].op
== op
)
71 return xorg_blends
[i
];
73 return xorg_blends
[BLEND_OP_OVER
];
77 draw_texture(struct exa_context
*exa
)
81 util_draw_vertex_buffer(pipe
, buf
, 0,
82 PIPE_PRIM_TRIANGLE_FAN
,
84 2); /* attribs/vert */
86 pipe_buffer_reference(&buf
, NULL
);
91 boolean
xorg_composite_accelerated(int op
,
92 PicturePtr pSrcPicture
,
93 PicturePtr pMaskPicture
,
94 PicturePtr pDstPicture
)
97 unsigned accel_ops_count
=
98 sizeof(accelerated_ops
)/sizeof(struct acceleration_info
);
101 /* component alpha not supported */
102 if (pSrcPicture
->componentAlpha
)
104 /* fills not supported */
105 if (pSrcPicture
->pSourcePict
)
109 for (i
= 0; i
< accel_ops_count
; ++i
) {
110 if (op
== accelerated_ops
[i
].op
) {
111 if (pMaskPicture
&& !accelerated_ops
[i
].with_mask
)
120 bind_framebuffer_state(struct exa_context
*exa
, PicturePtr pDstPicture
,
121 struct exa_pixmap_priv
*pDst
)
124 struct pipe_framebuffer_state state
;
125 struct pipe_surface
*surface
= exa_gpu_surface(exa
, pDst
);
126 memset(&state
, 0, sizeof(struct pipe_framebuffer_state
));
128 state
.width
= pDstPicture
->pDrawable
->width
;
129 state
.height
= pDstPicture
->pDrawable
->height
;
132 state
.cbufs
[0] = surface
;
133 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
136 /* currently we don't use depth/stencil */
139 cso_set_framebuffer(exa
->cso
, &state
);
142 enum AxisOrientation
{
148 set_viewport(struct exa_context
*exa
, int width
, int height
,
149 enum AxisOrientation orientation
)
151 struct pipe_viewport_state viewport
;
152 float y_scale
= (orientation
== Y0_BOTTOM
) ? -2.f
: 2.f
;
154 viewport
.scale
[0] = width
/ 2.f
;
155 viewport
.scale
[1] = height
/ y_scale
;
156 viewport
.scale
[2] = 1.0;
157 viewport
.scale
[3] = 1.0;
158 viewport
.translate
[0] = width
/ 2.f
;
159 viewport
.translate
[1] = height
/ 2.f
;
160 viewport
.translate
[2] = 0.0;
161 viewport
.translate
[3] = 0.0;
163 cso_set_viewport(exa
->cso
, &viewport
);
167 bind_viewport_state(struct exa_context
*exa
, PicturePtr pDstPicture
)
169 const int param_bytes
= 8 * sizeof(float);
170 int width
= pDstPicture
->pDrawable
->width
;
171 int height
= pDstPicture
->pDrawable
->height
;
172 float vs_consts
[8] = {
173 2.f
/width
, 2.f
/height
, 1, 1,
176 struct pipe_constant_buffer
*cbuf
= &exa
->vs_const_buffer
;
178 set_viewport(exa
, width
, height
, Y0_BOTTOM
);
180 pipe_buffer_reference(&cbuf
->buffer
, NULL
);
181 cbuf
->buffer
= pipe_buffer_create(exa
->ctx
->screen
, 16,
182 PIPE_BUFFER_USAGE_CONSTANT
,
186 pipe_buffer_write(exa
->ctx
->screen
, cbuf
->buffer
,
187 0, param_bytes
, vs_consts
);
189 exa
->ctx
->set_constant_buffer(exa
->ctx
, PIPE_SHADER_VERTEX
, 0, cbuf
);
193 bind_blend_state(struct exa_context
*exa
, int op
,
194 PicturePtr pSrcPicture
, PicturePtr pMaskPicture
)
196 boolean component_alpha
= pSrcPicture
->componentAlpha
;
197 struct xorg_composite_blend blend_opt
;
198 struct pipe_blend_state blend
;
200 if (component_alpha
) {
203 blend_opt
= blend_for_op(op
);
205 memset(&blend
, 0, sizeof(struct pipe_blend_state
));
206 blend
.blend_enable
= 1;
207 blend
.colormask
|= PIPE_MASK_R
;
208 blend
.colormask
|= PIPE_MASK_G
;
209 blend
.colormask
|= PIPE_MASK_B
;
210 blend
.colormask
|= PIPE_MASK_A
;
212 blend
.rgb_src_factor
= blend_opt
.rgb_src_factor
;
213 blend
.alpha_src_factor
= blend_opt
.alpha_src_factor
;
214 blend
.rgb_dst_factor
= blend_opt
.rgb_dst_factor
;
215 blend
.alpha_dst_factor
= blend_opt
.alpha_dst_factor
;
217 cso_set_blend(exa
->cso
, &blend
);
221 bind_rasterizer_state()
231 boolean
xorg_composite_bind_state(struct exa_context
*exa
,
233 PicturePtr pSrcPicture
,
234 PicturePtr pMaskPicture
,
235 PicturePtr pDstPicture
,
236 struct exa_pixmap_priv
*pSrc
,
237 struct exa_pixmap_priv
*pMask
,
238 struct exa_pixmap_priv
*pDst
)
240 bind_framebuffer_state(exa
, pDstPicture
, pDst
);
241 bind_viewport_state(exa
, pDstPicture
);
242 bind_blend_state(exa
, op
, pSrcPicture
, pMaskPicture
);
243 bind_rasterizer_state();
249 void xorg_composite(struct exa_context
*exa
,
250 struct exa_pixmap_priv
*dst
,
251 int srcX
, int srcY
, int maskX
, int maskY
,
252 int dstX
, int dstY
, int width
, int height
)