Home | History | Annotate | Download | only in vega
      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 "image.h"
     28 
     29 #include "vg_translate.h"
     30 #include "vg_context.h"
     31 #include "matrix.h"
     32 #include "renderer.h"
     33 #include "util_array.h"
     34 #include "api_consts.h"
     35 #include "shader.h"
     36 
     37 #include "pipe/p_context.h"
     38 #include "pipe/p_screen.h"
     39 #include "util/u_inlines.h"
     40 #include "util/u_format.h"
     41 #include "util/u_tile.h"
     42 #include "util/u_memory.h"
     43 #include "util/u_math.h"
     44 #include "util/u_sampler.h"
     45 #include "util/u_surface.h"
     46 
     47 static enum pipe_format vg_format_to_pipe(VGImageFormat format)
     48 {
     49    switch(format) {
     50    case VG_sRGB_565:
     51       return PIPE_FORMAT_B5G6R5_UNORM;
     52    case VG_sRGBA_5551:
     53       return PIPE_FORMAT_B5G5R5A1_UNORM;
     54    case VG_sRGBA_4444:
     55       return PIPE_FORMAT_B4G4R4A4_UNORM;
     56    case VG_sL_8:
     57    case VG_lL_8:
     58       return PIPE_FORMAT_L8_UNORM;
     59    case VG_BW_1:
     60       return PIPE_FORMAT_B8G8R8A8_UNORM;
     61    case VG_A_8:
     62       return PIPE_FORMAT_A8_UNORM;
     63 #ifdef OPENVG_VERSION_1_1
     64    case VG_A_1:
     65    case VG_A_4:
     66       return PIPE_FORMAT_A8_UNORM;
     67 #endif
     68    default:
     69       return PIPE_FORMAT_B8G8R8A8_UNORM;
     70    }
     71 }
     72 
     73 static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc)
     74 {
     75    src_loc[2] = MIN2(src_loc[2], dst_loc[2]);
     76    src_loc[3] = MIN2(src_loc[3], dst_loc[3]);
     77    dst_loc[2] = src_loc[2];
     78    dst_loc[3] = src_loc[3];
     79 }
     80 
     81 static void vg_get_copy_coords(VGfloat *src_loc,
     82                                VGfloat src_width, VGfloat src_height,
     83                                VGfloat *dst_loc,
     84                                VGfloat dst_width, VGfloat dst_height)
     85 {
     86    VGfloat dst_bounds[4], src_bounds[4];
     87    VGfloat src_shift[4], dst_shift[4], shift[4];
     88 
     89    dst_bounds[0] = 0.f;
     90    dst_bounds[1] = 0.f;
     91    dst_bounds[2] = dst_width;
     92    dst_bounds[3] = dst_height;
     93 
     94    src_bounds[0] = 0.f;
     95    src_bounds[1] = 0.f;
     96    src_bounds[2] = src_width;
     97    src_bounds[3] = src_height;
     98 
     99    vg_bound_rect(src_loc, src_bounds, src_shift);
    100    vg_bound_rect(dst_loc, dst_bounds, dst_shift);
    101    shift[0] = src_shift[0] - dst_shift[0];
    102    shift[1] = src_shift[1] - dst_shift[1];
    103 
    104    if (shift[0] < 0)
    105       vg_shift_rectx(src_loc, src_bounds, -shift[0]);
    106    else
    107       vg_shift_rectx(dst_loc, dst_bounds, shift[0]);
    108 
    109    if (shift[1] < 0)
    110       vg_shift_recty(src_loc, src_bounds, -shift[1]);
    111    else
    112       vg_shift_recty(dst_loc, dst_bounds, shift[1]);
    113 
    114    vg_sync_size(src_loc, dst_loc);
    115 }
    116 
    117 static void vg_copy_texture(struct vg_context *ctx,
    118                             struct pipe_resource *dst, VGint dx, VGint dy,
    119                             struct pipe_sampler_view *src, VGint sx, VGint sy,
    120                             VGint width, VGint height)
    121 {
    122    VGfloat dst_loc[4], src_loc[4];
    123 
    124    dst_loc[0] = dx;
    125    dst_loc[1] = dy;
    126    dst_loc[2] = width;
    127    dst_loc[3] = height;
    128 
    129    src_loc[0] = sx;
    130    src_loc[1] = sy;
    131    src_loc[2] = width;
    132    src_loc[3] = height;
    133 
    134    vg_get_copy_coords(src_loc, src->texture->width0, src->texture->height0,
    135                       dst_loc, dst->width0, dst->height0);
    136 
    137    if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
    138        dst_loc[2] >= 0 && dst_loc[3] >= 0) {
    139       struct pipe_surface *surf, surf_tmpl;
    140 
    141       /* get the destination surface */
    142       u_surface_default_template(&surf_tmpl, dst, PIPE_BIND_RENDER_TARGET);
    143       surf = ctx->pipe->create_surface(ctx->pipe, dst, &surf_tmpl);
    144       if (surf && renderer_copy_begin(ctx->renderer, surf, VG_TRUE, src)) {
    145          renderer_copy(ctx->renderer,
    146                dst_loc[0], dst_loc[1], dst_loc[2], dst_loc[3],
    147                src_loc[0], src_loc[1], src_loc[2], src_loc[3]);
    148          renderer_copy_end(ctx->renderer);
    149       }
    150 
    151       pipe_surface_reference(&surf, NULL);
    152    }
    153 }
    154 
    155 void vg_copy_surface(struct vg_context *ctx,
    156                      struct pipe_surface *dst, VGint dx, VGint dy,
    157                      struct pipe_surface *src, VGint sx, VGint sy,
    158                      VGint width, VGint height)
    159 {
    160    VGfloat dst_loc[4], src_loc[4];
    161 
    162    dst_loc[0] = dx;
    163    dst_loc[1] = dy;
    164    dst_loc[2] = width;
    165    dst_loc[3] = height;
    166 
    167    src_loc[0] = sx;
    168    src_loc[1] = sy;
    169    src_loc[2] = width;
    170    src_loc[3] = height;
    171 
    172    vg_get_copy_coords(src_loc, src->width, src->height,
    173                       dst_loc, dst->width, dst->height);
    174 
    175    if (src_loc[2] > 0 && src_loc[3] > 0 &&
    176        dst_loc[2] > 0 && dst_loc[3] > 0) {
    177       if (src == dst)
    178          renderer_copy_surface(ctx->renderer,
    179                                src,
    180                                src_loc[0],
    181                                src->height - (src_loc[1] + src_loc[3]),
    182                                src_loc[0] + src_loc[2],
    183                                src->height - src_loc[1],
    184                                dst,
    185                                dst_loc[0],
    186                                dst->height - (dst_loc[1] + dst_loc[3]),
    187                                dst_loc[0] + dst_loc[2],
    188                                dst->height - dst_loc[1],
    189                                0, 0);
    190       else
    191          renderer_copy_surface(ctx->renderer,
    192                                src,
    193                                src_loc[0],
    194                                src->height - src_loc[1],
    195                                src_loc[0] + src_loc[2],
    196                                src->height - (src_loc[1] + src_loc[3]),
    197                                dst,
    198                                dst_loc[0],
    199                                dst->height - (dst_loc[1] + dst_loc[3]),
    200                                dst_loc[0] + dst_loc[2],
    201                                dst->height - dst_loc[1],
    202                                0, 0);
    203    }
    204 
    205 }
    206 
    207 static struct pipe_resource *image_texture(struct vg_image *img)
    208 {
    209    struct pipe_resource *tex = img->sampler_view->texture;
    210    return tex;
    211 }
    212 
    213 
    214 static void image_cleari(struct vg_image *img, VGint clear_colori,
    215                          VGint x, VGint y, VGint width, VGint height)
    216 {
    217    VGint *clearbuf;
    218    VGint i;
    219    VGfloat dwidth, dheight;
    220 
    221    clearbuf = malloc(sizeof(VGint)*width*height);
    222    for (i = 0; i < width*height; ++i)
    223       clearbuf[i] = clear_colori;
    224 
    225    dwidth = MIN2(width, img->width);
    226    dheight = MIN2(height, img->height);
    227 
    228    image_sub_data(img, clearbuf, width * sizeof(VGint),
    229                   VG_sRGBA_8888,
    230                   x, y, dwidth, dheight);
    231    free(clearbuf);
    232 }
    233 
    234 struct vg_image * image_create(VGImageFormat format,
    235                                VGint width, VGint height)
    236 {
    237    struct vg_context *ctx = vg_current_context();
    238    struct pipe_context *pipe = ctx->pipe;
    239    struct vg_image *image = CALLOC_STRUCT(vg_image);
    240    enum pipe_format pformat = vg_format_to_pipe(format);
    241    struct pipe_resource pt, *newtex;
    242    struct pipe_sampler_view view_templ;
    243    struct pipe_sampler_view *view;
    244    struct pipe_screen *screen = ctx->pipe->screen;
    245 
    246    vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE);
    247 
    248    image->format = format;
    249    image->width = width;
    250    image->height = height;
    251 
    252    image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
    253    image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
    254    image->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
    255    image->sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
    256    image->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
    257    image->sampler.normalized_coords = 1;
    258 
    259    assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D,
    260                                       0, PIPE_BIND_SAMPLER_VIEW));
    261 
    262    memset(&pt, 0, sizeof(pt));
    263    pt.target = PIPE_TEXTURE_2D;
    264    pt.format = pformat;
    265    pt.last_level = 0;
    266    pt.width0 = width;
    267    pt.height0 = height;
    268    pt.depth0 = 1;
    269    pt.array_size = 1;
    270    pt.bind = PIPE_BIND_SAMPLER_VIEW;
    271 
    272    newtex = screen->resource_create(screen, &pt);
    273 
    274    debug_assert(newtex);
    275 
    276    u_sampler_view_default_template(&view_templ, newtex, newtex->format);
    277    /* R, G, and B are treated as 1.0 for alpha-only formats in OpenVG */
    278    if (newtex->format == PIPE_FORMAT_A8_UNORM) {
    279       view_templ.swizzle_r = PIPE_SWIZZLE_ONE;
    280       view_templ.swizzle_g = PIPE_SWIZZLE_ONE;
    281       view_templ.swizzle_b = PIPE_SWIZZLE_ONE;
    282    }
    283 
    284    view = pipe->create_sampler_view(pipe, newtex, &view_templ);
    285    /* want the texture to go away if the view is freed */
    286    pipe_resource_reference(&newtex, NULL);
    287 
    288    image->sampler_view = view;
    289 
    290    vg_context_add_object(ctx, &image->base);
    291 
    292    image_cleari(image, 0, 0, 0, image->width, image->height);
    293    return image;
    294 }
    295 
    296 void image_destroy(struct vg_image *img)
    297 {
    298    struct vg_context *ctx = vg_current_context();
    299    vg_context_remove_object(ctx, &img->base);
    300 
    301 
    302    if (img->parent) {
    303       /* remove img from the parent child array */
    304       int idx;
    305       struct vg_image **array =
    306          (struct vg_image **)img->parent->children_array->data;
    307 
    308       for (idx = 0; idx < img->parent->children_array->num_elements; ++idx) {
    309          struct vg_image *child = array[idx];
    310          if (child == img) {
    311             break;
    312          }
    313       }
    314       debug_assert(idx < img->parent->children_array->num_elements);
    315       array_remove_element(img->parent->children_array, idx);
    316    }
    317 
    318    if (img->children_array && img->children_array->num_elements) {
    319       /* reparent the children */
    320       VGint i;
    321       struct vg_image *parent = img->parent;
    322       struct vg_image **children =
    323          (struct vg_image **)img->children_array->data;
    324       if (!parent) {
    325          VGint min_x = children[0]->x;
    326          parent = children[0];
    327 
    328          for (i = 1; i < img->children_array->num_elements; ++i) {
    329             struct vg_image *child = children[i];
    330             if (child->x < min_x) {
    331                parent = child;
    332             }
    333          }
    334       }
    335 
    336       for (i = 0; i < img->children_array->num_elements; ++i) {
    337          struct vg_image *child = children[i];
    338          if (child != parent) {
    339             child->parent = parent;
    340             if (!parent->children_array) {
    341                parent->children_array = array_create(
    342                   sizeof(struct vg_image*));
    343             }
    344             array_append_data(parent->children_array,
    345                               &child, 1);
    346          } else
    347             child->parent = NULL;
    348       }
    349       array_destroy(img->children_array);
    350    }
    351 
    352    vg_free_object(&img->base);
    353 
    354    pipe_sampler_view_reference(&img->sampler_view, NULL);
    355    FREE(img);
    356 }
    357 
    358 void image_clear(struct vg_image *img,
    359                  VGint x, VGint y, VGint width, VGint height)
    360 {
    361    struct vg_context *ctx = vg_current_context();
    362    VGfloat *clear_colorf = ctx->state.vg.clear_color;
    363    VGubyte r, g, b ,a;
    364    VGint clear_colori;
    365    /* FIXME: this is very nasty */
    366    r = float_to_ubyte(clear_colorf[0]);
    367    g = float_to_ubyte(clear_colorf[1]);
    368    b = float_to_ubyte(clear_colorf[2]);
    369    a = float_to_ubyte(clear_colorf[3]);
    370    clear_colori = r << 24 | g << 16 | b << 8 | a;
    371    image_cleari(img, clear_colori, x, y, width, height);
    372 }
    373 
    374 void image_sub_data(struct vg_image *image,
    375                     const void * data,
    376                     VGint dataStride,
    377                     VGImageFormat dataFormat,
    378                     VGint x, VGint y,
    379                     VGint width, VGint height)
    380 {
    381    const VGint yStep = 1;
    382    VGubyte *src = (VGubyte *)data;
    383    VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
    384    VGfloat *df = (VGfloat*)temp;
    385    VGint i;
    386    struct vg_context *ctx = vg_current_context();
    387    struct pipe_context *pipe = ctx->pipe;
    388    struct pipe_resource *texture = image_texture(image);
    389    VGint xoffset = 0, yoffset = 0;
    390 
    391    if (x < 0) {
    392       xoffset -= x;
    393       width += x;
    394       x = 0;
    395    }
    396    if (y < 0) {
    397       yoffset -= y;
    398       height += y;
    399       y = 0;
    400    }
    401 
    402    if (width <= 0 || height <= 0) {
    403       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    404       return;
    405    }
    406 
    407    if (x > image->width || y > image->width) {
    408       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    409       return;
    410    }
    411 
    412    if (x + width > image->width) {
    413       width = image->width - x;
    414    }
    415 
    416    if (y + height > image->height) {
    417       height = image->height - y;
    418    }
    419 
    420    { /* upload color_data */
    421       struct pipe_transfer *transfer = pipe_get_transfer(
    422          pipe, texture, 0, 0,
    423          PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0);
    424       src += (dataStride * yoffset);
    425       for (i = 0; i < height; i++) {
    426          _vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp);
    427          pipe_put_tile_rgba(pipe, transfer, x+image->x, y+image->y, width, 1, df);
    428          y += yStep;
    429          src += dataStride;
    430       }
    431       pipe->transfer_destroy(pipe, transfer);
    432    }
    433 }
    434 
    435 void image_get_sub_data(struct vg_image * image,
    436                         void * data,
    437                         VGint dataStride,
    438                         VGImageFormat dataFormat,
    439                         VGint sx, VGint sy,
    440                         VGint width, VGint height)
    441 {
    442    struct vg_context *ctx = vg_current_context();
    443    struct pipe_context *pipe = ctx->pipe;
    444    VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
    445    VGfloat *df = (VGfloat*)temp;
    446    VGint y = 0, yStep = 1;
    447    VGint i;
    448    VGubyte *dst = (VGubyte *)data;
    449 
    450    {
    451       struct pipe_transfer *transfer =
    452          pipe_get_transfer(pipe,
    453                            image->sampler_view->texture,  0, 0,
    454                            PIPE_TRANSFER_READ,
    455                            0, 0,
    456                            image->x + image->width,
    457                            image->y + image->height);
    458       /* Do a row at a time to flip image data vertically */
    459       for (i = 0; i < height; i++) {
    460 #if 0
    461          debug_printf("%d-%d  == %d\n", sy, height, y);
    462 #endif
    463          pipe_get_tile_rgba(pipe, transfer, sx+image->x, y, width, 1, df);
    464          y += yStep;
    465          _vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst);
    466          dst += dataStride;
    467       }
    468 
    469       pipe->transfer_destroy(pipe, transfer);
    470    }
    471 }
    472 
    473 struct vg_image * image_child_image(struct vg_image *parent,
    474                                     VGint x, VGint y,
    475                                     VGint width, VGint height)
    476 {
    477    struct vg_context *ctx = vg_current_context();
    478    struct vg_image *image = CALLOC_STRUCT(vg_image);
    479 
    480    vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE);
    481 
    482    image->x = parent->x + x;
    483    image->y = parent->y + y;
    484    image->width = width;
    485    image->height = height;
    486    image->parent = parent;
    487    image->sampler_view = NULL;
    488    pipe_sampler_view_reference(&image->sampler_view,
    489                                parent->sampler_view);
    490 
    491    image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
    492    image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
    493    image->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
    494    image->sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
    495    image->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
    496    image->sampler.normalized_coords = 1;
    497 
    498    if (!parent->children_array)
    499       parent->children_array = array_create(
    500          sizeof(struct vg_image*));
    501 
    502    array_append_data(parent->children_array,
    503                      &image, 1);
    504 
    505    vg_context_add_object(ctx, &image->base);
    506 
    507    return image;
    508 }
    509 
    510 void image_copy(struct vg_image *dst, VGint dx, VGint dy,
    511                 struct vg_image *src, VGint sx, VGint sy,
    512                 VGint width, VGint height,
    513                 VGboolean dither)
    514 {
    515    struct vg_context *ctx = vg_current_context();
    516 
    517    if (width <= 0 || height <= 0) {
    518       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    519       return;
    520    }
    521    vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy,
    522                    src->sampler_view, src->x + sx, src->y + sy, width, height);
    523 }
    524 
    525 void image_draw(struct vg_image *img, struct matrix *matrix)
    526 {
    527    struct vg_context *ctx = vg_current_context();
    528    struct matrix paint_matrix;
    529    VGfloat x1, y1;
    530    VGfloat x2, y2;
    531    VGfloat x3, y3;
    532    VGfloat x4, y4;
    533 
    534    if (!vg_get_paint_matrix(ctx,
    535                             &ctx->state.vg.fill_paint_to_user_matrix,
    536                             matrix,
    537                             &paint_matrix))
    538       return;
    539 
    540    x1 = 0;
    541    y1 = 0;
    542    x2 = img->width;
    543    y2 = 0;
    544    x3 = img->width;
    545    y3 = img->height;
    546    x4 = 0;
    547    y4 = img->height;
    548 
    549    shader_set_surface_matrix(ctx->shader, matrix);
    550    shader_set_drawing_image(ctx->shader, VG_TRUE);
    551    shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
    552    shader_set_paint_matrix(ctx->shader, &paint_matrix);
    553    shader_set_image(ctx->shader, img);
    554    shader_bind(ctx->shader);
    555 
    556    renderer_texture_quad(ctx->renderer, image_texture(img),
    557                          img->x, img->y, img->x + img->width, img->y + img->height,
    558                          x1, y1, x2, y2, x3, y3, x4, y4);
    559 }
    560 
    561 void image_set_pixels(VGint dx, VGint dy,
    562                       struct vg_image *src, VGint sx, VGint sy,
    563                       VGint width, VGint height)
    564 {
    565    struct vg_context *ctx = vg_current_context();
    566    struct pipe_context *pipe = ctx->pipe;
    567    struct pipe_surface *surf, surf_tmpl;
    568    struct st_renderbuffer *strb = ctx->draw_buffer->strb;
    569 
    570    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
    571    u_surface_default_template(&surf_tmpl, image_texture(src),
    572                               0 /* no bind flag - not a surface*/);
    573    surf = pipe->create_surface(pipe, image_texture(src), &surf_tmpl);
    574 
    575    vg_copy_surface(ctx, strb->surface, dx, dy,
    576                    surf, sx+src->x, sy+src->y, width, height);
    577 
    578    pipe->surface_destroy(pipe, surf);
    579 }
    580 
    581 void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
    582                       VGint sx, VGint sy,
    583                       VGint width, VGint height)
    584 {
    585    struct vg_context *ctx = vg_current_context();
    586    struct pipe_context *pipe = ctx->pipe;
    587    struct pipe_surface *surf, surf_tmpl;
    588    struct st_renderbuffer *strb = ctx->draw_buffer->strb;
    589 
    590    /* flip the y coordinates */
    591    /*dy = dst->height - dy - height;*/
    592 
    593    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
    594    u_surface_default_template(&surf_tmpl, image_texture(dst),
    595                               PIPE_BIND_RENDER_TARGET);
    596    surf = pipe->create_surface(pipe, image_texture(dst), &surf_tmpl);
    597 
    598    vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy,
    599                    strb->surface, sx, sy, width, height);
    600 
    601    pipe_surface_reference(&surf, NULL);
    602 }
    603 
    604 
    605 VGboolean vg_image_overlaps(struct vg_image *dst,
    606                             struct vg_image *src)
    607 {
    608    if (dst == src || dst->parent == src ||
    609        dst == src->parent)
    610       return VG_TRUE;
    611    if (dst->parent && dst->parent == src->parent) {
    612       VGfloat left1 = dst->x;
    613       VGfloat left2 = src->x;
    614       VGfloat right1 = dst->x + dst->width;
    615       VGfloat right2 = src->x + src->width;
    616       VGfloat bottom1 = dst->y;
    617       VGfloat bottom2 = src->y;
    618       VGfloat top1 = dst->y + dst->height;
    619       VGfloat top2 = src->y + src->height;
    620 
    621       return !(left2 > right1 || right2 < left1 ||
    622                top2 > bottom1 || bottom2 < top1);
    623    }
    624    return VG_FALSE;
    625 }
    626 
    627 VGint image_bind_samplers(struct vg_image *img, struct pipe_sampler_state **samplers,
    628                           struct pipe_sampler_view **sampler_views)
    629 {
    630    img->sampler.min_img_filter = image_sampler_filter(img->base.ctx);
    631    img->sampler.mag_img_filter = image_sampler_filter(img->base.ctx);
    632    samplers[3] = &img->sampler;
    633    sampler_views[3] = img->sampler_view;
    634    return 1;
    635 }
    636 
    637 VGint image_sampler_filter(struct vg_context *ctx)
    638 {
    639     switch(ctx->state.vg.image_quality) {
    640     case VG_IMAGE_QUALITY_NONANTIALIASED:
    641        return PIPE_TEX_FILTER_NEAREST;
    642        break;
    643     case VG_IMAGE_QUALITY_FASTER:
    644        return PIPE_TEX_FILTER_NEAREST;
    645        break;
    646     case VG_IMAGE_QUALITY_BETTER:
    647        /* possibly use anisotropic filtering */
    648        return PIPE_TEX_FILTER_LINEAR;
    649        break;
    650     default:
    651        debug_printf("Unknown image quality");
    652     }
    653     return PIPE_TEX_FILTER_NEAREST;
    654 }
    655