diff options
Diffstat (limited to 'src/gallium/state_trackers/vega/image.c')
-rw-r--r-- | src/gallium/state_trackers/vega/image.c | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c deleted file mode 100644 index 4434550c629..00000000000 --- a/src/gallium/state_trackers/vega/image.c +++ /dev/null @@ -1,653 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "image.h" - -#include "vg_translate.h" -#include "vg_context.h" -#include "matrix.h" -#include "renderer.h" -#include "util_array.h" -#include "api_consts.h" -#include "shader.h" - -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_tile.h" -#include "util/u_memory.h" -#include "util/u_math.h" -#include "util/u_sampler.h" -#include "util/u_surface.h" - -static enum pipe_format vg_format_to_pipe(VGImageFormat format) -{ - switch(format) { - case VG_sRGB_565: - return PIPE_FORMAT_B5G6R5_UNORM; - case VG_sRGBA_5551: - return PIPE_FORMAT_B5G5R5A1_UNORM; - case VG_sRGBA_4444: - return PIPE_FORMAT_B4G4R4A4_UNORM; - case VG_sL_8: - case VG_lL_8: - return PIPE_FORMAT_L8_UNORM; - case VG_BW_1: - return PIPE_FORMAT_B8G8R8A8_UNORM; - case VG_A_8: - return PIPE_FORMAT_A8_UNORM; -#ifdef OPENVG_VERSION_1_1 - case VG_A_1: - case VG_A_4: - return PIPE_FORMAT_A8_UNORM; -#endif - default: - return PIPE_FORMAT_B8G8R8A8_UNORM; - } -} - -static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc) -{ - src_loc[2] = MIN2(src_loc[2], dst_loc[2]); - src_loc[3] = MIN2(src_loc[3], dst_loc[3]); - dst_loc[2] = src_loc[2]; - dst_loc[3] = src_loc[3]; -} - -static void vg_get_copy_coords(VGfloat *src_loc, - VGfloat src_width, VGfloat src_height, - VGfloat *dst_loc, - VGfloat dst_width, VGfloat dst_height) -{ - VGfloat dst_bounds[4], src_bounds[4]; - VGfloat src_shift[4], dst_shift[4], shift[4]; - - dst_bounds[0] = 0.f; - dst_bounds[1] = 0.f; - dst_bounds[2] = dst_width; - dst_bounds[3] = dst_height; - - src_bounds[0] = 0.f; - src_bounds[1] = 0.f; - src_bounds[2] = src_width; - src_bounds[3] = src_height; - - vg_bound_rect(src_loc, src_bounds, src_shift); - vg_bound_rect(dst_loc, dst_bounds, dst_shift); - shift[0] = src_shift[0] - dst_shift[0]; - shift[1] = src_shift[1] - dst_shift[1]; - - if (shift[0] < 0) - vg_shift_rectx(src_loc, src_bounds, -shift[0]); - else - vg_shift_rectx(dst_loc, dst_bounds, shift[0]); - - if (shift[1] < 0) - vg_shift_recty(src_loc, src_bounds, -shift[1]); - else - vg_shift_recty(dst_loc, dst_bounds, shift[1]); - - vg_sync_size(src_loc, dst_loc); -} - -static void vg_copy_texture(struct vg_context *ctx, - struct pipe_resource *dst, VGint dx, VGint dy, - struct pipe_sampler_view *src, VGint sx, VGint sy, - VGint width, VGint height) -{ - VGfloat dst_loc[4], src_loc[4]; - - dst_loc[0] = dx; - dst_loc[1] = dy; - dst_loc[2] = width; - dst_loc[3] = height; - - src_loc[0] = sx; - src_loc[1] = sy; - src_loc[2] = width; - src_loc[3] = height; - - vg_get_copy_coords(src_loc, src->texture->width0, src->texture->height0, - dst_loc, dst->width0, dst->height0); - - if (src_loc[2] >= 0 && src_loc[3] >= 0 && - dst_loc[2] >= 0 && dst_loc[3] >= 0) { - struct pipe_surface *surf, surf_tmpl; - - /* get the destination surface */ - u_surface_default_template(&surf_tmpl, dst); - surf = ctx->pipe->create_surface(ctx->pipe, dst, &surf_tmpl); - if (surf && renderer_copy_begin(ctx->renderer, surf, VG_TRUE, src)) { - renderer_copy(ctx->renderer, - dst_loc[0], dst_loc[1], dst_loc[2], dst_loc[3], - src_loc[0], src_loc[1], src_loc[2], src_loc[3]); - renderer_copy_end(ctx->renderer); - } - - pipe_surface_reference(&surf, NULL); - } -} - -void vg_copy_surface(struct vg_context *ctx, - struct pipe_surface *dst, VGint dx, VGint dy, - struct pipe_surface *src, VGint sx, VGint sy, - VGint width, VGint height) -{ - VGfloat dst_loc[4], src_loc[4]; - - dst_loc[0] = dx; - dst_loc[1] = dy; - dst_loc[2] = width; - dst_loc[3] = height; - - src_loc[0] = sx; - src_loc[1] = sy; - src_loc[2] = width; - src_loc[3] = height; - - vg_get_copy_coords(src_loc, src->width, src->height, - dst_loc, dst->width, dst->height); - - if (src_loc[2] > 0 && src_loc[3] > 0 && - dst_loc[2] > 0 && dst_loc[3] > 0) { - if (src == dst) - renderer_copy_surface(ctx->renderer, - src, - src_loc[0], - src->height - (src_loc[1] + src_loc[3]), - src_loc[0] + src_loc[2], - src->height - src_loc[1], - dst, - dst_loc[0], - dst->height - (dst_loc[1] + dst_loc[3]), - dst_loc[0] + dst_loc[2], - dst->height - dst_loc[1], - 0, 0); - else - renderer_copy_surface(ctx->renderer, - src, - src_loc[0], - src->height - src_loc[1], - src_loc[0] + src_loc[2], - src->height - (src_loc[1] + src_loc[3]), - dst, - dst_loc[0], - dst->height - (dst_loc[1] + dst_loc[3]), - dst_loc[0] + dst_loc[2], - dst->height - dst_loc[1], - 0, 0); - } - -} - -static struct pipe_resource *image_texture(struct vg_image *img) -{ - struct pipe_resource *tex = img->sampler_view->texture; - return tex; -} - - -static void image_cleari(struct vg_image *img, VGint clear_colori, - VGint x, VGint y, VGint width, VGint height) -{ - VGint *clearbuf; - VGint i; - VGfloat dwidth, dheight; - - clearbuf = malloc(sizeof(VGint)*width*height); - for (i = 0; i < width*height; ++i) - clearbuf[i] = clear_colori; - - dwidth = MIN2(width, img->width); - dheight = MIN2(height, img->height); - - image_sub_data(img, clearbuf, width * sizeof(VGint), - VG_sRGBA_8888, - x, y, dwidth, dheight); - free(clearbuf); -} - -struct vg_image * image_create(VGImageFormat format, - VGint width, VGint height) -{ - struct vg_context *ctx = vg_current_context(); - struct pipe_context *pipe = ctx->pipe; - struct vg_image *image = CALLOC_STRUCT(vg_image); - enum pipe_format pformat = vg_format_to_pipe(format); - struct pipe_resource pt, *newtex; - struct pipe_sampler_view view_templ; - struct pipe_sampler_view *view; - struct pipe_screen *screen = ctx->pipe->screen; - - vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE); - - image->format = format; - image->width = width; - image->height = height; - - image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - image->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - image->sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - image->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - image->sampler.normalized_coords = 1; - - assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D, - 0, PIPE_BIND_SAMPLER_VIEW)); - - memset(&pt, 0, sizeof(pt)); - pt.target = PIPE_TEXTURE_2D; - pt.format = pformat; - pt.last_level = 0; - pt.width0 = width; - pt.height0 = height; - pt.depth0 = 1; - pt.array_size = 1; - pt.bind = PIPE_BIND_SAMPLER_VIEW; - - newtex = screen->resource_create(screen, &pt); - - debug_assert(newtex); - - u_sampler_view_default_template(&view_templ, newtex, newtex->format); - /* R, G, and B are treated as 1.0 for alpha-only formats in OpenVG */ - if (newtex->format == PIPE_FORMAT_A8_UNORM) { - view_templ.swizzle_r = PIPE_SWIZZLE_ONE; - view_templ.swizzle_g = PIPE_SWIZZLE_ONE; - view_templ.swizzle_b = PIPE_SWIZZLE_ONE; - } - - view = pipe->create_sampler_view(pipe, newtex, &view_templ); - /* want the texture to go away if the view is freed */ - pipe_resource_reference(&newtex, NULL); - - image->sampler_view = view; - - vg_context_add_object(ctx, &image->base); - - image_cleari(image, 0, 0, 0, image->width, image->height); - return image; -} - -void image_destroy(struct vg_image *img) -{ - struct vg_context *ctx = vg_current_context(); - vg_context_remove_object(ctx, &img->base); - - - if (img->parent) { - /* remove img from the parent child array */ - int idx; - struct vg_image **array = - (struct vg_image **)img->parent->children_array->data; - - for (idx = 0; idx < img->parent->children_array->num_elements; ++idx) { - struct vg_image *child = array[idx]; - if (child == img) { - break; - } - } - debug_assert(idx < img->parent->children_array->num_elements); - array_remove_element(img->parent->children_array, idx); - } - - if (img->children_array && img->children_array->num_elements) { - /* reparent the children */ - VGint i; - struct vg_image *parent = img->parent; - struct vg_image **children = - (struct vg_image **)img->children_array->data; - if (!parent) { - VGint min_x = children[0]->x; - parent = children[0]; - - for (i = 1; i < img->children_array->num_elements; ++i) { - struct vg_image *child = children[i]; - if (child->x < min_x) { - parent = child; - } - } - } - - for (i = 0; i < img->children_array->num_elements; ++i) { - struct vg_image *child = children[i]; - if (child != parent) { - child->parent = parent; - if (!parent->children_array) { - parent->children_array = array_create( - sizeof(struct vg_image*)); - } - array_append_data(parent->children_array, - &child, 1); - } else - child->parent = NULL; - } - array_destroy(img->children_array); - } - - vg_free_object(&img->base); - - pipe_sampler_view_reference(&img->sampler_view, NULL); - FREE(img); -} - -void image_clear(struct vg_image *img, - VGint x, VGint y, VGint width, VGint height) -{ - struct vg_context *ctx = vg_current_context(); - VGfloat *clear_colorf = ctx->state.vg.clear_color; - VGubyte r, g, b ,a; - VGint clear_colori; - /* FIXME: this is very nasty */ - r = float_to_ubyte(clear_colorf[0]); - g = float_to_ubyte(clear_colorf[1]); - b = float_to_ubyte(clear_colorf[2]); - a = float_to_ubyte(clear_colorf[3]); - clear_colori = r << 24 | g << 16 | b << 8 | a; - image_cleari(img, clear_colori, x, y, width, height); -} - -void image_sub_data(struct vg_image *image, - const void * data, - VGint dataStride, - VGImageFormat dataFormat, - VGint x, VGint y, - VGint width, VGint height) -{ - const VGint yStep = 1; - VGubyte *src = (VGubyte *)data; - VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4]; - VGfloat *df = (VGfloat*)temp; - VGint i; - struct vg_context *ctx = vg_current_context(); - struct pipe_context *pipe = ctx->pipe; - struct pipe_resource *texture = image_texture(image); - VGint xoffset = 0, yoffset = 0; - - if (x < 0) { - xoffset -= x; - width += x; - x = 0; - } - if (y < 0) { - yoffset -= y; - height += y; - y = 0; - } - - if (width <= 0 || height <= 0) { - vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); - return; - } - - if (x > image->width || y > image->width) { - vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); - return; - } - - if (x + width > image->width) { - width = image->width - x; - } - - if (y + height > image->height) { - height = image->height - y; - } - - { /* upload color_data */ - struct pipe_transfer *transfer; - void *map = pipe_transfer_map(pipe, texture, 0, 0, - PIPE_TRANSFER_WRITE, 0, 0, - texture->width0, texture->height0, - &transfer); - src += (dataStride * yoffset); - for (i = 0; i < height; i++) { - _vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp); - pipe_put_tile_rgba(transfer, map, x+image->x, y+image->y, width, 1, df); - y += yStep; - src += dataStride; - } - pipe->transfer_unmap(pipe, transfer); - } -} - -void image_get_sub_data(struct vg_image * image, - void * data, - VGint dataStride, - VGImageFormat dataFormat, - VGint sx, VGint sy, - VGint width, VGint height) -{ - struct vg_context *ctx = vg_current_context(); - struct pipe_context *pipe = ctx->pipe; - VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4]; - VGfloat *df = (VGfloat*)temp; - VGint y = 0, yStep = 1; - VGint i; - VGubyte *dst = (VGubyte *)data; - - { - struct pipe_transfer *transfer; - void *map = - pipe_transfer_map(pipe, - image->sampler_view->texture, 0, 0, - PIPE_TRANSFER_READ, - 0, 0, - image->x + image->width, - image->y + image->height, &transfer); - /* Do a row at a time to flip image data vertically */ - for (i = 0; i < height; i++) { -#if 0 - debug_printf("%d-%d == %d\n", sy, height, y); -#endif - pipe_get_tile_rgba(transfer, map, sx+image->x, y, width, 1, df); - y += yStep; - _vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst); - dst += dataStride; - } - - pipe->transfer_unmap(pipe, transfer); - } -} - -struct vg_image * image_child_image(struct vg_image *parent, - VGint x, VGint y, - VGint width, VGint height) -{ - struct vg_context *ctx = vg_current_context(); - struct vg_image *image = CALLOC_STRUCT(vg_image); - - vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE); - - image->x = parent->x + x; - image->y = parent->y + y; - image->width = width; - image->height = height; - image->parent = parent; - image->sampler_view = NULL; - pipe_sampler_view_reference(&image->sampler_view, - parent->sampler_view); - - image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - image->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - image->sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - image->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - image->sampler.normalized_coords = 1; - - if (!parent->children_array) - parent->children_array = array_create( - sizeof(struct vg_image*)); - - array_append_data(parent->children_array, - &image, 1); - - vg_context_add_object(ctx, &image->base); - - return image; -} - -void image_copy(struct vg_image *dst, VGint dx, VGint dy, - struct vg_image *src, VGint sx, VGint sy, - VGint width, VGint height, - VGboolean dither) -{ - struct vg_context *ctx = vg_current_context(); - - if (width <= 0 || height <= 0) { - vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); - return; - } - vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy, - src->sampler_view, src->x + sx, src->y + sy, width, height); -} - -void image_draw(struct vg_image *img, struct matrix *matrix) -{ - struct vg_context *ctx = vg_current_context(); - struct matrix paint_matrix; - VGfloat x1, y1; - VGfloat x2, y2; - VGfloat x3, y3; - VGfloat x4, y4; - - if (!vg_get_paint_matrix(ctx, - &ctx->state.vg.fill_paint_to_user_matrix, - matrix, - &paint_matrix)) - return; - - x1 = 0; - y1 = 0; - x2 = img->width; - y2 = 0; - x3 = img->width; - y3 = img->height; - x4 = 0; - y4 = img->height; - - shader_set_surface_matrix(ctx->shader, matrix); - shader_set_drawing_image(ctx->shader, VG_TRUE); - shader_set_paint(ctx->shader, ctx->state.vg.fill_paint); - shader_set_paint_matrix(ctx->shader, &paint_matrix); - shader_set_image(ctx->shader, img); - shader_bind(ctx->shader); - - renderer_texture_quad(ctx->renderer, image_texture(img), - img->x, img->y, img->x + img->width, img->y + img->height, - x1, y1, x2, y2, x3, y3, x4, y4); -} - -void image_set_pixels(VGint dx, VGint dy, - struct vg_image *src, VGint sx, VGint sy, - VGint width, VGint height) -{ - struct vg_context *ctx = vg_current_context(); - struct pipe_context *pipe = ctx->pipe; - struct pipe_surface *surf, surf_tmpl; - struct st_renderbuffer *strb = ctx->draw_buffer->strb; - - u_surface_default_template(&surf_tmpl, image_texture(src)); - surf = pipe->create_surface(pipe, image_texture(src), &surf_tmpl); - - vg_copy_surface(ctx, strb->surface, dx, dy, - surf, sx+src->x, sy+src->y, width, height); - - pipe->surface_destroy(pipe, surf); -} - -void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy, - VGint sx, VGint sy, - VGint width, VGint height) -{ - struct vg_context *ctx = vg_current_context(); - struct pipe_context *pipe = ctx->pipe; - struct pipe_surface *surf, surf_tmpl; - struct st_renderbuffer *strb = ctx->draw_buffer->strb; - - /* flip the y coordinates */ - /*dy = dst->height - dy - height;*/ - - u_surface_default_template(&surf_tmpl, image_texture(dst)); - surf = pipe->create_surface(pipe, image_texture(dst), &surf_tmpl); - - vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy, - strb->surface, sx, sy, width, height); - - pipe_surface_reference(&surf, NULL); -} - - -VGboolean vg_image_overlaps(struct vg_image *dst, - struct vg_image *src) -{ - if (dst == src || dst->parent == src || - dst == src->parent) - return VG_TRUE; - if (dst->parent && dst->parent == src->parent) { - VGfloat left1 = dst->x; - VGfloat left2 = src->x; - VGfloat right1 = dst->x + dst->width; - VGfloat right2 = src->x + src->width; - VGfloat bottom1 = dst->y; - VGfloat bottom2 = src->y; - VGfloat top1 = dst->y + dst->height; - VGfloat top2 = src->y + src->height; - - return !(left2 > right1 || right2 < left1 || - top2 > bottom1 || bottom2 < top1); - } - return VG_FALSE; -} - -VGint image_bind_samplers(struct vg_image *img, struct pipe_sampler_state **samplers, - struct pipe_sampler_view **sampler_views) -{ - img->sampler.min_img_filter = image_sampler_filter(img->base.ctx); - img->sampler.mag_img_filter = image_sampler_filter(img->base.ctx); - samplers[3] = &img->sampler; - sampler_views[3] = img->sampler_view; - return 1; -} - -VGint image_sampler_filter(struct vg_context *ctx) -{ - switch(ctx->state.vg.image_quality) { - case VG_IMAGE_QUALITY_NONANTIALIASED: - return PIPE_TEX_FILTER_NEAREST; - break; - case VG_IMAGE_QUALITY_FASTER: - return PIPE_TEX_FILTER_NEAREST; - break; - case VG_IMAGE_QUALITY_BETTER: - /* possibly use anisotropic filtering */ - return PIPE_TEX_FILTER_LINEAR; - break; - default: - debug_printf("Unknown image quality"); - } - return PIPE_TEX_FILTER_NEAREST; -} |