Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**********************************************************
  2.  * Copyright 2009-2011 VMware, Inc. All rights reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person
  5.  * obtaining a copy of this software and associated documentation
  6.  * files (the "Software"), to deal in the Software without
  7.  * restriction, including without limitation the rights to use, copy,
  8.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  9.  * of the Software, and to permit persons to whom the Software is
  10.  * furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be
  13.  * included in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  *
  24.  *********************************************************
  25.  * Authors:
  26.  * Zack Rusin <zackr-at-vmware-dot-com>
  27.  */
  28.  
  29. #include "xa_context.h"
  30. #include "xa_priv.h"
  31. #include <math.h>
  32. #include "cso_cache/cso_context.h"
  33. #include "util/u_inlines.h"
  34. #include "util/u_sampler.h"
  35. #include "util/u_draw_quad.h"
  36.  
  37. #define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
  38. #define floatIsZero(x) (floatsEqual((x) + 1, 1))
  39.  
  40. #define NUM_COMPONENTS 4
  41.  
  42. void
  43.  
  44.  
  45. renderer_set_constants(struct xa_context *r,
  46.                        int shader_type, const float *params, int param_bytes);
  47.  
  48. static INLINE boolean
  49. is_affine(float *matrix)
  50. {
  51.     return floatIsZero(matrix[2]) && floatIsZero(matrix[5])
  52.         && floatsEqual(matrix[8], 1);
  53. }
  54.  
  55. static INLINE void
  56. map_point(float *mat, float x, float y, float *out_x, float *out_y)
  57. {
  58.     if (!mat) {
  59.         *out_x = x;
  60.         *out_y = y;
  61.         return;
  62.     }
  63.  
  64.     *out_x = mat[0] * x + mat[3] * y + mat[6];
  65.     *out_y = mat[1] * x + mat[4] * y + mat[7];
  66.     if (!is_affine(mat)) {
  67.         float w = 1 / (mat[2] * x + mat[5] * y + mat[8]);
  68.  
  69.         *out_x *= w;
  70.         *out_y *= w;
  71.     }
  72. }
  73.  
  74. static INLINE void
  75. renderer_draw(struct xa_context *r)
  76. {
  77.     int num_verts = r->buffer_size / (r->attrs_per_vertex * NUM_COMPONENTS);
  78.  
  79.     if (!r->buffer_size)
  80.         return;
  81.  
  82.     if (!r->scissor_valid) {
  83.         r->scissor.minx = 0;
  84.         r->scissor.miny = 0;
  85.         r->scissor.maxx = r->dst->tex->width0;
  86.         r->scissor.maxy = r->dst->tex->height0;
  87.     }
  88.  
  89.     r->pipe->set_scissor_states(r->pipe, 0, 1, &r->scissor);
  90.  
  91.     cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
  92.     util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
  93.                                  num_verts,     /* verts */
  94.                                  r->attrs_per_vertex);  /* attribs/vert */
  95.     r->buffer_size = 0;
  96.  
  97.     xa_scissor_reset(r);
  98. }
  99.  
  100. static INLINE void
  101. renderer_draw_conditional(struct xa_context *r, int next_batch)
  102. {
  103.     if (r->buffer_size + next_batch >= XA_VB_SIZE ||
  104.         (next_batch == 0 && r->buffer_size)) {
  105.         renderer_draw(r);
  106.     }
  107. }
  108.  
  109. void
  110. renderer_init_state(struct xa_context *r)
  111. {
  112.     struct pipe_depth_stencil_alpha_state dsa;
  113.     struct pipe_rasterizer_state raster;
  114.     unsigned i;
  115.  
  116.     /* set common initial clip state */
  117.     memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
  118.     cso_set_depth_stencil_alpha(r->cso, &dsa);
  119.  
  120.     /* XXX: move to renderer_init_state? */
  121.     memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
  122.     raster.half_pixel_center = 1;
  123.     raster.bottom_edge_rule = 1;
  124.     raster.depth_clip = 1;
  125.     raster.scissor = 1;
  126.     cso_set_rasterizer(r->cso, &raster);
  127.  
  128.     /* vertex elements state */
  129.     memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
  130.     for (i = 0; i < 3; i++) {
  131.         r->velems[i].src_offset = i * 4 * sizeof(float);
  132.         r->velems[i].instance_divisor = 0;
  133.         r->velems[i].vertex_buffer_index = 0;
  134.         r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  135.     }
  136. }
  137.  
  138. static INLINE void
  139. add_vertex_color(struct xa_context *r, float x, float y, float color[4])
  140. {
  141.     float *vertex = r->buffer + r->buffer_size;
  142.  
  143.     vertex[0] = x;
  144.     vertex[1] = y;
  145.     vertex[2] = 0.f;            /*z */
  146.     vertex[3] = 1.f;            /*w */
  147.  
  148.     vertex[4] = color[0];       /*r */
  149.     vertex[5] = color[1];       /*g */
  150.     vertex[6] = color[2];       /*b */
  151.     vertex[7] = color[3];       /*a */
  152.  
  153.     r->buffer_size += 8;
  154. }
  155.  
  156. static INLINE void
  157. add_vertex_1tex(struct xa_context *r, float x, float y, float s, float t)
  158. {
  159.     float *vertex = r->buffer + r->buffer_size;
  160.  
  161.     vertex[0] = x;
  162.     vertex[1] = y;
  163.     vertex[2] = 0.f;            /*z */
  164.     vertex[3] = 1.f;            /*w */
  165.  
  166.     vertex[4] = s;              /*s */
  167.     vertex[5] = t;              /*t */
  168.     vertex[6] = 0.f;            /*r */
  169.     vertex[7] = 1.f;            /*q */
  170.  
  171.     r->buffer_size += 8;
  172. }
  173.  
  174. static INLINE void
  175. add_vertex_2tex(struct xa_context *r,
  176.                 float x, float y, float s0, float t0, float s1, float t1)
  177. {
  178.     float *vertex = r->buffer + r->buffer_size;
  179.  
  180.     vertex[0] = x;
  181.     vertex[1] = y;
  182.     vertex[2] = 0.f;            /*z */
  183.     vertex[3] = 1.f;            /*w */
  184.  
  185.     vertex[4] = s0;             /*s */
  186.     vertex[5] = t0;             /*t */
  187.     vertex[6] = 0.f;            /*r */
  188.     vertex[7] = 1.f;            /*q */
  189.  
  190.     vertex[8] = s1;             /*s */
  191.     vertex[9] = t1;             /*t */
  192.     vertex[10] = 0.f;           /*r */
  193.     vertex[11] = 1.f;           /*q */
  194.  
  195.     r->buffer_size += 12;
  196. }
  197.  
  198. static void
  199. add_vertex_data1(struct xa_context *r,
  200.                  float srcX, float srcY,  float dstX, float dstY,
  201.                  float width, float height,
  202.                  struct pipe_resource *src, const float *src_matrix)
  203. {
  204.     float s0, t0, s1, t1, s2, t2, s3, t3;
  205.     float pt0[2], pt1[2], pt2[2], pt3[2];
  206.  
  207.     pt0[0] = srcX;
  208.     pt0[1] = srcY;
  209.     pt1[0] = (srcX + width);
  210.     pt1[1] = srcY;
  211.     pt2[0] = (srcX + width);
  212.     pt2[1] = (srcY + height);
  213.     pt3[0] = srcX;
  214.     pt3[1] = (srcY + height);
  215.  
  216.     if (src_matrix) {
  217.         map_point((float *)src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
  218.         map_point((float *)src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
  219.         map_point((float *)src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
  220.         map_point((float *)src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
  221.     }
  222.  
  223.     s0 =  pt0[0] / src->width0;
  224.     s1 =  pt1[0] / src->width0;
  225.     s2 =  pt2[0] / src->width0;
  226.     s3 =  pt3[0] / src->width0;
  227.     t0 =  pt0[1] / src->height0;
  228.     t1 =  pt1[1] / src->height0;
  229.     t2 =  pt2[1] / src->height0;
  230.     t3 =  pt3[1] / src->height0;
  231.  
  232.     /* 1st vertex */
  233.     add_vertex_1tex(r, dstX, dstY, s0, t0);
  234.     /* 2nd vertex */
  235.     add_vertex_1tex(r, dstX + width, dstY, s1, t1);
  236.     /* 3rd vertex */
  237.     add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
  238.     /* 4th vertex */
  239.     add_vertex_1tex(r, dstX, dstY + height, s3, t3);
  240. }
  241.  
  242. static void
  243. add_vertex_data2(struct xa_context *r,
  244.                  float srcX, float srcY, float maskX, float maskY,
  245.                  float dstX, float dstY, float width, float height,
  246.                  struct pipe_resource *src,
  247.                  struct pipe_resource *mask,
  248.                  const float *src_matrix, const float *mask_matrix)
  249. {
  250.     float src_s0, src_t0, src_s1, src_t1;
  251.     float mask_s0, mask_t0, mask_s1, mask_t1;
  252.     float spt0[2], spt1[2];
  253.     float mpt0[2], mpt1[2];
  254.  
  255.     spt0[0] = srcX;
  256.     spt0[1] = srcY;
  257.     spt1[0] = srcX + width;
  258.     spt1[1] = srcY + height;
  259.  
  260.     mpt0[0] = maskX;
  261.     mpt0[1] = maskY;
  262.     mpt1[0] = maskX + width;
  263.     mpt1[1] = maskY + height;
  264.  
  265.     if (src_matrix) {
  266.         map_point((float *)src_matrix, spt0[0], spt0[1], &spt0[0], &spt0[1]);
  267.         map_point((float *)src_matrix, spt1[0], spt1[1], &spt1[0], &spt1[1]);
  268.     }
  269.  
  270.     if (mask_matrix) {
  271.         map_point((float *)mask_matrix, mpt0[0], mpt0[1], &mpt0[0], &mpt0[1]);
  272.         map_point((float *)mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
  273.     }
  274.  
  275.     src_s0 = spt0[0] / src->width0;
  276.     src_t0 = spt0[1] / src->height0;
  277.     src_s1 = spt1[0] / src->width0;
  278.     src_t1 = spt1[1] / src->height0;
  279.  
  280.     mask_s0 = mpt0[0] / mask->width0;
  281.     mask_t0 = mpt0[1] / mask->height0;
  282.     mask_s1 = mpt1[0] / mask->width0;
  283.     mask_t1 = mpt1[1] / mask->height0;
  284.  
  285.     /* 1st vertex */
  286.     add_vertex_2tex(r, dstX, dstY,
  287.                     src_s0, src_t0, mask_s0, mask_t0);
  288.     /* 2nd vertex */
  289.     add_vertex_2tex(r, dstX + width, dstY,
  290.                     src_s1, src_t0, mask_s1, mask_t0);
  291.     /* 3rd vertex */
  292.     add_vertex_2tex(r, dstX + width, dstY + height,
  293.                     src_s1, src_t1, mask_s1, mask_t1);
  294.     /* 4th vertex */
  295.     add_vertex_2tex(r, dstX, dstY + height,
  296.                     src_s0, src_t1, mask_s0, mask_t1);
  297. }
  298.  
  299. static void
  300. setup_vertex_data_yuv(struct xa_context *r,
  301.                       float srcX,
  302.                       float srcY,
  303.                       float srcW,
  304.                       float srcH,
  305.                       float dstX,
  306.                       float dstY,
  307.                       float dstW, float dstH, struct xa_surface *srf[])
  308. {
  309.     float s0, t0, s1, t1;
  310.     float spt0[2], spt1[2];
  311.     struct pipe_resource *tex;
  312.  
  313.     spt0[0] = srcX;
  314.     spt0[1] = srcY;
  315.     spt1[0] = srcX + srcW;
  316.     spt1[1] = srcY + srcH;
  317.  
  318.     tex = srf[0]->tex;
  319.     s0 = spt0[0] / tex->width0;
  320.     t0 = spt0[1] / tex->height0;
  321.     s1 = spt1[0] / tex->width0;
  322.     t1 = spt1[1] / tex->height0;
  323.  
  324.     /* 1st vertex */
  325.     add_vertex_1tex(r, dstX, dstY, s0, t0);
  326.     /* 2nd vertex */
  327.     add_vertex_1tex(r, dstX + dstW, dstY, s1, t0);
  328.     /* 3rd vertex */
  329.     add_vertex_1tex(r, dstX + dstW, dstY + dstH, s1, t1);
  330.     /* 4th vertex */
  331.     add_vertex_1tex(r, dstX, dstY + dstH, s0, t1);
  332. }
  333.  
  334. /* Set up framebuffer, viewport and vertex shader constant buffer
  335.  * state for a particular destinaton surface.  In all our rendering,
  336.  * these concepts are linked.
  337.  */
  338. void
  339. renderer_bind_destination(struct xa_context *r,
  340.                           struct pipe_surface *surface)
  341. {
  342.     int width = surface->width;
  343.     int height = surface->height;
  344.  
  345.     struct pipe_framebuffer_state fb;
  346.     struct pipe_viewport_state viewport;
  347.  
  348.     xa_scissor_reset(r);
  349.  
  350.     /* Framebuffer uses actual surface width/height
  351.      */
  352.     memset(&fb, 0, sizeof fb);
  353.     fb.width = surface->width;
  354.     fb.height = surface->height;
  355.     fb.nr_cbufs = 1;
  356.     fb.cbufs[0] = surface;
  357.     fb.zsbuf = 0;
  358.  
  359.     /* Viewport just touches the bit we're interested in:
  360.      */
  361.     viewport.scale[0] = width / 2.f;
  362.     viewport.scale[1] = height / 2.f;
  363.     viewport.scale[2] = 1.0;
  364.     viewport.translate[0] = width / 2.f;
  365.     viewport.translate[1] = height / 2.f;
  366.     viewport.translate[2] = 0.0;
  367.  
  368.     /* Constant buffer set up to match viewport dimensions:
  369.      */
  370.     if (r->fb_width != width || r->fb_height != height) {
  371.         float vs_consts[8] = {
  372.             2.f / width, 2.f / height, 1, 1,
  373.             -1, -1, 0, 0
  374.         };
  375.  
  376.         r->fb_width = width;
  377.         r->fb_height = height;
  378.  
  379.         renderer_set_constants(r, PIPE_SHADER_VERTEX,
  380.                                vs_consts, sizeof vs_consts);
  381.     }
  382.  
  383.     cso_set_framebuffer(r->cso, &fb);
  384.     cso_set_viewport(r->cso, &viewport);
  385. }
  386.  
  387. void
  388. renderer_set_constants(struct xa_context *r,
  389.                        int shader_type, const float *params, int param_bytes)
  390. {
  391.     struct pipe_resource **cbuf =
  392.         (shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer :
  393.         &r->fs_const_buffer;
  394.  
  395.     pipe_resource_reference(cbuf, NULL);
  396.     *cbuf = pipe_buffer_create(r->pipe->screen,
  397.                                PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_DEFAULT,
  398.                                param_bytes);
  399.  
  400.     if (*cbuf) {
  401.         pipe_buffer_write(r->pipe, *cbuf, 0, param_bytes, params);
  402.     }
  403.     pipe_set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
  404. }
  405.  
  406. void
  407. renderer_copy_prepare(struct xa_context *r,
  408.                       struct pipe_surface *dst_surface,
  409.                       struct pipe_resource *src_texture,
  410.                       const enum xa_formats src_xa_format,
  411.                       const enum xa_formats dst_xa_format)
  412. {
  413.     struct pipe_context *pipe = r->pipe;
  414.     struct pipe_screen *screen = pipe->screen;
  415.     struct xa_shader shader;
  416.     uint32_t fs_traits = FS_COMPOSITE;
  417.  
  418.     assert(screen->is_format_supported(screen, dst_surface->format,
  419.                                        PIPE_TEXTURE_2D, 0,
  420.                                        PIPE_BIND_RENDER_TARGET));
  421.     (void)screen;
  422.  
  423.     renderer_bind_destination(r, dst_surface);
  424.  
  425.     /* set misc state we care about */
  426.     {
  427.         struct pipe_blend_state blend;
  428.  
  429.         memset(&blend, 0, sizeof(blend));
  430.         blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
  431.         blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  432.         blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
  433.         blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  434.         blend.rt[0].colormask = PIPE_MASK_RGBA;
  435.         cso_set_blend(r->cso, &blend);
  436.     }
  437.  
  438.     /* sampler */
  439.     {
  440.         struct pipe_sampler_state sampler;
  441.         const struct pipe_sampler_state *p_sampler = &sampler;
  442.  
  443.         memset(&sampler, 0, sizeof(sampler));
  444.         sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  445.         sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  446.         sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  447.         sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
  448.         sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
  449.         sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
  450.         sampler.normalized_coords = 1;
  451.         cso_set_samplers(r->cso, PIPE_SHADER_FRAGMENT, 1, &p_sampler);
  452.         r->num_bound_samplers = 1;
  453.     }
  454.  
  455.     /* texture/sampler view */
  456.     {
  457.         struct pipe_sampler_view templ;
  458.         struct pipe_sampler_view *src_view;
  459.  
  460.         u_sampler_view_default_template(&templ,
  461.                                         src_texture, src_texture->format);
  462.         src_view = pipe->create_sampler_view(pipe, src_texture, &templ);
  463.         cso_set_sampler_views(r->cso, PIPE_SHADER_FRAGMENT, 1, &src_view);
  464.         pipe_sampler_view_reference(&src_view, NULL);
  465.     }
  466.  
  467.     /* shaders */
  468.     if (src_texture->format == PIPE_FORMAT_L8_UNORM)
  469.         fs_traits |= FS_SRC_LUMINANCE;
  470.     if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
  471.         fs_traits |= FS_DST_LUMINANCE;
  472.     if (xa_format_a(dst_xa_format) != 0 &&
  473.         xa_format_a(src_xa_format) == 0)
  474.         fs_traits |= FS_SRC_SET_ALPHA;
  475.  
  476.     shader = xa_shaders_get(r->shaders, VS_COMPOSITE, fs_traits);
  477.     cso_set_vertex_shader_handle(r->cso, shader.vs);
  478.     cso_set_fragment_shader_handle(r->cso, shader.fs);
  479.  
  480.     r->buffer_size = 0;
  481.     r->attrs_per_vertex = 2;
  482. }
  483.  
  484. void
  485. renderer_copy(struct xa_context *r,
  486.               int dx,
  487.               int dy,
  488.               int sx,
  489.               int sy,
  490.               int width, int height, float src_width, float src_height)
  491. {
  492.     float s0, t0, s1, t1;
  493.     float x0, y0, x1, y1;
  494.  
  495.     /* XXX: could put the texcoord scaling calculation into the vertex
  496.      * shader.
  497.      */
  498.     s0 = sx / src_width;
  499.     s1 = (sx + width) / src_width;
  500.     t0 = sy / src_height;
  501.     t1 = (sy + height) / src_height;
  502.  
  503.     x0 = dx;
  504.     x1 = dx + width;
  505.     y0 = dy;
  506.     y1 = dy + height;
  507.  
  508.     /* draw quad */
  509.     renderer_draw_conditional(r, 4 * 8);
  510.     add_vertex_1tex(r, x0, y0, s0, t0);
  511.     add_vertex_1tex(r, x1, y0, s1, t0);
  512.     add_vertex_1tex(r, x1, y1, s1, t1);
  513.     add_vertex_1tex(r, x0, y1, s0, t1);
  514. }
  515.  
  516. void
  517. renderer_draw_yuv(struct xa_context *r,
  518.                   float src_x,
  519.                   float src_y,
  520.                   float src_w,
  521.                   float src_h,
  522.                   int dst_x,
  523.                   int dst_y, int dst_w, int dst_h, struct xa_surface *srf[])
  524. {
  525.    const int num_attribs = 2;   /*pos + tex coord */
  526.  
  527.    setup_vertex_data_yuv(r,
  528.                          src_x, src_y, src_w, src_h,
  529.                          dst_x, dst_y, dst_w, dst_h, srf);
  530.  
  531.    if (!r->scissor_valid) {
  532.        r->scissor.minx = 0;
  533.        r->scissor.miny = 0;
  534.        r->scissor.maxx = r->dst->tex->width0;
  535.        r->scissor.maxy = r->dst->tex->height0;
  536.    }
  537.  
  538.    r->pipe->set_scissor_states(r->pipe, 0, 1, &r->scissor);
  539.  
  540.    cso_set_vertex_elements(r->cso, num_attribs, r->velems);
  541.    util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
  542.                                 4,      /* verts */
  543.                                 num_attribs);   /* attribs/vert */
  544.    r->buffer_size = 0;
  545.  
  546.    xa_scissor_reset(r);
  547. }
  548.  
  549. void
  550. renderer_begin_solid(struct xa_context *r)
  551. {
  552.     r->buffer_size = 0;
  553.     r->attrs_per_vertex = 2;
  554. }
  555.  
  556. void
  557. renderer_solid(struct xa_context *r,
  558.                int x0, int y0, int x1, int y1, float *color)
  559. {
  560.     /*
  561.      * debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
  562.      * x0, y0, x1, y1, color[0], color[1], color[2], color[3]); */
  563.  
  564.     renderer_draw_conditional(r, 4 * 8);
  565.  
  566.     /* 1st vertex */
  567.     add_vertex_color(r, x0, y0, color);
  568.     /* 2nd vertex */
  569.     add_vertex_color(r, x1, y0, color);
  570.     /* 3rd vertex */
  571.     add_vertex_color(r, x1, y1, color);
  572.     /* 4th vertex */
  573.     add_vertex_color(r, x0, y1, color);
  574. }
  575.  
  576. void
  577. renderer_draw_flush(struct xa_context *r)
  578. {
  579.     renderer_draw_conditional(r, 0);
  580. }
  581.  
  582. void
  583. renderer_begin_textures(struct xa_context *r)
  584. {
  585.     r->attrs_per_vertex = 1 + r->num_bound_samplers;
  586.     r->buffer_size = 0;
  587. }
  588.  
  589. void
  590. renderer_texture(struct xa_context *r,
  591.                  int *pos,
  592.                  int width, int height,
  593.                  const float *src_matrix,
  594.                  const float *mask_matrix)
  595. {
  596.     struct pipe_sampler_view **sampler_view = r->bound_sampler_views;
  597.  
  598. #if 0
  599.     if (src_matrix) {
  600.         debug_printf("src_matrix = \n");
  601.         debug_printf("%f, %f, %f\n", src_matrix[0], src_matrix[1], src_matrix[2]);
  602.         debug_printf("%f, %f, %f\n", src_matrix[3], src_matrix[4], src_matrix[5]);
  603.         debug_printf("%f, %f, %f\n", src_matrix[6], src_matrix[7], src_matrix[8]);
  604.     }
  605.     if (mask_matrix) {
  606.         debug_printf("mask_matrix = \n");
  607.         debug_printf("%f, %f, %f\n", mask_matrix[0], mask_matrix[1], mask_matrix[2]);
  608.         debug_printf("%f, %f, %f\n", mask_matrix[3], mask_matrix[4], mask_matrix[5]);
  609.         debug_printf("%f, %f, %f\n", mask_matrix[6], mask_matrix[7], mask_matrix[8]);
  610.     }
  611. #endif
  612.  
  613.     switch(r->attrs_per_vertex) {
  614.     case 2:
  615.         renderer_draw_conditional(r, 4 * 8);
  616.         add_vertex_data1(r,
  617.                          pos[0], pos[1], /* src */
  618.                          pos[4], pos[5], /* dst */
  619.                          width, height,
  620.                          sampler_view[0]->texture, src_matrix);
  621.         break;
  622.     case 3:
  623.         renderer_draw_conditional(r, 4 * 12);
  624.         add_vertex_data2(r,
  625.                          pos[0], pos[1], /* src */
  626.                          pos[2], pos[3], /* mask */
  627.                          pos[4], pos[5], /* dst */
  628.                          width, height,
  629.                          sampler_view[0]->texture, sampler_view[1]->texture,
  630.                          src_matrix, mask_matrix);
  631.         break;
  632.     default:
  633.         break;
  634.     }
  635. }
  636.