* @{ */
/**
* @brief Create a new vkvg surface.
+ *
+ * This method will always return a valid pointer.
+ *
* @param dev The vkvg device used for creating the surface.
* @param width Width in pixel of the surface to create.
* @param height Height in pixel of the surface to create.
/**
* @brief Create a new vkvg surface by loading an image file.
* The resulting surface will have the same dimension as the supplied image.
+ * This method will always return a valid pointer.
*
* @param dev The vkvg device used for creating the surface.
* @param filePath The path of the image to load for creating the surface.
VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath);
/**
* @brief Create a new vkvg surface using an existing vulkan texture as backend.
+ * This method will always return a valid pointer.
* @param dev The vkvg device used for creating the surface.
* @param vkhImg The VkhImage to use as the backend texture for drawing operations.
* @return A new surface, or null if an error occured.
vkvg_public
void vkvg_surface_destroy (VkvgSurface surf);
/**
- * @brief Query the current status of the surface
+ * @brief Query the current status of the surface.
* @param The vkvg surface to query the status for.
* @return The current surface status.
*/
* @brief Create a new vkvg context used for drawing on surfaces.
*
* Creates a new #VkvgContext with all graphics state parameters set to default values and with surf as a target surface.
+ * This method will always return a valid pointer even if memory allocation failed.
* @remark This function references surf, so you can immediately call #vkvg_surface_destroy() on it if you don't need to maintain a separate reference to it.
* @param surf The target surface of the drawing operations.
* @return A new #VkvgContext or null if an error occured.
* and which may have special configuration for filtering and border repeat.
*
* @{ */
-
+/**
+ * @brief Get pattern current status.
+ *
+ * Querry the current status of a pattern.
+ * @param pat A valid pattern handle.
+ * @return The current status of the pattern.
+ */
+vkvg_public
+vkvg_status_t vkvg_pattern_status (VkvgPattern pat);
/**
* @brief add reference
*
LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf);
- if (ctx==NULL) {
- dev->status = VKVG_STATUS_NO_MEMORY;
- return NULL;
- }
+ if (!ctx)
+ return (VkvgContext)&_no_mem_status;
ctx->pSurf = surf;
void vkvg_destroy (VkvgContext ctx)
{
+ if (ctx->status)
+ return;
+
ctx->references--;
if (ctx->references > 0)
return;
}
void vkvg_set_opacity (VkvgContext ctx, float opacity) {
if (ctx->status)
- return;
+ return;
if (EQUF(ctx->pushConsts.opacity, opacity))
return;
ctx->pushCstDirty = true;
}
float vkvg_get_opacity (VkvgContext ctx) {
- return ctx->pushConsts.opacity;
+ if (ctx->status)
+ return 0;
+ return ctx->pushConsts.opacity;
}
vkvg_status_t vkvg_status (VkvgContext ctx) {
return ctx->status;
}
VkvgContext vkvg_reference (VkvgContext ctx) {
- ctx->references++;
+ if (!ctx->status)
+ ctx->references++;
return ctx;
}
uint32_t vkvg_get_reference_count (VkvgContext ctx) {
+ if (ctx->status)
+ return 0;
return ctx->references;
}
void vkvg_new_sub_path (VkvgContext ctx){
return !_current_path_is_empty(ctx);
}
void vkvg_get_current_point (VkvgContext ctx, float* x, float* y) {
- if (_current_path_is_empty(ctx)) {
+ if (ctx->status || _current_path_is_empty(ctx)) {
*x = *y = 0;
return;
}
vkvg_pattern_reference (pat);
}
void vkvg_set_line_width (VkvgContext ctx, float width){
+ if (ctx->status)
+ return;
RECORD(ctx, VKVG_CMD_SET_LINE_WIDTH, width);
ctx->lineWidth = width;
}
void vkvg_set_miter_limit (VkvgContext ctx, float limit){
+ if (ctx->status)
+ return;
RECORD(ctx, VKVG_CMD_SET_LINE_WIDTH, limit);
ctx->miterLimit = limit;
}
void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap){
+ if (ctx->status)
+ return;
RECORD(ctx, VKVG_CMD_SET_LINE_CAP, cap);
ctx->lineCap = cap;
}
void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join){
+ if (ctx->status)
+ return;
RECORD(ctx, VKVG_CMD_SET_LINE_JOIN, join);
ctx->lineJoin = join;
}
_bind_draw_pipeline (ctx);
}
void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr){
+ if (ctx->status)
+ return;
#ifndef __APPLE__
RECORD(ctx, VKVG_CMD_SET_FILL_RULE, fr);
ctx->curFillRule = fr;
#endif
}
vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx){
+ if (ctx->status)
+ return VKVG_FILL_RULE_NON_ZERO;
return ctx->curFillRule;
}
float vkvg_get_line_width (VkvgContext ctx){
+ if (ctx->status)
+ return 0;
return ctx->lineWidth;
}
void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset){
memcpy (ctx->dashes, dashes, sizeof(float) * ctx->dashCount);
}
void vkvg_get_dash (VkvgContext ctx, const float* dashes, uint32_t* num_dashes, float* offset){
+ if (ctx->status)
+ return;
*num_dashes = ctx->dashCount;
*offset = ctx->dashOffset;
if (ctx->dashCount == 0 || dashes == NULL)
vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx){
+ if (ctx->status)
+ return (vkvg_line_cap_t)0;
return ctx->lineCap;
}
vkvg_line_join_t vkvg_get_line_join (VkvgContext ctx){
+ if (ctx->status)
+ return (vkvg_line_join_t)0;
return ctx->lineJoin;
}
vkvg_operator_t vkvg_get_operator (VkvgContext ctx){
+ if (ctx->status)
+ return (vkvg_operator_t)0;
return ctx->curOperator;
}
VkvgPattern vkvg_get_source (VkvgContext ctx){
+ if (ctx->status)
+ return NULL;
vkvg_pattern_reference (ctx->pattern);
return ctx->pattern;
}
} vkvg_context_save_t;
typedef struct _vkvg_context_t {
+ vkvg_status_t status;
uint32_t references; //reference count
VkvgDevice dev;
push_constants pushConsts;
VkvgPattern pattern;
- vkvg_status_t status;
vkvg_context_save_t* pSavedCtxs; //last ctx saved ptr
uint8_t curSavBit; //current stencil bit used to save context, 6 bits used by stencil for save/restore
#define FONT_NAME_MAX_SIZE 128
#include "vkvg_internal.h"
-#include "vkvg.h"
-#include "vkvg_buff.h"
-#include "vkh.h"
-#include "vectors.h"
-
//texture coordinates of one character in font cache array texture.
typedef struct {
//30 seconds fence timeout
#define VKVG_FENCE_TIMEOUT 30000000000
//#define VKVG_FENCE_TIMEOUT 10000
+
+#include "vkvg.h"
+#include "vkvg_buff.h"
+#include "vkh.h"
+#include "vectors.h"
+
+/*typedef struct {
+ vkvg_status_t status;
+} _vkvg_no_mem_struct;*/
+
+static vkvg_status_t _no_mem_status = VKVG_STATUS_NO_MEMORY;
+
#endif
VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf){
VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t));
+ if (!pat)
+ return (VkvgPattern)&_no_mem_status;
+
pat->type = VKVG_PATTERN_TYPE_SURFACE;
pat->extend = VKVG_EXTEND_NONE;
pat->data = surf;
-
pat->references = 1;
+
vkvg_surface_reference (surf);
+ if (surf->status)
+ pat->status = surf->status;
return pat;
}
vkvg_status_t vkvg_pattern_get_linear_points (VkvgPattern pat, float* x0, float* y0, float* x1, float* y1) {
+ if (pat->status)
+ return pat->status;
if (pat->type != VKVG_PATTERN_TYPE_LINEAR)
return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
return VKVG_STATUS_SUCCESS;
}
vkvg_status_t vkvg_pattern_edit_linear (VkvgPattern pat, float x0, float y0, float x1, float y1){
+ if (pat->status)
+ return pat->status;
if (pat->type != VKVG_PATTERN_TYPE_LINEAR)
return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1){
VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t));
if (!pat)
- return NULL;
+ return (VkvgPattern)&_no_mem_status;
pat->type = VKVG_PATTERN_TYPE_LINEAR;
pat->extend = VKVG_EXTEND_NONE;
pat->data = (void*)calloc(1,sizeof(vkvg_gradient_t));
- if (!pat->data) {
- free (pat);
- return NULL;
- }
-
- vkvg_pattern_edit_linear(pat, x0, y0, x1, y1);
- pat->references = 1;
+ if (pat->data) {
+ vkvg_pattern_edit_linear(pat, x0, y0, x1, y1);
+ pat->references = 1;
+ } else
+ pat->status = VKVG_STATUS_NO_MEMORY;
return pat;
}
vkvg_status_t vkvg_pattern_edit_radial (VkvgPattern pat,
float cx0, float cy0, float radius0,
float cx1, float cy1, float radius1) {
+ if (pat->status)
+ return pat->status;
if (pat->type != VKVG_PATTERN_TYPE_RADIAL)
return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
float cx1, float cy1, float radius1){
VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t));
if (!pat)
- return NULL;
+ return (VkvgPattern)&_no_mem_status;
pat->type = VKVG_PATTERN_TYPE_RADIAL;
pat->extend = VKVG_EXTEND_NONE;
pat->data = (void*)calloc(1,sizeof(vkvg_gradient_t));
- if (!pat->data) {
- free (pat);
- return NULL;
- }
- vkvg_pattern_edit_radial (pat, cx0, cy0, radius0, cx1, cy1, radius1);
-
- pat->references = 1;
+ if (pat->data) {
+ vkvg_pattern_edit_radial (pat, cx0, cy0, radius0, cx1, cy1, radius1);
+ pat->references = 1;
+ } else
+ pat->status = VKVG_STATUS_NO_MEMORY;
return pat;
}
VkvgPattern vkvg_pattern_reference (VkvgPattern pat) {
- pat->references++;
+ if (!pat->status)
+ pat->references++;
return pat;
}
uint32_t vkvg_pattern_get_reference_count (VkvgPattern pat) {
+ if (pat->status)
+ return 0;
return pat->references;
}
vkvg_status_t vkvg_pattern_add_color_stop (VkvgPattern pat, float offset, float r, float g, float b, float a) {
+ if (pat->status)
+ return pat->status;
if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
grad->count++;
}
void vkvg_pattern_set_extend (VkvgPattern pat, vkvg_extend_t extend){
+ if (pat->status)
+ return;
pat->extend = extend;
}
void vkvg_pattern_set_filter (VkvgPattern pat, vkvg_filter_t filter){
+ if (pat->status)
+ return;
pat->filter = filter;
}
vkvg_extend_t vkvg_pattern_get_extend (VkvgPattern pat){
+ if (pat->status)
+ return (vkvg_extend_t)0;
return pat->extend;
}
vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat){
+ if (pat->status)
+ return (vkvg_filter_t)0;
return pat->filter;
}
vkvg_pattern_type_t vkvg_pattern_get_type (VkvgPattern pat){
+ if (pat->status)
+ return (vkvg_pattern_type_t)0;
return pat->type;
}
vkvg_status_t vkvg_pattern_get_color_stop_count (VkvgPattern pat, uint32_t* count) {
+ if (pat->status)
+ return pat->status;
if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
}
vkvg_status_t vkvg_pattern_get_color_stop_rgba (VkvgPattern pat, uint32_t index,
float* offset, float* r, float* g, float* b, float* a) {
+ if (pat->status)
+ return pat->status;
if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
return VKVG_STATUS_SUCCESS;
}
void vkvg_pattern_set_matrix (VkvgPattern pat, const vkvg_matrix_t* matrix) {
+ if (pat->status)
+ return;
pat->matrix = *matrix;
pat->hasMatrix = true;
}
void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix) {
+ if (pat->status)
+ return;
if (pat->hasMatrix)
*matrix = pat->matrix;
else
*matrix = VKVG_IDENTITY_MATRIX;
}
+vkvg_status_t vkvg_pattern_status (VkvgPattern pat) {
+ return pat->status;
+}
void vkvg_pattern_destroy(VkvgPattern pat)
{
+ if (pat->status)
+ return;
pat->references--;
if (pat->references > 0)
return;
#define VKVG_PATTERN_H
#include "vkvg_internal.h"
-#include "vkvg.h"
-#include "vkh.h"
typedef struct _vkvg_pattern_t {
+ vkvg_status_t status;
+ uint32_t references;
vkvg_pattern_type_t type;
vkvg_extend_t extend;
vkvg_filter_t filter;
vkvg_matrix_t matrix;
bool hasMatrix;
void* data;
- uint32_t references;
}vkvg_pattern_t;
typedef struct _vkvg_gradient_t {
}
VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height){
VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
- if (!surf || surf->status)
+ if (surf->status)
return surf;
surf->width = MAX(1, width);
}
VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg) {
VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
- if (!surf || surf->status)
+ if (surf->status)
return surf;
if (!vkhImg) {
//TODO: it would be better to blit in original size and create ms final image with dest surf dims
VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, uint32_t width, uint32_t height) {
VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
- if (!surf || surf->status)
+ if (surf->status)
return surf;
if (!img || width <= 0 || height <= 0) {
surf->status = VKVG_STATUS_INVALID_IMAGE;
h = 0,
channels = 0;
unsigned char *img = stbi_load(filePath, &w, &h, &channels, 4);//force 4 components per pixel
- if (img == NULL){
- fprintf (stderr, "Could not load texture from %s, %s\n", filePath, stbi_failure_reason());
- return NULL;
+ if (!img){
+ LOG(VKVG_LOG_ERR, "Could not load texture from %s, %s\n", filePath, stbi_failure_reason());
+ return (VkvgSurface)&_no_mem_status;
}
VkvgSurface surf = vkvg_surface_create_from_bitmap(dev, img, (uint32_t)w, (uint32_t)h);
void vkvg_surface_destroy(VkvgSurface surf)
{
+ if (surf->status)
+ return;
+
LOCK_SURFACE(surf)
surf->references--;
if (surf->references > 0) {
}
VkvgSurface vkvg_surface_reference (VkvgSurface surf) {
- LOCK_SURFACE(surf)
- surf->references++;
- UNLOCK_SURFACE(surf)
+ if (!surf->status) {
+ LOCK_SURFACE(surf)
+ surf->references++;
+ UNLOCK_SURFACE(surf)
+ }
return surf;
}
uint32_t vkvg_surface_get_reference_count (VkvgSurface surf) {
+ if (surf->status)
+ return 0;
return surf->references;
}
}
VkFormat vkvg_surface_get_vk_format(VkvgSurface surf)
{
+ if (surf->status)
+ return VK_FORMAT_UNDEFINED;
return surf->format;
}
uint32_t vkvg_surface_get_width (VkvgSurface surf) {
+ if (surf->status)
+ return 0;
return surf->width;
}
uint32_t vkvg_surface_get_height (VkvgSurface surf) {
+ if (surf->status)
+ return 0;
return surf->height;
}
}
VkvgSurface _create_surface (VkvgDevice dev, VkFormat format) {
VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface));
- if (!surf) {
- dev->status = VKVG_STATUS_NO_MEMORY;
- return NULL;
- }
+ if (!surf)
+ return (VkvgSurface)&_no_mem_status;
+
surf->references = 1;
if (dev->status != VKVG_STATUS_SUCCESS) {
surf->status = VKVG_STATUS_DEVICE_ERROR;
#include "vkh.h"
typedef struct _vkvg_surface_t {
+ vkvg_status_t status; /**< Current status of surface, affected by last operation */
+ uint32_t references;
VkvgDevice dev;
uint32_t width;
uint32_t height;
VkhImage img;
VkhImage imgMS;
VkhImage stencil;
- uint32_t references;
- vkvg_status_t status; /**< Current status of surface, affected by last operation */
bool new;
mtx_t mutex;
}vkvg_surface;