diff options
Diffstat (limited to 'src/glitz_geometry.c')
-rw-r--r-- | src/glitz_geometry.c | 905 |
1 files changed, 452 insertions, 453 deletions
diff --git a/src/glitz_geometry.c b/src/glitz_geometry.c index 9c16aa9..4a5cbdf 100644 --- a/src/glitz_geometry.c +++ b/src/glitz_geometry.c @@ -1,6 +1,6 @@ /* * Copyright © 2004 David Reveman - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies @@ -12,11 +12,11 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @@ -35,151 +35,151 @@ _glitz_data_type (glitz_data_type_t type) { switch (type) { case GLITZ_DATA_TYPE_SHORT: - return GLITZ_GL_SHORT; + return GLITZ_GL_SHORT; case GLITZ_DATA_TYPE_INT: - return GLITZ_GL_INT; + return GLITZ_GL_INT; case GLITZ_DATA_TYPE_DOUBLE: - return GLITZ_GL_DOUBLE; + return GLITZ_GL_DOUBLE; default: - return GLITZ_GL_FLOAT; + return GLITZ_GL_FLOAT; } } void glitz_set_geometry (glitz_surface_t *dst, - glitz_geometry_type_t type, - glitz_geometry_format_t *format, - glitz_buffer_t *buffer) + glitz_geometry_type_t type, + glitz_geometry_format_t *format, + glitz_buffer_t *buffer) { switch (type) { case GLITZ_GEOMETRY_TYPE_VERTEX: { - glitz_buffer_reference (buffer); - if (dst->geometry.buffer) - glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = buffer; - - dst->geometry.type = GLITZ_GEOMETRY_TYPE_VERTEX; - - switch (format->vertex.primitive) { - case GLITZ_PRIMITIVE_POINTS: - dst->geometry.u.v.prim = GLITZ_GL_POINTS; - break; - case GLITZ_PRIMITIVE_LINES: - dst->geometry.u.v.prim = GLITZ_GL_LINES; - break; - case GLITZ_PRIMITIVE_LINE_STRIP: - dst->geometry.u.v.prim = GLITZ_GL_LINE_STRIP; - break; - case GLITZ_PRIMITIVE_LINE_LOOP: - dst->geometry.u.v.prim = GLITZ_GL_LINE_LOOP; - break; - case GLITZ_PRIMITIVE_TRIANGLES: - dst->geometry.u.v.prim = GLITZ_GL_TRIANGLES; - break; - case GLITZ_PRIMITIVE_TRIANGLE_STRIP: - dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_STRIP; - break; - case GLITZ_PRIMITIVE_TRIANGLE_FAN: - dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_FAN; - break; - case GLITZ_PRIMITIVE_QUADS: - dst->geometry.u.v.prim = GLITZ_GL_QUADS; - break; - case GLITZ_PRIMITIVE_QUAD_STRIP: - dst->geometry.u.v.prim = GLITZ_GL_QUAD_STRIP; - break; - default: - dst->geometry.u.v.prim = GLITZ_GL_POLYGON; - break; - } - - dst->geometry.u.v.type = _glitz_data_type (format->vertex.type); - dst->geometry.stride = format->vertex.bytes_per_vertex; - dst->geometry.attributes = format->vertex.attributes; - - if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) - { - dst->geometry.u.v.src.type = - _glitz_data_type (format->vertex.src.type); - dst->geometry.u.v.src.offset = format->vertex.src.offset; - - if (format->vertex.src.size == GLITZ_COORDINATE_SIZE_XY) - dst->geometry.u.v.src.size = 2; - else - dst->geometry.u.v.src.size = 1; - } - - if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) - { - dst->geometry.u.v.mask.type = - _glitz_data_type (format->vertex.mask.type); - dst->geometry.u.v.mask.offset = format->vertex.mask.offset; - - if (format->vertex.mask.size == GLITZ_COORDINATE_SIZE_XY) - dst->geometry.u.v.mask.size = 2; - else - dst->geometry.u.v.mask.size = 1; - } + glitz_buffer_reference (buffer); + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.buffer = buffer; + + dst->geometry.type = GLITZ_GEOMETRY_TYPE_VERTEX; + + switch (format->vertex.primitive) { + case GLITZ_PRIMITIVE_POINTS: + dst->geometry.u.v.prim = GLITZ_GL_POINTS; + break; + case GLITZ_PRIMITIVE_LINES: + dst->geometry.u.v.prim = GLITZ_GL_LINES; + break; + case GLITZ_PRIMITIVE_LINE_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_LINE_STRIP; + break; + case GLITZ_PRIMITIVE_LINE_LOOP: + dst->geometry.u.v.prim = GLITZ_GL_LINE_LOOP; + break; + case GLITZ_PRIMITIVE_TRIANGLES: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLES; + break; + case GLITZ_PRIMITIVE_TRIANGLE_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_STRIP; + break; + case GLITZ_PRIMITIVE_TRIANGLE_FAN: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_FAN; + break; + case GLITZ_PRIMITIVE_QUADS: + dst->geometry.u.v.prim = GLITZ_GL_QUADS; + break; + case GLITZ_PRIMITIVE_QUAD_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_QUAD_STRIP; + break; + default: + dst->geometry.u.v.prim = GLITZ_GL_POLYGON; + break; + } + + dst->geometry.u.v.type = _glitz_data_type (format->vertex.type); + dst->geometry.stride = format->vertex.bytes_per_vertex; + dst->geometry.attributes = format->vertex.attributes; + + if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) + { + dst->geometry.u.v.src.type = + _glitz_data_type (format->vertex.src.type); + dst->geometry.u.v.src.offset = format->vertex.src.offset; + + if (format->vertex.src.size == GLITZ_COORDINATE_SIZE_XY) + dst->geometry.u.v.src.size = 2; + else + dst->geometry.u.v.src.size = 1; + } + + if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) + { + dst->geometry.u.v.mask.type = + _glitz_data_type (format->vertex.mask.type); + dst->geometry.u.v.mask.offset = format->vertex.mask.offset; + + if (format->vertex.mask.size == GLITZ_COORDINATE_SIZE_XY) + dst->geometry.u.v.mask.size = 2; + else + dst->geometry.u.v.mask.size = 1; + } } break; case GLITZ_GEOMETRY_TYPE_BITMAP: - glitz_buffer_reference (buffer); - if (dst->geometry.buffer) - glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = buffer; - - dst->geometry.type = GLITZ_GEOMETRY_TYPE_BITMAP; - - if (format->bitmap.scanline_order == - GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) - dst->geometry.u.b.top_down = 1; - else - dst->geometry.u.b.top_down = 0; - - switch (format->bitmap.pad) { - case 2: - dst->geometry.u.b.pad = 2; - break; - case 4: - dst->geometry.u.b.pad = 4; - break; - case 8: - dst->geometry.u.b.pad = 8; - break; - default: - dst->geometry.u.b.pad = 1; - break; - } - - dst->geometry.stride = format->bitmap.bytes_per_line; - dst->geometry.attributes = 0; - break; + glitz_buffer_reference (buffer); + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.buffer = buffer; + + dst->geometry.type = GLITZ_GEOMETRY_TYPE_BITMAP; + + if (format->bitmap.scanline_order == + GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) + dst->geometry.u.b.top_down = 1; + else + dst->geometry.u.b.top_down = 0; + + switch (format->bitmap.pad) { + case 2: + dst->geometry.u.b.pad = 2; + break; + case 4: + dst->geometry.u.b.pad = 4; + break; + case 8: + dst->geometry.u.b.pad = 8; + break; + default: + dst->geometry.u.b.pad = 1; + break; + } + + dst->geometry.stride = format->bitmap.bytes_per_line; + dst->geometry.attributes = 0; + break; default: - dst->geometry.type = GLITZ_GEOMETRY_TYPE_NONE; - if (dst->geometry.buffer) - glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.type = GLITZ_GEOMETRY_TYPE_NONE; + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = NULL; - dst->geometry.attributes = 0; - break; + dst->geometry.buffer = NULL; + dst->geometry.attributes = 0; + break; } } slim_hidden_def(glitz_set_geometry); void glitz_set_array (glitz_surface_t *dst, - int first, - int size, - unsigned int count, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off) + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) { if (dst->geometry.array) { - glitz_multi_array_destroy (dst->geometry.array); - dst->geometry.array = NULL; + glitz_multi_array_destroy (dst->geometry.array); + dst->geometry.array = NULL; } - + dst->geometry.first = first; dst->geometry.size = size; dst->geometry.count = count; @@ -191,33 +191,33 @@ slim_hidden_def(glitz_set_array); glitz_multi_array_t * glitz_multi_array_create (unsigned int size) { - glitz_multi_array_t *array; - int alloc_size; - - if (!size) - return NULL; - - alloc_size = sizeof (glitz_multi_array_t) + (sizeof (int) + - sizeof (int) + - sizeof (unsigned int) + - sizeof (glitz_vec2_t) + - sizeof (int)) * (size); - - array = (glitz_multi_array_t *) malloc (alloc_size); - if (array == NULL) - return NULL; - - array->ref_count = 1; - array->size = size; - array->first = (int *) (array + 1); - array->sizes = (int *) (array->first + size); - array->count = (int *) (array->sizes + size); - array->off = (glitz_vec2_t *) (array->count + size); - array->span = (int *) (array->off + size); - - array->n_arrays = 0; - - return array; + glitz_multi_array_t *array; + int alloc_size; + + if (!size) + return NULL; + + alloc_size = sizeof (glitz_multi_array_t) + (sizeof (int) + + sizeof (int) + + sizeof (unsigned int) + + sizeof (glitz_vec2_t) + + sizeof (int)) * (size); + + array = (glitz_multi_array_t *) malloc (alloc_size); + if (array == NULL) + return NULL; + + array->ref_count = 1; + array->size = size; + array->first = (int *) (array + 1); + array->sizes = (int *) (array->first + size); + array->count = (int *) (array->sizes + size); + array->off = (glitz_vec2_t *) (array->count + size); + array->span = (int *) (array->off + size); + + array->n_arrays = 0; + + return array; } slim_hidden_def(glitz_multi_array_create); @@ -225,12 +225,12 @@ void glitz_multi_array_destroy (glitz_multi_array_t *array) { if (!array) - return; - + return; + array->ref_count--; if (array->ref_count) - return; - + return; + free (array); } @@ -238,23 +238,23 @@ void glitz_multi_array_reference (glitz_multi_array_t *array) { if (array == NULL) - return; - + return; + array->ref_count++; } void glitz_multi_array_add (glitz_multi_array_t *array, - int first, - int size, - unsigned int count, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off) + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) { int i; if (array->size == array->n_arrays) - return; + return; i = array->n_arrays++; @@ -262,14 +262,14 @@ glitz_multi_array_add (glitz_multi_array_t *array, array->sizes[i] = size; array->count[i] = count; array->span[i] = 0; - + if (i == 0 || x_off || y_off) { - array->off[i].v[0] = FIXED_TO_FLOAT (x_off); - array->off[i].v[1] = FIXED_TO_FLOAT (y_off); - array->current_span = &array->span[i]; + array->off[i].v[0] = FIXED_TO_FLOAT (x_off); + array->off[i].v[1] = FIXED_TO_FLOAT (y_off); + array->current_span = &array->span[i]; } - + (*array->current_span)++; } slim_hidden_def(glitz_multi_array_add); @@ -283,14 +283,14 @@ slim_hidden_def(glitz_multi_array_reset); void glitz_set_multi_array (glitz_surface_t *dst, - glitz_multi_array_t *array, - glitz_fixed16_16_t x_off, - glitz_fixed16_16_t y_off) + glitz_multi_array_t *array, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) { glitz_multi_array_reference (array); - + if (dst->geometry.array) - glitz_multi_array_destroy (dst->geometry.array); + glitz_multi_array_destroy (dst->geometry.array); dst->geometry.array = array; dst->geometry.count = array->n_arrays; @@ -301,49 +301,49 @@ slim_hidden_def(glitz_set_multi_array); void glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *box) + glitz_surface_t *dst, + glitz_box_t *box) { - dst->geometry.data[0] = (glitz_float_t) box->x1; - dst->geometry.data[1] = (glitz_float_t) box->y1; - dst->geometry.data[2] = (glitz_float_t) box->x2; - dst->geometry.data[3] = (glitz_float_t) box->y1; - dst->geometry.data[4] = (glitz_float_t) box->x2; - dst->geometry.data[5] = (glitz_float_t) box->y2; - dst->geometry.data[6] = (glitz_float_t) box->x1; - dst->geometry.data[7] = (glitz_float_t) box->y2; - - gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, dst->geometry.data); + dst->geometry.data[0] = (glitz_float_t) box->x1; + dst->geometry.data[1] = (glitz_float_t) box->y1; + dst->geometry.data[2] = (glitz_float_t) box->x2; + dst->geometry.data[3] = (glitz_float_t) box->y1; + dst->geometry.data[4] = (glitz_float_t) box->x2; + dst->geometry.data[5] = (glitz_float_t) box->y2; + dst->geometry.data[6] = (glitz_float_t) box->x1; + dst->geometry.data[7] = (glitz_float_t) box->y2; + + gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, dst->geometry.data); } void glitz_geometry_enable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *box) + glitz_surface_t *dst, + glitz_box_t *box) { switch (dst->geometry.type) { case GLITZ_GEOMETRY_TYPE_VERTEX: - gl->vertex_pointer (2, dst->geometry.u.v.type, dst->geometry.stride, - glitz_buffer_bind (dst->geometry.buffer, - GLITZ_GL_ARRAY_BUFFER)); - break; + gl->vertex_pointer (2, dst->geometry.u.v.type, dst->geometry.stride, + glitz_buffer_bind (dst->geometry.buffer, + GLITZ_GL_ARRAY_BUFFER)); + break; case GLITZ_GEOMETRY_TYPE_BITMAP: - dst->geometry.u.b.base = - glitz_buffer_bind (dst->geometry.buffer, - GLITZ_GL_PIXEL_UNPACK_BUFFER); + dst->geometry.u.b.base = + glitz_buffer_bind (dst->geometry.buffer, + GLITZ_GL_PIXEL_UNPACK_BUFFER); - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0); - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); #if BITMAP_BIT_ORDER == MSBFirst - gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_FALSE); + gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_FALSE); #else - gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_TRUE); + gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_TRUE); #endif - - break; + + break; case GLITZ_GEOMETRY_TYPE_NONE: - glitz_geometry_enable_none (gl, dst, box); + glitz_geometry_enable_none (gl, dst, box); } } @@ -351,132 +351,130 @@ void glitz_geometry_disable (glitz_surface_t *dst) { if (dst->geometry.buffer) - glitz_buffer_unbind (dst->geometry.buffer); + glitz_buffer_unbind (dst->geometry.buffer); } static void _glitz_draw_rectangle (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) { glitz_box_t *clip = dst->clip; int n_clip = dst->n_clip; glitz_box_t box; - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - + while (n_clip--) { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds->x1 > box.x1) - box.x1 = bounds->x1; - if (bounds->y1 > box.y1) - box.y1 = bounds->y1; - if (bounds->x2 < box.x2) - box.x2 = bounds->x2; - if (bounds->y2 < box.y2) - box.y2 = bounds->y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - gl->scissor (box.x1 + dst->x, - target_height - dst->y - box.y2, - box.x2 - box.x1, box.y2 - box.y1); - - gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); - - if (damage) - glitz_surface_damage (dst, &box, damage); - } - - clip++; + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; } } -#define MULTI_DRAW_ARRAYS(surface) \ - ((surface)->drawable->backend->feature_mask & \ +#define MULTI_DRAW_ARRAYS(surface) \ + ((surface)->drawable->backend->feature_mask & \ GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) static void _glitz_draw_vertex_arrays (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) { glitz_multi_array_t *array = dst->geometry.array; glitz_box_t *clip = dst->clip; int i, n_clip = dst->n_clip; glitz_box_t box; - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - + while (n_clip--) { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds->x1 > box.x1) - box.x1 = bounds->x1; - if (bounds->y1 > box.y1) - box.y1 = bounds->y1; - if (bounds->x2 < box.x2) - box.x2 = bounds->x2; - if (bounds->y2 < box.y2) - box.y2 = bounds->y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - gl->scissor (box.x1 + dst->x, - target_height - dst->y - box.y2, - box.x2 - box.x1, box.y2 - box.y1); - - gl->push_matrix (); - - if (dst->geometry.off.v[0] || dst->geometry.off.v[1]) - gl->translate_f (dst->geometry.off.v[0], - dst->geometry.off.v[1], 0.0f); - - if (array) - { - for (i = 0; i < array->n_arrays;) - { - gl->translate_f (array->off[i].v[0], - array->off[i].v[1], 0.0f); - - if (MULTI_DRAW_ARRAYS (dst)) - { - gl->multi_draw_arrays (dst->geometry.u.v.prim, - &array->first[i], - &array->count[i], - array->span[i]); - i += array->span[i]; - } - else - { - do { - if (array->count[i]) - gl->draw_arrays (dst->geometry.u.v.prim, - array->first[i], - array->count[i]); - - } while (array->span[++i] == 0); - } - } - } else - gl->draw_arrays (dst->geometry.u.v.prim, - dst->geometry.first, - dst->geometry.count); - - gl->pop_matrix (); - - if (damage) - glitz_surface_damage (dst, &box, damage); - } - - clip++; + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + gl->push_matrix (); + + if (dst->geometry.off.v[0] || dst->geometry.off.v[1]) + gl->translate_f (dst->geometry.off.v[0], + dst->geometry.off.v[1], 0.0f); + + if (array) + { + for (i = 0; i < array->n_arrays;) + { + gl->translate_f (array->off[i].v[0], + array->off[i].v[1], 0.0f); + + if (MULTI_DRAW_ARRAYS (dst)) + { + gl->multi_draw_arrays (dst->geometry.u.v.prim, + &array->first[i], + &array->count[i], + array->span[i]); + i += array->span[i]; + } + else + { + do { + if (array->count[i]) + gl->draw_arrays (dst->geometry.u.v.prim, + array->first[i], + array->count[i]); + + } while (array->span[++i] == 0); + } + } + } else + gl->draw_arrays (dst->geometry.u.v.prim, + dst->geometry.first, + dst->geometry.count); + + gl->pop_matrix (); + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; } } @@ -486,43 +484,43 @@ _glitz_draw_vertex_arrays (glitz_gl_proc_address_list_t *gl, #define BITMAP_STRIDE(x, w, a) \ (((((x) & 3) + (w) + (((a) << 3) - 1)) / ((a) << 3)) * (a)) -#define BITMAP_SETUP(dst, first, size, count, _w, _h, _b_off, _p_off) \ - (_w) = (size); \ - (_h) = (count); \ - (_b_off) = (first) >> 3; \ - if ((_p_off) != ((first) & 3)) \ - { \ - (_p_off) = (first) & 3; \ - gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, _p_off); \ - } \ - if ((dst)->geometry.u.b.top_down) \ - { \ - dst_stride = BITMAP_STRIDE ((first), _w, BITMAP_PAD); \ - if ((dst)->geometry.stride) \ - src_stride = (dst)->geometry.stride; \ - else \ - src_stride = BITMAP_STRIDE ((first), _w, \ - (dst)->geometry.u.b.pad); \ - min_stride = MIN (src_stride, dst_stride); \ - base = (dst)->geometry.u.b.base + (_b_off); \ - y = (_h); \ - while (y--) \ - memcpy (bitmap + ((_h) - 1 - y) * dst_stride, \ - base + y * src_stride, \ - min_stride); \ - (_b_off) = 0; \ +#define BITMAP_SETUP(dst, first, size, count, _w, _h, _b_off, _p_off) \ + (_w) = (size); \ + (_h) = (count); \ + (_b_off) = (first) >> 3; \ + if ((_p_off) != ((first) & 3)) \ + { \ + (_p_off) = (first) & 3; \ + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, _p_off); \ + } \ + if ((dst)->geometry.u.b.top_down) \ + { \ + dst_stride = BITMAP_STRIDE ((first), _w, BITMAP_PAD); \ + if ((dst)->geometry.stride) \ + src_stride = (dst)->geometry.stride; \ + else \ + src_stride = BITMAP_STRIDE ((first), _w, \ + (dst)->geometry.u.b.pad); \ + min_stride = MIN (src_stride, dst_stride); \ + base = (dst)->geometry.u.b.base + (_b_off); \ + y = (_h); \ + while (y--) \ + memcpy (bitmap + ((_h) - 1 - y) * dst_stride, \ + base + y * src_stride, \ + min_stride); \ + (_b_off) = 0; \ } /* TODO: clipping could be done without glScissor, that might be faster. Other then solid colors can be used if bitmap fits into a stipple pattern. Maybe we should add a repeat parameter to glitz_bitmap_format_t as 2, 4, 8, 16 and 32 sized bitmaps can be tiled. - */ +*/ static void _glitz_draw_bitmap_arrays (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) { glitz_multi_array_t *array = dst->geometry.array; glitz_box_t *clip = dst->clip; @@ -534,148 +532,149 @@ _glitz_draw_bitmap_arrays (glitz_gl_proc_address_list_t *gl, int byte_offset, pixel_offset = 0; glitz_float_t x_off, y_off; glitz_box_t box; - int target_height = SURFACE_DRAWABLE_HEIGHT (dst); - + if (dst->geometry.u.b.top_down) { - int max_size = 0; - - if (array) - { - int size; - - for (i = 0, n = array->n_arrays; n--; i++) - { - x = array->first[i]; - w = array->sizes[i]; - size = BITMAP_STRIDE (x, w, BITMAP_PAD) * array->count[i]; - if (size > max_size) - max_size = size; - } - } - else - { - x = dst->geometry.first; - w = dst->geometry.size; - max_size = BITMAP_STRIDE (x, w, BITMAP_PAD) * dst->geometry.count; - } - - if (max_size > N_STACK_BITMAP) - { - heap_bitmap = malloc (max_size); - if (!heap_bitmap) - { - glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - bitmap = heap_bitmap; - } else - bitmap = stack_bitmap; - - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, BITMAP_PAD); - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); + int max_size = 0; + + if (array) + { + int size; + + for (i = 0, n = array->n_arrays; n--; i++) + { + x = array->first[i]; + w = array->sizes[i]; + size = BITMAP_STRIDE (x, w, BITMAP_PAD) * array->count[i]; + if (size > max_size) + max_size = size; + } + } + else + { + x = dst->geometry.first; + w = dst->geometry.size; + max_size = BITMAP_STRIDE (x, w, BITMAP_PAD) * dst->geometry.count; + } + + if (max_size > N_STACK_BITMAP) + { + heap_bitmap = malloc (max_size); + if (!heap_bitmap) + { + glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + bitmap = heap_bitmap; + } else + bitmap = stack_bitmap; + + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, BITMAP_PAD); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); } else { - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, dst->geometry.u.b.pad); - gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, - dst->geometry.stride * 8); + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, dst->geometry.u.b.pad); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, + dst->geometry.stride * 8); } - + while (n_clip--) { - box.x1 = clip->x1 + dst->x_clip; - box.y1 = clip->y1 + dst->y_clip; - box.x2 = clip->x2 + dst->x_clip; - box.y2 = clip->y2 + dst->y_clip; - if (bounds->x1 > box.x1) - box.x1 = bounds->x1; - if (bounds->y1 > box.y1) - box.y1 = bounds->y1; - if (bounds->x2 < box.x2) - box.x2 = bounds->x2; - if (bounds->y2 < box.y2) - box.y2 = bounds->y2; - - if (box.x1 < box.x2 && box.y1 < box.y2) - { - gl->scissor (box.x1 + dst->x, - target_height - dst->y - box.y2, - box.x2 - box.x1, box.y2 - box.y1); - - x_off = dst->x + dst->geometry.off.v[0]; - y_off = dst->y + dst->geometry.off.v[1]; - - if (array) - { - x_off += array->off->v[0]; - y_off += array->off->v[1]; - - glitz_set_raster_pos (gl, x_off, target_height - y_off); - - for (i = 0, n = array->n_arrays; n--; i++) - { - if (n) - { - x_off = array->off[i + 1].v[0]; - y_off = array->off[i + 1].v[1]; - } - - BITMAP_SETUP (dst, - array->first[i], - array->sizes[i], - array->count[i], - w, h, byte_offset, pixel_offset); - - gl->bitmap (w, h, - 0.0f, (glitz_gl_float_t) array->count[i], - x_off, -y_off, - bitmap + byte_offset); - } - } - else - { - glitz_set_raster_pos (gl, x_off, target_height - y_off); - - BITMAP_SETUP (dst, - dst->geometry.first, - dst->geometry.size, - dst->geometry.count, - w, h, byte_offset, pixel_offset); - - gl->bitmap (w, h, - 0.0f, (glitz_gl_float_t) dst->geometry.count, - 0.0f, 0.0f, - bitmap + byte_offset); - } - - if (damage) - glitz_surface_damage (dst, &box, damage); - } - - clip++; + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + x_off = dst->x + dst->geometry.off.v[0]; + y_off = dst->y + dst->geometry.off.v[1]; + + if (array) + { + x_off += array->off->v[0]; + y_off += array->off->v[1]; + + glitz_set_raster_pos (gl, x_off, + dst->attached->height - y_off); + + for (i = 0, n = array->n_arrays; n--; i++) + { + if (n) + { + x_off = array->off[i + 1].v[0]; + y_off = array->off[i + 1].v[1]; + } + + BITMAP_SETUP (dst, + array->first[i], + array->sizes[i], + array->count[i], + w, h, byte_offset, pixel_offset); + + gl->bitmap (w, h, + 0.0f, (glitz_gl_float_t) array->count[i], + x_off, -y_off, + bitmap + byte_offset); + } + } + else + { + glitz_set_raster_pos (gl, x_off, + dst->attached->height - y_off); + + BITMAP_SETUP (dst, + dst->geometry.first, + dst->geometry.size, + dst->geometry.count, + w, h, byte_offset, pixel_offset); + + gl->bitmap (w, h, + 0.0f, (glitz_gl_float_t) dst->geometry.count, + 0.0f, 0.0f, + bitmap + byte_offset); + } + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; } if (heap_bitmap) - free (heap_bitmap); + free (heap_bitmap); } void glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_geometry_type_t type, - glitz_box_t *bounds, - int damage) + glitz_surface_t *dst, + glitz_geometry_type_t type, + glitz_box_t *bounds, + int damage) { switch (type) { case GLITZ_GEOMETRY_TYPE_VERTEX: - _glitz_draw_vertex_arrays (gl, dst, bounds, damage); - break; + _glitz_draw_vertex_arrays (gl, dst, bounds, damage); + break; case GLITZ_GEOMETRY_TYPE_BITMAP: - _glitz_draw_bitmap_arrays (gl, dst, bounds, damage); - break; + _glitz_draw_bitmap_arrays (gl, dst, bounds, damage); + break; case GLITZ_GEOMETRY_TYPE_NONE: - _glitz_draw_rectangle (gl, dst, bounds, damage); - break; + _glitz_draw_rectangle (gl, dst, bounds, damage); + break; } } |