revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / mesa / src / gallium / state_trackers / vega / polygon.c
blobbcc5cb272ca45d93fb2d19c03ee1adce898906ef
1 /**************************************************************************
3 * Copyright 2009 VMware, Inc. All Rights Reserved.
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:
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.
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.
25 **************************************************************************/
27 #include "polygon.h"
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"
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"
42 #include "util/u_draw_quad.h"
43 #include "util/u_math.h"
45 #include <string.h>
46 #include <stdlib.h>
48 #define DEBUG_POLYGON 0
50 #define COMPONENTS 2
52 struct polygon
54 VGfloat *data;
55 VGint size;
57 VGint num_verts;
59 VGboolean dirty;
60 struct pipe_resource *vbuf;
61 struct pipe_screen *screen;
64 static float *ptr_to_vertex(float *data, int idx)
66 return data + (idx * COMPONENTS);
69 #if 0
70 static void polygon_print(struct polygon *poly)
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]);
79 debug_printf("\nend\n");
81 #endif
84 struct polygon * polygon_create(int size)
86 struct polygon *poly = (struct polygon*)malloc(sizeof(struct polygon));
88 poly->data = malloc(sizeof(float) * COMPONENTS * size);
89 poly->size = size;
90 poly->num_verts = 0;
91 poly->dirty = VG_TRUE;
92 poly->vbuf = NULL;
94 return poly;
97 struct polygon * polygon_create_from_data(float *data, int size)
99 struct polygon *poly = polygon_create(size);
101 memcpy(poly->data, data, sizeof(float) * COMPONENTS * size);
102 poly->num_verts = size;
103 poly->dirty = VG_TRUE;
104 poly->vbuf = NULL;
106 return poly;
109 void polygon_destroy(struct polygon *poly)
111 if (poly->vbuf)
112 pipe_resource_reference(&poly->vbuf, NULL);
114 free(poly->data);
115 free(poly);
118 void polygon_resize(struct polygon *poly, int new_size)
120 float *data = (float*)malloc(sizeof(float) * COMPONENTS * new_size);
121 int size = MIN2(sizeof(float) * COMPONENTS * new_size,
122 sizeof(float) * COMPONENTS * poly->size);
123 memcpy(data, poly->data, size);
124 free(poly->data);
125 poly->data = data;
126 poly->size = new_size;
127 poly->dirty = VG_TRUE;
130 int polygon_size(struct polygon *poly)
132 return poly->size;
135 int polygon_vertex_count(struct polygon *poly)
137 return poly->num_verts;
140 float * polygon_data(struct polygon *poly)
142 return poly->data;
145 void polygon_vertex_append(struct polygon *p,
146 float x, float y)
148 float *vert;
149 #if DEBUG_POLYGON
150 debug_printf("Append vertex [%f, %f]\n", x, y);
151 #endif
152 if (p->num_verts >= p->size) {
153 polygon_resize(p, p->size * 2);
156 vert = ptr_to_vertex(p->data, p->num_verts);
157 vert[0] = x;
158 vert[1] = y;
159 ++p->num_verts;
160 p->dirty = VG_TRUE;
163 void polygon_set_vertex(struct polygon *p, int idx,
164 float x, float y)
166 float *vert;
167 if (idx >= p->num_verts) {
168 /*fixme: error reporting*/
169 abort();
170 return;
173 vert = ptr_to_vertex(p->data, idx);
174 vert[0] = x;
175 vert[1] = y;
176 p->dirty = VG_TRUE;
179 void polygon_vertex(struct polygon *p, int idx,
180 float *vertex)
182 float *vert;
183 if (idx >= p->num_verts) {
184 /*fixme: error reporting*/
185 abort();
186 return;
189 vert = ptr_to_vertex(p->data, idx);
190 vertex[0] = vert[0];
191 vertex[1] = vert[1];
194 void polygon_bounding_rect(struct polygon *p,
195 float *rect)
197 int i;
198 float minx, miny, maxx, maxy;
199 float *vert = ptr_to_vertex(p->data, 0);
200 minx = vert[0];
201 maxx = vert[0];
202 miny = vert[1];
203 maxy = vert[1];
205 for (i = 1; i < p->num_verts; ++i) {
206 vert = ptr_to_vertex(p->data, i);
207 minx = MIN2(vert[0], minx);
208 miny = MIN2(vert[1], miny);
210 maxx = MAX2(vert[0], maxx);
211 maxy = MAX2(vert[1], maxy);
214 rect[0] = minx;
215 rect[1] = miny;
216 rect[2] = maxx - minx;
217 rect[3] = maxy - miny;
220 int polygon_contains_point(struct polygon *p,
221 float x, float y)
223 return 0;
226 void polygon_append_polygon(struct polygon *dst,
227 struct polygon *src)
229 if (dst->num_verts + src->num_verts >= dst->size) {
230 polygon_resize(dst, dst->num_verts + src->num_verts * 1.5);
232 memcpy(ptr_to_vertex(dst->data, dst->num_verts),
233 src->data, src->num_verts * COMPONENTS * sizeof(VGfloat));
234 dst->num_verts += src->num_verts;
237 VGboolean polygon_is_closed(struct polygon *p)
239 VGfloat start[2], end[2];
241 polygon_vertex(p, 0, start);
242 polygon_vertex(p, p->num_verts - 1, end);
244 return floatsEqual(start[0], end[0]) && floatsEqual(start[1], end[1]);
247 static void polygon_prepare_buffer(struct vg_context *ctx,
248 struct polygon *poly)
250 int vert_size;
251 struct pipe_context *pipe;
253 vert_size = poly->num_verts * COMPONENTS * sizeof(float);
255 /*polygon_print(poly);*/
257 pipe = ctx->pipe;
259 if (poly->vbuf == NULL || poly->dirty) {
260 if (poly->vbuf) {
261 pipe_resource_reference(&poly->vbuf,
262 NULL);
264 poly->screen = pipe->screen;
265 poly->vbuf= pipe_user_buffer_create(poly->screen,
266 poly->data,
267 vert_size,
268 PIPE_BIND_VERTEX_BUFFER);
269 poly->dirty = VG_FALSE;
273 void polygon_fill(struct polygon *poly, struct vg_context *ctx)
275 struct pipe_vertex_element velement;
276 struct pipe_vertex_buffer vbuffer;
277 VGfloat bounds[4];
278 VGfloat min_x, min_y, max_x, max_y;
280 assert(poly);
281 polygon_bounding_rect(poly, bounds);
282 min_x = bounds[0];
283 min_y = bounds[1];
284 max_x = bounds[0] + bounds[2];
285 max_y = bounds[1] + bounds[3];
287 #if DEBUG_POLYGON
288 debug_printf("Poly bounds are [%f, %f], [%f, %f]\n",
289 min_x, min_y, max_x, max_y);
290 #endif
292 polygon_prepare_buffer(ctx, poly);
294 /* tell renderer about the vertex attributes */
295 memset(&velement, 0, sizeof(velement));
296 velement.src_offset = 0;
297 velement.instance_divisor = 0;
298 velement.vertex_buffer_index = 0;
299 velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
301 /* tell renderer about the vertex buffer */
302 memset(&vbuffer, 0, sizeof(vbuffer));
303 vbuffer.buffer = poly->vbuf;
304 vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
305 vbuffer.buffer_offset = 0;
307 renderer_polygon_stencil_begin(ctx->renderer,
308 &velement, ctx->state.vg.fill_rule, VG_FALSE);
309 renderer_polygon_stencil(ctx->renderer, &vbuffer,
310 PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
311 renderer_polygon_stencil_end(ctx->renderer);
313 renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
314 renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
315 renderer_polygon_fill_end(ctx->renderer);
318 void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
320 struct array *polys = polyarray->array;
321 VGfloat min_x = polyarray->min_x;
322 VGfloat min_y = polyarray->min_y;
323 VGfloat max_x = polyarray->max_x;
324 VGfloat max_y = polyarray->max_y;
325 struct pipe_vertex_element velement;
326 struct pipe_vertex_buffer vbuffer;
327 VGint i;
330 #if DEBUG_POLYGON
331 debug_printf("%s: Poly bounds are [%f, %f], [%f, %f]\n",
332 __FUNCTION__,
333 min_x, min_y, max_x, max_y);
334 #endif
336 /* tell renderer about the vertex attributes */
337 memset(&velement, 0, sizeof(velement));
338 velement.src_offset = 0;
339 velement.instance_divisor = 0;
340 velement.vertex_buffer_index = 0;
341 velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
343 /* tell renderer about the vertex buffer */
344 memset(&vbuffer, 0, sizeof(vbuffer));
345 vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
346 vbuffer.buffer_offset = 0;
348 /* prepare the stencil buffer */
349 renderer_polygon_stencil_begin(ctx->renderer,
350 &velement, ctx->state.vg.fill_rule, VG_FALSE);
351 for (i = 0; i < polys->num_elements; ++i) {
352 struct polygon *poly = (((struct polygon**)polys->data)[i]);
354 polygon_prepare_buffer(ctx, poly);
355 vbuffer.buffer = poly->vbuf;
357 renderer_polygon_stencil(ctx->renderer, &vbuffer,
358 PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
360 renderer_polygon_stencil_end(ctx->renderer);
362 /* fill it */
363 renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
364 renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
365 renderer_polygon_fill_end(ctx->renderer);