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
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 **************************************************************************/
29 #include "matrix.h" /*for floatsEqual*/
30 #include "vg_context.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"
48 #define DEBUG_POLYGON 0
61 struct pipe_screen
*screen
;
64 static float *ptr_to_vertex(float *data
, int idx
)
66 return data
+ (idx
* COMPONENTS
);
70 static void polygon_print(struct polygon
*poly
)
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");
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
);
91 poly
->dirty
= VG_TRUE
;
92 poly
->user_vbuf
= NULL
;
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
->user_vbuf
= NULL
;
109 void polygon_destroy(struct polygon
*poly
)
115 void polygon_resize(struct polygon
*poly
, int new_size
)
117 float *data
= (float*)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
);
123 poly
->size
= new_size
;
124 poly
->dirty
= VG_TRUE
;
127 int polygon_size(struct polygon
*poly
)
132 int polygon_vertex_count(struct polygon
*poly
)
134 return poly
->num_verts
;
137 float * polygon_data(struct polygon
*poly
)
142 void polygon_vertex_append(struct polygon
*p
,
147 debug_printf("Append vertex [%f, %f]\n", x
, y
);
149 if (p
->num_verts
>= p
->size
) {
150 polygon_resize(p
, p
->size
* 2);
153 vert
= ptr_to_vertex(p
->data
, p
->num_verts
);
160 void polygon_set_vertex(struct polygon
*p
, int idx
,
164 if (idx
>= p
->num_verts
) {
165 /*fixme: error reporting*/
170 vert
= ptr_to_vertex(p
->data
, idx
);
176 void polygon_vertex(struct polygon
*p
, int idx
,
180 if (idx
>= p
->num_verts
) {
181 /*fixme: error reporting*/
186 vert
= ptr_to_vertex(p
->data
, idx
);
191 void polygon_bounding_rect(struct polygon
*p
,
195 float minx
, miny
, maxx
, maxy
;
196 float *vert
= ptr_to_vertex(p
->data
, 0);
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
);
207 maxx
= MAX2(vert
[0], maxx
);
208 maxy
= MAX2(vert
[1], maxy
);
213 rect
[2] = maxx
- minx
;
214 rect
[3] = maxy
- miny
;
217 int polygon_contains_point(struct polygon
*p
,
223 void polygon_append_polygon(struct polygon
*dst
,
226 if (dst
->num_verts
+ src
->num_verts
>= dst
->size
) {
227 polygon_resize(dst
, dst
->num_verts
+ src
->num_verts
* 1.5);
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
;
234 VGboolean
polygon_is_closed(struct polygon
*p
)
236 VGfloat start
[2], end
[2];
238 polygon_vertex(p
, 0, start
);
239 polygon_vertex(p
, p
->num_verts
- 1, end
);
241 return floatsEqual(start
[0], end
[0]) && floatsEqual(start
[1], end
[1]);
244 static void polygon_prepare_buffer(struct vg_context
*ctx
,
245 struct polygon
*poly
)
247 struct pipe_context
*pipe
;
249 /*polygon_print(poly);*/
253 if (poly
->user_vbuf
== NULL
|| poly
->dirty
) {
254 poly
->screen
= pipe
->screen
;
255 poly
->user_vbuf
= poly
->data
;
256 poly
->dirty
= VG_FALSE
;
260 void polygon_fill(struct polygon
*poly
, struct vg_context
*ctx
)
262 struct pipe_vertex_element velement
;
263 struct pipe_vertex_buffer vbuffer
;
265 VGfloat min_x
, min_y
, max_x
, max_y
;
268 polygon_bounding_rect(poly
, bounds
);
271 max_x
= bounds
[0] + bounds
[2];
272 max_y
= bounds
[1] + bounds
[3];
275 debug_printf("Poly bounds are [%f, %f], [%f, %f]\n",
276 min_x
, min_y
, max_x
, max_y
);
279 polygon_prepare_buffer(ctx
, poly
);
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
;
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 */
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
);
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
);
304 void polygon_array_fill(struct polygon_array
*polyarray
, struct vg_context
*ctx
)
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
;
317 debug_printf("%s: Poly bounds are [%f, %f], [%f, %f]\n",
319 min_x
, min_y
, max_x
, max_y
);
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
;
329 /* tell renderer about the vertex buffer */
330 memset(&vbuffer
, 0, sizeof(vbuffer
));
331 vbuffer
.stride
= COMPONENTS
* sizeof(float); /* vertex size */
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
]);
339 polygon_prepare_buffer(ctx
, poly
);
340 vbuffer
.user_buffer
= poly
->user_vbuf
;
342 renderer_polygon_stencil(ctx
->renderer
, &vbuffer
,
343 PIPE_PRIM_TRIANGLE_FAN
, 0, (VGuint
) poly
->num_verts
);
345 renderer_polygon_stencil_end(ctx
->renderer
);
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
);