Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 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 
46
#include 
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
}