diff --git a/library/include/borealis/extern/nanovg/nanovg_gxm.h b/library/include/borealis/extern/nanovg/nanovg_gxm.h index f0f33cc6c..263250118 100644 --- a/library/include/borealis/extern/nanovg/nanovg_gxm.h +++ b/library/include/borealis/extern/nanovg/nanovg_gxm.h @@ -26,8 +26,7 @@ extern "C" #include "nanovg_gxm_utils.h" // Create flags - enum NVGcreateFlags - { + enum NVGcreateFlags { // Flag indicating if geometry based anti-aliasing is used (may not be needed when using MSAA). NVG_ANTIALIAS = 1 << 0, // Flag indicating if strokes should be drawn using stencil buffer. The rendering will be a little @@ -37,13 +36,16 @@ extern "C" NVG_DEBUG = 1 << 2, }; - NVGcontext* nvgCreateGXM(NVGXMframebuffer* fb, int flags); + NVGcontext *nvgCreateGXM(SceGxmContext *context, SceGxmShaderPatcher *shader_patcher, int flags); + + void nvgDeleteGXM(NVGcontext *ctx); - void nvgDeleteGXM(NVGcontext* ctx); + int nvgxmCreateImageFromHandle(NVGcontext *ctx, SceGxmTexture *texture); + + NVGXMtexture *nvgxmImageHandle(NVGcontext *ctx, int image); // These are additional flags on top of NVGimageFlags. - enum NVGimageFlagsGXM - { + enum NVGimageFlagsGXM { NVG_IMAGE_NODELETE = 1 << 16, // Do not delete GXM texture handle. }; @@ -68,48 +70,44 @@ extern "C" #include -static void shark_log_cb(const char* msg, shark_log_level msg_level, int line) -{ - switch (msg_level) - { +static void shark_log_cb(const char *msg, shark_log_level msg_level, int line) { + switch (msg_level) { case SHARK_LOG_INFO: - sceClibPrintf("\033[0;34m[GXP #%d]\033[0m %s\n", line, msg); + fprintf(stdout, "\033[0;34m[GXP #%d]\033[0m %s\n", line, msg); break; case SHARK_LOG_WARNING: - sceClibPrintf("\033[0;33m[GXP #%d]\033[0m %s\n", line, msg); + fprintf(stdout, "\033[0;33m[GXP #%d]\033[0m %s\n", line, msg); break; case SHARK_LOG_ERROR: - sceClibPrintf("\033[0;31m[GXP #%d]\033[0m %s\n", line, msg); + fprintf(stdout, "\033[0;31m[GXP #%d]\033[0m %s\n", line, msg); break; } + fflush(stdout); } #endif -enum GXMNVGuniformLoc -{ +enum GXMNVGuniformLoc { GXMNVG_LOC_VIEWSIZE, GXMNVG_LOC_FRAG, GXMNVG_MAX_LOCS }; -enum GXMNVGshaderType -{ +enum GXMNVGshaderType { + NSVG_SHADER_FILLCOLOR, NSVG_SHADER_FILLGRAD, NSVG_SHADER_FILLIMG, NSVG_SHADER_SIMPLE, NSVG_SHADER_IMG }; -struct GXMNVGshader -{ +struct GXMNVGshader { NVGXMshaderProgram prog; - const SceGxmProgramParameter* loc[GXMNVG_MAX_LOCS]; + const SceGxmProgramParameter *loc[GXMNVG_MAX_LOCS]; }; typedef struct GXMNVGshader GXMNVGshader; -struct GXMNVGtexture -{ +struct GXMNVGtexture { int id; int width, height; int type; @@ -117,14 +115,12 @@ struct GXMNVGtexture int stride; int unused; - SceGxmTexture gxm_tex; - uint8_t* tex_data; - SceUID data_UID; + + NVGXMtexture texture; }; typedef struct GXMNVGtexture GXMNVGtexture; -struct GXMNVGblend -{ +struct GXMNVGblend { SceGxmBlendFactor srcRGB; SceGxmBlendFactor dstRGB; SceGxmBlendFactor srcAlpha; @@ -132,8 +128,7 @@ struct GXMNVGblend }; typedef struct GXMNVGblend GXMNVGblend; -enum GXMNVGcallType -{ +enum GXMNVGcallType { GXMNVG_NONE = 0, GXMNVG_FILL, GXMNVG_CONVEXFILL, @@ -141,8 +136,7 @@ enum GXMNVGcallType GXMNVG_TRIANGLES, }; -struct GXMNVGcall -{ +struct GXMNVGcall { int type; int image; int pathOffset; @@ -154,8 +148,7 @@ struct GXMNVGcall }; typedef struct GXMNVGcall GXMNVGcall; -struct GXMNVGpath -{ +struct GXMNVGpath { int fillOffset; int fillCount; int strokeOffset; @@ -163,15 +156,12 @@ struct GXMNVGpath }; typedef struct GXMNVGpath GXMNVGpath; -struct GXMNVGfragUniforms -{ +struct GXMNVGfragUniforms { // note: after modifying layout or size of uniform array, // don't forget to also update the fragment shader source! #define NANOVG_GXM_UNIFORMARRAY_SIZE 11 - union - { - struct - { + union { + struct { float scissorMat[12]; // matrices are actually float3x4 float paintMat[12]; struct NVGcolor innerCol; @@ -191,19 +181,17 @@ struct GXMNVGfragUniforms }; typedef struct GXMNVGfragUniforms GXMNVGfragUniforms; -struct GXMNVGcontext -{ - SceGxmContext* context; - SceGxmShaderPatcher* shader_patcher; - SceGxmMultisampleMode msaa; +struct GXMNVGcontext { + SceGxmContext *context; + SceGxmShaderPatcher *shader_patcher; GXMNVGshader shader; SceUID verticesUid; - struct NVGvertex* vertBuf; + struct NVGvertex *vertBuf; GXMNVGshader depth_shader; - GXMNVGtexture* textures; + GXMNVGtexture *textures; float view[2]; int ntextures; int ctextures; @@ -212,16 +200,16 @@ struct GXMNVGcontext int flags; // Per frame buffers - GXMNVGcall* calls; + GXMNVGcall *calls; int ccalls; int ncalls; - GXMNVGpath* paths; + GXMNVGpath *paths; int cpaths; int npaths; - struct NVGvertex* verts; + struct NVGvertex *verts; int cverts; int nverts; - unsigned char* uniforms; + unsigned char *uniforms; int cuniforms; int nuniforms; @@ -229,16 +217,14 @@ struct GXMNVGcontext }; typedef struct GXMNVGcontext GXMNVGcontext; -static void gxmDrawArrays(GXMNVGcontext* gxm, SceGxmPrimitiveType type, int fillOffset, int fillCount) -{ - if (fillCount > UINT16_MAX) - { + +static void gxmDrawArrays(GXMNVGcontext *gxm, SceGxmPrimitiveType type, int fillOffset, int fillCount) { + if (fillCount > UINT16_MAX) { return; } static int index = 0; - if (index + fillCount > nvg_gxm_vertex_buffer_size) - { + if (index + fillCount > nvg_gxm_vertex_buffer_size) { index = 0; } @@ -251,57 +237,38 @@ static void gxmDrawArrays(GXMNVGcontext* gxm, SceGxmPrimitiveType type, int fill static int gxmnvg__maxi(int a, int b) { return a > b ? a : b; } -static unsigned int gxmnvg__nearestPow2(unsigned int num) -{ - unsigned n = num > 0 ? num - 1 : 0; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - n++; - return n; -} - static void -gxmnvg__stencilFunc(GXMNVGcontext* gxm, SceGxmStencilFunc func, SceGxmStencilOp stencilFail, SceGxmStencilOp depthFail, - SceGxmStencilOp depthPass) -{ +gxmnvg__stencilFunc(GXMNVGcontext *gxm, SceGxmStencilFunc func, SceGxmStencilOp stencilFail, SceGxmStencilOp depthFail, + SceGxmStencilOp depthPass) { sceGxmSetFrontStencilFunc(gxm->context, func, stencilFail, depthFail, depthPass, 0xff, 0xff); sceGxmSetBackStencilFunc(gxm->context, func, stencilFail, depthFail, depthPass, 0xff, 0xff); } -static void gxmnvg__disableStencilTest(GXMNVGcontext* gxm) -{ +static void gxmnvg__disableStencilTest(GXMNVGcontext *gxm) { gxmnvg__stencilFunc(gxm, SCE_GXM_STENCIL_FUNC_ALWAYS, SCE_GXM_STENCIL_OP_KEEP, SCE_GXM_STENCIL_OP_KEEP, SCE_GXM_STENCIL_OP_KEEP); } -// static void gxmnvg__blendFuncSeparate(GXMNVGcontext *gxm, const GXMNVGblend *blend) {} +//static void gxmnvg__blendFuncSeparate(GXMNVGcontext *gxm, const GXMNVGblend *blend) {} -static GXMNVGtexture* gxmnvg__allocTexture(GXMNVGcontext* gxm) -{ - GXMNVGtexture* tex = NULL; +static GXMNVGtexture *gxmnvg__allocTexture(GXMNVGcontext *gxm) { + GXMNVGtexture *tex = NULL; int i; - for (i = 0; i < gxm->ntextures; i++) - { - if (gxm->textures[i].id == 0) - { + for (i = 0; i < gxm->ntextures; i++) { + if (gxm->textures[i].id == 0) { tex = &gxm->textures[i]; break; } } - if (tex == NULL) - { - if (gxm->ntextures + 1 > gxm->ctextures) - { - GXMNVGtexture* textures; + if (tex == NULL) { + if (gxm->ntextures + 1 > gxm->ctextures) { + GXMNVGtexture *textures; int ctextures = gxmnvg__maxi(gxm->ntextures + 1, 4) + gxm->ctextures / 2; // 1.5x Overallocate - textures = (GXMNVGtexture*)realloc(gxm->textures, sizeof(GXMNVGtexture) * ctextures); + textures = (GXMNVGtexture *) realloc(gxm->textures, sizeof(GXMNVGtexture) * ctextures); if (textures == NULL) return NULL; - gxm->textures = textures; + gxm->textures = textures; gxm->ctextures = ctextures; } tex = &gxm->textures[gxm->ntextures++]; @@ -313,8 +280,7 @@ static GXMNVGtexture* gxmnvg__allocTexture(GXMNVGcontext* gxm) return tex; } -static GXMNVGtexture* gxmnvg__findTexture(GXMNVGcontext* gxm, int id) -{ +static GXMNVGtexture *gxmnvg__findTexture(GXMNVGcontext *gxm, int id) { int i; for (i = 0; i < gxm->ntextures; i++) if (gxm->textures[i].id == id) @@ -322,15 +288,11 @@ static GXMNVGtexture* gxmnvg__findTexture(GXMNVGcontext* gxm, int id) return NULL; } -static int gxmnvg__deleteTexture(GXMNVGcontext* gxm, int id) -{ +static int gxmnvg__deleteTexture(GXMNVGcontext *gxm, int id) { int i; - for (i = 0; i < gxm->ntextures; i++) - { - if (gxm->textures[i].id == id) - { - if (gxm->textures[i].data_UID != 0 && (gxm->textures[i].flags & NVG_IMAGE_NODELETE) == 0) - { + for (i = 0; i < gxm->ntextures; i++) { + if (gxm->textures[i].id == id) { + if (gxm->textures[i].texture.uid != 0 && (gxm->textures[i].flags & NVG_IMAGE_NODELETE) == 0) { gxm->textures[i].unused = 1; } return 1; @@ -339,41 +301,35 @@ static int gxmnvg__deleteTexture(GXMNVGcontext* gxm, int id) return 0; } -static int gxmnvg__garbageCollector(GXMNVGcontext* gxm) -{ +static int gxmnvg__garbageCollector(GXMNVGcontext *gxm) { int i; - for (i = 0; i < gxm->ntextures; i++) - { + for (i = 0; i < gxm->ntextures; i++) { if (gxm->textures[i].unused == 0) continue; - gpu_unmap_free(gxm->textures[i].data_UID); + gpu_unmap_free(gxm->textures[i].texture.uid); memset(&gxm->textures[i], 0, sizeof(gxm->textures[i])); } return 0; } -static int gxmnvg__createShader(GXMNVGshader* shader, const char* name, const char* vshader, const char* fshader) -{ +static int gxmnvg__createShader(GXMNVGshader *shader, const char *name, const char *vshader, const char *fshader) { return gxmCreateShader(&shader->prog, name, vshader, fshader); } -static void gxmnvg__deleteShader(GXMNVGshader* shader) -{ +static void gxmnvg__deleteShader(GXMNVGshader *shader) { gxmDeleteShader(&shader->prog); } -static void gxmnvg__getUniforms(GXMNVGshader* shader) -{ +static void gxmnvg__getUniforms(GXMNVGshader *shader) { shader->loc[GXMNVG_LOC_VIEWSIZE] = sceGxmProgramFindParameterByName(shader->prog.vert_gxp, "viewSize"); - shader->loc[GXMNVG_LOC_FRAG] = sceGxmProgramFindParameterByName(shader->prog.frag_gxp, "frag"); + shader->loc[GXMNVG_LOC_FRAG] = sceGxmProgramFindParameterByName(shader->prog.frag_gxp, "frag"); } -static int gxmnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data); +static int gxmnvg__renderCreateTexture(void *uptr, int type, int w, int h, int imageFlags, const unsigned char *data); -static int gxmnvg__renderCreate(void* uptr) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - int align = 4; +static int gxmnvg__renderCreate(void *uptr) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + int align = 4; #if USE_VITA_SHARK char fillVertShader[500] = "struct VS_OUTPUT\n" @@ -441,26 +397,27 @@ static int gxmnvg__renderCreate(void* uptr) "#else\n" " float strokeAlpha = 1.0f;\n" "#endif\n" - " if (type == 0.0f) {\n" // Gradient + " if (type == 0.0f) {\n" // simple color + " float2 pt = (mul(paintMat, float3(fpos,1.0))).xy;\n" + " float4 color = innerCol;\n" + " color *= strokeAlpha * scissor;\n" + " result = color;\n" + " } else if (type == 1.0f) {\n" // Gradient " float2 pt = (mul(paintMat, float3(fpos,1.0))).xy;\n" " float d = clamp((sdroundrect(pt, extent, radius) + feather*0.5) / feather, 0.0, 1.0);\n" " float4 color = lerp(innerCol, outerCol, d);\n" - " color *= strokeAlpha * scissor;\n" // Combine alpha + " color *= strokeAlpha * scissor;\n" " result = color;\n" - " } else if (type == 1.0f) {\n" // Image + " } else if (type == 2.0f) {\n" // Image " float2 pt = (mul(paintMat, float3(fpos,1.0))).xy / extent.xy;\n" " float4 color = tex2D(tex, pt);\n" - " if (texType == 1.0f) color = float4(color.xyz*color.w, color.w);\n" - " if (texType == 2.0f) color = float4(color.x, color.x, color.x, color.x);\n" + " color = float4(color.xyz*color.w, color.w);\n" " color *= innerCol;\n" " color *= strokeAlpha * scissor;\n" " result = color;\n" - " } else if (type == 2.0f) {\n" // Stencil fill - " result = float4(1.0f, 1.0f, 1.0f, 1.0f);\n" " } else {\n" // Textured tris " float4 color = tex2D(tex, ftcoord);\n" - " if (texType == 1.0f) color = float4(color.xyz*color.w, color.w);\n" - " if (texType == 2.0f) color = float4(color.x, color.x, color.x, color.x);\n" + " color = float4(color.x, color.x, color.x, color.x);\n" " color *= scissor;\n" " result = (color * innerCol);\n" " }\n" @@ -469,14 +426,11 @@ static int gxmnvg__renderCreate(void* uptr) char depthFragShader[20] = "void main() {}"; - if (gxm->flags & NVG_ANTIALIAS) - { + if (gxm->flags & NVG_ANTIALIAS) { fillFragShader[16] = '1'; // #define EDGE_AA 1 if (gxmnvg__createShader(&gxm->shader, "fillAA", fillVertShader, fillFragShader) == 0) return 0; - } - else - { + } else { if (gxmnvg__createShader(&gxm->shader, "fill", fillVertShader, fillFragShader) == 0) return 0; } @@ -519,239 +473,204 @@ static int gxmnvg__renderCreate(void* uptr) 0x76, 0x69, 0x65, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00 }; - static const unsigned char fillFragShader[1184] = { - 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x00, 0x03, 0x9d, 0x04, 0x00, + static const unsigned char fillFragShader[984] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x00, 0x03, 0xd5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2c, 0x04, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x36, 0x00, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x5f, 0x00, 0x00, 0x00, 0xdc, 0x00, - 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xcc, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x64, 0x03, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x34, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0x00, 0x00, 0x00, 0xd4, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x2c, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x90, 0x3a, - 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd8, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xb0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x03, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0xdc, 0x03, + 0x00, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x90, 0x3a, + 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xe8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x10, 0x40, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x68, 0x43, 0x0a, 0x05, 0x82, 0x38, 0x01, 0x09, 0x80, 0x82, - 0x02, 0x00, 0x80, 0x30, 0x02, 0x09, 0x80, 0x82, 0x0a, 0x00, 0x80, - 0x30, 0xd2, 0x14, 0xc0, 0xa2, 0xa2, 0x41, 0x80, 0x08, 0xd9, 0x84, - 0xa4, 0xa2, 0x82, 0x00, 0x84, 0x08, 0x82, 0x09, 0x20, 0x80, 0x0a, - 0x00, 0x80, 0x30, 0x0e, 0x13, 0x04, 0xa1, 0xa6, 0x41, 0xa4, 0x08, - 0x4f, 0x13, 0x44, 0xa1, 0xaa, 0x41, 0xc0, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, 0x80, 0x8a, 0x03, 0xd0, 0x91, - 0xc1, 0xc9, 0x48, 0x02, 0x80, 0x81, 0xff, 0x9c, 0x0d, 0x80, 0x40, - 0x01, 0xd2, 0x11, 0x80, 0x80, 0x88, 0x81, 0x18, 0x06, 0x82, 0xa1, - 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x90, 0x00, 0x89, - 0x81, 0x18, 0x22, 0x90, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, 0x00, - 0x11, 0x1d, 0x00, 0xb4, 0x81, 0xa1, 0x18, 0x0c, 0xd0, 0x0f, 0x10, - 0xa0, 0x11, 0xa1, 0x00, 0x40, 0xd6, 0x24, 0xc0, 0x84, 0x41, 0xc0, - 0x08, 0x00, 0x60, 0x00, 0x40, 0x80, 0x41, 0x82, 0x08, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x10, 0x80, 0x08, 0x80, 0x18, 0x00, 0xe0, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x09, 0x80, 0x82, 0x02, 0x00, 0x80, 0x30, 0x02, 0x09, 0x80, 0x82, + 0x0a, 0x00, 0x80, 0x30, 0xd2, 0x14, 0xc0, 0xa2, 0xa2, 0x41, 0x80, + 0x08, 0xd9, 0x84, 0xa4, 0xa2, 0x82, 0x00, 0x84, 0x08, 0x82, 0x09, + 0x20, 0x80, 0x0a, 0x00, 0x80, 0x30, 0x0e, 0x13, 0x04, 0xa1, 0xa6, + 0x41, 0xa4, 0x08, 0x4f, 0x13, 0x44, 0xa1, 0xaa, 0x41, 0xc0, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, 0x80, 0x8a, + 0x03, 0xd0, 0x91, 0xc1, 0xc9, 0x48, 0x02, 0x80, 0x81, 0xff, 0x9c, + 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x80, 0x80, 0x88, 0x81, 0x18, + 0x06, 0x82, 0xa1, 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, + 0x90, 0x00, 0x89, 0x81, 0x18, 0x22, 0x90, 0xb9, 0xff, 0xbc, 0x0d, + 0xc0, 0x40, 0x00, 0x11, 0x1d, 0x00, 0xb4, 0x81, 0xa1, 0x18, 0x0c, + 0xd0, 0x0f, 0x10, 0xa0, 0x11, 0xa1, 0x00, 0x40, 0xd6, 0x24, 0xc0, + 0x84, 0x41, 0xc0, 0x08, 0x00, 0x60, 0x00, 0x40, 0x80, 0x41, 0x82, + 0x08, 0x00, 0x00, 0x80, 0x00, 0x80, 0x10, 0x80, 0x08, 0x80, 0x18, + 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, 0x00, 0x18, 0x00, 0xe0, 0x08, + 0x00, 0x81, 0x55, 0x30, 0x00, 0x0a, 0x30, 0x81, 0x02, 0xa8, 0x48, + 0x02, 0x03, 0x04, 0xc0, 0x84, 0x01, 0xa4, 0x08, 0x42, 0x03, 0x44, + 0xc0, 0x88, 0x01, 0xc0, 0x08, 0x35, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0xf9, 0x82, 0x8a, 0x03, 0xd0, 0x91, 0xc1, 0x89, 0x48, 0x80, + 0x18, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, 0x00, 0x18, 0x00, 0xe0, + 0x08, 0x00, 0x81, 0x55, 0x30, 0x00, 0x0a, 0x30, 0x81, 0x02, 0xa8, + 0x48, 0x1a, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf9, 0x84, 0x8a, + 0x03, 0xd0, 0x91, 0xc1, 0x89, 0x48, 0x80, 0x18, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, 0x00, 0x18, 0x00, 0xe0, 0x08, 0x00, 0x81, 0x55, - 0x30, 0x00, 0x0a, 0x30, 0x81, 0x02, 0xa8, 0x48, 0x39, 0x00, 0x00, - 0x00, 0x40, 0x00, 0x00, 0xf9, 0x82, 0x8a, 0x03, 0xd0, 0x91, 0xc1, - 0x89, 0x48, 0x80, 0x18, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, 0x00, - 0x18, 0x00, 0xe0, 0x08, 0x00, 0x81, 0x55, 0x30, 0x00, 0x0a, 0x30, - 0x81, 0x02, 0xa8, 0x48, 0x1c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, - 0xf9, 0x84, 0x8a, 0x03, 0xd0, 0x91, 0xc1, 0x89, 0x48, 0x80, 0x18, - 0x40, 0xe0, 0x02, 0x10, 0x81, 0x91, 0x00, 0x18, 0x40, 0xe0, 0x0a, - 0x00, 0x81, 0x55, 0x30, 0x01, 0x0a, 0xb0, 0x81, 0x02, 0xa8, 0x48, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf9, 0x82, 0x8a, 0x03, - 0xd0, 0x81, 0x81, 0x89, 0x48, 0x00, 0x0b, 0x00, 0xe0, 0x04, 0xc4, - 0x01, 0xe0, 0x80, 0x18, 0x00, 0xe0, 0x02, 0x10, 0x81, 0x91, 0x00, - 0x18, 0x00, 0xe0, 0x0a, 0x00, 0x81, 0x55, 0x30, 0x00, 0x0a, 0xb0, - 0x81, 0x02, 0xa8, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - 0xf9, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xfd, 0x40, 0x80, - 0x24, 0x00, 0x80, 0x41, 0x84, 0x08, 0x41, 0x00, 0x44, 0x00, 0x88, - 0x10, 0xc0, 0x08, 0x84, 0x8a, 0x03, 0xd0, 0x81, 0x81, 0x89, 0x48, - 0x80, 0x18, 0x00, 0xe0, 0x02, 0x10, 0x81, 0x91, 0x00, 0x18, 0x00, - 0xe0, 0x0a, 0x00, 0x81, 0x55, 0x30, 0x00, 0x0a, 0xb0, 0x81, 0x02, - 0x88, 0x48, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x80, 0x39, 0x00, - 0x00, 0x04, 0x03, 0x20, 0x0d, 0x80, 0x39, 0x02, 0x00, 0x04, 0x0f, - 0x84, 0x0f, 0xa4, 0x08, 0x0c, 0x81, 0x11, 0xc0, 0x82, 0x81, 0xe1, - 0x18, 0x0d, 0x0f, 0x4d, 0x30, 0x82, 0x41, 0x80, 0x08, 0x32, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x00, 0xf8, 0x34, 0x1a, 0x03, 0xf0, 0x8e, - 0x0d, 0x80, 0x40, 0x34, 0x1a, 0x43, 0xf0, 0x8e, 0x0d, 0x80, 0x40, - 0x2f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf8, 0x82, 0x8a, 0x03, - 0xd0, 0x81, 0x81, 0xc9, 0x48, 0x0e, 0x86, 0x81, 0xff, 0x9c, 0x0d, - 0x00, 0x40, 0x01, 0xd2, 0x11, 0x80, 0x82, 0x88, 0x01, 0x18, 0x12, - 0x88, 0xa1, 0xff, 0x9c, 0x0d, 0x00, 0x40, 0x01, 0xd2, 0x11, 0x90, - 0x02, 0x81, 0x01, 0x18, 0x14, 0x00, 0x04, 0xb0, 0x86, 0x41, 0x24, - 0x08, 0x00, 0x0b, 0x00, 0xe0, 0x04, 0xc4, 0x01, 0xe0, 0x80, 0x18, - 0x00, 0xe0, 0x02, 0x10, 0x81, 0x91, 0x00, 0x18, 0x00, 0xe0, 0x0a, - 0x00, 0x81, 0x55, 0x30, 0x00, 0x0a, 0xb0, 0x81, 0x02, 0xa8, 0x48, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf9, 0x03, 0x00, 0x00, - 0x00, 0x40, 0x00, 0x00, 0xfd, 0x40, 0x80, 0x24, 0x00, 0x80, 0x41, - 0x84, 0x08, 0x41, 0x00, 0x44, 0x00, 0x88, 0x10, 0xc0, 0x08, 0x84, - 0x8a, 0x03, 0xd0, 0x81, 0x81, 0x89, 0x48, 0x80, 0x18, 0x00, 0xe0, - 0x02, 0x10, 0x81, 0x91, 0x00, 0x18, 0x00, 0xe0, 0x0a, 0x00, 0x81, - 0x55, 0x30, 0x00, 0x0a, 0xb0, 0x81, 0x02, 0xc8, 0x48, 0x02, 0x80, - 0x99, 0x0f, 0xbc, 0x0d, 0xc0, 0x40, 0x00, 0x0f, 0xf0, 0x0f, 0x00, - 0x0d, 0x80, 0x39, 0x3c, 0x03, 0x04, 0xcf, 0x84, 0x4f, 0xa4, 0x08, - 0x02, 0x80, 0x11, 0x00, 0x82, 0x81, 0xe1, 0x18, 0x02, 0x0f, 0x4d, - 0x00, 0x82, 0x01, 0x80, 0x08, 0x17, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0xf8, 0x0e, - 0x86, 0x81, 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x80, - 0x82, 0x88, 0x81, 0x18, 0x12, 0x88, 0xa1, 0xff, 0x9c, 0x0d, 0x80, - 0x40, 0x01, 0xd2, 0x11, 0x90, 0x02, 0x81, 0x81, 0x18, 0xc0, 0x12, - 0x04, 0xe0, 0xb6, 0x49, 0xa4, 0x08, 0x00, 0x60, 0x04, 0xaf, 0x84, - 0x18, 0xa4, 0x08, 0x00, 0x5f, 0x44, 0x1f, 0x84, 0x08, 0xa5, 0x08, - 0x00, 0x60, 0x04, 0x9f, 0x84, 0x09, 0xa5, 0x08, 0x3c, 0x42, 0x3e, - 0x0f, 0x80, 0x88, 0x81, 0x18, 0x01, 0x3e, 0x80, 0x0f, 0x00, 0x0a, - 0x80, 0x30, 0x01, 0x3e, 0x80, 0x0f, 0x00, 0x08, 0x80, 0x30, 0x3d, - 0x00, 0x1c, 0x0f, 0x84, 0x88, 0xa1, 0x18, 0xfc, 0x14, 0x10, 0xcf, - 0xa8, 0x08, 0xc0, 0x08, 0x0a, 0x00, 0x1c, 0xcf, 0x84, 0x88, 0xa1, - 0x18, 0x41, 0x80, 0x01, 0xcf, 0x80, 0x88, 0xe1, 0x18, 0x7c, 0xd6, - 0x28, 0xcf, 0x84, 0x08, 0xc0, 0x08, 0x3c, 0x60, 0x00, 0x4f, 0x80, - 0x08, 0x82, 0x08, 0x1a, 0x8c, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, - 0x04, 0x11, 0x01, 0xcf, 0x80, 0x8f, 0xb1, 0x18, 0x02, 0x80, 0x11, - 0x00, 0x82, 0x81, 0xe1, 0x18, 0x02, 0x0f, 0x4d, 0x00, 0x82, 0x01, - 0x80, 0x08, 0x02, 0x80, 0x19, 0xa0, 0x7e, 0x0d, 0x80, 0x40, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x01, 0xe4, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x02, 0x04, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x30, 0x00, 0x0a, 0x30, 0x81, 0x02, 0xa8, 0x48, 0x07, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0xf9, 0x00, 0x0b, 0x00, 0xe0, 0x84, 0xc4, + 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xf9, 0x02, + 0x00, 0x00, 0x8f, 0x80, 0x08, 0x80, 0x08, 0x0c, 0x81, 0x01, 0xc0, + 0x80, 0x81, 0xe1, 0x18, 0x0d, 0x81, 0x41, 0xc0, 0x80, 0x81, 0xe1, + 0x18, 0x25, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf8, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x09, 0x00, 0xf8, 0x0e, 0x86, 0x81, 0xff, 0x9c, + 0x0d, 0x00, 0x40, 0x01, 0xd2, 0x11, 0x80, 0x82, 0x88, 0x01, 0x18, + 0x12, 0x88, 0xa1, 0xff, 0x9c, 0x0d, 0x00, 0x40, 0x01, 0xd2, 0x11, + 0x90, 0x02, 0x81, 0x01, 0x18, 0x14, 0x00, 0x04, 0xb0, 0x86, 0x41, + 0x24, 0x08, 0x00, 0x0b, 0x00, 0xe0, 0x84, 0xc4, 0x01, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xf9, 0x02, 0x80, 0x99, 0xaf, + 0xbc, 0x0d, 0xc0, 0x40, 0x7c, 0x80, 0x24, 0x8f, 0x80, 0x4f, 0xc4, + 0x08, 0x3c, 0x03, 0x04, 0xcf, 0x84, 0x4f, 0xa4, 0x08, 0x02, 0x80, + 0x11, 0x00, 0x80, 0x81, 0xe1, 0x18, 0x02, 0x0f, 0x4d, 0x00, 0x80, + 0x01, 0x80, 0x08, 0x17, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0xf8, 0x0e, 0x86, 0x81, + 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x80, 0x82, 0x88, + 0x81, 0x18, 0x12, 0x88, 0xa1, 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, + 0xd2, 0x11, 0x90, 0x02, 0x81, 0x81, 0x18, 0xc0, 0x12, 0x04, 0xe0, + 0xb6, 0x49, 0xa4, 0x08, 0x00, 0x60, 0x04, 0xaf, 0x84, 0x18, 0xa4, + 0x08, 0x00, 0x5f, 0x44, 0x1f, 0x84, 0x08, 0xa5, 0x08, 0x00, 0x60, + 0x04, 0x9f, 0x84, 0x09, 0xa5, 0x08, 0x3c, 0x42, 0x3e, 0x0f, 0x80, + 0x88, 0x81, 0x18, 0x01, 0x3e, 0x80, 0x0f, 0x00, 0x0a, 0x80, 0x30, + 0x01, 0x3e, 0x80, 0x0f, 0x00, 0x08, 0x80, 0x30, 0x3d, 0x00, 0x1c, + 0x0f, 0x84, 0x88, 0xa1, 0x18, 0xfc, 0x14, 0x10, 0xcf, 0xa8, 0x08, + 0xc0, 0x08, 0x0a, 0x00, 0x1c, 0xcf, 0x84, 0x88, 0xa1, 0x18, 0x41, + 0x80, 0x01, 0xcf, 0x80, 0x88, 0xe1, 0x18, 0x7c, 0xd6, 0x28, 0xcf, + 0x84, 0x08, 0xc0, 0x08, 0x3c, 0x60, 0x00, 0x4f, 0x80, 0x08, 0x82, + 0x08, 0x1a, 0x8c, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, 0x04, 0x11, + 0x01, 0xcf, 0x80, 0x8f, 0xb1, 0x18, 0x02, 0x80, 0x11, 0x00, 0x80, + 0x81, 0xe1, 0x18, 0x02, 0x0f, 0x4d, 0x00, 0x80, 0x01, 0x80, 0x08, + 0x02, 0x80, 0x19, 0x00, 0x7e, 0x0d, 0x80, 0x40, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x2c, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x00, - 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x00, 0x74, 0x65, + 0x78, 0x00, 0x00, 0x00, 0x00 }; - static const unsigned char fillAAFragShader[1324] = { - 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x00, 0x03, 0x29, 0x05, 0x00, + static const unsigned char fillAAFragShader[1140] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x00, 0x03, 0x71, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x3a, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x6e, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xcc, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x38, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, 0x00, 0x00, 0x00, 0xd8, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x2c, 0x00, 0x00, 0x00, 0x58, 0x04, 0x00, 0x00, 0x90, 0x3a, - 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x64, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x3c, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x04, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x00, 0x68, 0x04, + 0x00, 0x2c, 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0x00, 0x90, 0x3a, + 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xac, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x84, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x03, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x84, 0x03, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x10, 0x40, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x70, 0x43, 0x0a, 0x05, 0x82, 0x38, 0x01, 0x09, 0x60, 0x83, - 0x02, 0x00, 0x80, 0x30, 0x02, 0x09, 0x60, 0x83, 0x0a, 0x00, 0x80, - 0x30, 0xd2, 0x14, 0xc0, 0xa2, 0xa2, 0x41, 0x80, 0x08, 0xd9, 0x84, - 0xa4, 0xa2, 0x82, 0x10, 0x84, 0x08, 0x82, 0x09, 0x20, 0x80, 0x0a, - 0x00, 0x80, 0x30, 0x0e, 0x13, 0x04, 0xa1, 0xa6, 0x41, 0xa4, 0x08, - 0x4f, 0x13, 0x44, 0xa1, 0xaa, 0x41, 0xc0, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0xfa, 0x9a, - 0x06, 0x00, 0xf0, 0x8c, 0x28, 0x80, 0x00, 0x1a, 0x10, 0x04, 0x3f, - 0xe4, 0x10, 0xa4, 0x08, 0x14, 0x80, 0x01, 0xc0, 0x80, 0x80, 0xe1, - 0x18, 0x80, 0x00, 0x20, 0xa0, 0x08, 0x00, 0x81, 0x50, 0x80, 0xd6, - 0x24, 0xc0, 0x84, 0x41, 0xc0, 0x08, 0x00, 0x00, 0xc0, 0x00, 0x80, - 0x10, 0x80, 0x08, 0x03, 0x8a, 0x00, 0xc0, 0x91, 0xc6, 0x8c, 0x48, - 0x00, 0x19, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, 0x80, 0x16, 0x00, - 0xe0, 0x08, 0x00, 0x81, 0x55, 0x2d, 0x00, 0x0a, 0x30, 0x85, 0x01, - 0x88, 0x48, 0x2c, 0x16, 0x00, 0xf0, 0x06, 0x04, 0x30, 0xf9, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x07, 0x44, 0xfa, 0x80, 0x8a, 0x03, 0xd0, 0x91, 0xc1, 0xc9, - 0x48, 0x02, 0x80, 0x81, 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, - 0x11, 0x80, 0x80, 0x88, 0x81, 0x18, 0x06, 0x82, 0xa1, 0xff, 0x9c, - 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x90, 0x00, 0x89, 0x81, 0x18, - 0x22, 0x90, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, 0x00, 0x11, 0x1d, - 0x00, 0xb4, 0x81, 0xa1, 0x18, 0x0c, 0xd0, 0x0f, 0x10, 0xa0, 0x11, - 0xa1, 0x00, 0x80, 0xd6, 0x24, 0xc0, 0x84, 0x41, 0xc0, 0x08, 0x00, - 0x60, 0x00, 0x40, 0x80, 0x41, 0x82, 0x08, 0x00, 0x00, 0x80, 0x00, - 0x80, 0x10, 0x80, 0x08, 0x00, 0x19, 0x00, 0xe0, 0x00, 0x10, 0x81, - 0x91, 0x80, 0x16, 0x00, 0xe0, 0x08, 0x00, 0x81, 0x55, 0x2d, 0x00, - 0x0a, 0x30, 0x81, 0x02, 0xa8, 0x48, 0x3a, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0xf9, 0x82, 0x8a, 0x03, 0xd0, 0x91, 0xc1, 0x89, 0x48, - 0x00, 0x19, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, 0x80, 0x16, 0x00, - 0xe0, 0x08, 0x00, 0x81, 0x55, 0x2d, 0x00, 0x0a, 0x30, 0x81, 0x02, - 0xa8, 0x48, 0x1c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf9, 0x84, - 0x8a, 0x03, 0xd0, 0x91, 0xc1, 0x89, 0x48, 0x00, 0x19, 0x40, 0xe0, - 0x02, 0x10, 0x81, 0x91, 0x80, 0x16, 0x40, 0xe0, 0x0a, 0x00, 0x81, - 0x55, 0x2d, 0x01, 0x0a, 0xb0, 0x81, 0x02, 0xa8, 0x48, 0x14, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x00, 0xf9, 0x82, 0x8a, 0x03, 0xd0, 0x81, - 0x81, 0x89, 0x48, 0x80, 0x0b, 0x00, 0xe0, 0x04, 0xc4, 0x01, 0xe0, - 0x00, 0x19, 0x00, 0xe0, 0x02, 0x10, 0x81, 0x91, 0x80, 0x16, 0x00, - 0xe0, 0x0a, 0x00, 0x81, 0x55, 0x2d, 0x00, 0x0a, 0xb0, 0x81, 0x02, - 0xa8, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf9, 0x03, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xfd, 0x40, 0x80, 0x24, 0x00, - 0x80, 0x41, 0x84, 0x08, 0x41, 0x00, 0x44, 0x00, 0x88, 0x10, 0xc0, - 0x08, 0x84, 0x8a, 0x03, 0xd0, 0x81, 0x81, 0x89, 0x48, 0x00, 0x19, - 0x00, 0xe0, 0x02, 0x10, 0x81, 0x91, 0x80, 0x16, 0x00, 0xe0, 0x0a, - 0x00, 0x81, 0x55, 0x2d, 0x00, 0x0a, 0xb0, 0x81, 0x02, 0x88, 0x48, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x80, 0x39, 0x00, 0x00, 0x04, - 0x03, 0x20, 0x0d, 0x80, 0x39, 0x02, 0x00, 0x04, 0x0f, 0x84, 0x0f, - 0xa4, 0x08, 0x0c, 0x81, 0x11, 0xc0, 0x82, 0x81, 0xe1, 0x18, 0x0d, - 0x0f, 0x4d, 0x30, 0x82, 0x41, 0x80, 0x08, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0xf8, 0x38, 0x1c, 0x03, 0xf0, 0x8e, 0x0d, 0x80, - 0x40, 0x38, 0x1c, 0x43, 0xf0, 0x8e, 0x0d, 0x80, 0x40, 0x31, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x00, 0xf8, 0x82, 0x8a, 0x03, 0xd0, 0x81, - 0x81, 0xc9, 0x48, 0x0e, 0x86, 0x81, 0xff, 0x9c, 0x0d, 0x00, 0x40, - 0x01, 0xd2, 0x11, 0x80, 0x82, 0x88, 0x01, 0x18, 0x12, 0x88, 0xa1, - 0xff, 0x9c, 0x0d, 0x00, 0x40, 0x01, 0xd2, 0x11, 0x90, 0x02, 0x81, - 0x01, 0x18, 0x1b, 0x00, 0x04, 0xb0, 0x86, 0x41, 0x24, 0x08, 0x80, - 0x0b, 0x00, 0xe0, 0x04, 0xc4, 0x01, 0xe0, 0x00, 0x19, 0x00, 0xe0, - 0x02, 0x10, 0x81, 0x91, 0x80, 0x16, 0x00, 0xe0, 0x0a, 0x00, 0x81, - 0x55, 0x2d, 0x00, 0x0a, 0xb0, 0x81, 0x02, 0xa8, 0x48, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0xf9, 0x03, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0xfd, 0x40, 0x80, 0x24, 0x00, 0x80, 0x41, 0x84, 0x08, - 0x41, 0x00, 0x44, 0x00, 0x88, 0x10, 0xc0, 0x08, 0x84, 0x8a, 0x03, - 0xd0, 0x81, 0x81, 0x89, 0x48, 0x00, 0x19, 0x00, 0xe0, 0x02, 0x10, - 0x81, 0x91, 0x80, 0x16, 0x00, 0xe0, 0x0a, 0x00, 0x81, 0x55, 0x2d, - 0x00, 0x0a, 0xb0, 0x81, 0x02, 0xc8, 0x48, 0x02, 0x80, 0x99, 0x0f, - 0xbc, 0x0d, 0xc0, 0x40, 0x00, 0x0f, 0xf0, 0x0f, 0x00, 0x0d, 0x80, - 0x39, 0x3c, 0x03, 0x04, 0xcf, 0x84, 0x4f, 0xa4, 0x08, 0xc2, 0x00, - 0x40, 0x0f, 0x80, 0x08, 0x80, 0x08, 0x3c, 0x81, 0x01, 0x10, 0x82, - 0x81, 0xe1, 0x18, 0x3d, 0x0f, 0x4d, 0x00, 0x82, 0x01, 0x80, 0x08, - 0x18, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x09, 0x00, 0xf8, 0x0e, 0x86, 0x81, 0xff, 0x9c, 0x0d, - 0x80, 0x40, 0x01, 0xd2, 0x11, 0x80, 0x82, 0x88, 0x81, 0x18, 0x12, - 0x88, 0xa1, 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x90, - 0x02, 0x81, 0x81, 0x18, 0xc0, 0x12, 0x04, 0xe0, 0xb6, 0x49, 0xa4, - 0x08, 0x00, 0x60, 0x04, 0xaf, 0x84, 0x18, 0xa4, 0x08, 0x00, 0x5f, - 0x44, 0x1f, 0x84, 0x08, 0xa5, 0x08, 0x00, 0x60, 0x04, 0x9f, 0x84, - 0x09, 0xa5, 0x08, 0x3c, 0x42, 0x3e, 0x0f, 0x80, 0x88, 0x81, 0x18, - 0x01, 0x3e, 0x80, 0x0f, 0x00, 0x0a, 0x80, 0x30, 0x01, 0x3e, 0x80, - 0x0f, 0x00, 0x08, 0x80, 0x30, 0x3d, 0x00, 0x1c, 0x0f, 0x84, 0x88, - 0xa1, 0x18, 0xfc, 0x14, 0x10, 0xcf, 0xa8, 0x08, 0xc0, 0x08, 0x0a, - 0x00, 0x1c, 0xcf, 0x84, 0x88, 0xa1, 0x18, 0x41, 0x80, 0x01, 0xcf, - 0x80, 0x88, 0xe1, 0x18, 0xbc, 0xd6, 0x28, 0xcf, 0x84, 0x08, 0xc0, - 0x08, 0x3c, 0x60, 0x00, 0x4f, 0x80, 0x08, 0x82, 0x08, 0x1a, 0x8c, - 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, 0x04, 0x11, 0x01, 0xcf, 0x80, - 0x8f, 0xb1, 0x18, 0xc2, 0x00, 0x40, 0x0f, 0x80, 0x08, 0x80, 0x08, - 0x3c, 0x81, 0x01, 0x10, 0x82, 0x81, 0xe1, 0x18, 0x3d, 0x0f, 0x4d, - 0x00, 0x82, 0x01, 0x80, 0x08, 0x02, 0x80, 0x19, 0xa0, 0x7e, 0x0d, - 0x80, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, - 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x13, 0x00, 0x00, - 0x00, 0x2c, 0x00, 0x0a, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0xe4, - 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x09, 0x60, 0x83, 0x02, 0x00, 0x80, 0x30, 0x02, 0x09, 0x60, 0x83, + 0x0a, 0x00, 0x80, 0x30, 0xd2, 0x14, 0xc0, 0xa2, 0xa2, 0x41, 0x80, + 0x08, 0xd9, 0x84, 0xa4, 0xa2, 0x82, 0x10, 0x84, 0x08, 0x82, 0x09, + 0x20, 0x80, 0x0a, 0x00, 0x80, 0x30, 0x0e, 0x13, 0x04, 0xa1, 0xa6, + 0x41, 0xa4, 0x08, 0x4f, 0x13, 0x44, 0xa1, 0xaa, 0x41, 0xc0, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x44, 0xfa, 0x9a, 0x06, 0x00, 0xf0, 0x8c, 0x28, 0x80, 0x00, 0x1a, + 0x10, 0x04, 0x3f, 0xe4, 0x10, 0xa4, 0x08, 0x14, 0x80, 0x01, 0xc0, + 0x80, 0x80, 0xe1, 0x18, 0x80, 0x00, 0x20, 0xa0, 0x08, 0x00, 0x81, + 0x50, 0x80, 0xd6, 0x24, 0xc0, 0x84, 0x41, 0xc0, 0x08, 0x00, 0x00, + 0x80, 0x00, 0x80, 0x10, 0x80, 0x08, 0x02, 0x8a, 0x00, 0xc0, 0x91, + 0xc6, 0x8c, 0x48, 0x00, 0x19, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, + 0x80, 0x16, 0x00, 0xe0, 0x08, 0x00, 0x81, 0x55, 0x2d, 0x00, 0x0a, + 0x30, 0x85, 0x01, 0x88, 0x48, 0x2c, 0x16, 0x00, 0xf0, 0x06, 0x04, + 0x30, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x04, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, 0x80, 0x8a, 0x03, 0xd0, + 0x91, 0xc1, 0xc9, 0x48, 0x02, 0x80, 0x81, 0xff, 0x9c, 0x0d, 0x80, + 0x40, 0x01, 0xd2, 0x11, 0x80, 0x80, 0x88, 0x81, 0x18, 0x06, 0x82, + 0xa1, 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x90, 0x00, + 0x89, 0x81, 0x18, 0x22, 0x90, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, + 0x00, 0x11, 0x1d, 0x00, 0xb4, 0x81, 0xa1, 0x18, 0x0c, 0xd0, 0x0f, + 0x10, 0xa0, 0x11, 0xa1, 0x00, 0x80, 0xd6, 0x24, 0xc0, 0x84, 0x41, + 0xc0, 0x08, 0x00, 0x60, 0x00, 0x40, 0x80, 0x41, 0x82, 0x08, 0x00, + 0x00, 0x40, 0x00, 0x80, 0x10, 0x80, 0x08, 0x00, 0x19, 0x00, 0xe0, + 0x00, 0x10, 0x81, 0x91, 0x80, 0x16, 0x00, 0xe0, 0x08, 0x00, 0x81, + 0x55, 0x2d, 0x00, 0x0a, 0x30, 0x81, 0x02, 0xa8, 0x48, 0x38, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0xf9, 0x82, 0x8a, 0x03, 0xd0, 0x91, + 0xc1, 0x89, 0x48, 0x00, 0x19, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, + 0x80, 0x16, 0x00, 0xe0, 0x08, 0x00, 0x81, 0x55, 0x2d, 0x00, 0x0a, + 0x30, 0x81, 0x02, 0xa8, 0x48, 0x1b, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0xf9, 0x84, 0x8a, 0x03, 0xd0, 0x91, 0xc1, 0x89, 0x48, 0x00, + 0x19, 0x00, 0xe0, 0x00, 0x10, 0x81, 0x91, 0x80, 0x16, 0x00, 0xe0, + 0x08, 0x00, 0x81, 0x55, 0x2d, 0x00, 0x0a, 0x30, 0x81, 0x02, 0xa8, + 0x48, 0x07, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf9, 0x80, 0x0b, + 0x00, 0xe0, 0x84, 0xc4, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x20, 0xf9, 0x01, 0x00, 0x00, 0x8f, 0x80, 0x08, 0x80, 0x08, + 0x0c, 0x81, 0x01, 0xc0, 0x80, 0x81, 0xe1, 0x18, 0x0d, 0x81, 0x41, + 0xc0, 0x80, 0x81, 0xe1, 0x18, 0x2b, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0xf8, 0x0e, + 0x86, 0x81, 0xff, 0x9c, 0x0d, 0x00, 0x40, 0x01, 0xd2, 0x11, 0x80, + 0x82, 0x88, 0x01, 0x18, 0x12, 0x88, 0xa1, 0xff, 0x9c, 0x0d, 0x00, + 0x40, 0x01, 0xd2, 0x11, 0x90, 0x02, 0x81, 0x01, 0x18, 0x1b, 0x00, + 0x04, 0xb0, 0x86, 0x41, 0x24, 0x08, 0x80, 0x0b, 0x00, 0xe0, 0x84, + 0xc4, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xf9, + 0x02, 0x80, 0x99, 0xaf, 0xbc, 0x0d, 0xc0, 0x40, 0x7c, 0x80, 0x24, + 0x8f, 0x80, 0x4f, 0xc4, 0x08, 0x3c, 0x03, 0x04, 0xcf, 0x84, 0x4f, + 0xa4, 0x08, 0x81, 0x00, 0x40, 0x0f, 0x80, 0x08, 0x80, 0x08, 0x3c, + 0x81, 0x01, 0x10, 0x80, 0x81, 0xe1, 0x18, 0x3d, 0x0f, 0x4d, 0x00, + 0x80, 0x01, 0x80, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0xf8, 0x0e, 0x86, + 0x81, 0xff, 0x9c, 0x0d, 0x80, 0x40, 0x01, 0xd2, 0x11, 0x80, 0x82, + 0x88, 0x81, 0x18, 0x12, 0x88, 0xa1, 0xff, 0x9c, 0x0d, 0x80, 0x40, + 0x01, 0xd2, 0x11, 0x90, 0x02, 0x81, 0x81, 0x18, 0xc0, 0x12, 0x04, + 0xe0, 0xb6, 0x49, 0xa4, 0x08, 0x00, 0x60, 0x04, 0xaf, 0x84, 0x18, + 0xa4, 0x08, 0x00, 0x5f, 0x44, 0x1f, 0x84, 0x08, 0xa5, 0x08, 0x00, + 0x60, 0x04, 0x9f, 0x84, 0x09, 0xa5, 0x08, 0x3c, 0x42, 0x3e, 0x0f, + 0x80, 0x88, 0x81, 0x18, 0x01, 0x3e, 0x80, 0x0f, 0x00, 0x0a, 0x80, + 0x30, 0x01, 0x3e, 0x80, 0x0f, 0x00, 0x08, 0x80, 0x30, 0x3d, 0x00, + 0x1c, 0x0f, 0x84, 0x88, 0xa1, 0x18, 0xfc, 0x14, 0x10, 0xcf, 0xa8, + 0x08, 0xc0, 0x08, 0x0a, 0x00, 0x1c, 0xcf, 0x84, 0x88, 0xa1, 0x18, + 0x41, 0x80, 0x01, 0xcf, 0x80, 0x88, 0xe1, 0x18, 0xbc, 0xd6, 0x28, + 0xcf, 0x84, 0x08, 0xc0, 0x08, 0x3c, 0x60, 0x00, 0x4f, 0x80, 0x08, + 0x82, 0x08, 0x1a, 0x8c, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, 0x04, + 0x11, 0x01, 0xcf, 0x80, 0x8f, 0xb1, 0x18, 0x81, 0x00, 0x40, 0x0f, + 0x80, 0x08, 0x80, 0x08, 0x3c, 0x81, 0x01, 0x10, 0x80, 0x81, 0xe1, + 0x18, 0x3d, 0x0f, 0x4d, 0x00, 0x80, 0x01, 0x80, 0x08, 0x04, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0xf8, 0x81, 0x00, 0x00, 0x00, 0x82, + 0x00, 0x80, 0x08, 0x00, 0x03, 0x04, 0xe0, 0x84, 0x01, 0xa4, 0x08, + 0x40, 0x03, 0x44, 0xe0, 0x88, 0x01, 0xc0, 0x08, 0x02, 0x80, 0x19, + 0x00, 0x7e, 0x0d, 0x80, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, + 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x0a, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0xe4, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x02, 0x04, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x00, 0x74, 0x65, 0x78, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x00, + 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char depthFragShader[188] = { @@ -775,47 +694,44 @@ static int gxmnvg__renderCreate(void* uptr) 0xfa }; - if (gxm->flags & NVG_ANTIALIAS) - { + if (gxm->flags & NVG_ANTIALIAS) { if (gxmnvg__createShader(&gxm->shader, "fillAA", (const char*)fillVertShader, (const char*)fillAAFragShader) == 0) return 0; - } - else - { + } else { if (gxmnvg__createShader(&gxm->shader, "fill", (const char*)fillVertShader, (const char*)fillFragShader) == 0) return 0; } #endif - if (gxmnvg__createShader(&gxm->depth_shader, "depth", NULL, (const char*)depthFragShader) == 0) + if (gxmnvg__createShader(&gxm->depth_shader, "depth", NULL, (const char *) depthFragShader) == 0) return 0; - gxm->vertBuf = (struct NVGvertex*)gpu_alloc_map( + gxm->vertBuf = (struct NVGvertex *) gpu_alloc_map( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_MEMORY_ATTRIB_READ, sizeof(struct NVGvertex) * nvg_gxm_vertex_buffer_size, &gxm->verticesUid); - const SceGxmProgramParameter* basic_vertex_param = sceGxmProgramFindParameterByName(gxm->shader.prog.vert_gxp, + const SceGxmProgramParameter *basic_vertex_param = sceGxmProgramFindParameterByName(gxm->shader.prog.vert_gxp, "vertex"); - const SceGxmProgramParameter* basic_tcoord_param = sceGxmProgramFindParameterByName(gxm->shader.prog.vert_gxp, + const SceGxmProgramParameter *basic_tcoord_param = sceGxmProgramFindParameterByName(gxm->shader.prog.vert_gxp, "tcoord"); SceGxmVertexAttribute basic_vertex_attributes[2]; - basic_vertex_attributes[0].streamIndex = 0; - basic_vertex_attributes[0].offset = 0; - basic_vertex_attributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + basic_vertex_attributes[0].streamIndex = 0; + basic_vertex_attributes[0].offset = 0; + basic_vertex_attributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; basic_vertex_attributes[0].componentCount = 2; - basic_vertex_attributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(basic_vertex_param); - basic_vertex_attributes[1].streamIndex = 0; - basic_vertex_attributes[1].offset = 2 * sizeof(float); - basic_vertex_attributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + basic_vertex_attributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(basic_vertex_param); + basic_vertex_attributes[1].streamIndex = 0; + basic_vertex_attributes[1].offset = 2 * sizeof(float); + basic_vertex_attributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; basic_vertex_attributes[1].componentCount = 2; - basic_vertex_attributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(basic_tcoord_param); + basic_vertex_attributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(basic_tcoord_param); SceGxmVertexStream basic_vertex_stream[1]; - basic_vertex_stream[0].stride = sizeof(struct NVGvertex); + basic_vertex_stream[0].stride = sizeof(struct NVGvertex); basic_vertex_stream[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; - GXM_CHECK(sceGxmShaderPatcherCreateVertexProgram(gxm->shader_patcher, gxm->shader.prog.vert_id, + GXM_CHECK(gxmCreateVertexProgram(gxm->shader.prog.vert_id, basic_vertex_attributes, sizeof(basic_vertex_attributes) / sizeof(SceGxmVertexAttribute), basic_vertex_stream, @@ -832,22 +748,21 @@ static int gxmnvg__renderCreate(void* uptr) blendInfo.colorMask = SCE_GXM_COLOR_MASK_ALL; blendInfo.colorFunc = SCE_GXM_BLEND_FUNC_ADD; blendInfo.alphaFunc = SCE_GXM_BLEND_FUNC_ADD; - blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE; - blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE; - blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; - - GXM_CHECK(sceGxmShaderPatcherCreateFragmentProgram(gxm->shader_patcher, - gxm->shader.prog.frag_id, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, - gxm->msaa, &blendInfo, gxm->shader.prog.vert_gxp, + blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE; + blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE; + blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; + + GXM_CHECK(gxmCreateFragmentProgram(gxm->shader.prog.frag_id, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + &blendInfo, gxm->shader.prog.vert_gxp, &gxm->shader.prog.frag)); gxmnvg__getUniforms(&gxm->shader); - GXM_CHECK(sceGxmShaderPatcherCreateFragmentProgram(gxm->shader_patcher, - gxm->depth_shader.prog.frag_id, + GXM_CHECK(gxmCreateFragmentProgram(gxm->depth_shader.prog.frag_id, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, - gxm->msaa, NULL, gxm->shader.prog.vert_gxp, + NULL, gxm->shader.prog.vert_gxp, &gxm->depth_shader.prog.frag)); gxm->fragSize = ALIGN(sizeof(GXMNVGfragUniforms), align); @@ -859,39 +774,37 @@ static int gxmnvg__renderCreate(void* uptr) return 1; } -static int gxmnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - GXMNVGtexture* tex = gxmnvg__allocTexture(gxm); +static int gxmnvg__renderCreateTexture(void *uptr, int type, int w, int h, int imageFlags, const unsigned char *data) { + if (w > 4096 || h > 4096) + return 0; + + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + GXMNVGtexture *tex = gxmnvg__allocTexture(gxm); if (tex == NULL) return 0; - SceGxmTextureFormat format = type == NVG_TEXTURE_RGBA ? SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR : SCE_GXM_TEXTURE_FORMAT_U8_R; - int aligned_w = ALIGN(w, 8); - int texture_w = w; - int spp = type == NVG_TEXTURE_RGBA ? 4 : 1; - int tex_size = aligned_w * h * spp; + SceGxmTextureFormat format = + type == NVG_TEXTURE_RGBA ? SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR : SCE_GXM_TEXTURE_FORMAT_U8_R; + int aligned_w = ALIGN(w, 8); + int texture_w = w; + int spp = type == NVG_TEXTURE_RGBA ? 4 : 1; + int tex_size = aligned_w * h * spp; int ret; - tex->stride = aligned_w * spp; - tex->tex_data = (uint8_t*)gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_MEMORY_ATTRIB_RW, - tex_size, &tex->data_UID); - if (tex->tex_data == NULL) - { + tex->stride = aligned_w * spp; + tex->texture.data = (uint8_t *) gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCE_GXM_MEMORY_ATTRIB_RW, + tex_size, &tex->texture.uid); + if (tex->texture.data == NULL) { return 0; } /* Clear the texture */ - if (data == NULL) - { - memset(tex->tex_data, 0, tex_size); - } - else - { - for (int i = 0; i < h; i++) - { - memcpy(tex->tex_data + i * tex->stride, data + i * w * spp, w * spp); + if (data == NULL) { + memset(tex->texture.data, 0, tex_size); + } else { + for (int i = 0; i < h; i++) { + memcpy(tex->texture.data + i * tex->stride, data + i * w * spp, w * spp); } } @@ -899,90 +812,77 @@ static int gxmnvg__renderCreateTexture(void* uptr, int type, int w, int h, int i imageFlags &= ~NVG_IMAGE_GENERATE_MIPMAPS; /* Create the gxm texture */ - ret = sceGxmTextureInitLinear(&tex->gxm_tex, tex->tex_data, format, texture_w, h, 0); - if (ret < 0) - { + ret = sceGxmTextureInitLinear(&tex->texture.tex, tex->texture.data, format, texture_w, h, 0); + if (ret < 0) { GXM_PRINT_ERROR(ret); - gpu_unmap_free(tex->data_UID); - tex->data_UID = 0; + gpu_unmap_free(tex->texture.uid); + tex->texture.uid = 0; return 0; } - if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) - { - if (imageFlags & NVG_IMAGE_NEAREST) - { - sceGxmTextureSetMinFilter(&tex->gxm_tex, SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT); - } - else - { - sceGxmTextureSetMinFilter(&tex->gxm_tex, SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR); - } - } - else - { - if (imageFlags & NVG_IMAGE_NEAREST) - { - sceGxmTextureSetMinFilter(&tex->gxm_tex, SCE_GXM_TEXTURE_FILTER_POINT); + if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) { + if (imageFlags & NVG_IMAGE_NEAREST) { + sceGxmTextureSetMinFilter(&tex->texture.tex, SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT); + } else { + sceGxmTextureSetMinFilter(&tex->texture.tex, SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR); } - else - { - sceGxmTextureSetMinFilter(&tex->gxm_tex, SCE_GXM_TEXTURE_FILTER_LINEAR); + } else { + if (imageFlags & NVG_IMAGE_NEAREST) { + sceGxmTextureSetMinFilter(&tex->texture.tex, SCE_GXM_TEXTURE_FILTER_POINT); + } else { + sceGxmTextureSetMinFilter(&tex->texture.tex, SCE_GXM_TEXTURE_FILTER_LINEAR); } } if (imageFlags & NVG_IMAGE_NEAREST) - sceGxmTextureSetMagFilter(&tex->gxm_tex, SCE_GXM_TEXTURE_FILTER_POINT); + sceGxmTextureSetMagFilter(&tex->texture.tex, SCE_GXM_TEXTURE_FILTER_POINT); else - sceGxmTextureSetMagFilter(&tex->gxm_tex, SCE_GXM_TEXTURE_FILTER_LINEAR); + sceGxmTextureSetMagFilter(&tex->texture.tex, SCE_GXM_TEXTURE_FILTER_LINEAR); + if (imageFlags & NVG_IMAGE_REPEATX) - sceGxmTextureSetUAddrMode(&tex->gxm_tex, SCE_GXM_TEXTURE_ADDR_REPEAT); + sceGxmTextureSetUAddrMode(&tex->texture.tex, SCE_GXM_TEXTURE_ADDR_REPEAT); else - sceGxmTextureSetUAddrMode(&tex->gxm_tex, SCE_GXM_TEXTURE_ADDR_CLAMP); + sceGxmTextureSetUAddrMode(&tex->texture.tex, SCE_GXM_TEXTURE_ADDR_CLAMP); if (imageFlags & NVG_IMAGE_REPEATY) - sceGxmTextureSetVAddrMode(&tex->gxm_tex, SCE_GXM_TEXTURE_ADDR_REPEAT); + sceGxmTextureSetVAddrMode(&tex->texture.tex, SCE_GXM_TEXTURE_ADDR_REPEAT); else - sceGxmTextureSetVAddrMode(&tex->gxm_tex, SCE_GXM_TEXTURE_ADDR_CLAMP); + sceGxmTextureSetVAddrMode(&tex->texture.tex, SCE_GXM_TEXTURE_ADDR_CLAMP); - tex->width = w; + tex->width = w; tex->height = h; - tex->type = type; - tex->flags = imageFlags; + tex->type = type; + tex->flags = imageFlags; return tex->id; } -static int gxmnvg__renderDeleteTexture(void* uptr, int image) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; +static int gxmnvg__renderDeleteTexture(void *uptr, int image) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; return gxmnvg__deleteTexture(gxm, image); } -static int gxmnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - GXMNVGtexture* tex = gxmnvg__findTexture(gxm, image); +static int gxmnvg__renderUpdateTexture(void *uptr, int image, int x, int y, int w, int h, const unsigned char *data) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + GXMNVGtexture *tex = gxmnvg__findTexture(gxm, image); if (tex == NULL) return 0; int spp = tex->type == NVG_TEXTURE_RGBA ? 4 : 1; - for (int i = 0; i < h; i++) - { + for (int i = 0; i < h; i++) { int start = (i + y) * tex->stride + x * spp; - memcpy(tex->tex_data + start, data + start, w * spp); + memcpy(tex->texture.data + start, data + start, w * spp); } return 1; } -static int gxmnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - GXMNVGtexture* tex = gxmnvg__findTexture(gxm, image); +static int gxmnvg__renderGetTextureSize(void *uptr, int image, int *w, int *h) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + GXMNVGtexture *tex = gxmnvg__findTexture(gxm, image); if (tex == NULL) return 0; *w = tex->width; @@ -990,35 +890,32 @@ static int gxmnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h) return 1; } -static void gxmnvg__xformToMat3x4(float* m3, float* t) -{ +static void gxmnvg__xformToMat3x4(float *m3, float *t) { // transpose - m3[0] = t[0]; - m3[1] = t[2]; - m3[2] = t[4]; - m3[3] = 0.0f; - m3[4] = t[1]; - m3[5] = t[3]; - m3[6] = t[5]; - m3[7] = 0.0f; - m3[8] = 0.0f; - m3[9] = 0.0f; + m3[0] = t[0]; + m3[1] = t[2]; + m3[2] = t[4]; + m3[3] = 0.0f; + m3[4] = t[1]; + m3[5] = t[3]; + m3[6] = t[5]; + m3[7] = 0.0f; + m3[8] = 0.0f; + m3[9] = 0.0f; m3[10] = 1.0f; m3[11] = 0.0f; } -static NVGcolor gxmnvg__premulColor(NVGcolor c) -{ +static NVGcolor gxmnvg__premulColor(NVGcolor c) { c.r *= c.a; c.g *= c.a; c.b *= c.a; return c; } -static int gxmnvg__convertPaint(GXMNVGcontext* gxm, GXMNVGfragUniforms* frag, NVGpaint* paint, - NVGscissor* scissor, float width, float fringe, float strokeThr) -{ - GXMNVGtexture* tex = NULL; +static int gxmnvg__convertPaint(GXMNVGcontext *gxm, GXMNVGfragUniforms *frag, NVGpaint *paint, + NVGscissor *scissor, float width, float fringe, float strokeThr) { + GXMNVGtexture *tex = NULL; float invxform[6]; memset(frag, 0, sizeof(*frag)); @@ -1026,35 +923,32 @@ static int gxmnvg__convertPaint(GXMNVGcontext* gxm, GXMNVGfragUniforms* frag, NV frag->innerCol = gxmnvg__premulColor(paint->innerColor); frag->outerCol = gxmnvg__premulColor(paint->outerColor); - if (scissor->extent[0] < -0.5f || scissor->extent[1] < -0.5f) - { + if (scissor->extent[0] < -0.5f || scissor->extent[1] < -0.5f) { memset(frag->scissorMat, 0, sizeof(frag->scissorMat)); - frag->scissorExt[0] = 1.0f; - frag->scissorExt[1] = 1.0f; + frag->scissorExt[0] = 1.0f; + frag->scissorExt[1] = 1.0f; frag->scissorScale[0] = 1.0f; frag->scissorScale[1] = 1.0f; - } - else - { + } else { nvgTransformInverse(invxform, scissor->xform); gxmnvg__xformToMat3x4(frag->scissorMat, invxform); - frag->scissorExt[0] = scissor->extent[0]; - frag->scissorExt[1] = scissor->extent[1]; - frag->scissorScale[0] = sqrtf(scissor->xform[0] * scissor->xform[0] + scissor->xform[2] * scissor->xform[2]) / fringe; - frag->scissorScale[1] = sqrtf(scissor->xform[1] * scissor->xform[1] + scissor->xform[3] * scissor->xform[3]) / fringe; + frag->scissorExt[0] = scissor->extent[0]; + frag->scissorExt[1] = scissor->extent[1]; + frag->scissorScale[0] = + sqrtf(scissor->xform[0] * scissor->xform[0] + scissor->xform[2] * scissor->xform[2]) / fringe; + frag->scissorScale[1] = + sqrtf(scissor->xform[1] * scissor->xform[1] + scissor->xform[3] * scissor->xform[3]) / fringe; } memcpy(frag->extent, paint->extent, sizeof(frag->extent)); frag->strokeMult = (width * 0.5f + fringe * 0.5f) / fringe; - frag->strokeThr = strokeThr; + frag->strokeThr = strokeThr; - if (paint->image != 0) - { + if (paint->image != 0) { tex = gxmnvg__findTexture(gxm, paint->image); if (tex == NULL) return 0; - if ((tex->flags & NVG_IMAGE_FLIPY) != 0) - { + if ((tex->flags & NVG_IMAGE_FLIPY) != 0) { float m1[6], m2[6]; nvgTransformTranslate(m1, 0.0f, frag->extent[1] * 0.5f); nvgTransformMultiply(m1, paint->xform); @@ -1063,9 +957,7 @@ static int gxmnvg__convertPaint(GXMNVGcontext* gxm, GXMNVGfragUniforms* frag, NV nvgTransformTranslate(m1, 0.0f, -frag->extent[1] * 0.5f); nvgTransformMultiply(m1, m2); nvgTransformInverse(invxform, m1); - } - else - { + } else { nvgTransformInverse(invxform, paint->xform); } frag->type = NSVG_SHADER_FILLIMG; @@ -1074,11 +966,13 @@ static int gxmnvg__convertPaint(GXMNVGcontext* gxm, GXMNVGfragUniforms* frag, NV frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0.0f : 1.0f; else frag->texType = 2.0f; - } - else - { - frag->type = NSVG_SHADER_FILLGRAD; - frag->radius = paint->radius; + } else { + frag->type = NSVG_SHADER_FILLGRAD; + // if innerColor == outerColor, then solid fill + if (!memcmp(&paint->innerColor, &paint->outerColor, sizeof(NVGcolor))) { + frag->type = NSVG_SHADER_FILLCOLOR; + } + frag->radius = paint->radius; frag->feather = paint->feather; nvgTransformInverse(invxform, paint->xform); } @@ -1087,44 +981,38 @@ static int gxmnvg__convertPaint(GXMNVGcontext* gxm, GXMNVGfragUniforms* frag, NV return 1; } -static GXMNVGfragUniforms* nvg__fragUniformPtr(GXMNVGcontext* gxm, int i); +static GXMNVGfragUniforms *nvg__fragUniformPtr(GXMNVGcontext *gxm, int i); -static void gxmnvg__setUniforms(GXMNVGcontext* gxm, int uniformOffset, int image) -{ - GXMNVGtexture* tex = NULL; - GXMNVGfragUniforms* frag = nvg__fragUniformPtr(gxm, uniformOffset); +static void gxmnvg__setUniforms(GXMNVGcontext *gxm, int uniformOffset, int image) { + GXMNVGtexture *tex = NULL; + GXMNVGfragUniforms *frag = nvg__fragUniformPtr(gxm, uniformOffset); - void* buffer; + void *buffer; sceGxmReserveFragmentDefaultUniformBuffer(gxm->context, &buffer); sceGxmSetUniformDataF(buffer, gxm->shader.loc[GXMNVG_LOC_FRAG], 0, sizeof(float) * NANOVG_GXM_UNIFORMARRAY_SIZE, - (const float*)frag->uniformArray); + (const float *) frag->uniformArray); - if (image != 0) - { + if (image != 0) { tex = gxmnvg__findTexture(gxm, image); } // If no image is set, use empty texture - if (tex == NULL) - { + if (tex == NULL) { tex = gxmnvg__findTexture(gxm, gxm->dummyTex); } - if (tex != NULL) - { - GXM_CHECK_VOID(sceGxmSetFragmentTexture(gxm->context, 0, &tex->gxm_tex)); + if (tex != NULL) { + GXM_CHECK_VOID(sceGxmSetFragmentTexture(gxm->context, 0, &tex->texture.tex)); } } -static void gxmnvg__renderViewport(void* uptr, float width, float height, float devicePixelRatio) -{ +static void gxmnvg__renderViewport(void *uptr, float width, float height, float devicePixelRatio) { NVG_NOTUSED(devicePixelRatio); - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - gxm->view[0] = width; - gxm->view[1] = height; + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + gxm->view[0] = width; + gxm->view[1] = height; } -static void gxmnvg__fill(GXMNVGcontext* gxm, GXMNVGcall* call) -{ - GXMNVGpath* paths = &gxm->paths[call->pathOffset]; +static void gxmnvg__fill(GXMNVGcontext *gxm, GXMNVGcall *call) { + GXMNVGpath *paths = &gxm->paths[call->pathOffset]; int i, npaths = call->pathCount; // set bindpoint for solid loc @@ -1149,9 +1037,11 @@ static void gxmnvg__fill(GXMNVGcontext* gxm, GXMNVGcall* call) for (i = 0; i < npaths; i++) gxmDrawArrays(gxm, SCE_GXM_PRIMITIVE_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount); + sceGxmSetCullMode(gxm->context, SCE_GXM_CULL_CW); sceGxmSetTwoSidedEnable(gxm->context, SCE_GXM_TWO_SIDED_DISABLED); + // Enable color output sceGxmSetFragmentProgram(gxm->context, gxm->shader.prog.frag); } @@ -1159,8 +1049,7 @@ static void gxmnvg__fill(GXMNVGcontext* gxm, GXMNVGcall* call) // Draw anti-aliased pixels gxmnvg__setUniforms(gxm, call->uniformOffset + gxm->fragSize, call->image); - if (gxm->flags & NVG_ANTIALIAS) - { + if (gxm->flags & NVG_ANTIALIAS) { gxmnvg__stencilFunc(gxm, SCE_GXM_STENCIL_FUNC_EQUAL, SCE_GXM_STENCIL_OP_KEEP, SCE_GXM_STENCIL_OP_KEEP, SCE_GXM_STENCIL_OP_KEEP); @@ -1169,6 +1058,7 @@ static void gxmnvg__fill(GXMNVGcontext* gxm, GXMNVGcall* call) gxmDrawArrays(gxm, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount); } + // Draw fill gxmnvg__stencilFunc(gxm, SCE_GXM_STENCIL_FUNC_NOT_EQUAL, SCE_GXM_STENCIL_OP_ZERO, SCE_GXM_STENCIL_OP_ZERO, SCE_GXM_STENCIL_OP_ZERO); @@ -1178,32 +1068,27 @@ static void gxmnvg__fill(GXMNVGcontext* gxm, GXMNVGcall* call) gxmnvg__disableStencilTest(gxm); } -static void gxmnvg__convexFill(GXMNVGcontext* gxm, GXMNVGcall* call) -{ - GXMNVGpath* paths = &gxm->paths[call->pathOffset]; +static void gxmnvg__convexFill(GXMNVGcontext *gxm, GXMNVGcall *call) { + GXMNVGpath *paths = &gxm->paths[call->pathOffset]; int i, npaths = call->pathCount; gxmnvg__setUniforms(gxm, call->uniformOffset, call->image); - for (i = 0; i < npaths; i++) - { + for (i = 0; i < npaths; i++) { gxmDrawArrays(gxm, SCE_GXM_PRIMITIVE_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount); // Draw fringes - if (paths[i].strokeCount > 0) - { + if (paths[i].strokeCount > 0) { gxmDrawArrays(gxm, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount); } } } -static void gxmnvg__stroke(GXMNVGcontext* gxm, GXMNVGcall* call) -{ - GXMNVGpath* paths = &gxm->paths[call->pathOffset]; - int npaths = call->pathCount, i; +static void gxmnvg__stroke(GXMNVGcontext *gxm, GXMNVGcall *call) { + GXMNVGpath *paths = &gxm->paths[call->pathOffset]; + int npaths = call->pathCount, i; - if (gxm->flags & NVG_STENCIL_STROKES) - { + if (gxm->flags & NVG_STENCIL_STROKES) { gxmnvg__stencilFunc(gxm, SCE_GXM_STENCIL_FUNC_EQUAL, SCE_GXM_STENCIL_OP_KEEP, SCE_GXM_STENCIL_OP_KEEP, SCE_GXM_STENCIL_OP_INCR); @@ -1245,37 +1130,30 @@ static void gxmnvg__stroke(GXMNVGcontext* gxm, GXMNVGcall* call) } // gxmnvg__convertPaint(gxm, nvg__fragUniformPtr(gxm, call->uniformOffset + gl->fragSize), paint, scissor, strokeWidth, fringe, 1.0f - 0.5f/255.0f); - } - else - { + } else { gxmnvg__setUniforms(gxm, call->uniformOffset, call->image); // Draw Strokes - for (i = 0; i < npaths; i++) - { + for (i = 0; i < npaths; i++) { gxmDrawArrays(gxm, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount); } } } -static void gxmnvg__triangles(GXMNVGcontext* gxm, GXMNVGcall* call) -{ +static void gxmnvg__triangles(GXMNVGcontext *gxm, GXMNVGcall *call) { gxmnvg__setUniforms(gxm, call->uniformOffset, call->image); gxmDrawArrays(gxm, SCE_GXM_PRIMITIVE_TRIANGLES, call->triangleOffset, call->triangleCount); } -static void gxmnvg__renderCancel(void* uptr) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - gxm->nverts = 0; - gxm->npaths = 0; - gxm->ncalls = 0; - gxm->nuniforms = 0; +static void gxmnvg__renderCancel(void *uptr) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + gxm->nverts = 0; + gxm->npaths = 0; + gxm->ncalls = 0; + gxm->nuniforms = 0; } -static SceGxmBlendFactor gxmnvg_convertBlendFuncFactor(int factor) -{ - switch (factor) - { +static SceGxmBlendFactor gxmnvg_convertBlendFuncFactor(int factor) { + switch (factor) { case NVG_ZERO: return SCE_GXM_BLEND_FACTOR_ZERO; case NVG_ONE: @@ -1304,31 +1182,30 @@ static SceGxmBlendFactor gxmnvg_convertBlendFuncFactor(int factor) return SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE; } -static GXMNVGblend gxmnvg__blendCompositeOperation(NVGcompositeOperationState op) -{ +static GXMNVGblend gxmnvg__blendCompositeOperation(NVGcompositeOperationState op) { GXMNVGblend blend; - blend.srcRGB = gxmnvg_convertBlendFuncFactor(op.srcRGB); - blend.dstRGB = gxmnvg_convertBlendFuncFactor(op.dstRGB); + blend.srcRGB = gxmnvg_convertBlendFuncFactor(op.srcRGB); + blend.dstRGB = gxmnvg_convertBlendFuncFactor(op.dstRGB); blend.srcAlpha = gxmnvg_convertBlendFuncFactor(op.srcAlpha); blend.dstAlpha = gxmnvg_convertBlendFuncFactor(op.dstAlpha); // act like invalid - if (blend.srcRGB == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE || blend.dstRGB == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE || blend.srcAlpha == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE || blend.dstAlpha == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE) - { - blend.srcRGB = SCE_GXM_BLEND_FACTOR_ONE; - blend.dstRGB = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + if (blend.srcRGB == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE || + blend.dstRGB == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE || + blend.srcAlpha == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE || + blend.dstAlpha == SCE_GXM_BLEND_FACTOR_DST_ALPHA_SATURATE) { + blend.srcRGB = SCE_GXM_BLEND_FACTOR_ONE; + blend.dstRGB = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; blend.srcAlpha = SCE_GXM_BLEND_FACTOR_ONE; blend.dstAlpha = SCE_GXM_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; } return blend; } -static void gxmnvg__renderFlush(void* uptr) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; +static void gxmnvg__renderFlush(void *uptr) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; int i; - if (gxm->ncalls > 0) - { + if (gxm->ncalls > 0) { // Setup require GXM state. sceGxmSetVertexProgram(gxm->context, gxm->shader.prog.vert); sceGxmSetFragmentProgram(gxm->context, gxm->shader.prog.frag); @@ -1342,14 +1219,13 @@ static void gxmnvg__renderFlush(void* uptr) // Set view just once per frame. { - void* uniform_buffer; + void *uniform_buffer; sceGxmReserveVertexDefaultUniformBuffer(gxm->context, &uniform_buffer); sceGxmSetUniformDataF(uniform_buffer, gxm->shader.loc[GXMNVG_LOC_VIEWSIZE], 0, 2, gxm->view); } - for (i = 0; i < gxm->ncalls; i++) - { - GXMNVGcall* call = &gxm->calls[i]; + for (i = 0; i < gxm->ncalls; i++) { + GXMNVGcall *call = &gxm->calls[i]; // gxmnvg__blendFuncSeparate(gxm, &call->blendFunc); if (call->type == GXMNVG_FILL) gxmnvg__fill(gxm, call); @@ -1363,37 +1239,33 @@ static void gxmnvg__renderFlush(void* uptr) } // Reset calls - gxm->nverts = 0; - gxm->npaths = 0; - gxm->ncalls = 0; + gxm->nverts = 0; + gxm->npaths = 0; + gxm->ncalls = 0; gxm->nuniforms = 0; // texture gc gxmnvg__garbageCollector(gxm); } -static int gxmnvg__maxVertCount(const NVGpath* paths, int npaths) -{ +static int gxmnvg__maxVertCount(const NVGpath *paths, int npaths) { int i, count = 0; - for (i = 0; i < npaths; i++) - { + for (i = 0; i < npaths; i++) { count += paths[i].nfill; count += paths[i].nstroke; } return count; } -static GXMNVGcall* gxmnvg__allocCall(GXMNVGcontext* gxm) -{ - GXMNVGcall* ret = NULL; - if (gxm->ncalls + 1 > gxm->ccalls) - { - GXMNVGcall* calls; +static GXMNVGcall *gxmnvg__allocCall(GXMNVGcontext *gxm) { + GXMNVGcall *ret = NULL; + if (gxm->ncalls + 1 > gxm->ccalls) { + GXMNVGcall *calls; int ccalls = gxmnvg__maxi(gxm->ncalls + 1, 128) + gxm->ccalls / 2; // 1.5x Overallocate - calls = (GXMNVGcall*)realloc(gxm->calls, sizeof(GXMNVGcall) * ccalls); + calls = (GXMNVGcall *) realloc(gxm->calls, sizeof(GXMNVGcall) * ccalls); if (calls == NULL) return NULL; - gxm->calls = calls; + gxm->calls = calls; gxm->ccalls = ccalls; } ret = &gxm->calls[gxm->ncalls++]; @@ -1401,17 +1273,15 @@ static GXMNVGcall* gxmnvg__allocCall(GXMNVGcontext* gxm) return ret; } -static int gxmnvg__allocPaths(GXMNVGcontext* gxm, int n) -{ +static int gxmnvg__allocPaths(GXMNVGcontext *gxm, int n) { int ret = 0; - if (gxm->npaths + n > gxm->cpaths) - { - GXMNVGpath* paths; + if (gxm->npaths + n > gxm->cpaths) { + GXMNVGpath *paths; int cpaths = gxmnvg__maxi(gxm->npaths + n, 128) + gxm->cpaths / 2; // 1.5x Overallocate - paths = (GXMNVGpath*)realloc(gxm->paths, sizeof(GXMNVGpath) * cpaths); + paths = (GXMNVGpath *) realloc(gxm->paths, sizeof(GXMNVGpath) * cpaths); if (paths == NULL) return -1; - gxm->paths = paths; + gxm->paths = paths; gxm->cpaths = cpaths; } ret = gxm->npaths; @@ -1419,17 +1289,15 @@ static int gxmnvg__allocPaths(GXMNVGcontext* gxm, int n) return ret; } -static int gxmnvg__allocVerts(GXMNVGcontext* gxm, int n) -{ +static int gxmnvg__allocVerts(GXMNVGcontext *gxm, int n) { int ret = 0; - if (gxm->nverts + n > gxm->cverts) - { - NVGvertex* verts; + if (gxm->nverts + n > gxm->cverts) { + NVGvertex *verts; int cverts = gxmnvg__maxi(gxm->nverts + n, 4096) + gxm->cverts / 2; // 1.5x Overallocate - verts = (NVGvertex*)realloc(gxm->verts, sizeof(NVGvertex) * cverts); + verts = (NVGvertex *) realloc(gxm->verts, sizeof(NVGvertex) * cverts); if (verts == NULL) return -1; - gxm->verts = verts; + gxm->verts = verts; gxm->cverts = cverts; } ret = gxm->nverts; @@ -1437,17 +1305,15 @@ static int gxmnvg__allocVerts(GXMNVGcontext* gxm, int n) return ret; } -static int gxmnvg__allocFragUniforms(GXMNVGcontext* gxm, int n) -{ +static int gxmnvg__allocFragUniforms(GXMNVGcontext *gxm, int n) { int ret = 0, structSize = gxm->fragSize; - if (gxm->nuniforms + n > gxm->cuniforms) - { - unsigned char* uniforms; + if (gxm->nuniforms + n > gxm->cuniforms) { + unsigned char *uniforms; int cuniforms = gxmnvg__maxi(gxm->nuniforms + n, 128) + gxm->cuniforms / 2; // 1.5x Overallocate - uniforms = (unsigned char*)realloc(gxm->uniforms, structSize * cuniforms); + uniforms = (unsigned char *) realloc(gxm->uniforms, structSize * cuniforms); if (uniforms == NULL) return -1; - gxm->uniforms = uniforms; + gxm->uniforms = uniforms; gxm->cuniforms = cuniforms; } ret = gxm->nuniforms * structSize; @@ -1455,80 +1321,72 @@ static int gxmnvg__allocFragUniforms(GXMNVGcontext* gxm, int n) return ret; } -static GXMNVGfragUniforms* nvg__fragUniformPtr(GXMNVGcontext* gxm, int i) -{ - return (GXMNVGfragUniforms*)&gxm->uniforms[i]; +static GXMNVGfragUniforms *nvg__fragUniformPtr(GXMNVGcontext *gxm, int i) { + return (GXMNVGfragUniforms *) &gxm->uniforms[i]; } -static void gxmnvg__vset(NVGvertex* vtx, float x, float y, float u, float v) -{ +static void gxmnvg__vset(NVGvertex *vtx, float x, float y, float u, float v) { vtx->x = x; vtx->y = y; vtx->u = u; vtx->v = v; } -static void gxmnvg__renderFill(void* uptr, NVGpaint* paint, - NVGcompositeOperationState compositeOperation, NVGscissor* scissor, - float fringe, const float* bounds, const NVGpath* paths, int npaths) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - GXMNVGcall* call = gxmnvg__allocCall(gxm); - NVGvertex* quad; - GXMNVGfragUniforms* frag; +static void gxmnvg__renderFill(void *uptr, NVGpaint *paint, + NVGcompositeOperationState compositeOperation, NVGscissor *scissor, + float fringe, const float *bounds, const NVGpath *paths, int npaths) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + GXMNVGcall *call = gxmnvg__allocCall(gxm); + NVGvertex *quad; + GXMNVGfragUniforms *frag; int i, maxverts, offset; if (call == NULL) return; - call->type = GXMNVG_FILL; + call->type = GXMNVG_FILL; call->triangleCount = 4; - call->pathOffset = gxmnvg__allocPaths(gxm, npaths); + call->pathOffset = gxmnvg__allocPaths(gxm, npaths); if (call->pathOffset == -1) goto error; call->pathCount = npaths; - call->image = paint->image; + call->image = paint->image; call->blendFunc = gxmnvg__blendCompositeOperation(compositeOperation); - if (npaths == 1 && paths[0].convex) - { - call->type = GXMNVG_CONVEXFILL; + if (npaths == 1 && paths[0].convex) { + call->type = GXMNVG_CONVEXFILL; call->triangleCount = 0; // Bounding box fill quad not needed for convex fill } // Allocate vertices for all the paths. maxverts = gxmnvg__maxVertCount(paths, npaths) + call->triangleCount; - offset = gxmnvg__allocVerts(gxm, maxverts); + offset = gxmnvg__allocVerts(gxm, maxverts); if (offset == -1) goto error; - for (i = 0; i < npaths; i++) - { - GXMNVGpath* copy = &gxm->paths[call->pathOffset + i]; - const NVGpath* path = &paths[i]; + for (i = 0; i < npaths; i++) { + GXMNVGpath *copy = &gxm->paths[call->pathOffset + i]; + const NVGpath *path = &paths[i]; memset(copy, 0, sizeof(GXMNVGpath)); - if (path->nfill > 0) - { + if (path->nfill > 0) { copy->fillOffset = offset; - copy->fillCount = path->nfill; + copy->fillCount = path->nfill; memcpy(&gxm->verts[offset], path->fill, sizeof(NVGvertex) * path->nfill); offset += path->nfill; } - if (path->nstroke > 0) - { + if (path->nstroke > 0) { copy->strokeOffset = offset; - copy->strokeCount = path->nstroke; + copy->strokeCount = path->nstroke; memcpy(&gxm->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke); offset += path->nstroke; } } // Setup uniforms for draw calls - if (call->type == GXMNVG_FILL) - { + if (call->type == GXMNVG_FILL) { // Quad call->triangleOffset = offset; - quad = &gxm->verts[call->triangleOffset]; + quad = &gxm->verts[call->triangleOffset]; gxmnvg__vset(&quad[0], bounds[2], bounds[3], 0.5f, 1.0f); gxmnvg__vset(&quad[1], bounds[2], bounds[1], 0.5f, 1.0f); gxmnvg__vset(&quad[2], bounds[0], bounds[3], 0.5f, 1.0f); @@ -1541,13 +1399,11 @@ static void gxmnvg__renderFill(void* uptr, NVGpaint* paint, frag = nvg__fragUniformPtr(gxm, call->uniformOffset); memset(frag, 0, sizeof(*frag)); frag->strokeThr = -1.0f; - frag->type = NSVG_SHADER_SIMPLE; + frag->type = NSVG_SHADER_SIMPLE; // Fill shader gxmnvg__convertPaint(gxm, nvg__fragUniformPtr(gxm, call->uniformOffset + gxm->fragSize), paint, scissor, fringe, fringe, -1.0f); - } - else - { + } else { call->uniformOffset = gxmnvg__allocFragUniforms(gxm, 1); if (call->uniformOffset == -1) goto error; @@ -1564,47 +1420,43 @@ static void gxmnvg__renderFill(void* uptr, NVGpaint* paint, gxm->ncalls--; } -static void gxmnvg__renderStroke(void* uptr, NVGpaint* paint, - NVGcompositeOperationState compositeOperation, NVGscissor* scissor, - float fringe, float strokeWidth, const NVGpath* paths, int npaths) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - GXMNVGcall* call = gxmnvg__allocCall(gxm); +static void gxmnvg__renderStroke(void *uptr, NVGpaint *paint, + NVGcompositeOperationState compositeOperation, NVGscissor *scissor, + float fringe, float strokeWidth, const NVGpath *paths, int npaths) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + GXMNVGcall *call = gxmnvg__allocCall(gxm); int i, maxverts, offset; if (call == NULL) return; - call->type = GXMNVG_STROKE; + call->type = GXMNVG_STROKE; call->pathOffset = gxmnvg__allocPaths(gxm, npaths); if (call->pathOffset == -1) goto error; call->pathCount = npaths; - call->image = paint->image; + call->image = paint->image; call->blendFunc = gxmnvg__blendCompositeOperation(compositeOperation); // Allocate vertices for all the paths. maxverts = gxmnvg__maxVertCount(paths, npaths); - offset = gxmnvg__allocVerts(gxm, maxverts); + offset = gxmnvg__allocVerts(gxm, maxverts); if (offset == -1) goto error; - for (i = 0; i < npaths; i++) - { - GXMNVGpath* copy = &gxm->paths[call->pathOffset + i]; - const NVGpath* path = &paths[i]; + for (i = 0; i < npaths; i++) { + GXMNVGpath *copy = &gxm->paths[call->pathOffset + i]; + const NVGpath *path = &paths[i]; memset(copy, 0, sizeof(GXMNVGpath)); - if (path->nstroke) - { + if (path->nstroke) { copy->strokeOffset = offset; - copy->strokeCount = path->nstroke; + copy->strokeCount = path->nstroke; memcpy(&gxm->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke); offset += path->nstroke; } } - if (gxm->flags & NVG_STENCIL_STROKES) - { + if (gxm->flags & NVG_STENCIL_STROKES) { // Fill shader call->uniformOffset = gxmnvg__allocFragUniforms(gxm, 2); if (call->uniformOffset == -1) @@ -1614,9 +1466,7 @@ static void gxmnvg__renderStroke(void* uptr, NVGpaint* paint, -1.0f); gxmnvg__convertPaint(gxm, nvg__fragUniformPtr(gxm, call->uniformOffset + gxm->fragSize), paint, scissor, strokeWidth, fringe, 1.0f - 0.5f / 255.0f); - } - else - { + } else { // Fill shader call->uniformOffset = gxmnvg__allocFragUniforms(gxm, 1); if (call->uniformOffset == -1) @@ -1634,19 +1484,18 @@ static void gxmnvg__renderStroke(void* uptr, NVGpaint* paint, gxm->ncalls--; } -static void gxmnvg__renderTriangles(void* uptr, NVGpaint* paint, - NVGcompositeOperationState compositeOperation, NVGscissor* scissor, - const NVGvertex* verts, int nverts, float fringe) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; - GXMNVGcall* call = gxmnvg__allocCall(gxm); - GXMNVGfragUniforms* frag; +static void gxmnvg__renderTriangles(void *uptr, NVGpaint *paint, + NVGcompositeOperationState compositeOperation, NVGscissor *scissor, + const NVGvertex *verts, int nverts, float fringe) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; + GXMNVGcall *call = gxmnvg__allocCall(gxm); + GXMNVGfragUniforms *frag; if (call == NULL) return; - call->type = GXMNVG_TRIANGLES; - call->image = paint->image; + call->type = GXMNVG_TRIANGLES; + call->image = paint->image; call->blendFunc = gxmnvg__blendCompositeOperation(compositeOperation); // Allocate vertices for all the paths. @@ -1674,9 +1523,8 @@ static void gxmnvg__renderTriangles(void* uptr, NVGpaint* paint, gxm->ncalls--; } -static void gxmnvg__renderDelete(void* uptr) -{ - GXMNVGcontext* gxm = (GXMNVGcontext*)uptr; +static void gxmnvg__renderDelete(void *uptr) { + GXMNVGcontext *gxm = (GXMNVGcontext *) uptr; int i; if (gxm == NULL) return; @@ -1687,10 +1535,9 @@ static void gxmnvg__renderDelete(void* uptr) gpu_unmap_free(gxm->verticesUid); // vertex stream - for (i = 0; i < gxm->ntextures; i++) - { - if (gxm->textures[i].data_UID != 0 && (gxm->textures[i].flags & NVG_IMAGE_NODELETE) == 0) - gpu_unmap_free(gxm->textures[i].data_UID); + for (i = 0; i < gxm->ntextures; i++) { + if (gxm->textures[i].texture.uid != 0 && (gxm->textures[i].flags & NVG_IMAGE_NODELETE) == 0) + gpu_unmap_free(gxm->textures[i].texture.uid); } gxmnvg__deleteShader(&gxm->shader); @@ -1705,39 +1552,36 @@ static void gxmnvg__renderDelete(void* uptr) free(gxm); } -NVGcontext* nvgCreateGXM(NVGXMframebuffer* fb, int flags) -{ +NVGcontext *nvgCreateGXM(SceGxmContext *context, SceGxmShaderPatcher *shader_patcher, int flags) { NVGparams params; - NVGcontext* ctx = NULL; - GXMNVGcontext* gxm = (GXMNVGcontext*)malloc(sizeof(GXMNVGcontext)); + NVGcontext *ctx = NULL; + GXMNVGcontext *gxm = (GXMNVGcontext *) malloc(sizeof(GXMNVGcontext)); if (gxm == NULL) goto error; memset(gxm, 0, sizeof(GXMNVGcontext)); - gxm->context = fb->context; - gxm->shader_patcher = fb->shader_patcher; - gxm->msaa = fb->msaa; + gxm->context = context; + gxm->shader_patcher = shader_patcher; memset(¶ms, 0, sizeof(params)); - params.renderCreate = gxmnvg__renderCreate; - params.renderCreateTexture = gxmnvg__renderCreateTexture; - params.renderDeleteTexture = gxmnvg__renderDeleteTexture; - params.renderUpdateTexture = gxmnvg__renderUpdateTexture; + params.renderCreate = gxmnvg__renderCreate; + params.renderCreateTexture = gxmnvg__renderCreateTexture; + params.renderDeleteTexture = gxmnvg__renderDeleteTexture; + params.renderUpdateTexture = gxmnvg__renderUpdateTexture; params.renderGetTextureSize = gxmnvg__renderGetTextureSize; - params.renderViewport = gxmnvg__renderViewport; - params.renderCancel = gxmnvg__renderCancel; - params.renderFlush = gxmnvg__renderFlush; - params.renderFill = gxmnvg__renderFill; - params.renderStroke = gxmnvg__renderStroke; - params.renderTriangles = gxmnvg__renderTriangles; - params.renderDelete = gxmnvg__renderDelete; - params.userPtr = gxm; - params.edgeAntiAlias = flags & NVG_ANTIALIAS ? 1 : 0; + params.renderViewport = gxmnvg__renderViewport; + params.renderCancel = gxmnvg__renderCancel; + params.renderFlush = gxmnvg__renderFlush; + params.renderFill = gxmnvg__renderFill; + params.renderStroke = gxmnvg__renderStroke; + params.renderTriangles = gxmnvg__renderTriangles; + params.renderDelete = gxmnvg__renderDelete; + params.userPtr = gxm; + params.edgeAntiAlias = flags & NVG_ANTIALIAS ? 1 : 0; gxm->flags = flags; #ifdef USE_VITA_SHARK - if (flags & NVG_DEBUG) - { + if (flags & NVG_DEBUG) { shark_set_warnings_level(SHARK_WARN_MAX); shark_install_log_cb(shark_log_cb); } @@ -1756,9 +1600,31 @@ NVGcontext* nvgCreateGXM(NVGXMframebuffer* fb, int flags) return NULL; } -void nvgDeleteGXM(NVGcontext* ctx) -{ +void nvgDeleteGXM(NVGcontext *ctx) { nvgDeleteInternal(ctx); } +int nvgxmCreateImageFromHandle(NVGcontext *ctx, SceGxmTexture *texture) { + GXMNVGcontext *gxm = (GXMNVGcontext *) nvgInternalParams(ctx)->userPtr; + GXMNVGtexture *tex = gxmnvg__allocTexture(gxm); + + if (tex == NULL) return 0; + + tex->type = NVG_TEXTURE_RGBA; + tex->texture.tex = *texture; + tex->texture.uid = 0; + tex->texture.data = (uint8_t *) sceGxmTextureGetData(texture); + tex->flags = NVG_IMAGE_NODELETE; + tex->width = (int) sceGxmTextureGetWidth(texture); + tex->height = (int) sceGxmTextureGetHeight(texture); + + return tex->id; +} + +NVGXMtexture *nvgxmImageHandle(NVGcontext *ctx, int image) { + GXMNVGcontext *gxm = (GXMNVGcontext *) nvgInternalParams(ctx)->userPtr; + GXMNVGtexture *tex = gxmnvg__findTexture(gxm, image); + return &tex->texture; +} + #endif /* NANOVG_GL_IMPLEMENTATION */ diff --git a/library/include/borealis/extern/nanovg/nanovg_gxm_utils.h b/library/include/borealis/extern/nanovg/nanovg_gxm_utils.h index 739681cdb..5cd934f79 100644 --- a/library/include/borealis/extern/nanovg/nanovg_gxm_utils.h +++ b/library/include/borealis/extern/nanovg/nanovg_gxm_utils.h @@ -30,11 +30,13 @@ extern "C" #ifdef USE_VITA_SHARK #include +#include #endif #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) +// Default framebuffer settings #define DISPLAY_WIDTH 960 #define DISPLAY_HEIGHT 544 #define DISPLAY_STRIDE 960 @@ -42,6 +44,7 @@ extern "C" #define MAX_PENDING_SWAPS (DISPLAY_BUFFER_COUNT - 1) #define DISPLAY_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8 +#define DISPLAY_COLOR_SURFACE_TYPE SCE_GXM_COLOR_SURFACE_LINEAR #define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 static int gxm__error_status = SCE_OK; @@ -56,88 +59,177 @@ extern "C" #define GXM_CHECK(func) GXM_CHECK_RETURN(func, 0) #define GXM_CHECK_VOID(func) GXM_CHECK_RETURN(func, ) - struct NVGXMinitOptions - { + struct NVGXMinitOptions { SceGxmMultisampleMode msaa; int swapInterval; int dumpShader; // dump shader to ux0:data/nvg_name_type.c + int scenesPerFrame; }; typedef struct NVGXMinitOptions NVGXMinitOptions; - struct NVGXMshaderProgram - { + struct NVGXMshaderProgram { SceGxmShaderPatcherId vert_id; SceGxmShaderPatcherId frag_id; - SceGxmVertexProgram* vert; - SceGxmFragmentProgram* frag; + SceGxmVertexProgram *vert; + SceGxmFragmentProgram *frag; - SceGxmProgram* vert_gxp; - SceGxmProgram* frag_gxp; + SceGxmProgram *vert_gxp; + SceGxmProgram *frag_gxp; }; typedef struct NVGXMshaderProgram NVGXMshaderProgram; - struct NVGXMframebuffer - { - SceGxmContext* context; - SceGxmShaderPatcher* shader_patcher; - SceGxmMultisampleMode msaa; + struct NVGXMtexture { + SceGxmTexture tex; + uint8_t *data; + SceUID uid; + }; + typedef struct NVGXMtexture NVGXMtexture; + + struct NVGXMframebufferInitOptions { + int display_buffer_count; + int scenesPerFrame; + + /** + * render_target is the framebuffer to render to. + * NULL for default framebuffer + */ + NVGXMtexture *render_target; + SceGxmColorFormat color_format; + SceGxmColorSurfaceType color_surface_type; + int display_width; + int display_height; + int display_stride; + }; + typedef struct NVGXMframebufferInitOptions NVGXMframebufferInitOptions; + + struct NVGXMcolorSurface { + SceGxmColorSurface surface; + SceUID surface_uid; + void *surface_addr; + SceGxmSyncObject *sync_object; + }; + typedef struct NVGXMcolorSurface NVGXMcolorSurface; + + struct NVGXMframebuffer { + SceGxmRenderTarget *gxm_render_target; + + NVGXMcolorSurface *gxm_color_surfaces; + unsigned int gxm_front_buffer_index; + unsigned int gxm_back_buffer_index; + + SceUID gxm_depth_stencil_surface_uid; + void *gxm_depth_stencil_surface_addr; + SceGxmDepthStencilSurface gxm_depth_stencil_surface; + + NVGXMframebufferInitOptions initOptions; }; typedef struct NVGXMframebuffer NVGXMframebuffer; - // Helper function to init gxm. - NVGXMframebuffer* nvgxmCreateFramebuffer(const NVGXMinitOptions* opts); + struct NVGXMwindow { + SceGxmContext *context; + SceGxmShaderPatcher *shader_patcher; + SceGxmMultisampleMode msaa; - void nvgxmDeleteFramebuffer(NVGXMframebuffer* gxm); + SceUID vdm_ring_buffer_uid; + void *vdm_ring_buffer_addr; + SceUID vertex_ring_buffer_uid; + void *vertex_ring_buffer_addr; + SceUID fragment_ring_buffer_uid; + void *fragment_ring_buffer_addr; + SceUID fragment_usse_ring_buffer_uid; + void *fragment_usse_ring_buffer_addr; + + SceUID gxm_shader_patcher_buffer_uid; + void *gxm_shader_patcher_buffer_addr; + SceUID gxm_shader_patcher_vertex_usse_uid; + void *gxm_shader_patcher_vertex_usse_addr; + SceUID gxm_shader_patcher_fragment_usse_uid; + void *gxm_shader_patcher_fragment_usse_addr; + + NVGXMframebuffer *fb; + }; + typedef struct NVGXMwindow NVGXMwindow; /** - * @brief Begin a scene. + * Helper functions to create shader program. + */ + int gxmCreateFragmentProgram(SceGxmShaderPatcherId programId, + SceGxmOutputRegisterFormat outputFormat, + const SceGxmBlendInfo *blendInfo, + const SceGxmProgram *vertexProgram, + SceGxmFragmentProgram **fragmentProgram); + + int gxmCreateVertexProgram(SceGxmShaderPatcherId programId, + const SceGxmVertexAttribute *attributes, + unsigned int attributeCount, + const SceGxmVertexStream *streams, + unsigned int streamCount, + SceGxmVertexProgram **vertexProgram); + + NVGXMwindow *gxmCreateWindow(const NVGXMinitOptions *opts); + + NVGXMwindow *gxmGetWindow(); + + void gxmDeleteWindow(NVGXMwindow *window); + + NVGXMframebuffer *gxmCreateFramebuffer(const NVGXMframebufferInitOptions *opts); + + void gxmDeleteFramebuffer(NVGXMframebuffer *fb); + + NVGXMtexture *gxmCreateTexture(int width, int height, SceGxmTextureFormat format, void *data); + + void gxmDeleteTexture(NVGXMtexture *texture); + + /** + * @brief Begin a scene. */ void gxmBeginFrame(void); + void gxmBeginFrameEx(NVGXMframebuffer *fb, unsigned int flags); /** - * @brief End a scene. + * @brief End a scene. */ void gxmEndFrame(void); /** - * @brief Swap the buffers. + * @brief Swap the buffers. */ void gxmSwapBuffer(void); /** - * @brief Set the clear color. + * @brief Set the clear color. */ void gxmClearColor(float r, float g, float b, float a); /** - * @brief Clear the framebuffer and stencil buffer. - * Must be called between gxmBeginFrame and gxmEndFrame. + * @brief Clear the framebuffer and stencil buffer. + * Must be called between gxmBeginFrame and gxmEndFrame. */ void gxmClear(void); /** - * @brief Get framebuffer data. + * @brief Get framebuffer data. */ - void* gxmReadPixels(void); + void *gxmReadPixels(void); /** - * @brief Set the swap interval. - * @param interval N for vsync, 0 for immediate. + * @brief Set the swap interval. + * @param interval N for vsync, 0 for immediate. */ void gxmSwapInterval(int interval); int gxmDialogUpdate(void); - unsigned short* gxmGetSharedIndices(void); + unsigned short *gxmGetSharedIndices(void); - int gxmCreateShader(NVGXMshaderProgram* shader, const char* name, const char* vshader, const char* fshader); + int gxmCreateShader(NVGXMshaderProgram *shader, const char *name, const char *vshader, const char *fshader); - void gxmDeleteShader(NVGXMshaderProgram* prog); + void gxmDeleteShader(NVGXMshaderProgram *prog); void gpu_unmap_free(SceUID uid); - void* gpu_alloc_map(SceKernelMemBlockType type, SceGxmMemoryAttribFlags gpu_attrib, size_t size, SceUID* uid); + void *gpu_alloc_map(SceKernelMemBlockType type, SceGxmMemoryAttribFlags gpu_attrib, size_t size, SceUID *uid); #ifdef __cplusplus } @@ -147,69 +239,43 @@ extern "C" #ifdef NANOVG_GXM_UTILS_IMPLEMENTATION -#include #include #include +#include + #include #include +#include -struct display_queue_callback_data -{ - void* addr; +struct display_queue_callback_data { + void *addr; }; -struct clear_vertex -{ +struct clear_vertex { float x, y; }; -static struct gxm_internal -{ - SceGxmContext* context; - SceGxmShaderPatcher* shader_patcher; +static struct gxm_internal { + SceGxmContext *context; + SceGxmShaderPatcher *shader_patcher; NVGXMinitOptions initOptions; // clear shader NVGXMshaderProgram clearProg; - NVGcolor* clearColor; - SceUID clearColorUid; + NVGcolor clearColor; + const SceGxmProgramParameter *clearParam; SceUID clearVerticesUid; - struct clear_vertex* clearVertices; + struct clear_vertex *clearVertices; // shared indices SceUID linearIndicesUid; - unsigned short* linearIndices; + unsigned short *linearIndices; + + NVGXMwindow *window; } gxm_internal; -static SceUID vdm_ring_buffer_uid; -static void* vdm_ring_buffer_addr; -static SceUID vertex_ring_buffer_uid; -static void* vertex_ring_buffer_addr; -static SceUID fragment_ring_buffer_uid; -static void* fragment_ring_buffer_addr; -static SceUID fragment_usse_ring_buffer_uid; -static void* fragment_usse_ring_buffer_addr; -static SceGxmRenderTarget* gxm_render_target; -static SceGxmColorSurface gxm_color_surfaces[DISPLAY_BUFFER_COUNT]; -static SceUID gxm_color_surfaces_uid[DISPLAY_BUFFER_COUNT]; -static void* gxm_color_surfaces_addr[DISPLAY_BUFFER_COUNT]; -static SceGxmSyncObject* gxm_sync_objects[DISPLAY_BUFFER_COUNT]; -static unsigned int gxm_front_buffer_index; -static unsigned int gxm_back_buffer_index; -static SceUID gxm_depth_stencil_surface_uid; -static void* gxm_depth_stencil_surface_addr; -static SceGxmDepthStencilSurface gxm_depth_stencil_surface; -static SceUID gxm_shader_patcher_buffer_uid; -static void* gxm_shader_patcher_buffer_addr; -static SceUID gxm_shader_patcher_vertex_usse_uid; -static void* gxm_shader_patcher_vertex_usse_addr; -static SceUID gxm_shader_patcher_fragment_usse_uid; -static void* gxm_shader_patcher_fragment_usse_addr; - -static const char* gxmnvg__easy_strerror(int code) -{ - switch ((SceGxmErrorCode)code) - { +static const char *gxmnvg__easy_strerror(int code) { + switch ((SceGxmErrorCode) code) { case SCE_GXM_ERROR_UNINITIALIZED: return "SCE_GXM_ERROR_UNINITIALIZED"; case SCE_GXM_ERROR_ALREADY_INITIALIZED: @@ -269,31 +335,28 @@ static const char* gxmnvg__easy_strerror(int code) } } -static void display_queue_callback(const void* callbackData) -{ +static void display_queue_callback(const void *callbackData) { SceDisplayFrameBuf display_fb; - const struct display_queue_callback_data* cb_data = (struct display_queue_callback_data*)callbackData; + const struct display_queue_callback_data *cb_data = (struct display_queue_callback_data *) callbackData; memset(&display_fb, 0, sizeof(display_fb)); - display_fb.size = sizeof(display_fb); - display_fb.base = cb_data->addr; - display_fb.pitch = DISPLAY_STRIDE; + display_fb.size = sizeof(display_fb); + display_fb.base = cb_data->addr; + display_fb.pitch = DISPLAY_STRIDE; display_fb.pixelformat = DISPLAY_PIXEL_FORMAT; - display_fb.width = DISPLAY_WIDTH; - display_fb.height = DISPLAY_HEIGHT; + display_fb.width = DISPLAY_WIDTH; + display_fb.height = DISPLAY_HEIGHT; sceDisplaySetFrameBuf(&display_fb, SCE_DISPLAY_SETBUF_NEXTFRAME); - if (gxm_internal.initOptions.swapInterval) - { + if (gxm_internal.initOptions.swapInterval) { GXM_CHECK_VOID(sceDisplayWaitVblankStartMulti(gxm_internal.initOptions.swapInterval)); } } -void* gpu_alloc_map(SceKernelMemBlockType type, SceGxmMemoryAttribFlags gpu_attrib, size_t size, SceUID* uid) -{ +void *gpu_alloc_map(SceKernelMemBlockType type, SceGxmMemoryAttribFlags gpu_attrib, size_t size, SceUID *uid) { SceUID memuid; - void* addr; + void *addr; if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) size = ALIGN(size, 256 * 1024); @@ -307,8 +370,7 @@ void* gpu_alloc_map(SceKernelMemBlockType type, SceGxmMemoryAttribFlags gpu_attr if (sceKernelGetMemBlockBase(memuid, &addr) < 0) return NULL; - if (sceGxmMapMemory(addr, size, gpu_attrib) < 0) - { + if (sceGxmMapMemory(addr, size, gpu_attrib) < 0) { sceKernelFreeMemBlock(memuid); return NULL; } @@ -319,9 +381,11 @@ void* gpu_alloc_map(SceKernelMemBlockType type, SceGxmMemoryAttribFlags gpu_attr return addr; } -void gpu_unmap_free(SceUID uid) -{ - void* addr; +void gpu_unmap_free(SceUID uid) { + void *addr; + + if (uid == 0) + return; if (sceKernelGetMemBlockBase(uid, &addr) < 0) return; @@ -331,10 +395,9 @@ void gpu_unmap_free(SceUID uid) sceKernelFreeMemBlock(uid); } -static void* gpu_vertex_usse_alloc_map(size_t size, SceUID* uid, unsigned int* usse_offset) -{ +static void *gpu_vertex_usse_alloc_map(size_t size, SceUID *uid, unsigned int *usse_offset) { SceUID memuid; - void* addr; + void *addr; size = ALIGN(size, 4 * 1024); @@ -349,12 +412,17 @@ static void* gpu_vertex_usse_alloc_map(size_t size, SceUID* uid, unsigned int* u if (sceGxmMapVertexUsseMemory(addr, size, usse_offset) < 0) return NULL; + if (uid) + *uid = memuid; + return addr; } -static void gpu_vertex_usse_unmap_free(SceUID uid) -{ - void* addr; +static void gpu_vertex_usse_unmap_free(SceUID uid) { + void *addr; + + if (uid == 0) + return; if (sceKernelGetMemBlockBase(uid, &addr) < 0) return; @@ -364,10 +432,9 @@ static void gpu_vertex_usse_unmap_free(SceUID uid) sceKernelFreeMemBlock(uid); } -static void* gpu_fragment_usse_alloc_map(size_t size, SceUID* uid, unsigned int* usse_offset) -{ +static void *gpu_fragment_usse_alloc_map(size_t size, SceUID *uid, unsigned int *usse_offset) { SceUID memuid; - void* addr; + void *addr; size = ALIGN(size, 4 * 1024); @@ -382,12 +449,17 @@ static void* gpu_fragment_usse_alloc_map(size_t size, SceUID* uid, unsigned int* if (sceGxmMapFragmentUsseMemory(addr, size, usse_offset) < 0) return NULL; + if (uid) + *uid = memuid; + return addr; } -static void gpu_fragment_usse_unmap_free(SceUID uid) -{ - void* addr; +static void gpu_fragment_usse_unmap_free(SceUID uid) { + void *addr; + + if (uid == 0) + return; if (sceKernelGetMemBlockBase(uid, &addr) < 0) return; @@ -397,196 +469,170 @@ static void gpu_fragment_usse_unmap_free(SceUID uid) sceKernelFreeMemBlock(uid); } -static void* shader_patcher_host_alloc_cb(void* user_data, unsigned int size) -{ +static void *shader_patcher_host_alloc_cb(void *user_data, unsigned int size) { return malloc(size); } -static void shader_patcher_host_free_cb(void* user_data, void* mem) -{ +static void shader_patcher_host_free_cb(void *user_data, void *mem) { return free(mem); } -NVGXMframebuffer* nvgxmCreateFramebuffer(const NVGXMinitOptions* opts) -{ - NVGXMframebuffer* fb = NULL; - fb = (NVGXMframebuffer*)malloc(sizeof(NVGXMframebuffer)); - if (fb == NULL) - { - nvgxmDeleteFramebuffer(fb); +NVGXMwindow *gxmCreateWindow(const NVGXMinitOptions *opts) { + NVGXMwindow *window = NULL; + + /** + * Alloc window + */ + window = (NVGXMwindow *) malloc(sizeof(NVGXMwindow)); + if (window == NULL) { return NULL; } - memset(fb, 0, sizeof(NVGXMframebuffer)); + memset(window, 0, sizeof(NVGXMwindow)); memcpy(&gxm_internal.initOptions, opts, sizeof(NVGXMinitOptions)); - fb->msaa = opts->msaa; + window->msaa = opts->msaa; + /** + * Create gxm context + */ SceGxmInitializeParams gxm_init_params; memset(&gxm_init_params, 0, sizeof(gxm_init_params)); - gxm_init_params.flags = 0; - gxm_init_params.displayQueueMaxPendingCount = MAX_PENDING_SWAPS; - gxm_init_params.displayQueueCallback = display_queue_callback; + gxm_init_params.flags = 0; + gxm_init_params.displayQueueMaxPendingCount = MAX_PENDING_SWAPS; + gxm_init_params.displayQueueCallback = display_queue_callback; gxm_init_params.displayQueueCallbackDataSize = sizeof(struct display_queue_callback_data); - gxm_init_params.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; + gxm_init_params.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; sceGxmInitialize(&gxm_init_params); - vdm_ring_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, - SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, - &vdm_ring_buffer_uid); + window->vdm_ring_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCE_GXM_MEMORY_ATTRIB_READ, + SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, + &window->vdm_ring_buffer_uid); - vertex_ring_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, - SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, - &vertex_ring_buffer_uid); + window->vertex_ring_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCE_GXM_MEMORY_ATTRIB_READ, + SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, + &window->vertex_ring_buffer_uid); - fragment_ring_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, - SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, - &fragment_ring_buffer_uid); + window->fragment_ring_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCE_GXM_MEMORY_ATTRIB_READ, + SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, + &window->fragment_ring_buffer_uid); unsigned int fragment_usse_offset; - fragment_usse_ring_buffer_addr = gpu_fragment_usse_alloc_map( + window->fragment_usse_ring_buffer_addr = gpu_fragment_usse_alloc_map( SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE, - &fragment_ring_buffer_uid, &fragment_usse_offset); + &window->fragment_usse_ring_buffer_uid, &fragment_usse_offset); SceGxmContextParams gxm_context_params; memset(&gxm_context_params, 0, sizeof(gxm_context_params)); - gxm_context_params.hostMem = malloc(SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE); - gxm_context_params.hostMemSize = SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE; - gxm_context_params.vdmRingBufferMem = vdm_ring_buffer_addr; - gxm_context_params.vdmRingBufferMemSize = SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE; - gxm_context_params.vertexRingBufferMem = vertex_ring_buffer_addr; - gxm_context_params.vertexRingBufferMemSize = SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE; - gxm_context_params.fragmentRingBufferMem = fragment_ring_buffer_addr; - gxm_context_params.fragmentRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE; - gxm_context_params.fragmentUsseRingBufferMem = fragment_usse_ring_buffer_addr; + gxm_context_params.hostMem = malloc(SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE); + gxm_context_params.hostMemSize = SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE; + gxm_context_params.vdmRingBufferMem = window->vdm_ring_buffer_addr; + gxm_context_params.vdmRingBufferMemSize = SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE; + gxm_context_params.vertexRingBufferMem = window->vertex_ring_buffer_addr; + gxm_context_params.vertexRingBufferMemSize = SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE; + gxm_context_params.fragmentRingBufferMem = window->fragment_ring_buffer_addr; + gxm_context_params.fragmentRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE; + gxm_context_params.fragmentUsseRingBufferMem = window->fragment_usse_ring_buffer_addr; gxm_context_params.fragmentUsseRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE; - gxm_context_params.fragmentUsseRingBufferOffset = fragment_usse_offset; - - sceGxmCreateContext(&gxm_context_params, &fb->context); + gxm_context_params.fragmentUsseRingBufferOffset = fragment_usse_offset; - SceGxmRenderTargetParams render_target_params; - memset(&render_target_params, 0, sizeof(render_target_params)); - render_target_params.flags = 0; - render_target_params.width = DISPLAY_WIDTH; - render_target_params.height = DISPLAY_HEIGHT; - render_target_params.scenesPerFrame = 1; - render_target_params.multisampleMode = opts->msaa; - render_target_params.multisampleLocations = 0; - render_target_params.driverMemBlock = -1; - - sceGxmCreateRenderTarget(&render_target_params, &gxm_render_target); - - for (int i = 0; i < DISPLAY_BUFFER_COUNT; i++) - { - gxm_color_surfaces_addr[i] = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, - SCE_GXM_MEMORY_ATTRIB_RW, - ALIGN(4 * DISPLAY_STRIDE * DISPLAY_HEIGHT, 1 * 1024 * 1024), - &gxm_color_surfaces_uid[i]); - - memset(gxm_color_surfaces_addr[i], 0, DISPLAY_STRIDE * DISPLAY_HEIGHT); - - sceGxmColorSurfaceInit(&gxm_color_surfaces[i], - DISPLAY_COLOR_FORMAT, - SCE_GXM_COLOR_SURFACE_LINEAR, - (opts->msaa == SCE_GXM_MULTISAMPLE_NONE) ? SCE_GXM_COLOR_SURFACE_SCALE_NONE - : SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE, - SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, - DISPLAY_WIDTH, - DISPLAY_HEIGHT, - DISPLAY_STRIDE, - gxm_color_surfaces_addr[i]); - - sceGxmSyncObjectCreate(&gxm_sync_objects[i]); + sceGxmCreateContext(&gxm_context_params, &window->context); + if (window->context == NULL) { + gxmDeleteWindow(window); + return NULL; } - unsigned int depth_stencil_width = ALIGN(DISPLAY_WIDTH, SCE_GXM_TILE_SIZEX); - unsigned int depth_stencil_height = ALIGN(DISPLAY_HEIGHT, SCE_GXM_TILE_SIZEY); - unsigned int depth_stencil_samples = depth_stencil_width * depth_stencil_height; - - if (opts->msaa == SCE_GXM_MULTISAMPLE_4X) - { - // samples increase in X and Y - depth_stencil_samples *= 4; - depth_stencil_width *= 2; - } - else if (opts->msaa == SCE_GXM_MULTISAMPLE_2X) - { - // samples increase in Y only - depth_stencil_samples *= 2; + /** + * Create default framebuffer + */ + NVGXMframebufferInitOptions framebufferOpts = { + .display_buffer_count = DISPLAY_BUFFER_COUNT, + .scenesPerFrame = opts->scenesPerFrame, + .render_target = NULL, + .color_format = DISPLAY_COLOR_FORMAT, + .color_surface_type = DISPLAY_COLOR_SURFACE_TYPE, + .display_width = DISPLAY_WIDTH, + .display_height = DISPLAY_HEIGHT, + .display_stride = DISPLAY_STRIDE, + }; + window->fb = gxmCreateFramebuffer(&framebufferOpts); + if (!window->fb) { + gxmDeleteWindow(window); + return NULL; } - gxm_depth_stencil_surface_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, - SCE_GXM_MEMORY_ATTRIB_RW, - 4 * depth_stencil_samples, &gxm_depth_stencil_surface_uid); - sceGxmDepthStencilSurfaceInit(&gxm_depth_stencil_surface, - SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24, - SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, - depth_stencil_width, - gxm_depth_stencil_surface_addr, - NULL); - - static const unsigned int shader_patcher_buffer_size = 64 * 1024; - static const unsigned int shader_patcher_vertex_usse_size = 64 * 1024; + /** + * Create shader patcher + */ + static const unsigned int shader_patcher_buffer_size = 64 * 1024; + static const unsigned int shader_patcher_vertex_usse_size = 64 * 1024; static const unsigned int shader_patcher_fragment_usse_size = 64 * 1024; - gxm_shader_patcher_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + window->gxm_shader_patcher_buffer_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCE_GXM_MEMORY_ATTRIB_RW, - shader_patcher_buffer_size, &gxm_shader_patcher_buffer_uid); + shader_patcher_buffer_size, + &window->gxm_shader_patcher_buffer_uid); unsigned int shader_patcher_vertex_usse_offset; - gxm_shader_patcher_vertex_usse_addr = gpu_vertex_usse_alloc_map( - shader_patcher_vertex_usse_size, &gxm_shader_patcher_vertex_usse_uid, + window->gxm_shader_patcher_vertex_usse_addr = gpu_vertex_usse_alloc_map( + shader_patcher_vertex_usse_size, &window->gxm_shader_patcher_vertex_usse_uid, &shader_patcher_vertex_usse_offset); unsigned int shader_patcher_fragment_usse_offset; - gxm_shader_patcher_fragment_usse_addr = gpu_fragment_usse_alloc_map( - shader_patcher_fragment_usse_size, &gxm_shader_patcher_fragment_usse_uid, + window->gxm_shader_patcher_fragment_usse_addr = gpu_fragment_usse_alloc_map( + shader_patcher_fragment_usse_size, &window->gxm_shader_patcher_fragment_usse_uid, &shader_patcher_fragment_usse_offset); SceGxmShaderPatcherParams shader_patcher_params; memset(&shader_patcher_params, 0, sizeof(shader_patcher_params)); - shader_patcher_params.userData = NULL; - shader_patcher_params.hostAllocCallback = shader_patcher_host_alloc_cb; - shader_patcher_params.hostFreeCallback = shader_patcher_host_free_cb; - shader_patcher_params.bufferAllocCallback = NULL; - shader_patcher_params.bufferFreeCallback = NULL; - shader_patcher_params.bufferMem = gxm_shader_patcher_buffer_addr; - shader_patcher_params.bufferMemSize = shader_patcher_buffer_size; - shader_patcher_params.vertexUsseAllocCallback = NULL; - shader_patcher_params.vertexUsseFreeCallback = NULL; - shader_patcher_params.vertexUsseMem = gxm_shader_patcher_vertex_usse_addr; - shader_patcher_params.vertexUsseMemSize = shader_patcher_vertex_usse_size; - shader_patcher_params.vertexUsseOffset = shader_patcher_vertex_usse_offset; + shader_patcher_params.userData = NULL; + shader_patcher_params.hostAllocCallback = shader_patcher_host_alloc_cb; + shader_patcher_params.hostFreeCallback = shader_patcher_host_free_cb; + shader_patcher_params.bufferAllocCallback = NULL; + shader_patcher_params.bufferFreeCallback = NULL; + shader_patcher_params.bufferMem = window->gxm_shader_patcher_buffer_addr; + shader_patcher_params.bufferMemSize = shader_patcher_buffer_size; + shader_patcher_params.vertexUsseAllocCallback = NULL; + shader_patcher_params.vertexUsseFreeCallback = NULL; + shader_patcher_params.vertexUsseMem = window->gxm_shader_patcher_vertex_usse_addr; + shader_patcher_params.vertexUsseMemSize = shader_patcher_vertex_usse_size; + shader_patcher_params.vertexUsseOffset = shader_patcher_vertex_usse_offset; shader_patcher_params.fragmentUsseAllocCallback = NULL; - shader_patcher_params.fragmentUsseFreeCallback = NULL; - shader_patcher_params.fragmentUsseMem = gxm_shader_patcher_fragment_usse_addr; - shader_patcher_params.fragmentUsseMemSize = shader_patcher_fragment_usse_size; - shader_patcher_params.fragmentUsseOffset = shader_patcher_fragment_usse_offset; + shader_patcher_params.fragmentUsseFreeCallback = NULL; + shader_patcher_params.fragmentUsseMem = window->gxm_shader_patcher_fragment_usse_addr; + shader_patcher_params.fragmentUsseMemSize = shader_patcher_fragment_usse_size; + shader_patcher_params.fragmentUsseOffset = shader_patcher_fragment_usse_offset; - sceGxmShaderPatcherCreate(&shader_patcher_params, &fb->shader_patcher); + sceGxmShaderPatcherCreate(&shader_patcher_params, &window->shader_patcher); - gxm_internal.context = fb->context; - gxm_internal.shader_patcher = fb->shader_patcher; + gxm_internal.context = window->context; + gxm_internal.shader_patcher = window->shader_patcher; - // shared indices - gxm_internal.linearIndices = (unsigned short*)gpu_alloc_map( + /** + * Alloc shared linear indices + */ + gxm_internal.linearIndices = (unsigned short *) gpu_alloc_map( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_MEMORY_ATTRIB_READ, UINT16_MAX * sizeof(unsigned short), &gxm_internal.linearIndicesUid); - for (uint32_t i = 0; i < UINT16_MAX; ++i) - { + for (uint32_t i = 0; i < UINT16_MAX; ++i) { gxm_internal.linearIndices[i] = i; } - // clear shader + /** + * Create clear shader + */ #if USE_VITA_SHARK - static const char* clearVertShader = "float4 main(float2 position) : POSITION\n" + static const char *clearVertShader = "float4 main(float2 position) : POSITION\n" "{\n" " return float4(position, 1.f, 1.f);\n" "}\n"; - static const char* clearFragShader = "float4 main(uniform float4 color : BUFFER[0]) : COLOR\n" + static const char *clearFragShader = "float4 main(uniform float4 color) : COLOR\n" "{\n" " return color;\n" "}\n"; @@ -617,69 +663,59 @@ NVGXMframebuffer* nvgxmCreateFramebuffer(const NVGXMinitOptions* opts) 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00 }; - static const unsigned char clearFragShader[276] = { - 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x00, 0x03, 0x12, 0x01, 0x00, + static const unsigned char clearFragShader[228] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x00, 0x03, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x8c, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x7c, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x74, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x90, 0x3a, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x90, 0x3a, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0xa0, 0x84, 0x30, 0x83, 0xe8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, - 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x44, 0xfa, 0x04, 0x81, 0x19, 0xf0, 0x7e, 0x0d, 0x80, 0x40, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x01, 0x04, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, - 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, + 0xfa, 0x02, 0x80, 0x19, 0xf0, 0x7e, 0x0d, 0x80, 0x40, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00 }; #endif - gxmCreateShader(&gxm_internal.clearProg, "clear", (const char*)clearVertShader, (const char*)clearFragShader); + if (gxmCreateShader(&gxm_internal.clearProg, "clear", (const char *) clearVertShader, + (const char *) clearFragShader) == 0) { + gxmDeleteWindow(window); + return NULL; + } - gxm_internal.clearVertices = (struct clear_vertex*)gpu_alloc_map( + gxm_internal.clearVertices = (struct clear_vertex *) gpu_alloc_map( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_MEMORY_ATTRIB_READ, 3 * sizeof(struct clear_vertex), &gxm_internal.clearVerticesUid); - gxm_internal.clearVertices[0] = (struct clear_vertex) { -1.0f, -1.0f }; - gxm_internal.clearVertices[1] = (struct clear_vertex) { 3.0f, -1.0f }; - gxm_internal.clearVertices[2] = (struct clear_vertex) { -1.0f, 3.0f }; + gxm_internal.clearVertices[0] = (struct clear_vertex) {-1.0f, -1.0f}; + gxm_internal.clearVertices[1] = (struct clear_vertex) {3.0f, -1.0f}; + gxm_internal.clearVertices[2] = (struct clear_vertex) {-1.0f, 3.0f}; + gxm_internal.clearParam = sceGxmProgramFindParameterByName(gxm_internal.clearProg.frag_gxp, "color"); + gxmClearColor(1.0f, 1.0f, 1.0f, 1.0f); - gxm_internal.clearColor = (NVGcolor*)gpu_alloc_map( - SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, - SCE_GXM_MEMORY_ATTRIB_READ, - sizeof(NVGcolor), - &gxm_internal.clearColorUid); - gxm_internal.clearColor->r = 1.0f; - gxm_internal.clearColor->g = 1.0f; - gxm_internal.clearColor->b = 1.0f; - gxm_internal.clearColor->a = 1.0f; - sceGxmSetFragmentUniformBuffer(gxm_internal.context, 0, gxm_internal.clearColor->rgba); - - const SceGxmProgramParameter* clear_position_param = sceGxmProgramFindParameterByName( + const SceGxmProgramParameter *clear_position_param = sceGxmProgramFindParameterByName( gxm_internal.clearProg.vert_gxp, "position"); SceGxmVertexAttribute clear_vertex_attribute; - clear_vertex_attribute.streamIndex = 0; - clear_vertex_attribute.offset = 0; - clear_vertex_attribute.format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + clear_vertex_attribute.streamIndex = 0; + clear_vertex_attribute.offset = 0; + clear_vertex_attribute.format = SCE_GXM_ATTRIBUTE_FORMAT_F32; clear_vertex_attribute.componentCount = 2; - clear_vertex_attribute.regIndex = sceGxmProgramParameterGetResourceIndex(clear_position_param); + clear_vertex_attribute.regIndex = sceGxmProgramParameterGetResourceIndex(clear_position_param); SceGxmVertexStream clear_vertex_stream; - clear_vertex_stream.stride = sizeof(struct clear_vertex); + clear_vertex_stream.stride = sizeof(struct clear_vertex); clear_vertex_stream.indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; GXM_CHECK(sceGxmShaderPatcherCreateVertexProgram( @@ -694,65 +730,254 @@ NVGXMframebuffer* nvgxmCreateFramebuffer(const NVGXMinitOptions* opts) NULL, gxm_internal.clearProg.vert_gxp, &gxm_internal.clearProg.frag)); - return fb; + gxm_internal.window = window; + return window; } -void nvgxmDeleteFramebuffer(NVGXMframebuffer* gxm) -{ - if (gxm == NULL) - return; +void gxmDeleteWindow(NVGXMwindow *window) { + if (window == NULL) return; gpu_unmap_free(gxm_internal.linearIndicesUid); // linear index buffer gpu_unmap_free(gxm_internal.clearVerticesUid); // clear vertex stream - gpu_unmap_free(gxm_internal.clearColorUid); // clear color uniform buffer gxmDeleteShader(&gxm_internal.clearProg); - sceGxmShaderPatcherDestroy(gxm->shader_patcher); + if (window->shader_patcher) + sceGxmShaderPatcherDestroy(window->shader_patcher); - gpu_unmap_free(gxm_shader_patcher_buffer_uid); - gpu_vertex_usse_unmap_free(gxm_shader_patcher_vertex_usse_uid); - gpu_fragment_usse_unmap_free(gxm_shader_patcher_fragment_usse_uid); + gpu_unmap_free(window->gxm_shader_patcher_buffer_uid); + gpu_vertex_usse_unmap_free(window->gxm_shader_patcher_vertex_usse_uid); + gpu_fragment_usse_unmap_free(window->gxm_shader_patcher_fragment_usse_uid); - gpu_unmap_free(gxm_depth_stencil_surface_uid); + gxmDeleteFramebuffer(window->fb); - for (int i = 0; i < DISPLAY_BUFFER_COUNT; i++) - { - gpu_unmap_free(gxm_color_surfaces_uid[i]); - sceGxmSyncObjectDestroy(gxm_sync_objects[i]); + gpu_unmap_free(window->vdm_ring_buffer_uid); + gpu_unmap_free(window->vertex_ring_buffer_uid); + gpu_unmap_free(window->fragment_ring_buffer_uid); + gpu_fragment_usse_unmap_free(window->fragment_usse_ring_buffer_uid); + + if (window->context) + sceGxmDestroyContext(window->context); + sceGxmTerminate(); + + free(window); +} + +NVGXMwindow *gxmGetWindow() { + return gxm_internal.window; +} + +NVGXMframebuffer *gxmCreateFramebuffer(const NVGXMframebufferInitOptions *opts) { + NVGXMframebuffer *fb = (NVGXMframebuffer *) malloc(sizeof(NVGXMframebuffer)); + if (fb == NULL) { + return NULL; } + assert(opts->scenesPerFrame >= 1 && opts->scenesPerFrame <= 8); + assert(opts->display_buffer_count >= 1); + assert(opts->render_target && opts->display_buffer_count == 1 || !opts->render_target); + memset(fb, 0, sizeof(NVGXMframebuffer)); + memcpy(&fb->initOptions, opts, sizeof(NVGXMframebufferInitOptions)); + + SceGxmRenderTargetParams render_target_params; + memset(&render_target_params, 0, sizeof(render_target_params)); + render_target_params.flags = 0; + render_target_params.width = opts->display_width; + render_target_params.height = opts->display_height; + render_target_params.scenesPerFrame = opts->scenesPerFrame; + render_target_params.multisampleMode = gxm_internal.initOptions.msaa; + render_target_params.multisampleLocations = 0; + render_target_params.driverMemBlock = -1; + + sceGxmCreateRenderTarget(&render_target_params, &fb->gxm_render_target); - sceGxmDestroyRenderTarget(gxm_render_target); + fb->gxm_color_surfaces = (NVGXMcolorSurface *) malloc(opts->display_buffer_count * sizeof(NVGXMcolorSurface)); + if (fb->gxm_color_surfaces == NULL) { + gxmDeleteFramebuffer(fb); + return NULL; + } - gpu_unmap_free(vdm_ring_buffer_uid); - gpu_unmap_free(vertex_ring_buffer_uid); - gpu_unmap_free(fragment_ring_buffer_uid); - gpu_fragment_usse_unmap_free(fragment_usse_ring_buffer_uid); + memset(fb->gxm_color_surfaces, 0, opts->display_buffer_count * sizeof(NVGXMcolorSurface)); + for (int i = 0; i < opts->display_buffer_count; i++) { + if (opts->render_target) { + // Share the same data address between color surface and texture + fb->gxm_color_surfaces[i].surface_addr = opts->render_target->data; + } else { + fb->gxm_color_surfaces[i].surface_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCE_GXM_MEMORY_ATTRIB_RW, + 4 * opts->display_stride * opts->display_height, + &fb->gxm_color_surfaces[i].surface_uid); + if (fb->gxm_color_surfaces[i].surface_addr == NULL) { + gxmDeleteFramebuffer(fb); + return NULL; + } + sceGxmSyncObjectCreate(&fb->gxm_color_surfaces[i].sync_object); + } - sceGxmDestroyContext(gxm->context); - sceGxmTerminate(); + memset(fb->gxm_color_surfaces[i].surface_addr, 0, 4 * opts->display_stride * opts->display_height); - free(gxm); + sceGxmColorSurfaceInit(&fb->gxm_color_surfaces[i].surface, + opts->color_format, + opts->color_surface_type, + (gxm_internal.initOptions.msaa == SCE_GXM_MULTISAMPLE_NONE) + ? SCE_GXM_COLOR_SURFACE_SCALE_NONE + : SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE, + SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, + opts->display_width, + opts->display_height, + opts->display_stride, + fb->gxm_color_surfaces[i].surface_addr); + + } + + unsigned int depth_stencil_width = ALIGN(opts->display_width, SCE_GXM_TILE_SIZEX); + unsigned int depth_stencil_height = ALIGN(opts->display_height, SCE_GXM_TILE_SIZEY); + unsigned int depth_stencil_samples = depth_stencil_width * depth_stencil_height; + + if (gxm_internal.initOptions.msaa == SCE_GXM_MULTISAMPLE_4X) { + // samples increase in X and Y + depth_stencil_samples *= 4; + depth_stencil_width *= 2; + } else if (gxm_internal.initOptions.msaa == SCE_GXM_MULTISAMPLE_2X) { + // samples increase in Y only + depth_stencil_samples *= 2; + } + fb->gxm_depth_stencil_surface_addr = gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCE_GXM_MEMORY_ATTRIB_RW, + 4 * depth_stencil_samples, &fb->gxm_depth_stencil_surface_uid); + if (fb->gxm_depth_stencil_surface_addr == NULL) { + gxmDeleteFramebuffer(fb); + return NULL; + } + + sceGxmDepthStencilSurfaceInit(&fb->gxm_depth_stencil_surface, + SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24, + SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, + depth_stencil_width, + fb->gxm_depth_stencil_surface_addr, + NULL); + + return fb; } -void gxmClearColor(float r, float g, float b, float a) -{ - gxm_internal.clearColor->r = r; - gxm_internal.clearColor->g = g; - gxm_internal.clearColor->b = b; - gxm_internal.clearColor->a = a; +void gxmDeleteFramebuffer(NVGXMframebuffer *fb) { + if (fb == NULL) + return; - // TODO: Fix screen tearing - GXM_CHECK_VOID(sceGxmSetFragmentUniformBuffer(gxm_internal.context, 0, gxm_internal.clearColor->rgba)); + if (fb->gxm_depth_stencil_surface_uid) + gpu_unmap_free(fb->gxm_depth_stencil_surface_uid); + + if (fb->gxm_color_surfaces) { + for (int i = 0; i < fb->initOptions.display_buffer_count; i++) { + if (fb->gxm_color_surfaces[i].surface_uid) + gpu_unmap_free(fb->gxm_color_surfaces[i].surface_uid); + if (fb->gxm_color_surfaces[i].sync_object) + sceGxmSyncObjectDestroy(fb->gxm_color_surfaces[i].sync_object); + } + free(fb->gxm_color_surfaces); + } + + sceGxmDestroyRenderTarget(fb->gxm_render_target); + + free(fb); } -void gxmClear(void) +static int tex_format_to_bytespp(SceGxmTextureFormat format) { + switch (format & 0x9f000000U) { + case SCE_GXM_TEXTURE_BASE_FORMAT_U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8: + case SCE_GXM_TEXTURE_BASE_FORMAT_P8: + return 1; + case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4: + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2: + case SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5: + case SCE_GXM_TEXTURE_BASE_FORMAT_U5U6U5: + case SCE_GXM_TEXTURE_BASE_FORMAT_S5S5U6: + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8: + return 2; + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8: + return 3; + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8: + case SCE_GXM_TEXTURE_BASE_FORMAT_F32: + case SCE_GXM_TEXTURE_BASE_FORMAT_U32: + case SCE_GXM_TEXTURE_BASE_FORMAT_S32: + default: + return 4; + } +} + +NVGXMtexture *gxmCreateTexture(int width, int height, SceGxmTextureFormat format, void *data) { + int aligned_w = ALIGN(width, 8); + int spp = tex_format_to_bytespp(format); + int stride = aligned_w * spp; + int tex_size = stride * height; + int ret; + + NVGXMtexture *texture = (NVGXMtexture *) malloc(sizeof(NVGXMtexture)); + if (texture == NULL) { + return NULL; + } + + memset(texture, 0, sizeof(NVGXMtexture)); + texture->data = (uint8_t *) gpu_alloc_map(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCE_GXM_MEMORY_ATTRIB_RW, + tex_size, + &texture->uid); + if (texture->data == NULL) { + gxmDeleteTexture(texture); + return NULL; + } + + /* Clear the texture */ + if (data == NULL) { + memset(texture->data, 0, tex_size); + } else { + for (int i = 0; i < height; i++) { + memcpy(texture->data + i * stride, data + i * width * spp, width * spp); + } + } + + /* Create the gxm texture */ + ret = sceGxmTextureInitLinear(&texture->tex, texture->data, format, width, height, 0); + if (ret < 0) { + GXM_PRINT_ERROR(ret); + gxmDeleteTexture(texture); + return NULL; + } + + return texture; +} + +void gxmDeleteTexture(NVGXMtexture *texture) { + if (texture == NULL) return; + + if (texture->uid) + gpu_unmap_free(texture->uid); + + free(texture); +} + +void gxmClearColor(float r, float g, float b, float a) { + gxm_internal.clearColor.r = r; + gxm_internal.clearColor.g = g; + gxm_internal.clearColor.b = b; + gxm_internal.clearColor.a = a; +} + +void gxmClear(void) { sceGxmSetVertexProgram(gxm_internal.context, gxm_internal.clearProg.vert); sceGxmSetFragmentProgram(gxm_internal.context, gxm_internal.clearProg.frag); sceGxmSetVertexStream(gxm_internal.context, 0, gxm_internal.clearVertices); + // set clear color + void *buffer; + sceGxmReserveFragmentDefaultUniformBuffer(gxm_internal.context, &buffer); + sceGxmSetUniformDataF(buffer, gxm_internal.clearParam, 0, 4, gxm_internal.clearColor.rgba); + // clear stencil buffer sceGxmSetFrontStencilRef(gxm_internal.context, 0); sceGxmSetBackStencilRef(gxm_internal.context, 0); @@ -761,92 +986,105 @@ void gxmClear(void) sceGxmSetBackStencilFunc(gxm_internal.context, SCE_GXM_STENCIL_FUNC_ALWAYS, SCE_GXM_STENCIL_OP_ZERO, SCE_GXM_STENCIL_OP_ZERO, SCE_GXM_STENCIL_OP_ZERO, 0xff, 0xff); - sceGxmDraw(gxm_internal.context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, gxm_internal.linearIndices, + sceGxmDraw(gxm_internal.context, + SCE_GXM_PRIMITIVE_TRIANGLES, + SCE_GXM_INDEX_FORMAT_U16, + gxm_internal.linearIndices, 3); } -void gxmBeginFrame(void) -{ +void gxmBeginFrame(void) { + NVGXMwindow *window = gxm_internal.window; + if (!window) return; + NVGXMframebuffer *fb = window->fb; + if (!fb) return; + gxmBeginFrameEx(fb, 0); +} + +void gxmBeginFrameEx(NVGXMframebuffer *fb, unsigned int flags) { GXM_CHECK_VOID(sceGxmBeginScene(gxm_internal.context, - 0, - gxm_render_target, + flags, + fb->gxm_render_target, NULL, NULL, - gxm_sync_objects[gxm_back_buffer_index], - &gxm_color_surfaces[gxm_back_buffer_index], - &gxm_depth_stencil_surface)); + fb->gxm_color_surfaces[fb->gxm_back_buffer_index].sync_object, + &fb->gxm_color_surfaces[fb->gxm_back_buffer_index].surface, + &fb->gxm_depth_stencil_surface)); } -void gxmEndFrame(void) -{ +void gxmEndFrame(void) { GXM_CHECK_VOID(sceGxmEndScene(gxm_internal.context, NULL, NULL)); } -void gxmSwapBuffer(void) -{ +void gxmSwapBuffer(void) { + NVGXMwindow *window = gxm_internal.window; + if (!window) return; + NVGXMframebuffer *fb = window->fb; + if (!fb) return; struct display_queue_callback_data queue_cb_data; - queue_cb_data.addr = gxm_color_surfaces_addr[gxm_back_buffer_index]; + queue_cb_data.addr = fb->gxm_color_surfaces[fb->gxm_back_buffer_index].surface_addr; GXM_CHECK_VOID(sceGxmDisplayQueueAddEntry( - gxm_sync_objects[gxm_front_buffer_index], - gxm_sync_objects[gxm_back_buffer_index], + fb->gxm_color_surfaces[fb->gxm_front_buffer_index].sync_object, + fb->gxm_color_surfaces[fb->gxm_back_buffer_index].sync_object, &queue_cb_data)); - gxm_front_buffer_index = gxm_back_buffer_index; - gxm_back_buffer_index = (gxm_back_buffer_index + 1) % DISPLAY_BUFFER_COUNT; + fb->gxm_front_buffer_index = fb->gxm_back_buffer_index; + fb->gxm_back_buffer_index = (fb->gxm_back_buffer_index + 1) % fb->initOptions.display_buffer_count; } -void gxmSwapInterval(int interval) -{ +void gxmSwapInterval(int interval) { gxm_internal.initOptions.swapInterval = interval; } -int gxmDialogUpdate(void) -{ +int gxmDialogUpdate(void) { + NVGXMwindow *window = gxm_internal.window; + if (!window) return SCE_COMMON_DIALOG_RESULT_ABORTED; + NVGXMframebuffer *fb = window->fb; + if (!fb) return SCE_COMMON_DIALOG_RESULT_ABORTED; SceCommonDialogUpdateParam updateParam; memset(&updateParam, 0, sizeof(updateParam)); - updateParam.renderTarget.colorFormat = DISPLAY_COLOR_FORMAT; - updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR; - updateParam.renderTarget.width = DISPLAY_WIDTH; - updateParam.renderTarget.height = DISPLAY_HEIGHT; - updateParam.renderTarget.strideInPixels = DISPLAY_STRIDE; + updateParam.renderTarget.colorFormat = fb->initOptions.color_format; + updateParam.renderTarget.surfaceType = fb->initOptions.color_surface_type; + updateParam.renderTarget.width = fb->initOptions.display_width; + updateParam.renderTarget.height = fb->initOptions.display_height; + updateParam.renderTarget.strideInPixels = fb->initOptions.display_stride; - updateParam.renderTarget.colorSurfaceData = gxm_color_surfaces_addr[gxm_back_buffer_index]; - updateParam.renderTarget.depthSurfaceData = gxm_depth_stencil_surface_addr; - updateParam.displaySyncObject = gxm_sync_objects[gxm_back_buffer_index]; + updateParam.renderTarget.colorSurfaceData = fb->gxm_color_surfaces[fb->gxm_back_buffer_index].surface_addr; + updateParam.renderTarget.depthSurfaceData = fb->gxm_depth_stencil_surface_addr; + updateParam.displaySyncObject = fb->gxm_color_surfaces[fb->gxm_back_buffer_index].sync_object; return sceCommonDialogUpdate(&updateParam); } -void* gxmReadPixels(void) -{ - return sceGxmColorSurfaceGetData(&gxm_color_surfaces[gxm_front_buffer_index]); +void *gxmReadPixels(void) { + NVGXMwindow *window = gxm_internal.window; + if (!window) return NULL; + NVGXMframebuffer *fb = window->fb; + if (!fb) return NULL; + return sceGxmColorSurfaceGetData(&fb->gxm_color_surfaces[fb->gxm_front_buffer_index].surface); } -unsigned short* gxmGetSharedIndices(void) -{ +unsigned short *gxmGetSharedIndices(void) { return gxm_internal.linearIndices; } #ifdef USE_VITA_SHARK -void dumpShader(const char* name, const char* type, const SceGxmProgram* program, uint32_t size) -{ +void dumpShader(const char *name, const char *type, const SceGxmProgram *program, uint32_t size) { char path[256]; int need_comma = 0; - char* buf = (char*)malloc(0x5000); + char *buf = (char *) malloc(0x5000); memset(buf, 0, 0x5000); memcpy(buf, program, size); snprintf(path, sizeof(path), "ux0:data/nvg_%s%s.c", name, type); - FILE* fp = fopen(path, "w"); - if (fp) - { + FILE *fp = fopen(path, "w"); + if (fp) { fprintf(fp, "static const unsigned char %s%sShader[%i] = {", name, type, size); - for (int i = 0; i < size; ++i) - { + for (int i = 0; i < size; ++i) { if (need_comma) fprintf(fp, ", "); else @@ -860,46 +1098,41 @@ void dumpShader(const char* name, const char* type, const SceGxmProgram* program } } -int gxmCreateShader(NVGXMshaderProgram* shader, const char* name, const char* vshader, const char* fshader) -{ - if (vshader != NULL) - { - uint32_t size = strlen(vshader); - SceGxmProgram* p = shark_compile_shader(vshader, &size, SHARK_VERTEX_SHADER); - if (!p) - { +int gxmCreateShader(NVGXMshaderProgram *shader, const char *name, const char *vshader, const char *fshader) { + if (vshader != NULL) { + uint32_t size = strlen(vshader); + SceGxmProgram *p = shark_compile_shader(vshader, &size, SHARK_VERTEX_SHADER); + if (!p) { sceClibPrintf("shark_compile_shader failed (vert): %s\n", name); + shark_clear_output(); return 0; } - shader->vert_gxp = (SceGxmProgram*)malloc(size); - sceClibMemcpy((void*)shader->vert_gxp, (void*)p, size); + shader->vert_gxp = (SceGxmProgram *) malloc(size); + sceClibMemcpy((void *) shader->vert_gxp, (void *) p, size); shark_clear_output(); GXM_CHECK(sceGxmShaderPatcherRegisterProgram(gxm_internal.shader_patcher, shader->vert_gxp, &shader->vert_id)); GXM_CHECK(sceGxmProgramCheck(shader->vert_gxp)); - if (gxm_internal.initOptions.dumpShader) - { + if (gxm_internal.initOptions.dumpShader) { dumpShader(name, "Vert", shader->vert_gxp, size); } } - if (fshader != NULL) - { - uint32_t size = strlen(fshader); - SceGxmProgram* p = shark_compile_shader(fshader, &size, SHARK_FRAGMENT_SHADER); - if (!p) - { + if (fshader != NULL) { + uint32_t size = strlen(fshader); + SceGxmProgram *p = shark_compile_shader(fshader, &size, SHARK_FRAGMENT_SHADER); + if (!p) { sceClibPrintf("shark_compile_shader failed (frag): %s\n", name); + shark_clear_output(); return 0; } - shader->frag_gxp = (SceGxmProgram*)malloc(size); - sceClibMemcpy((void*)shader->frag_gxp, (void*)p, size); + shader->frag_gxp = (SceGxmProgram *) malloc(size); + sceClibMemcpy((void *) shader->frag_gxp, (void *) p, size); shark_clear_output(); GXM_CHECK(sceGxmShaderPatcherRegisterProgram(gxm_internal.shader_patcher, shader->frag_gxp, &shader->frag_id)); GXM_CHECK(sceGxmProgramCheck(shader->frag_gxp)); - if (gxm_internal.initOptions.dumpShader) - { + if (gxm_internal.initOptions.dumpShader) { dumpShader(name, "Frag", shader->frag_gxp, size); } } @@ -908,19 +1141,16 @@ int gxmCreateShader(NVGXMshaderProgram* shader, const char* name, const char* vs #else -int gxmCreateShader(NVGXMshaderProgram* shader, const char* name, const char* vshader, const char* fshader) -{ - (void)name; - if (vshader != NULL) - { - shader->vert_gxp = (SceGxmProgram*)vshader; +int gxmCreateShader(NVGXMshaderProgram *shader, const char *name, const char *vshader, const char *fshader) { + (void) name; + if (vshader != NULL) { + shader->vert_gxp = (SceGxmProgram *) vshader; GXM_CHECK(sceGxmShaderPatcherRegisterProgram(gxm_internal.shader_patcher, shader->vert_gxp, &shader->vert_id)); GXM_CHECK(sceGxmProgramCheck(shader->vert_gxp)); } - if (fshader != NULL) - { - shader->frag_gxp = (SceGxmProgram*)fshader; + if (fshader != NULL) { + shader->frag_gxp = (SceGxmProgram *) fshader; GXM_CHECK(sceGxmShaderPatcherRegisterProgram(gxm_internal.shader_patcher, shader->frag_gxp, &shader->frag_id)); GXM_CHECK(sceGxmProgramCheck(shader->frag_gxp)); } @@ -929,8 +1159,7 @@ int gxmCreateShader(NVGXMshaderProgram* shader, const char* name, const char* vs #endif -void gxmDeleteShader(NVGXMshaderProgram* prog) -{ +void gxmDeleteShader(NVGXMshaderProgram *prog) { if (gxm_internal.shader_patcher == NULL) return; @@ -952,4 +1181,33 @@ void gxmDeleteShader(NVGXMshaderProgram* prog) #endif } +int gxmCreateFragmentProgram(SceGxmShaderPatcherId programId, + SceGxmOutputRegisterFormat outputFormat, + const SceGxmBlendInfo *blendInfo, + const SceGxmProgram *vertexProgram, + SceGxmFragmentProgram **fragmentProgram) { + return sceGxmShaderPatcherCreateFragmentProgram(gxm_internal.shader_patcher, + programId, + outputFormat, + gxm_internal.initOptions.msaa, + blendInfo, + vertexProgram, + fragmentProgram); +} + +int gxmCreateVertexProgram(SceGxmShaderPatcherId programId, + const SceGxmVertexAttribute *attributes, + unsigned int attributeCount, + const SceGxmVertexStream *streams, + unsigned int streamCount, + SceGxmVertexProgram **vertexProgram) { + return sceGxmShaderPatcherCreateVertexProgram(gxm_internal.shader_patcher, + programId, + attributes, + attributeCount, + streams, + streamCount, + vertexProgram); +} + #endif // NANOVG_GXM_UTILS_IMPLEMENTATION diff --git a/library/include/borealis/platforms/psv/psv_video.hpp b/library/include/borealis/platforms/psv/psv_video.hpp index 704e3dffe..788ebc684 100644 --- a/library/include/borealis/platforms/psv/psv_video.hpp +++ b/library/include/borealis/platforms/psv/psv_video.hpp @@ -35,11 +35,11 @@ class PsvVideoContext : public VideoContext double getScaleFactor() override; NVGcontext* getNVGContext() override; - NVGXMframebuffer *getFramebuffer(); + NVGXMwindow *getWindow(); private: NVGcontext* nvgContext; - NVGXMframebuffer* gxm; + NVGXMwindow* window; }; } // namespace brls diff --git a/library/lib/platforms/psv/psv_video.cpp b/library/lib/platforms/psv/psv_video.cpp index bffa3af7c..5c87311c6 100644 --- a/library/lib/platforms/psv/psv_video.cpp +++ b/library/lib/platforms/psv/psv_video.cpp @@ -38,14 +38,15 @@ PsvVideoContext::PsvVideoContext() .msaa = SCE_GXM_MULTISAMPLE_4X, .swapInterval = 1, .dumpShader = 0, + .scenesPerFrame = 1, }; - gxm = nvgxmCreateFramebuffer(&initOptions); - if (gxm == NULL) { + window = gxmCreateWindow(&initOptions); + if (window == NULL) { fatal("gxm: failed to initialize"); } - this->nvgContext = nvgCreateGXM(gxm, 0); + this->nvgContext = nvgCreateGXM(window->context, window->shader_patcher, 0); if (!this->nvgContext) { brls::fatal("sdl: unable to init nanovg"); @@ -61,7 +62,7 @@ PsvVideoContext::~PsvVideoContext() if (this->nvgContext) { nvgDeleteGXM(this->nvgContext); - nvgxmDeleteFramebuffer(gxm); + gxmDeleteWindow(window); } } catch (...) @@ -102,9 +103,9 @@ NVGcontext* PsvVideoContext::getNVGContext() { return this->nvgContext; } -NVGXMframebuffer* PsvVideoContext::getFramebuffer() +NVGXMwindow* PsvVideoContext::getWindow() { - return this->gxm; + return this->window; } } \ No newline at end of file