Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2009 VMware, Inc.  All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sub license, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial portions
  15.  * of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  20.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  21.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  **************************************************************************/
  26.  
  27. #include "polygon.h"
  28.  
  29. #include "matrix.h" /*for floatsEqual*/
  30. #include "vg_context.h"
  31. #include "vg_state.h"
  32. #include "renderer.h"
  33. #include "util_array.h"
  34. #include "VG/openvg.h"
  35.  
  36. #include "pipe/p_context.h"
  37. #include "pipe/p_defines.h"
  38. #include "pipe/p_state.h"
  39. #include "util/u_inlines.h"
  40. #include "pipe/p_screen.h"
  41.  
  42. #include "util/u_draw_quad.h"
  43. #include "util/u_math.h"
  44.  
  45. #include <string.h>
  46. #include <stdlib.h>
  47.  
  48. #define DEBUG_POLYGON 0
  49.  
  50. #define COMPONENTS 2
  51.  
  52. struct polygon
  53. {
  54.    VGfloat *data;
  55.    VGint    size;
  56.  
  57.    VGint    num_verts;
  58.  
  59.    VGboolean dirty;
  60.    void *user_vbuf;
  61.    struct pipe_screen *screen;
  62. };
  63.  
  64. static float *ptr_to_vertex(float *data, int idx)
  65. {
  66.    return data + (idx * COMPONENTS);
  67. }
  68.  
  69. #if 0
  70. static void polygon_print(struct polygon *poly)
  71. {
  72.    int i;
  73.    float *vert;
  74.    debug_printf("Polygon %p, size = %d\n", poly, poly->num_verts);
  75.    for (i = 0; i < poly->num_verts; ++i) {
  76.       vert = ptr_to_vertex(poly->data, i);
  77.       debug_printf("%f, %f,  ", vert[0], vert[1]);
  78.    }
  79.    debug_printf("\nend\n");
  80. }
  81. #endif
  82.  
  83.  
  84. struct polygon * polygon_create(int size)
  85. {
  86.    struct polygon *poly = malloc(sizeof(struct polygon));
  87.  
  88.    poly->data = malloc(sizeof(float) * COMPONENTS * size);
  89.    poly->size = size;
  90.    poly->num_verts = 0;
  91.    poly->dirty = VG_TRUE;
  92.    poly->user_vbuf = NULL;
  93.  
  94.    return poly;
  95. }
  96.  
  97. struct polygon * polygon_create_from_data(float *data, int size)
  98. {
  99.    struct polygon *poly = polygon_create(size);
  100.  
  101.    memcpy(poly->data, data, sizeof(float) * COMPONENTS * size);
  102.    poly->num_verts = size;
  103.    poly->dirty = VG_TRUE;
  104.    poly->user_vbuf = NULL;
  105.  
  106.    return poly;
  107. }
  108.  
  109. void polygon_destroy(struct polygon *poly)
  110. {
  111.    free(poly->data);
  112.    free(poly);
  113. }
  114.  
  115. void polygon_resize(struct polygon *poly, int new_size)
  116. {
  117.    float *data = malloc(sizeof(float) * COMPONENTS * new_size);
  118.    int size = MIN2(sizeof(float) * COMPONENTS * new_size,
  119.                    sizeof(float) * COMPONENTS * poly->size);
  120.    memcpy(data, poly->data, size);
  121.    free(poly->data);
  122.    poly->data = data;
  123.    poly->size = new_size;
  124.    poly->dirty = VG_TRUE;
  125. }
  126.  
  127. int polygon_size(struct polygon *poly)
  128. {
  129.    return poly->size;
  130. }
  131.  
  132. int polygon_vertex_count(struct polygon *poly)
  133. {
  134.    return poly->num_verts;
  135. }
  136.  
  137. float * polygon_data(struct polygon *poly)
  138. {
  139.    return poly->data;
  140. }
  141.  
  142. void polygon_vertex_append(struct polygon *p,
  143.                            float x, float y)
  144. {
  145.    float *vert;
  146. #if DEBUG_POLYGON
  147.    debug_printf("Append vertex [%f, %f]\n", x, y);
  148. #endif
  149.    if (p->num_verts >= p->size) {
  150.       polygon_resize(p, p->size * 2);
  151.    }
  152.  
  153.    vert = ptr_to_vertex(p->data, p->num_verts);
  154.    vert[0] = x;
  155.    vert[1] = y;
  156.    ++p->num_verts;
  157.    p->dirty = VG_TRUE;
  158. }
  159.  
  160. void polygon_set_vertex(struct polygon *p, int idx,
  161.                         float x, float y)
  162. {
  163.    float *vert;
  164.    if (idx >= p->num_verts) {
  165.       /*fixme: error reporting*/
  166.       abort();
  167.       return;
  168.    }
  169.  
  170.    vert = ptr_to_vertex(p->data, idx);
  171.    vert[0] = x;
  172.    vert[1] = y;
  173.    p->dirty = VG_TRUE;
  174. }
  175.  
  176. void polygon_vertex(struct polygon *p, int idx,
  177.                     float *vertex)
  178. {
  179.    float *vert;
  180.    if (idx >= p->num_verts) {
  181.       /*fixme: error reporting*/
  182.       abort();
  183.       return;
  184.    }
  185.  
  186.    vert = ptr_to_vertex(p->data, idx);
  187.    vertex[0] = vert[0];
  188.    vertex[1] = vert[1];
  189. }
  190.  
  191. void polygon_bounding_rect(struct polygon *p,
  192.                            float *rect)
  193. {
  194.    int i;
  195.    float minx, miny, maxx, maxy;
  196.    float *vert = ptr_to_vertex(p->data, 0);
  197.    minx = vert[0];
  198.    maxx = vert[0];
  199.    miny = vert[1];
  200.    maxy = vert[1];
  201.  
  202.    for (i = 1; i < p->num_verts; ++i) {
  203.       vert = ptr_to_vertex(p->data, i);
  204.       minx = MIN2(vert[0], minx);
  205.       miny = MIN2(vert[1], miny);
  206.  
  207.       maxx = MAX2(vert[0], maxx);
  208.       maxy = MAX2(vert[1], maxy);
  209.    }
  210.  
  211.    rect[0] = minx;
  212.    rect[1] = miny;
  213.    rect[2] = maxx - minx;
  214.    rect[3] = maxy - miny;
  215. }
  216.  
  217. int polygon_contains_point(struct polygon *p,
  218.                            float x, float y)
  219. {
  220.    return 0;
  221. }
  222.  
  223. void polygon_append_polygon(struct polygon *dst,
  224.                             struct polygon *src)
  225. {
  226.    if (dst->num_verts + src->num_verts >= dst->size) {
  227.       polygon_resize(dst, dst->num_verts + src->num_verts * 1.5);
  228.    }
  229.    memcpy(ptr_to_vertex(dst->data, dst->num_verts),
  230.           src->data, src->num_verts * COMPONENTS * sizeof(VGfloat));
  231.    dst->num_verts += src->num_verts;
  232. }
  233.  
  234. VGboolean polygon_is_closed(struct polygon *p)
  235. {
  236.    VGfloat start[2], end[2];
  237.  
  238.    polygon_vertex(p, 0, start);
  239.    polygon_vertex(p, p->num_verts - 1, end);
  240.  
  241.    return floatsEqual(start[0], end[0]) && floatsEqual(start[1], end[1]);
  242. }
  243.  
  244. static void polygon_prepare_buffer(struct vg_context *ctx,
  245.                                    struct polygon *poly)
  246. {
  247.    struct pipe_context *pipe;
  248.  
  249.    /*polygon_print(poly);*/
  250.  
  251.    pipe = ctx->pipe;
  252.  
  253.    if (poly->user_vbuf == NULL || poly->dirty) {
  254.       poly->screen = pipe->screen;
  255.       poly->user_vbuf = poly->data;
  256.       poly->dirty = VG_FALSE;
  257.    }
  258. }
  259.  
  260. void polygon_fill(struct polygon *poly, struct vg_context *ctx)
  261. {
  262.    struct pipe_vertex_element velement;
  263.    struct pipe_vertex_buffer vbuffer;
  264.    VGfloat bounds[4];
  265.    VGfloat min_x, min_y, max_x, max_y;
  266.  
  267.    assert(poly);
  268.    polygon_bounding_rect(poly, bounds);
  269.    min_x = bounds[0];
  270.    min_y = bounds[1];
  271.    max_x = bounds[0] + bounds[2];
  272.    max_y = bounds[1] + bounds[3];
  273.  
  274. #if DEBUG_POLYGON
  275.    debug_printf("Poly bounds are [%f, %f], [%f, %f]\n",
  276.                 min_x, min_y, max_x, max_y);
  277. #endif
  278.  
  279.    polygon_prepare_buffer(ctx, poly);
  280.  
  281.    /* tell renderer about the vertex attributes */
  282.    memset(&velement, 0, sizeof(velement));
  283.    velement.src_offset = 0;
  284.    velement.instance_divisor = 0;
  285.    velement.vertex_buffer_index = 0;
  286.    velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
  287.  
  288.    /* tell renderer about the vertex buffer */
  289.    memset(&vbuffer, 0, sizeof(vbuffer));
  290.    vbuffer.user_buffer = poly->user_vbuf;
  291.    vbuffer.stride = COMPONENTS * sizeof(float);  /* vertex size */
  292.  
  293.    renderer_polygon_stencil_begin(ctx->renderer,
  294.          &velement, ctx->state.vg.fill_rule, VG_FALSE);
  295.    renderer_polygon_stencil(ctx->renderer, &vbuffer,
  296.          PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
  297.    renderer_polygon_stencil_end(ctx->renderer);
  298.  
  299.    renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
  300.    renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
  301.    renderer_polygon_fill_end(ctx->renderer);
  302. }
  303.  
  304. void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
  305. {
  306.    struct array *polys = polyarray->array;
  307.    VGfloat min_x = polyarray->min_x;
  308.    VGfloat min_y = polyarray->min_y;
  309.    VGfloat max_x = polyarray->max_x;
  310.    VGfloat max_y = polyarray->max_y;
  311.    struct pipe_vertex_element velement;
  312.    struct pipe_vertex_buffer vbuffer;
  313.    VGint i;
  314.  
  315.  
  316. #if DEBUG_POLYGON
  317.    debug_printf("%s: Poly bounds are [%f, %f], [%f, %f]\n",
  318.                 __FUNCTION__,
  319.                 min_x, min_y, max_x, max_y);
  320. #endif
  321.  
  322.    /* tell renderer about the vertex attributes */
  323.    memset(&velement, 0, sizeof(velement));
  324.    velement.src_offset = 0;
  325.    velement.instance_divisor = 0;
  326.    velement.vertex_buffer_index = 0;
  327.    velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
  328.  
  329.    /* tell renderer about the vertex buffer */
  330.    memset(&vbuffer, 0, sizeof(vbuffer));
  331.    vbuffer.stride = COMPONENTS * sizeof(float);  /* vertex size */
  332.  
  333.    /* prepare the stencil buffer */
  334.    renderer_polygon_stencil_begin(ctx->renderer,
  335.          &velement, ctx->state.vg.fill_rule, VG_FALSE);
  336.    for (i = 0; i < polys->num_elements; ++i) {
  337.       struct polygon *poly = (((struct polygon**)polys->data)[i]);
  338.  
  339.       polygon_prepare_buffer(ctx, poly);
  340.       vbuffer.user_buffer = poly->user_vbuf;
  341.  
  342.       renderer_polygon_stencil(ctx->renderer, &vbuffer,
  343.             PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
  344.    }
  345.    renderer_polygon_stencil_end(ctx->renderer);
  346.  
  347.    /* fill it */
  348.    renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
  349.    renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
  350.    renderer_polygon_fill_end(ctx->renderer);
  351. }
  352.