VGImage vgCreateImage(VGImageFormat format, VGint width, VGint height, VGbitfield allowedQuality) { struct vg_context *ctx = vg_current_context(); if (!supported_image_format(format)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); return VG_INVALID_HANDLE; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return VG_INVALID_HANDLE; } if (width > vgGeti(VG_MAX_IMAGE_WIDTH) || height > vgGeti(VG_MAX_IMAGE_HEIGHT)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return VG_INVALID_HANDLE; } if (width * height > vgGeti(VG_MAX_IMAGE_PIXELS)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return VG_INVALID_HANDLE; } if (!(allowedQuality & ((VG_IMAGE_QUALITY_NONANTIALIASED | VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_BETTER)))) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return VG_INVALID_HANDLE; } return (VGImage)image_create(format, width, height); }
void vgGetImageSubData(VGImage image, void * data, VGint dataStride, VGImageFormat dataFormat, VGint x, VGint y, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; if (image == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!supported_image_format(dataFormat)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); return; } if (width <= 0 || height <= 0 || !data || !is_aligned(data)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } img = (struct vg_image*)image; image_get_sub_data(img, data, dataStride, dataFormat, x, y, width, height); }
void vgWritePixels(const void * data, VGint dataStride, VGImageFormat dataFormat, VGint dx, VGint dy, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct pipe_context *pipe = ctx->pipe; if (!supported_image_format(dataFormat)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); return; } if (!data || !is_aligned(data)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } vg_validate_state(ctx); { struct vg_image *img = image_create(dataFormat, width, height); image_sub_data(img, data, dataStride, dataFormat, 0, 0, width, height); #if 0 struct matrix *matrix = &ctx->state.vg.image_user_to_surface_matrix; matrix_translate(matrix, dx, dy); image_draw(img); matrix_translate(matrix, -dx, -dy); #else /* this looks like a better approach */ image_set_pixels(dx, dy, img, 0, 0, width, height); #endif image_destroy(img); } /* make sure rendering has completed */ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); }
void vgReadPixels(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; struct pipe_screen *screen = pipe->screen; struct st_framebuffer *stfb = ctx->draw_buffer; struct st_renderbuffer *strb = stfb->strb; struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4]; VGfloat *df = (VGfloat*)temp; VGint y = (fb->height - sy) - 1, yStep = -1; VGint i; VGubyte *dst = (VGubyte *)data; VGint xoffset = 0, yoffset = 0; if (!supported_image_format(dataFormat)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); return; } if (!data || !is_aligned(data)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } /* make sure rendering has completed */ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); if (sx < 0) { xoffset = -sx; xoffset *= _vega_size_for_format(dataFormat); width += sx; sx = 0; } if (sy < 0) { yoffset = -sy; height += sy; sy = 0; y = (fb->height - sy) - 1; yoffset *= dataStride; } { struct pipe_transfer *transfer; transfer = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, width, height); /* 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, sx, y, width, 1, df); y += yStep; _vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst + yoffset + xoffset); dst += dataStride; } screen->tex_transfer_destroy(transfer); } }
void vegaReadPixels(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; struct st_framebuffer *stfb = ctx->draw_buffer; struct st_renderbuffer *strb = stfb->strb; VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4]; VGfloat *df = (VGfloat*)temp; VGint i; VGubyte *dst = (VGubyte *)data; VGint xoffset = 0, yoffset = 0; if (!supported_image_format(dataFormat)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); return; } if (!data || !is_aligned(data)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (sx < 0) { xoffset = -sx; xoffset *= _vega_size_for_format(dataFormat); width += sx; sx = 0; } if (sy < 0) { yoffset = -sy; yoffset *= dataStride; height += sy; sy = 0; } if (sx + width > stfb->width || sy + height > stfb->height) { width = stfb->width - sx; height = stfb->height - sy; /* nothing to read */ if (width <= 0 || height <= 0) return; } { VGint y = (stfb->height - sy) - 1, yStep = -1; struct pipe_transfer *transfer; void *map; map = pipe_transfer_map(pipe, strb->texture, 0, 0, PIPE_TRANSFER_READ, 0, 0, sx + width, stfb->height - sy, &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, y, width, 1, df); y += yStep; _vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst + yoffset + xoffset); dst += dataStride; } pipe->transfer_unmap(pipe, transfer); } }