2 #include "xorg_renderer.h"
4 #include "xorg_exa_tgsi.h"
6 #include "cso_cache/cso_context.h"
7 #include "util/u_draw_quad.h"
8 #include "util/u_math.h"
9 #include "util/u_memory.h"
10 #include "util/u_rect.h"
12 #include "pipe/p_inlines.h"
16 enum AxisOrientation
{
21 #define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
22 #define floatIsZero(x) (floatsEqual((x) + 1, 1))
24 #define NUM_COMPONENTS 4
26 static INLINE boolean
is_affine(float *matrix
)
28 return floatIsZero(matrix
[2]) && floatIsZero(matrix
[5])
29 && floatsEqual(matrix
[8], 1);
31 static INLINE
void map_point(float *mat
, float x
, float y
,
32 float *out_x
, float *out_y
)
40 *out_x
= mat
[0]*x
+ mat
[3]*y
+ mat
[6];
41 *out_y
= mat
[1]*x
+ mat
[4]*y
+ mat
[7];
42 if (!is_affine(mat
)) {
43 float w
= 1/(mat
[2]*x
+ mat
[5]*y
+ mat
[8]);
49 static INLINE
struct pipe_buffer
*
50 renderer_buffer_create(struct xorg_renderer
*r
)
52 struct pipe_buffer
*buf
=
53 pipe_user_buffer_create(r
->pipe
->screen
,
63 renderer_draw(struct xorg_renderer
*r
)
65 struct pipe_context
*pipe
= r
->pipe
;
66 struct pipe_buffer
*buf
= 0;
67 int num_verts
= r
->num_vertices
/(r
->num_attributes
* NUM_COMPONENTS
);
72 buf
= renderer_buffer_create(r
);
76 util_draw_vertex_buffer(pipe
, buf
, 0,
78 num_verts
, /* verts */
79 r
->num_attributes
); /* attribs/vert */
81 pipe_buffer_reference(&buf
, NULL
);
86 renderer_draw_conditional(struct xorg_renderer
*r
,
89 if (r
->num_vertices
+ next_batch
>= BUF_SIZE
||
90 (next_batch
== 0 && r
->num_vertices
)) {
96 renderer_init_state(struct xorg_renderer
*r
)
98 struct pipe_depth_stencil_alpha_state dsa
;
100 /* set common initial clip state */
101 memset(&dsa
, 0, sizeof(struct pipe_depth_stencil_alpha_state
));
102 cso_set_depth_stencil_alpha(r
->cso
, &dsa
);
107 add_vertex_color(struct xorg_renderer
*r
,
111 float *vertex
= r
->vertices
+ r
->num_vertices
;
115 vertex
[2] = 0.f
; /*z*/
116 vertex
[3] = 1.f
; /*w*/
118 vertex
[4] = color
[0]; /*r*/
119 vertex
[5] = color
[1]; /*g*/
120 vertex
[6] = color
[2]; /*b*/
121 vertex
[7] = color
[3]; /*a*/
123 r
->num_vertices
+= 8;
127 add_vertex_1tex(struct xorg_renderer
*r
,
128 float x
, float y
, float s
, float t
)
130 float *vertex
= r
->vertices
+ r
->num_vertices
;
134 vertex
[2] = 0.f
; /*z*/
135 vertex
[3] = 1.f
; /*w*/
139 vertex
[6] = 0.f
; /*r*/
140 vertex
[7] = 1.f
; /*q*/
142 r
->num_vertices
+= 8;
146 add_vertex_data1(struct xorg_renderer
*r
,
147 float srcX
, float srcY
, float dstX
, float dstY
,
148 float width
, float height
,
149 struct pipe_texture
*src
, float *src_matrix
)
151 float s0
, t0
, s1
, t1
;
152 float pt0
[2], pt1
[2];
156 pt1
[0] = (srcX
+ width
);
157 pt1
[1] = (srcY
+ height
);
160 map_point(src_matrix
, pt0
[0], pt0
[1], &pt0
[0], &pt0
[1]);
161 map_point(src_matrix
, pt1
[0], pt1
[1], &pt1
[0], &pt1
[1]);
164 s0
= pt0
[0] / src
->width
[0];
165 s1
= pt1
[0] / src
->width
[0];
166 t0
= pt0
[1] / src
->height
[0];
167 t1
= pt1
[1] / src
->height
[0];
170 add_vertex_1tex(r
, dstX
, dstY
, s0
, t0
);
172 add_vertex_1tex(r
, dstX
+ width
, dstY
, s1
, t0
);
174 add_vertex_1tex(r
, dstX
+ width
, dstY
+ height
, s1
, t1
);
176 add_vertex_1tex(r
, dstX
, dstY
+ height
, s0
, t1
);
179 static struct pipe_buffer
*
180 setup_vertex_data_tex(struct xorg_renderer
*r
,
181 float x0
, float y0
, float x1
, float y1
,
182 float s0
, float t0
, float s1
, float t1
,
186 add_vertex_1tex(r
, x0
, y0
, s0
, t0
);
188 add_vertex_1tex(r
, x1
, y0
, s1
, t0
);
190 add_vertex_1tex(r
, x1
, y1
, s1
, t1
);
192 add_vertex_1tex(r
, x0
, y1
, s0
, t1
);
194 return renderer_buffer_create(r
);
198 add_vertex_2tex(struct xorg_renderer
*r
,
200 float s0
, float t0
, float s1
, float t1
)
202 float *vertex
= r
->vertices
+ r
->num_vertices
;
206 vertex
[2] = 0.f
; /*z*/
207 vertex
[3] = 1.f
; /*w*/
209 vertex
[4] = s0
; /*s*/
210 vertex
[5] = t0
; /*t*/
211 vertex
[6] = 0.f
; /*r*/
212 vertex
[7] = 1.f
; /*q*/
214 vertex
[8] = s1
; /*s*/
215 vertex
[9] = t1
; /*t*/
216 vertex
[10] = 0.f
; /*r*/
217 vertex
[11] = 1.f
; /*q*/
219 r
->num_vertices
+= 12;
223 add_vertex_data2(struct xorg_renderer
*r
,
224 float srcX
, float srcY
, float maskX
, float maskY
,
225 float dstX
, float dstY
, float width
, float height
,
226 struct pipe_texture
*src
,
227 struct pipe_texture
*mask
,
228 float *src_matrix
, float *mask_matrix
)
230 float src_s0
, src_t0
, src_s1
, src_t1
;
231 float mask_s0
, mask_t0
, mask_s1
, mask_t1
;
232 float spt0
[2], spt1
[2];
233 float mpt0
[2], mpt1
[2];
237 spt1
[0] = srcX
+ width
;
238 spt1
[1] = srcY
+ height
;
242 mpt1
[0] = maskX
+ width
;
243 mpt1
[1] = maskY
+ height
;
246 map_point(src_matrix
, spt0
[0], spt0
[1], &spt0
[0], &spt0
[1]);
247 map_point(src_matrix
, spt1
[0], spt1
[1], &spt1
[0], &spt1
[1]);
251 map_point(mask_matrix
, mpt0
[0], mpt0
[1], &mpt0
[0], &mpt0
[1]);
252 map_point(mask_matrix
, mpt1
[0], mpt1
[1], &mpt1
[0], &mpt1
[1]);
255 src_s0
= spt0
[0] / src
->width
[0];
256 src_t0
= spt0
[1] / src
->height
[0];
257 src_s1
= spt1
[0] / src
->width
[0];
258 src_t1
= spt1
[1] / src
->height
[0];
260 mask_s0
= mpt0
[0] / mask
->width
[0];
261 mask_t0
= mpt0
[1] / mask
->height
[0];
262 mask_s1
= mpt1
[0] / mask
->width
[0];
263 mask_t1
= mpt1
[1] / mask
->height
[0];
266 add_vertex_2tex(r
, dstX
, dstY
,
267 src_s0
, src_t0
, mask_s0
, mask_t0
);
269 add_vertex_2tex(r
, dstX
+ width
, dstY
,
270 src_s1
, src_t0
, mask_s1
, mask_t0
);
272 add_vertex_2tex(r
, dstX
+ width
, dstY
+ height
,
273 src_s1
, src_t1
, mask_s1
, mask_t1
);
275 add_vertex_2tex(r
, dstX
, dstY
+ height
,
276 src_s0
, src_t1
, mask_s0
, mask_t1
);
279 static struct pipe_buffer
*
280 setup_vertex_data_yuv(struct xorg_renderer
*r
,
281 float srcX
, float srcY
, float srcW
, float srcH
,
282 float dstX
, float dstY
, float dstW
, float dstH
,
283 struct pipe_texture
**tex
)
285 float s0
, t0
, s1
, t1
;
286 float spt0
[2], spt1
[2];
290 spt1
[0] = srcX
+ srcW
;
291 spt1
[1] = srcY
+ srcH
;
293 s0
= spt0
[0] / tex
[0]->width
[0];
294 t0
= spt0
[1] / tex
[0]->height
[0];
295 s1
= spt1
[0] / tex
[0]->width
[0];
296 t1
= spt1
[1] / tex
[0]->height
[0];
299 add_vertex_1tex(r
, dstX
, dstY
, s0
, t0
);
301 add_vertex_1tex(r
, dstX
+ dstW
, dstY
,
304 add_vertex_1tex(r
, dstX
+ dstW
, dstY
+ dstH
,
307 add_vertex_1tex(r
, dstX
, dstY
+ dstH
,
310 return renderer_buffer_create(r
);
316 set_viewport(struct xorg_renderer
*r
, int width
, int height
,
317 enum AxisOrientation orientation
)
319 struct pipe_viewport_state viewport
;
320 float y_scale
= (orientation
== Y0_BOTTOM
) ? -2.f
: 2.f
;
322 viewport
.scale
[0] = width
/ 2.f
;
323 viewport
.scale
[1] = height
/ y_scale
;
324 viewport
.scale
[2] = 1.0;
325 viewport
.scale
[3] = 1.0;
326 viewport
.translate
[0] = width
/ 2.f
;
327 viewport
.translate
[1] = height
/ 2.f
;
328 viewport
.translate
[2] = 0.0;
329 viewport
.translate
[3] = 0.0;
331 cso_set_viewport(r
->cso
, &viewport
);
336 struct xorg_renderer
* renderer_create(struct pipe_context
*pipe
)
338 struct xorg_renderer
*renderer
= CALLOC_STRUCT(xorg_renderer
);
340 renderer
->pipe
= pipe
;
341 renderer
->cso
= cso_create_context(pipe
);
342 renderer
->shaders
= xorg_shaders_create(renderer
);
344 renderer_init_state(renderer
);
349 void renderer_destroy(struct xorg_renderer
*r
)
351 struct pipe_constant_buffer
*vsbuf
= &r
->vs_const_buffer
;
352 struct pipe_constant_buffer
*fsbuf
= &r
->fs_const_buffer
;
354 if (vsbuf
&& vsbuf
->buffer
)
355 pipe_buffer_reference(&vsbuf
->buffer
, NULL
);
357 if (fsbuf
&& fsbuf
->buffer
)
358 pipe_buffer_reference(&fsbuf
->buffer
, NULL
);
361 xorg_shaders_destroy(r
->shaders
);
366 cso_release_all(r
->cso
);
367 cso_destroy_context(r
->cso
);
372 void renderer_bind_framebuffer(struct xorg_renderer
*r
,
373 struct exa_pixmap_priv
*priv
)
376 struct pipe_framebuffer_state state
;
377 struct pipe_surface
*surface
= xorg_gpu_surface(r
->pipe
->screen
, priv
);
378 memset(&state
, 0, sizeof(struct pipe_framebuffer_state
));
380 state
.width
= priv
->tex
->width
[0];
381 state
.height
= priv
->tex
->height
[0];
384 state
.cbufs
[0] = surface
;
385 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
388 /* currently we don't use depth/stencil */
391 cso_set_framebuffer(r
->cso
, &state
);
393 /* we do fire and forget for the framebuffer, this is the forget part */
394 pipe_surface_reference(&surface
, NULL
);
397 void renderer_bind_viewport(struct xorg_renderer
*r
,
398 struct exa_pixmap_priv
*dst
)
400 int width
= dst
->tex
->width
[0];
401 int height
= dst
->tex
->height
[0];
403 /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
405 set_viewport(r
, width
, height
, Y0_TOP
);
408 void renderer_bind_rasterizer(struct xorg_renderer
*r
)
410 struct pipe_rasterizer_state raster
;
412 /* XXX: move to renderer_init_state? */
413 memset(&raster
, 0, sizeof(struct pipe_rasterizer_state
));
414 raster
.gl_rasterization_rules
= 1;
415 cso_set_rasterizer(r
->cso
, &raster
);
418 void renderer_set_constants(struct xorg_renderer
*r
,
423 struct pipe_constant_buffer
*cbuf
=
424 (shader_type
== PIPE_SHADER_VERTEX
) ? &r
->vs_const_buffer
:
427 pipe_buffer_reference(&cbuf
->buffer
, NULL
);
428 cbuf
->buffer
= pipe_buffer_create(r
->pipe
->screen
, 16,
429 PIPE_BUFFER_USAGE_CONSTANT
,
433 pipe_buffer_write(r
->pipe
->screen
, cbuf
->buffer
,
434 0, param_bytes
, params
);
436 r
->pipe
->set_constant_buffer(r
->pipe
, shader_type
, 0, cbuf
);
440 setup_vs_constant_buffer(struct xorg_renderer
*r
,
441 int width
, int height
)
443 const int param_bytes
= 8 * sizeof(float);
444 float vs_consts
[8] = {
445 2.f
/width
, 2.f
/height
, 1, 1,
448 renderer_set_constants(r
, PIPE_SHADER_VERTEX
,
449 vs_consts
, param_bytes
);
453 setup_fs_constant_buffer(struct xorg_renderer
*r
)
455 const int param_bytes
= 4 * sizeof(float);
456 const float fs_consts
[8] = {
459 renderer_set_constants(r
, PIPE_SHADER_FRAGMENT
,
460 fs_consts
, param_bytes
);
463 static INLINE
void shift_rectx(float coords
[4],
470 coords
[2] = MIN2(coords
[2], bounds
[2]);
471 /* bound x/y + width/height */
472 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
473 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
478 static INLINE
void shift_recty(float coords
[4],
485 coords
[3] = MIN2(coords
[3], bounds
[3]);
486 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
487 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
492 static INLINE
void bound_rect(float coords
[4],
493 const float bounds
[4],
496 /* if outside the bounds */
497 if (coords
[0] > (bounds
[0] + bounds
[2]) ||
498 coords
[1] > (bounds
[1] + bounds
[3]) ||
499 (coords
[0] + coords
[2]) < bounds
[0] ||
500 (coords
[1] + coords
[3]) < bounds
[1]) {
511 if (coords
[0] < bounds
[0]) {
512 shift
[0] = bounds
[0] - coords
[0];
513 coords
[2] -= shift
[0];
514 coords
[0] = bounds
[0];
519 if (coords
[1] < bounds
[1]) {
520 shift
[1] = bounds
[1] - coords
[1];
521 coords
[3] -= shift
[1];
522 coords
[1] = bounds
[1];
526 shift
[2] = bounds
[2] - coords
[2];
527 shift
[3] = bounds
[3] - coords
[3];
528 /* bound width/height */
529 coords
[2] = MIN2(coords
[2], bounds
[2]);
530 coords
[3] = MIN2(coords
[3], bounds
[3]);
532 /* bound x/y + width/height */
533 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
534 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
536 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
537 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
540 /* if outside the bounds */
541 if ((coords
[0] + coords
[2]) < bounds
[0] ||
542 (coords
[1] + coords
[3]) < bounds
[1]) {
551 static INLINE
void sync_size(float *src_loc
, float *dst_loc
)
553 src_loc
[2] = MIN2(src_loc
[2], dst_loc
[2]);
554 src_loc
[3] = MIN2(src_loc
[3], dst_loc
[3]);
555 dst_loc
[2] = src_loc
[2];
556 dst_loc
[3] = src_loc
[3];
559 static void renderer_copy_texture(struct xorg_renderer
*r
,
560 struct pipe_texture
*src
,
561 float sx1
, float sy1
,
562 float sx2
, float sy2
,
563 struct pipe_texture
*dst
,
564 float dx1
, float dy1
,
565 float dx2
, float dy2
)
567 struct pipe_context
*pipe
= r
->pipe
;
568 struct pipe_screen
*screen
= pipe
->screen
;
569 struct pipe_buffer
*buf
;
570 struct pipe_surface
*dst_surf
= screen
->get_tex_surface(
571 screen
, dst
, 0, 0, 0,
572 PIPE_BUFFER_USAGE_GPU_WRITE
);
573 struct pipe_framebuffer_state fb
;
574 float s0
, t0
, s1
, t1
;
575 struct xorg_shader shader
;
577 assert(src
->width
[0] != 0);
578 assert(src
->height
[0] != 0);
579 assert(dst
->width
[0] != 0);
580 assert(dst
->height
[0] != 0);
583 s0
= sx1
/ src
->width
[0];
584 s1
= sx2
/ src
->width
[0];
585 t0
= sy1
/ src
->height
[0];
586 t1
= sy2
/ src
->height
[0];
595 debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
596 sx1
, sy1
, sx2
, sy2
, dx1
, dy1
, dx2
, dy2
,
600 assert(screen
->is_format_supported(screen
, dst_surf
->format
,
602 PIPE_TEXTURE_USAGE_RENDER_TARGET
,
605 /* save state (restored below) */
606 cso_save_blend(r
->cso
);
607 cso_save_samplers(r
->cso
);
608 cso_save_sampler_textures(r
->cso
);
609 cso_save_framebuffer(r
->cso
);
610 cso_save_fragment_shader(r
->cso
);
611 cso_save_vertex_shader(r
->cso
);
613 cso_save_viewport(r
->cso
);
616 /* set misc state we care about */
618 struct pipe_blend_state blend
;
619 memset(&blend
, 0, sizeof(blend
));
620 blend
.rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
621 blend
.alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
622 blend
.rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
623 blend
.alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
624 blend
.colormask
= PIPE_MASK_RGBA
;
625 cso_set_blend(r
->cso
, &blend
);
630 struct pipe_sampler_state sampler
;
631 memset(&sampler
, 0, sizeof(sampler
));
632 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
633 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
634 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
635 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
636 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
637 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
638 sampler
.normalized_coords
= 1;
639 cso_single_sampler(r
->cso
, 0, &sampler
);
640 cso_single_sampler_done(r
->cso
);
643 set_viewport(r
, dst_surf
->width
, dst_surf
->height
, Y0_TOP
);
646 cso_set_sampler_textures(r
->cso
, 1, &src
);
648 renderer_bind_rasterizer(r
);
651 shader
= xorg_shaders_get(r
->shaders
,
654 cso_set_vertex_shader_handle(r
->cso
, shader
.vs
);
655 cso_set_fragment_shader_handle(r
->cso
, shader
.fs
);
658 memset(&fb
, 0, sizeof(fb
));
659 fb
.width
= dst_surf
->width
;
660 fb
.height
= dst_surf
->height
;
662 fb
.cbufs
[0] = dst_surf
;
665 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
668 cso_set_framebuffer(r
->cso
, &fb
);
669 setup_vs_constant_buffer(r
, fb
.width
, fb
.height
);
670 setup_fs_constant_buffer(r
);
673 buf
= setup_vertex_data_tex(r
,
680 util_draw_vertex_buffer(r
->pipe
, buf
, 0,
683 2); /* attribs/vert */
685 pipe_buffer_reference(&buf
, NULL
);
688 /* restore state we changed */
689 cso_restore_blend(r
->cso
);
690 cso_restore_samplers(r
->cso
);
691 cso_restore_sampler_textures(r
->cso
);
692 cso_restore_framebuffer(r
->cso
);
693 cso_restore_vertex_shader(r
->cso
);
694 cso_restore_fragment_shader(r
->cso
);
695 cso_restore_viewport(r
->cso
);
697 pipe_surface_reference(&dst_surf
, NULL
);
700 static struct pipe_texture
*
701 create_sampler_texture(struct xorg_renderer
*r
,
702 struct pipe_texture
*src
)
704 enum pipe_format format
;
705 struct pipe_context
*pipe
= r
->pipe
;
706 struct pipe_screen
*screen
= pipe
->screen
;
707 struct pipe_texture
*pt
;
708 struct pipe_texture templ
;
710 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
712 /* the coming in texture should already have that invariance */
713 debug_assert(screen
->is_format_supported(screen
, src
->format
,
715 PIPE_TEXTURE_USAGE_SAMPLER
, 0));
717 format
= src
->format
;
719 memset(&templ
, 0, sizeof(templ
));
720 templ
.target
= PIPE_TEXTURE_2D
;
721 templ
.format
= format
;
722 templ
.last_level
= 0;
723 templ
.width
[0] = src
->width
[0];
724 templ
.height
[0] = src
->height
[0];
726 pf_get_block(format
, &templ
.block
);
727 templ
.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
;
729 pt
= screen
->texture_create(screen
, &templ
);
731 debug_assert(!pt
|| pipe_is_referenced(&pt
->reference
));
737 /* copy source framebuffer surface into texture */
738 struct pipe_surface
*ps_read
= screen
->get_tex_surface(
739 screen
, src
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
);
740 struct pipe_surface
*ps_tex
= screen
->get_tex_surface(
741 screen
, pt
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE
);
742 if (pipe
->surface_copy
) {
743 pipe
->surface_copy(pipe
,
747 0, 0, src
->width
[0], src
->height
[0]);
749 util_surface_copy(pipe
, FALSE
,
753 0, 0, src
->width
[0], src
->height
[0]);
755 pipe_surface_reference(&ps_read
, NULL
);
756 pipe_surface_reference(&ps_tex
, NULL
);
763 void renderer_copy_pixmap(struct xorg_renderer
*r
,
764 struct exa_pixmap_priv
*dst_priv
, int dx
, int dy
,
765 struct exa_pixmap_priv
*src_priv
, int sx
, int sy
,
766 int width
, int height
)
768 float dst_loc
[4], src_loc
[4];
769 float dst_bounds
[4], src_bounds
[4];
770 float src_shift
[4], dst_shift
[4], shift
[4];
771 struct pipe_texture
*dst
= dst_priv
->tex
;
772 struct pipe_texture
*src
= src_priv
->tex
;
774 if (r
->pipe
->is_texture_referenced(r
->pipe
, src
, 0, 0) &
775 PIPE_REFERENCED_FOR_WRITE
)
776 r
->pipe
->flush(r
->pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
784 dst_bounds
[2] = dst
->width
[0];
785 dst_bounds
[3] = dst
->height
[0];
793 src_bounds
[2] = src
->width
[0];
794 src_bounds
[3] = src
->height
[0];
796 bound_rect(src_loc
, src_bounds
, src_shift
);
797 bound_rect(dst_loc
, dst_bounds
, dst_shift
);
798 shift
[0] = src_shift
[0] - dst_shift
[0];
799 shift
[1] = src_shift
[1] - dst_shift
[1];
802 shift_rectx(src_loc
, src_bounds
, -shift
[0]);
804 shift_rectx(dst_loc
, dst_bounds
, shift
[0]);
807 shift_recty(src_loc
, src_bounds
, -shift
[1]);
809 shift_recty(dst_loc
, dst_bounds
, shift
[1]);
811 sync_size(src_loc
, dst_loc
);
813 if (src_loc
[2] >= 0 && src_loc
[3] >= 0 &&
814 dst_loc
[2] >= 0 && dst_loc
[3] >= 0) {
815 struct pipe_texture
*temp_src
= src
;
818 temp_src
= create_sampler_texture(r
, src
);
820 renderer_copy_texture(r
,
824 src_loc
[0] + src_loc
[2],
825 src_loc
[1] + src_loc
[3],
829 dst_loc
[0] + dst_loc
[2],
830 dst_loc
[1] + dst_loc
[3]);
833 pipe_texture_reference(&temp_src
, NULL
);
837 void renderer_draw_yuv(struct xorg_renderer
*r
,
838 int src_x
, int src_y
, int src_w
, int src_h
,
839 int dst_x
, int dst_y
, int dst_w
, int dst_h
,
840 struct pipe_texture
**textures
)
842 struct pipe_context
*pipe
= r
->pipe
;
843 struct pipe_buffer
*buf
= 0;
845 buf
= setup_vertex_data_yuv(r
,
846 src_x
, src_y
, src_w
, src_h
,
847 dst_x
, dst_y
, dst_w
, dst_h
,
851 const int num_attribs
= 2; /*pos + tex coord*/
853 util_draw_vertex_buffer(pipe
, buf
, 0,
856 num_attribs
); /* attribs/vert */
858 pipe_buffer_reference(&buf
, NULL
);
862 void renderer_begin_solid(struct xorg_renderer
*r
)
865 r
->num_attributes
= 2;
868 void renderer_solid(struct xorg_renderer
*r
,
874 debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
875 x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
877 renderer_draw_conditional(r
, 4 * 8);
880 add_vertex_color(r
, x0
, y0
, color
);
882 add_vertex_color(r
, x1
, y0
, color
);
884 add_vertex_color(r
, x1
, y1
, color
);
886 add_vertex_color(r
, x0
, y1
, color
);
889 void renderer_draw_flush(struct xorg_renderer
*r
)
891 renderer_draw_conditional(r
, 0);
894 void renderer_begin_textures(struct xorg_renderer
*r
,
895 struct pipe_texture
**textures
,
898 r
->num_attributes
= 1 + num_textures
;
902 void renderer_texture(struct xorg_renderer
*r
,
904 int width
, int height
,
905 struct pipe_texture
**textures
,
913 debug_printf("src_matrix = \n");
914 debug_printf("%f, %f, %f\n", src_matrix
[0], src_matrix
[1], src_matrix
[2]);
915 debug_printf("%f, %f, %f\n", src_matrix
[3], src_matrix
[4], src_matrix
[5]);
916 debug_printf("%f, %f, %f\n", src_matrix
[6], src_matrix
[7], src_matrix
[8]);
919 debug_printf("mask_matrix = \n");
920 debug_printf("%f, %f, %f\n", mask_matrix
[0], mask_matrix
[1], mask_matrix
[2]);
921 debug_printf("%f, %f, %f\n", mask_matrix
[3], mask_matrix
[4], mask_matrix
[5]);
922 debug_printf("%f, %f, %f\n", mask_matrix
[6], mask_matrix
[7], mask_matrix
[8]);
926 switch(r
->num_attributes
) {
928 renderer_draw_conditional(r
, 4 * 8);
930 pos
[0], pos
[1], /* src */
931 pos
[4], pos
[5], /* dst */
933 textures
[0], src_matrix
);
936 renderer_draw_conditional(r
, 4 * 12);
938 pos
[0], pos
[1], /* src */
939 pos
[2], pos
[3], /* mask */
940 pos
[4], pos
[5], /* dst */
942 textures
[0], textures
[1],
943 src_matrix
, mask_matrix
);
946 debug_assert(!"Unsupported number of textures");