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 "VG/openvg.h"
     28 
     29 #include "mask.h"
     30 #include "api.h"
     31 #include "handle.h"
     32 #include "renderer.h"
     33 
     34 #include "vg_context.h"
     35 #include "pipe/p_context.h"
     36 
     37 void vegaMask(VGHandle mask, VGMaskOperation operation,
     38               VGint x, VGint y,
     39               VGint width, VGint height)
     40 {
     41    struct vg_context *ctx = vg_current_context();
     42 
     43    if (width <=0 || height <= 0) {
     44       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
     45       return;
     46    }
     47 
     48    if (operation < VG_CLEAR_MASK || operation > VG_SUBTRACT_MASK) {
     49       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
     50       return;
     51    }
     52 
     53 
     54    vg_validate_state(ctx);
     55 
     56    if (operation == VG_CLEAR_MASK) {
     57       mask_fill(x, y, width, height, 0.f);
     58    } else if (operation == VG_FILL_MASK) {
     59       mask_fill(x, y, width, height, 1.f);
     60    } else if (vg_object_is_valid(mask, VG_OBJECT_IMAGE)) {
     61       struct vg_image *image = handle_to_image(mask);
     62       mask_using_image(image, operation, x, y, width, height);
     63    } else if (vg_object_is_valid(mask, VG_OBJECT_MASK)) {
     64       struct vg_mask_layer *layer = handle_to_masklayer(mask);
     65       mask_using_layer(layer, operation, x, y, width, height);
     66    } else {
     67       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
     68    }
     69 }
     70 
     71 void vegaClear(VGint x, VGint y,
     72                VGint width, VGint height)
     73 {
     74    struct vg_context *ctx = vg_current_context();
     75    struct st_framebuffer *stfb = ctx->draw_buffer;
     76 
     77    if (width <= 0 || height <= 0) {
     78       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
     79       return;
     80    }
     81 
     82    vg_validate_state(ctx);
     83 #if 0
     84    debug_printf("Clear [%d, %d, %d, %d] with [%f, %f, %f, %f]\n",
     85                 x, y, width, height,
     86                 ctx->state.vg.clear_color[0],
     87                 ctx->state.vg.clear_color[1],
     88                 ctx->state.vg.clear_color[2],
     89                 ctx->state.vg.clear_color[3]);
     90 #endif
     91 
     92    /* check for a whole surface clear */
     93    if (!ctx->state.vg.scissoring &&
     94        (x == 0 && y == 0 && width == stfb->width && height == stfb->height)) {
     95       union pipe_color_union clear_color;
     96       clear_color.f[0] = ctx->state.vg.clear_color[0];
     97       clear_color.f[1] = ctx->state.vg.clear_color[1];
     98       clear_color.f[2] = ctx->state.vg.clear_color[2];
     99       clear_color.f[3] = ctx->state.vg.clear_color[3];
    100       ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
    101                        &clear_color, 1., 0);
    102    } else if (renderer_clear_begin(ctx->renderer)) {
    103       /* XXX verify coord round-off */
    104       renderer_clear(ctx->renderer, x, y, width, height, ctx->state.vg.clear_color);
    105       renderer_clear_end(ctx->renderer);
    106    }
    107 }
    108 
    109 
    110 #ifdef OPENVG_VERSION_1_1
    111 
    112 
    113 void vegaRenderToMask(VGPath path,
    114                       VGbitfield paintModes,
    115                       VGMaskOperation operation)
    116 {
    117    struct vg_context *ctx = vg_current_context();
    118 
    119    if (path == VG_INVALID_HANDLE) {
    120       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    121       return;
    122    }
    123    if (!paintModes || (paintModes&(~(VG_STROKE_PATH|VG_FILL_PATH)))) {
    124       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    125       return;
    126    }
    127    if (operation < VG_CLEAR_MASK ||
    128        operation > VG_SUBTRACT_MASK) {
    129       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    130       return;
    131    }
    132    if (!vg_object_is_valid(path, VG_OBJECT_PATH)) {
    133       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    134       return;
    135    }
    136 
    137    vg_validate_state(ctx);
    138 
    139    mask_render_to(handle_to_path(path), paintModes, operation);
    140 }
    141 
    142 VGMaskLayer vegaCreateMaskLayer(VGint width, VGint height)
    143 {
    144    struct vg_context *ctx = vg_current_context();
    145 
    146    if (width <= 0 || height <= 0 ||
    147        width > vegaGeti(VG_MAX_IMAGE_WIDTH) ||
    148        height > vegaGeti(VG_MAX_IMAGE_HEIGHT)) {
    149       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    150       return VG_INVALID_HANDLE;
    151    }
    152 
    153    return masklayer_to_handle(mask_layer_create(width, height));
    154 }
    155 
    156 void vegaDestroyMaskLayer(VGMaskLayer maskLayer)
    157 {
    158    struct vg_mask_layer *mask = 0;
    159    struct vg_context *ctx = vg_current_context();
    160 
    161    if (maskLayer == VG_INVALID_HANDLE) {
    162       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    163       return;
    164    }
    165    if (!vg_object_is_valid(maskLayer, VG_OBJECT_MASK)) {
    166       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    167       return;
    168    }
    169 
    170    mask = handle_to_masklayer(maskLayer);
    171    mask_layer_destroy(mask);
    172 }
    173 
    174 void vegaFillMaskLayer(VGMaskLayer maskLayer,
    175                        VGint x, VGint y,
    176                        VGint width, VGint height,
    177                        VGfloat value)
    178 {
    179    struct vg_mask_layer *mask = 0;
    180    struct vg_context *ctx = vg_current_context();
    181 
    182    if (maskLayer == VG_INVALID_HANDLE) {
    183       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    184       return;
    185    }
    186 
    187    if (value < 0 || value > 1) {
    188       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    189       return;
    190    }
    191 
    192    if (width <= 0 || height <= 0) {
    193       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    194       return;
    195    }
    196    if (x < 0 || y < 0 || (x + width) < 0 || (y + height) < 0) {
    197       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    198       return;
    199    }
    200 
    201    if (!vg_object_is_valid(maskLayer, VG_OBJECT_MASK)) {
    202       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    203       return;
    204    }
    205 
    206    mask = handle_to_masklayer(maskLayer);
    207 
    208    if (x + width > mask_layer_width(mask) ||
    209        y + height > mask_layer_height(mask)) {
    210       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    211       return;
    212    }
    213 
    214    vg_validate_state(ctx);
    215 
    216    mask_layer_fill(mask, x, y, width, height, value);
    217 }
    218 
    219 void vegaCopyMask(VGMaskLayer maskLayer,
    220                   VGint sx, VGint sy,
    221                   VGint dx, VGint dy,
    222                   VGint width, VGint height)
    223 {
    224    struct vg_context *ctx = vg_current_context();
    225    struct vg_mask_layer *mask = 0;
    226 
    227    if (maskLayer == VG_INVALID_HANDLE) {
    228       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    229       return;
    230    }
    231    if (width <= 0 || height <= 0) {
    232       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
    233       return;
    234    }
    235    if (!vg_object_is_valid(maskLayer, VG_OBJECT_MASK)) {
    236       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
    237       return;
    238    }
    239 
    240    vg_validate_state(ctx);
    241 
    242    mask = handle_to_masklayer(maskLayer);
    243    mask_copy(mask, sx, sy, dx, dy, width, height);
    244 }
    245 
    246 #endif
    247