Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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.     cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
  83.     util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
  84.                                  num_verts,     /* verts */
  85.                                  r->attrs_per_vertex);  /* attribs/vert */
  86.     r->buffer_size = 0;
  87. }
  88.  
  89. static INLINE void
  90. renderer_draw_conditional(struct xa_context *r, int next_batch)
  91. {
  92.     if (r->buffer_size + next_batch >= XA_VB_SIZE ||
  93.         (next_batch == 0 && r->buffer_size)) {
  94.         renderer_draw(r);
  95.     }
  96. }
  97.  
  98. void
  99. renderer_init_state(struct xa_context *r)
  100. {
  101.     struct pipe_depth_stencil_alpha_state dsa;
  102.     struct pipe_rasterizer_state raster;
  103.     unsigned i;
  104.  
  105.     /* set common initial clip state */
  106.     memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
  107.     cso_set_depth_stencil_alpha(r->cso, &dsa);
  108.  
  109.     /* XXX: move to renderer_init_state? */
  110.     memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
  111.     raster.half_pixel_center = 1;
  112.     raster.bottom_edge_rule = 1;
  113.     raster.depth_clip = 1;
  114.     cso_set_rasterizer(r->cso, &raster);
  115.  
  116.     /* vertex elements state */
  117.     memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
  118.     for (i = 0; i < 3; i++) {
  119.         r->velems[i].src_offset = i * 4 * sizeof(float);
  120.         r->velems[i].instance_divisor = 0;
  121.         r->velems[i].vertex_buffer_index = 0;
  122.         r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  123.     }
  124. }
  125.  
  126. static INLINE void
  127. add_vertex_color(struct xa_context *r, float x, float y, float color[4])
  128. {
  129.     float *vertex = r->buffer + r->buffer_size;
  130.  
  131.     vertex[0] = x;
  132.     vertex[1] = y;
  133.     vertex[2] = 0.f;            /*z */
  134.     vertex[3] = 1.f;            /*w */
  135.  
  136.     vertex[4] = color[0];       /*r */
  137.     vertex[5] = color[1];       /*g */
  138.     vertex[6] = color[2];       /*b */
  139.     vertex[7] = color[3];       /*a */
  140.  
  141.     r->buffer_size += 8;
  142. }
  143.  
  144. static INLINE void
  145. add_vertex_1tex(struct xa_context *r, float x, float y, float s, float t)
  146. {
  147.     float *vertex = r->buffer + r->buffer_size;
  148.  
  149.     vertex[0] = x;
  150.     vertex[1] = y;
  151.     vertex[2] = 0.f;            /*z */
  152.     vertex[3] = 1.f;            /*w */
  153.  
  154.     vertex[4] = s;              /*s */
  155.     vertex[5] = t;              /*t */
  156.     vertex[6] = 0.f;            /*r */
  157.     vertex[7] = 1.f;            /*q */
  158.  
  159.     r->buffer_size += 8;
  160. }
  161.  
  162. static INLINE void
  163. add_vertex_2tex(struct xa_context *r,
  164.                 float x, float y, float s0, float t0, float s1, float t1)
  165. {
  166.     float *vertex = r->buffer + r->buffer_size;
  167.  
  168.     vertex[0] = x;
  169.     vertex[1] = y;
  170.     vertex[2] = 0.f;            /*z */
  171.     vertex[3] = 1.f;            /*w */
  172.  
  173.     vertex[4] = s0;             /*s */
  174.     vertex[5] = t0;             /*t */
  175.     vertex[6] = 0.f;            /*r */
  176.     vertex[7] = 1.f;            /*q */
  177.  
  178.     vertex[8] = s1;             /*s */
  179.     vertex[9] = t1;             /*t */
  180.     vertex[10] = 0.f;           /*r */
  181.     vertex[11] = 1.f;           /*q */
  182.  
  183.     r->buffer_size += 12;
  184. }
  185.  
  186. static void
  187. add_vertex_data1(struct xa_context *r,
  188.                  float srcX, float srcY,  float dstX, float dstY,
  189.                  float width, float height,
  190.                  struct pipe_resource *src, const float *src_matrix)
  191. {
  192.     float s0, t0, s1, t1, s2, t2, s3, t3;
  193.     float pt0[2], pt1[2], pt2[2], pt3[2];
  194.  
  195.     pt0[0] = srcX;
  196.     pt0[1] = srcY;
  197.     pt1[0] = (srcX + width);
  198.     pt1[1] = srcY;
  199.     pt2[0] = (srcX + width);
  200.     pt2[1] = (srcY + height);
  201.     pt3[0] = srcX;
  202.     pt3[1] = (srcY + height);
  203.  
  204.     if (src_matrix) {
  205.         map_point((float *)src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
  206.         map_point((float *)src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
  207.         map_point((float *)src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
  208.         map_point((float *)src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
  209.     }
  210.  
  211.     s0 =  pt0[0] / src->width0;
  212.     s1 =  pt1[0] / src->width0;
  213.     s2 =  pt2[0] / src->width0;
  214.     s3 =  pt3[0] / src->width0;
  215.     t0 =  pt0[1] / src->height0;
  216.     t1 =  pt1[1] / src->height0;
  217.     t2 =  pt2[1] / src->height0;
  218.     t3 =  pt3[1] / src->height0;
  219.  
  220.     /* 1st vertex */
  221.     add_vertex_1tex(r, dstX, dstY, s0, t0);
  222.     /* 2nd vertex */
  223.     add_vertex_1tex(r, dstX + width, dstY, s1, t1);
  224.     /* 3rd vertex */
  225.     add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
  226.     /* 4th vertex */
  227.     add_vertex_1tex(r, dstX, dstY + height, s3, t3);
  228. }
  229.  
  230. static void
  231. add_vertex_data2(struct xa_context *r,
  232.                  float srcX, float srcY, float maskX, float maskY,
  233.                  float dstX, float dstY, float width, float height,
  234.                  struct pipe_resource *src,
  235.                  struct pipe_resource *mask,
  236.                  const float *src_matrix, const float *mask_matrix)
  237. {
  238.     float src_s0, src_t0, src_s1, src_t1;
  239.     float mask_s0, mask_t0, mask_s1, mask_t1;
  240.     float spt0[2], spt1[2];
  241.     float mpt0[2], mpt1[2];
  242.  
  243.     spt0[0] = srcX;
  244.     spt0[1] = srcY;
  245.     spt1[0] = srcX + width;
  246.     spt1[1] = srcY + height;
  247.  
  248.     mpt0[0] = maskX;
  249.     mpt0[1] = maskY;
  250.     mpt1[0] = maskX + width;
  251.     mpt1[1] = maskY + height;
  252.  
  253.     if (src_matrix) {
  254.         map_point((float *)src_matrix, spt0[0], spt0[1], &spt0[0], &spt0[1]);
  255.         map_point((float *)src_matrix, spt1[0], spt1[1], &spt1[0], &spt1[1]);
  256.     }
  257.  
  258.     if (mask_matrix) {
  259.         map_point((float *)mask_matrix, mpt0[0], mpt0[1], &mpt0[0], &mpt0[1]);
  260.         map_point((float *)mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
  261.     }
  262.  
  263.     src_s0 = spt0[0] / src->width0;
  264.     src_t0 = spt0[1] / src->height0;
  265.     src_s1 = spt1[0] / src->width0;
  266.     src_t1 = spt1[1] / src->height0;
  267.  
  268.     mask_s0 = mpt0[0] / mask->width0;
  269.     mask_t0 = mpt0[1] / mask->height0;
  270.     mask_s1 = mpt1[0] / mask->width0;
  271.     mask_t1 = mpt1[1] / mask->height0;
  272.  
  273.     /* 1st vertex */
  274.     add_vertex_2tex(r, dstX, dstY,
  275.                     src_s0, src_t0, mask_s0, mask_t0);
  276.     /* 2nd vertex */
  277.     add_vertex_2tex(r, dstX + width, dstY,
  278.                     src_s1, src_t0, mask_s1, mask_t0);
  279.     /* 3rd vertex */
  280.     add_vertex_2tex(r, dstX + width, dstY + height,
  281.                     src_s1, src_t1, mask_s1, mask_t1);
  282.     /* 4th vertex */
  283.     add_vertex_2tex(r, dstX, dstY + height,
  284.                     src_s0, src_t1, mask_s0, mask_t1);
  285. }
  286.  
  287. static void
  288. setup_vertex_data_yuv(struct xa_context *r,
  289.                       float srcX,
  290.                       float srcY,
  291.                       float srcW,
  292.                       float srcH,
  293.                       float dstX,
  294.                       float dstY,
  295.                       float dstW, float dstH, struct xa_surface *srf[])
  296. {
  297.     float s0, t0, s1, t1;
  298.     float spt0[2], spt1[2];
  299.     struct pipe_resource *tex;
  300.  
  301.     spt0[0] = srcX;
  302.     spt0[1] = srcY;
  303.     spt1[0] = srcX + srcW;
  304.     spt1[1] = srcY + srcH;
  305.  
  306.     tex = srf[0]->tex;
  307.     s0 = spt0[0] / tex->width0;
  308.     t0 = spt0[1] / tex->height0;
  309.     s1 = spt1[0] / tex->width0;
  310.     t1 = spt1[1] / tex->height0;
  311.  
  312.     /* 1st vertex */
  313.     add_vertex_1tex(r, dstX, dstY, s0, t0);
  314.     /* 2nd vertex */
  315.     add_vertex_1tex(r, dstX + dstW, dstY, s1, t0);
  316.     /* 3rd vertex */
  317.     add_vertex_1tex(r, dstX + dstW, dstY + dstH, s1, t1);
  318.     /* 4th vertex */
  319.     add_vertex_1tex(r, dstX, dstY + dstH, s0, t1);
  320. }
  321.  
  322. /* Set up framebuffer, viewport and vertex shader constant buffer
  323.  * state for a particular destinaton surface.  In all our rendering,
  324.  * these concepts are linked.
  325.  */
  326. void
  327. renderer_bind_destination(struct xa_context *r,
  328.                           struct pipe_surface *surface, int width, int height)
  329. {
  330.  
  331.     struct pipe_framebuffer_state fb;
  332.     struct pipe_viewport_state viewport;
  333.  
  334.     /* Framebuffer uses actual surface width/height
  335.      */
  336.     memset(&fb, 0, sizeof fb);
  337.     fb.width = surface->width;
  338.     fb.height = surface->height;
  339.     fb.nr_cbufs = 1;
  340.     fb.cbufs[0] = surface;
  341.     fb.zsbuf = 0;
  342.  
  343.     /* Viewport just touches the bit we're interested in:
  344.      */
  345.     viewport.scale[0] = width / 2.f;
  346.     viewport.scale[1] = height / 2.f;
  347.     viewport.scale[2] = 1.0;
  348.     viewport.scale[3] = 1.0;
  349.     viewport.translate[0] = width / 2.f;
  350.     viewport.translate[1] = height / 2.f;
  351.     viewport.translate[2] = 0.0;
  352.     viewport.translate[3] = 0.0;
  353.  
  354.     /* Constant buffer set up to match viewport dimensions:
  355.      */
  356.     if (r->fb_width != width || r->fb_height != height) {
  357.         float vs_consts[8] = {
  358.             2.f / width, 2.f / height, 1, 1,
  359.             -1, -1, 0, 0
  360.         };
  361.  
  362.         r->fb_width = width;
  363.         r->fb_height = height;
  364.  
  365.         renderer_set_constants(r, PIPE_SHADER_VERTEX,
  366.                                vs_consts, sizeof vs_consts);
  367.     }
  368.  
  369.     cso_set_framebuffer(r->cso, &fb);
  370.     cso_set_viewport(r->cso, &viewport);
  371. }
  372.  
  373. void
  374. renderer_set_constants(struct xa_context *r,
  375.                        int shader_type, const float *params, int param_bytes)
  376. {
  377.     struct pipe_resource **cbuf =
  378.         (shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer :
  379.         &r->fs_const_buffer;
  380.  
  381.     pipe_resource_reference(cbuf, NULL);
  382.     *cbuf = pipe_buffer_create(r->pipe->screen,
  383.                                PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC,
  384.                                param_bytes);
  385.  
  386.     if (*cbuf) {
  387.         pipe_buffer_write(r->pipe, *cbuf, 0, param_bytes, params);
  388.     }
  389.     pipe_set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
  390. }
  391.  
  392. void
  393. renderer_copy_prepare(struct xa_context *r,
  394.                       struct pipe_surface *dst_surface,
  395.                       struct pipe_resource *src_texture,
  396.                       const enum xa_formats src_xa_format,
  397.                       const enum xa_formats dst_xa_format)
  398. {
  399.     struct pipe_context *pipe = r->pipe;
  400.     struct pipe_screen *screen = pipe->screen;
  401.     struct xa_shader shader;
  402.     uint32_t fs_traits = FS_COMPOSITE;
  403.  
  404.     assert(screen->is_format_supported(screen, dst_surface->format,
  405.                                        PIPE_TEXTURE_2D, 0,
  406.                                        PIPE_BIND_RENDER_TARGET));
  407.     (void)screen;
  408.  
  409.     /* set misc state we care about */
  410.     {
  411.         struct pipe_blend_state blend;
  412.  
  413.         memset(&blend, 0, sizeof(blend));
  414.         blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
  415.         blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  416.         blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
  417.         blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  418.         blend.rt[0].colormask = PIPE_MASK_RGBA;
  419.         cso_set_blend(r->cso, &blend);
  420.     }
  421.  
  422.     /* sampler */
  423.     {
  424.         struct pipe_sampler_state sampler;
  425.  
  426.         memset(&sampler, 0, sizeof(sampler));
  427.         sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  428.         sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  429.         sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  430.         sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
  431.         sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
  432.         sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
  433.         sampler.normalized_coords = 1;
  434.         cso_single_sampler(r->cso, PIPE_SHADER_FRAGMENT, 0, &sampler);
  435.         cso_single_sampler_done(r->cso, PIPE_SHADER_FRAGMENT);
  436.     }
  437.  
  438.     renderer_bind_destination(r, dst_surface,
  439.                               dst_surface->width, dst_surface->height);
  440.  
  441.     /* texture/sampler view */
  442.     {
  443.         struct pipe_sampler_view templ;
  444.         struct pipe_sampler_view *src_view;
  445.  
  446.         u_sampler_view_default_template(&templ,
  447.                                         src_texture, src_texture->format);
  448.         src_view = pipe->create_sampler_view(pipe, src_texture, &templ);
  449.         cso_set_sampler_views(r->cso, PIPE_SHADER_FRAGMENT, 1, &src_view);
  450.         pipe_sampler_view_reference(&src_view, NULL);
  451.     }
  452.  
  453.     /* shaders */
  454.     if (src_texture->format == PIPE_FORMAT_L8_UNORM)
  455.         fs_traits |= FS_SRC_LUMINANCE;
  456.     if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
  457.         fs_traits |= FS_DST_LUMINANCE;
  458.     if (xa_format_a(dst_xa_format) != 0 &&
  459.         xa_format_a(src_xa_format) == 0)
  460.         fs_traits |= FS_SRC_SET_ALPHA;
  461.  
  462.     shader = xa_shaders_get(r->shaders, VS_COMPOSITE, fs_traits);
  463.     cso_set_vertex_shader_handle(r->cso, shader.vs);
  464.     cso_set_fragment_shader_handle(r->cso, shader.fs);
  465.  
  466.     r->buffer_size = 0;
  467.     r->attrs_per_vertex = 2;
  468. }
  469.  
  470. void
  471. renderer_copy(struct xa_context *r,
  472.               int dx,
  473.               int dy,
  474.               int sx,
  475.               int sy,
  476.               int width, int height, float src_width, float src_height)
  477. {
  478.     float s0, t0, s1, t1;
  479.     float x0, y0, x1, y1;
  480.  
  481.     /* XXX: could put the texcoord scaling calculation into the vertex
  482.      * shader.
  483.      */
  484.     s0 = sx / src_width;
  485.     s1 = (sx + width) / src_width;
  486.     t0 = sy / src_height;
  487.     t1 = (sy + height) / src_height;
  488.  
  489.     x0 = dx;
  490.     x1 = dx + width;
  491.     y0 = dy;
  492.     y1 = dy + height;
  493.  
  494.     /* draw quad */
  495.     renderer_draw_conditional(r, 4 * 8);
  496.     add_vertex_1tex(r, x0, y0, s0, t0);
  497.     add_vertex_1tex(r, x1, y0, s1, t0);
  498.     add_vertex_1tex(r, x1, y1, s1, t1);
  499.     add_vertex_1tex(r, x0, y1, s0, t1);
  500. }
  501.  
  502. void
  503. renderer_draw_yuv(struct xa_context *r,
  504.                   float src_x,
  505.                   float src_y,
  506.                   float src_w,
  507.                   float src_h,
  508.                   int dst_x,
  509.                   int dst_y, int dst_w, int dst_h, struct xa_surface *srf[])
  510. {
  511.    const int num_attribs = 2;   /*pos + tex coord */
  512.  
  513.    setup_vertex_data_yuv(r,
  514.                          src_x, src_y, src_w, src_h,
  515.                          dst_x, dst_y, dst_w, dst_h, srf);
  516.  
  517.    cso_set_vertex_elements(r->cso, num_attribs, r->velems);
  518.    util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
  519.                                 4,      /* verts */
  520.                                 num_attribs);   /* attribs/vert */
  521.    r->buffer_size = 0;
  522. }
  523.  
  524. void
  525. renderer_begin_solid(struct xa_context *r)
  526. {
  527.     r->buffer_size = 0;
  528.     r->attrs_per_vertex = 2;
  529. }
  530.  
  531. void
  532. renderer_solid(struct xa_context *r,
  533.                int x0, int y0, int x1, int y1, float *color)
  534. {
  535.     /*
  536.      * debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
  537.      * x0, y0, x1, y1, color[0], color[1], color[2], color[3]); */
  538.  
  539.     renderer_draw_conditional(r, 4 * 8);
  540.  
  541.     /* 1st vertex */
  542.     add_vertex_color(r, x0, y0, color);
  543.     /* 2nd vertex */
  544.     add_vertex_color(r, x1, y0, color);
  545.     /* 3rd vertex */
  546.     add_vertex_color(r, x1, y1, color);
  547.     /* 4th vertex */
  548.     add_vertex_color(r, x0, y1, color);
  549. }
  550.  
  551. void
  552. renderer_draw_flush(struct xa_context *r)
  553. {
  554.     renderer_draw_conditional(r, 0);
  555. }
  556.  
  557. void
  558. renderer_begin_textures(struct xa_context *r)
  559. {
  560.     r->attrs_per_vertex = 1 + r->num_bound_samplers;
  561.     r->buffer_size = 0;
  562. }
  563.  
  564. void
  565. renderer_texture(struct xa_context *r,
  566.                  int *pos,
  567.                  int width, int height,
  568.                  const float *src_matrix,
  569.                  const float *mask_matrix)
  570. {
  571.     struct pipe_sampler_view **sampler_view = r->bound_sampler_views;
  572.  
  573. #if 0
  574.     if (src_matrix) {
  575.         debug_printf("src_matrix = \n");
  576.         debug_printf("%f, %f, %f\n", src_matrix[0], src_matrix[1], src_matrix[2]);
  577.         debug_printf("%f, %f, %f\n", src_matrix[3], src_matrix[4], src_matrix[5]);
  578.         debug_printf("%f, %f, %f\n", src_matrix[6], src_matrix[7], src_matrix[8]);
  579.     }
  580.     if (mask_matrix) {
  581.         debug_printf("mask_matrix = \n");
  582.         debug_printf("%f, %f, %f\n", mask_matrix[0], mask_matrix[1], mask_matrix[2]);
  583.         debug_printf("%f, %f, %f\n", mask_matrix[3], mask_matrix[4], mask_matrix[5]);
  584.         debug_printf("%f, %f, %f\n", mask_matrix[6], mask_matrix[7], mask_matrix[8]);
  585.     }
  586. #endif
  587.  
  588.     switch(r->attrs_per_vertex) {
  589.     case 2:
  590.         renderer_draw_conditional(r, 4 * 8);
  591.         add_vertex_data1(r,
  592.                          pos[0], pos[1], /* src */
  593.                          pos[4], pos[5], /* dst */
  594.                          width, height,
  595.                          sampler_view[0]->texture, src_matrix);
  596.         break;
  597.     case 3:
  598.         renderer_draw_conditional(r, 4 * 12);
  599.         add_vertex_data2(r,
  600.                          pos[0], pos[1], /* src */
  601.                          pos[2], pos[3], /* mask */
  602.                          pos[4], pos[5], /* dst */
  603.                          width, height,
  604.                          sampler_view[0]->texture, sampler_view[1]->texture,
  605.                          src_matrix, mask_matrix);
  606.         break;
  607.     default:
  608.         break;
  609.     }
  610. }
  611.