DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

nanovg_gl.h (51729B)


      1 //
      2 // Copyright (c) 2009-2013 Mikko Mononen memon@inside.org
      3 //
      4 // This software is provided 'as-is', without any express or implied
      5 // warranty.  In no event will the authors be held liable for any damages
      6 // arising from the use of this software.
      7 // Permission is granted to anyone to use this software for any purpose,
      8 // including commercial applications, and to alter it and redistribute it
      9 // freely, subject to the following restrictions:
     10 // 1. The origin of this software must not be misrepresented; you must not
     11 //    claim that you wrote the original software. If you use this software
     12 //    in a product, an acknowledgment in the product documentation would be
     13 //    appreciated but is not required.
     14 // 2. Altered source versions must be plainly marked as such, and must not be
     15 //    misrepresented as being the original software.
     16 // 3. This notice may not be removed or altered from any source distribution.
     17 //
     18 #ifndef NANOVG_GL_H
     19 #define NANOVG_GL_H
     20 
     21 #if defined NANOVG_GL2_FORCED
     22 #  undef NANOVG_GL3
     23 #  undef NANOVG_GLES2
     24 #  undef NANOVG_GLES3
     25 #  define NANOVG_GL2 1
     26 #elif defined NANOVG_GL3_FORCED
     27 #  undef NANOVG_GL2
     28 #  undef NANOVG_GLES2
     29 #  undef NANOVG_GLES3
     30 #  define NANOVG_GL3 1
     31 #elif defined NANOVG_GLES2_FORCED
     32 #  undef NANOVG_GL2
     33 #  undef NANOVG_GL3
     34 #  undef NANOVG_GLES3
     35 #  define NANOVG_GLES2 1
     36 #elif defined NANOVG_GLES3_FORCED
     37 #  undef NANOVG_GL2
     38 #  undef NANOVG_GL3
     39 #  undef NANOVG_GLES2
     40 #  define NANOVG_GLES3 1
     41 #endif
     42 
     43 #ifdef __cplusplus
     44 extern "C" {
     45 #endif
     46 
     47 // Create flags
     48 
     49 enum NVGcreateFlags {
     50 	// Flag indicating if geometry based anti-aliasing is used (may not be needed when using MSAA).
     51 	NVG_ANTIALIAS 		= 1<<0,
     52 	// Flag indicating if strokes should be drawn using stencil buffer. The rendering will be a little
     53 	// slower, but path overlaps (i.e. self-intersecting or sharp turns) will be drawn just once.
     54 	NVG_STENCIL_STROKES	= 1<<1,
     55 	// Flag indicating that additional debug checks are done.
     56 	NVG_DEBUG 			= 1<<2,
     57 };
     58 
     59 #if defined NANOVG_GL2_IMPLEMENTATION
     60 #  define NANOVG_GL2 1
     61 #  define NANOVG_GL_IMPLEMENTATION 1
     62 #elif defined NANOVG_GL3_IMPLEMENTATION
     63 #  define NANOVG_GL3 1
     64 #  define NANOVG_GL_IMPLEMENTATION 1
     65 #  define NANOVG_GL_USE_UNIFORMBUFFER 1
     66 #elif defined NANOVG_GLES2_IMPLEMENTATION
     67 #  define NANOVG_GLES2 1
     68 #  define NANOVG_GL_IMPLEMENTATION 1
     69 #elif defined NANOVG_GLES3_IMPLEMENTATION
     70 #  define NANOVG_GLES3 1
     71 #  define NANOVG_GL_IMPLEMENTATION 1
     72 #endif
     73 
     74 #define NANOVG_GL_USE_STATE_FILTER (1)
     75 
     76 // Creates NanoVG contexts for different OpenGL (ES) versions.
     77 // Flags should be combination of the create flags above.
     78 
     79 #if defined NANOVG_GL2
     80 
     81 NVGcontext* nvgCreateGL2(int flags);
     82 NVGcontext* nvgCreateSharedGL2(NVGcontext* other, int flags);
     83 void nvgDeleteGL2(NVGcontext* ctx);
     84 
     85 int nvglCreateImageFromHandleGL2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
     86 GLuint nvglImageHandleGL2(NVGcontext* ctx, int image);
     87 
     88 #endif
     89 
     90 #if defined NANOVG_GL3
     91 
     92 NVGcontext* nvgCreateGL3(int flags);
     93 NVGcontext* nvgCreateSharedGL3(NVGcontext* other, int flags);
     94 void nvgDeleteGL3(NVGcontext* ctx);
     95 
     96 int nvglCreateImageFromHandleGL3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
     97 GLuint nvglImageHandleGL3(NVGcontext* ctx, int image);
     98 
     99 #endif
    100 
    101 #if defined NANOVG_GLES2
    102 
    103 NVGcontext* nvgCreateGLES2(int flags);
    104 NVGcontext* nvgCreateSharedGLES2(NVGcontext* other, int flags);
    105 void nvgDeleteGLES2(NVGcontext* ctx);
    106 
    107 int nvglCreateImageFromHandleGLES2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
    108 GLuint nvglImageHandleGLES2(NVGcontext* ctx, int image);
    109 
    110 #endif
    111 
    112 #if defined NANOVG_GLES3
    113 
    114 NVGcontext* nvgCreateGLES3(int flags);
    115 NVGcontext* nvgCreateSharedGLES3(NVGcontext* other, int flags);
    116 void nvgDeleteGLES3(NVGcontext* ctx);
    117 
    118 int nvglCreateImageFromHandleGLES3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
    119 GLuint nvglImageHandleGLES3(NVGcontext* ctx, int image);
    120 
    121 #endif
    122 
    123 // These are additional flags on top of NVGimageFlags.
    124 enum NVGimageFlagsGL {
    125 	NVG_IMAGE_NODELETE			= 1<<16,	// Do not delete GL texture handle.
    126 };
    127 
    128 #ifdef __cplusplus
    129 }
    130 #endif
    131 
    132 #endif /* NANOVG_GL_H */
    133 
    134 #ifdef NANOVG_GL_IMPLEMENTATION
    135 
    136 #include <stdlib.h>
    137 #include <stdio.h>
    138 #include <string.h>
    139 #include <math.h>
    140 #include "nanovg.h"
    141 
    142 enum GLNVGuniformLoc {
    143 	GLNVG_LOC_VIEWSIZE,
    144 	GLNVG_LOC_TEX,
    145 	GLNVG_LOC_FRAG,
    146 	GLNVG_MAX_LOCS
    147 };
    148 
    149 enum GLNVGshaderType {
    150 	NSVG_SHADER_FILLGRAD,
    151 	NSVG_SHADER_FILLIMG,
    152 	NSVG_SHADER_SIMPLE,
    153 	NSVG_SHADER_IMG
    154 };
    155 
    156 #if NANOVG_GL_USE_UNIFORMBUFFER
    157 enum GLNVGuniformBindings {
    158 	GLNVG_FRAG_BINDING = 0,
    159 };
    160 #endif
    161 
    162 struct GLNVGshader {
    163 	GLuint prog;
    164 	GLuint frag;
    165 	GLuint vert;
    166 	GLint loc[GLNVG_MAX_LOCS];
    167 };
    168 typedef struct GLNVGshader GLNVGshader;
    169 
    170 struct GLNVGtexture {
    171 	int id;
    172 	GLuint tex;
    173 	int width, height;
    174 	int type;
    175 	int flags;
    176 #if defined NANOVG_GLES2
    177 	unsigned char* data;
    178 #endif
    179 };
    180 typedef struct GLNVGtexture GLNVGtexture;
    181 
    182 struct GLNVGblend
    183 {
    184 	GLenum srcRGB;
    185 	GLenum dstRGB;
    186 	GLenum srcAlpha;
    187 	GLenum dstAlpha;
    188 };
    189 typedef struct GLNVGblend GLNVGblend;
    190 
    191 enum GLNVGcallType {
    192 	GLNVG_NONE = 0,
    193 	GLNVG_FILL,
    194 	GLNVG_CONVEXFILL,
    195 	GLNVG_STROKE,
    196 	GLNVG_TRIANGLES,
    197 };
    198 
    199 struct GLNVGcall {
    200 	int type;
    201 	int image;
    202 	int pathOffset;
    203 	int pathCount;
    204 	int triangleOffset;
    205 	int triangleCount;
    206 	int uniformOffset;
    207 	GLNVGblend blendFunc;
    208 };
    209 typedef struct GLNVGcall GLNVGcall;
    210 
    211 struct GLNVGpath {
    212 	int fillOffset;
    213 	int fillCount;
    214 	int strokeOffset;
    215 	int strokeCount;
    216 };
    217 typedef struct GLNVGpath GLNVGpath;
    218 
    219 struct GLNVGfragUniforms {
    220 	#if NANOVG_GL_USE_UNIFORMBUFFER
    221 		float scissorMat[12]; // matrices are actually 3 vec4s
    222 		float paintMat[12];
    223 		struct NVGcolor innerCol;
    224 		struct NVGcolor outerCol;
    225 		float scissorExt[2];
    226 		float scissorScale[2];
    227 		float extent[2];
    228 		float radius;
    229 		float feather;
    230 		float strokeMult;
    231 		float strokeThr;
    232 		int texType;
    233 		int type;
    234 	#else
    235 		// note: after modifying layout or size of uniform array,
    236 		// don't forget to also update the fragment shader source!
    237 		#define NANOVG_GL_UNIFORMARRAY_SIZE 11
    238 		union {
    239 			struct {
    240 				float scissorMat[12]; // matrices are actually 3 vec4s
    241 				float paintMat[12];
    242 				struct NVGcolor innerCol;
    243 				struct NVGcolor outerCol;
    244 				float scissorExt[2];
    245 				float scissorScale[2];
    246 				float extent[2];
    247 				float radius;
    248 				float feather;
    249 				float strokeMult;
    250 				float strokeThr;
    251 				float texType;
    252 				float type;
    253 			};
    254 			float uniformArray[NANOVG_GL_UNIFORMARRAY_SIZE][4];
    255 		};
    256 	#endif
    257 };
    258 typedef struct GLNVGfragUniforms GLNVGfragUniforms;
    259 
    260 struct GLNVGtextureContext {  // Textures; shared between shared NanoVG contexts.
    261 	int refCount;
    262 	GLNVGtexture* textures;
    263 	int ntextures;
    264 	int ctextures;
    265 	int textureId;
    266 };
    267 typedef struct GLNVGtextureContext GLNVGtextureContext;
    268 
    269 struct GLNVGcontext {
    270 	GLNVGshader shader;
    271 	GLNVGtextureContext* textureContext;
    272 	float view[2];
    273 	GLuint vertBuf;
    274 #if defined NANOVG_GL3
    275 	GLuint vertArr;
    276 #endif
    277 #if NANOVG_GL_USE_UNIFORMBUFFER
    278 	GLuint fragBuf;
    279 #endif
    280 	int fragSize;
    281 	int flags;
    282 
    283 	// Per frame buffers
    284 	GLNVGcall* calls;
    285 	int ccalls;
    286 	int ncalls;
    287 	GLNVGpath* paths;
    288 	int cpaths;
    289 	int npaths;
    290 	struct NVGvertex* verts;
    291 	int cverts;
    292 	int nverts;
    293 	unsigned char* uniforms;
    294 	int cuniforms;
    295 	int nuniforms;
    296 
    297 	// cached state
    298 	#if NANOVG_GL_USE_STATE_FILTER
    299 	GLuint boundTexture;
    300 	GLuint stencilMask;
    301 	GLenum stencilFunc;
    302 	GLint stencilFuncRef;
    303 	GLuint stencilFuncMask;
    304 	GLNVGblend blendFunc;
    305 	#endif
    306 
    307 	int dummyTex;
    308 };
    309 typedef struct GLNVGcontext GLNVGcontext;
    310 
    311 static int glnvg__maxi(int a, int b) { return a > b ? a : b; }
    312 
    313 #ifdef NANOVG_GLES2
    314 static unsigned int glnvg__nearestPow2(unsigned int num)
    315 {
    316 	unsigned n = num > 0 ? num - 1 : 0;
    317 	n |= n >> 1;
    318 	n |= n >> 2;
    319 	n |= n >> 4;
    320 	n |= n >> 8;
    321 	n |= n >> 16;
    322 	n++;
    323 	return n;
    324 }
    325 #endif
    326 
    327 static void glnvg__bindTexture(GLNVGcontext* gl, GLuint tex)
    328 {
    329 #if NANOVG_GL_USE_STATE_FILTER
    330 	if (gl->boundTexture != tex) {
    331 		gl->boundTexture = tex;
    332 		glBindTexture(GL_TEXTURE_2D, tex);
    333 	}
    334 #else
    335 	glBindTexture(GL_TEXTURE_2D, tex);
    336 #endif
    337 }
    338 
    339 static void glnvg__stencilMask(GLNVGcontext* gl, GLuint mask)
    340 {
    341 #if NANOVG_GL_USE_STATE_FILTER
    342 	if (gl->stencilMask != mask) {
    343 		gl->stencilMask = mask;
    344 		glStencilMask(mask);
    345 	}
    346 #else
    347 	glStencilMask(mask);
    348 #endif
    349 }
    350 
    351 static void glnvg__stencilFunc(GLNVGcontext* gl, GLenum func, GLint ref, GLuint mask)
    352 {
    353 #if NANOVG_GL_USE_STATE_FILTER
    354 	if ((gl->stencilFunc != func) ||
    355 		(gl->stencilFuncRef != ref) ||
    356 		(gl->stencilFuncMask != mask)) {
    357 
    358 		gl->stencilFunc = func;
    359 		gl->stencilFuncRef = ref;
    360 		gl->stencilFuncMask = mask;
    361 		glStencilFunc(func, ref, mask);
    362 	}
    363 #else
    364 	glStencilFunc(func, ref, mask);
    365 #endif
    366 }
    367 static void glnvg__blendFuncSeparate(GLNVGcontext* gl, const GLNVGblend* blend)
    368 {
    369 #if NANOVG_GL_USE_STATE_FILTER
    370 	if ((gl->blendFunc.srcRGB != blend->srcRGB) ||
    371 		(gl->blendFunc.dstRGB != blend->dstRGB) ||
    372 		(gl->blendFunc.srcAlpha != blend->srcAlpha) ||
    373 		(gl->blendFunc.dstAlpha != blend->dstAlpha)) {
    374 
    375 		gl->blendFunc = *blend;
    376 		glBlendFuncSeparate(blend->srcRGB, blend->dstRGB, blend->srcAlpha,blend->dstAlpha);
    377 	}
    378 #else
    379 	glBlendFuncSeparate(blend->srcRGB, blend->dstRGB, blend->srcAlpha,blend->dstAlpha);
    380 #endif
    381 }
    382 
    383 static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
    384 {
    385 	GLNVGtexture* tex = NULL;
    386 	int i;
    387 
    388 	for (i = 0; i < gl->textureContext->ntextures; i++) {
    389 		if (gl->textureContext->textures[i].id == 0) {
    390 			tex = &gl->textureContext->textures[i];
    391 			break;
    392 		}
    393 	}
    394 	if (tex == NULL) {
    395 		if (gl->textureContext->ntextures+1 > gl->textureContext->ctextures) {
    396 			GLNVGtexture* textures;
    397 			int ctextures = glnvg__maxi(gl->textureContext->ntextures+1, 4) +  gl->textureContext->ctextures/2; // 1.5x Overallocate
    398 			textures = (GLNVGtexture*)realloc(gl->textureContext->textures, sizeof(GLNVGtexture)*ctextures);
    399 			if (textures == NULL) return NULL;
    400 			gl->textureContext->textures = textures;
    401 			gl->textureContext->ctextures = ctextures;
    402 		}
    403 		tex = &gl->textureContext->textures[gl->textureContext->ntextures++];
    404 	}
    405 
    406 	memset(tex, 0, sizeof(*tex));
    407 	tex->id = ++gl->textureContext->textureId;
    408 
    409 	return tex;
    410 }
    411 
    412 static GLNVGtexture* glnvg__findTexture(GLNVGcontext* gl, int id)
    413 {
    414 	int i;
    415 	for (i = 0; i < gl->textureContext->ntextures; i++)
    416 		if (gl->textureContext->textures[i].id == id)
    417 			return &gl->textureContext->textures[i];
    418 	return NULL;
    419 }
    420 
    421 static int glnvg__deleteTexture(GLNVGcontext* gl, int id)
    422 {
    423 	int i;
    424 	for (i = 0; i < gl->textureContext->ntextures; i++) {
    425 		if (gl->textureContext->textures[i].id == id) {
    426 			if (gl->textureContext->textures[i].tex != 0 && (gl->textureContext->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
    427 			{
    428 				glDeleteTextures(1, &gl->textureContext->textures[i].tex);
    429 #if defined NANOVG_GLES2
    430 				free(gl->textureContext->textures[i].data);
    431 #endif
    432 			}
    433 			memset(&gl->textureContext->textures[i], 0, sizeof(gl->textureContext->textures[i]));
    434 			return 1;
    435 		}
    436 	}
    437 	return 0;
    438 }
    439 
    440 static void glnvg__dumpShaderError(GLuint shader, const char* name, const char* type)
    441 {
    442 	GLchar str[512+1];
    443 	GLsizei len = 0;
    444 	glGetShaderInfoLog(shader, 512, &len, str);
    445 	if (len > 512) len = 512;
    446 	str[len] = '\0';
    447 	printf("Shader %s/%s error:\n%s\n", name, type, str);
    448 }
    449 
    450 static void glnvg__dumpProgramError(GLuint prog, const char* name)
    451 {
    452 	GLchar str[512+1];
    453 	GLsizei len = 0;
    454 	glGetProgramInfoLog(prog, 512, &len, str);
    455 	if (len > 512) len = 512;
    456 	str[len] = '\0';
    457 	printf("Program %s error:\n%s\n", name, str);
    458 }
    459 
    460 static void glnvg__checkError(GLNVGcontext* gl, const char* str)
    461 {
    462 	GLenum err;
    463 	if ((gl->flags & NVG_DEBUG) == 0) return;
    464 	err = glGetError();
    465 	if (err != GL_NO_ERROR) {
    466 		printf("Error %08x after %s\n", err, str);
    467 		return;
    468 	}
    469 }
    470 
    471 static int glnvg__createShader(GLNVGshader* shader, const char* name, const char* header, const char* opts, const char* vshader, const char* fshader)
    472 {
    473 	GLint status;
    474 	GLuint prog, vert, frag;
    475 	const char* str[3];
    476 	str[0] = header;
    477 	str[1] = opts != NULL ? opts : "";
    478 
    479 	memset(shader, 0, sizeof(*shader));
    480 
    481 	prog = glCreateProgram();
    482 	vert = glCreateShader(GL_VERTEX_SHADER);
    483 	frag = glCreateShader(GL_FRAGMENT_SHADER);
    484 	str[2] = vshader;
    485 	glShaderSource(vert, 3, str, 0);
    486 	str[2] = fshader;
    487 	glShaderSource(frag, 3, str, 0);
    488 
    489 	glCompileShader(vert);
    490 	glGetShaderiv(vert, GL_COMPILE_STATUS, &status);
    491 	if (status != GL_TRUE) {
    492 		glnvg__dumpShaderError(vert, name, "vert");
    493 		return 0;
    494 	}
    495 
    496 	glCompileShader(frag);
    497 	glGetShaderiv(frag, GL_COMPILE_STATUS, &status);
    498 	if (status != GL_TRUE) {
    499 		glnvg__dumpShaderError(frag, name, "frag");
    500 		return 0;
    501 	}
    502 
    503 	glAttachShader(prog, vert);
    504 	glAttachShader(prog, frag);
    505 
    506 	glBindAttribLocation(prog, 0, "vertex");
    507 	glBindAttribLocation(prog, 1, "tcoord");
    508 
    509 	glLinkProgram(prog);
    510 	glGetProgramiv(prog, GL_LINK_STATUS, &status);
    511 	if (status != GL_TRUE) {
    512 		glnvg__dumpProgramError(prog, name);
    513 		return 0;
    514 	}
    515 
    516 	shader->prog = prog;
    517 	shader->vert = vert;
    518 	shader->frag = frag;
    519 
    520 	return 1;
    521 }
    522 
    523 static void glnvg__deleteShader(GLNVGshader* shader)
    524 {
    525 	if (shader->prog != 0)
    526 		glDeleteProgram(shader->prog);
    527 	if (shader->vert != 0)
    528 		glDeleteShader(shader->vert);
    529 	if (shader->frag != 0)
    530 		glDeleteShader(shader->frag);
    531 }
    532 
    533 static void glnvg__getUniforms(GLNVGshader* shader)
    534 {
    535 	shader->loc[GLNVG_LOC_VIEWSIZE] = glGetUniformLocation(shader->prog, "viewSize");
    536 	shader->loc[GLNVG_LOC_TEX] = glGetUniformLocation(shader->prog, "tex");
    537 
    538 #if NANOVG_GL_USE_UNIFORMBUFFER
    539 	shader->loc[GLNVG_LOC_FRAG] = glGetUniformBlockIndex(shader->prog, "frag");
    540 #else
    541 	shader->loc[GLNVG_LOC_FRAG] = glGetUniformLocation(shader->prog, "frag");
    542 #endif
    543 }
    544 
    545 static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data);
    546 
    547 static int glnvg__renderCreate(void* uptr, void* otherUptr)   // Share the textures of GLNVGcontext 'otherUptr' if it's non-NULL.
    548 {
    549 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
    550 
    551 	if (otherUptr) {
    552 	    GLNVGcontext* other = (GLNVGcontext*)otherUptr;
    553 		gl->textureContext = other->textureContext;
    554 		gl->textureContext->refCount++;
    555 	} else {
    556 		gl->textureContext = (GLNVGtextureContext*)malloc(sizeof(GLNVGtextureContext));
    557 		memset(gl->textureContext, 0, sizeof(GLNVGtextureContext));
    558 		gl->textureContext->refCount = 1;
    559 	}
    560 
    561 	int align = 4;
    562 
    563 	// TODO: mediump float may not be enough for GLES2 in iOS.
    564 	// see the following discussion: https://github.com/memononen/nanovg/issues/46
    565 	static const char* shaderHeader =
    566 #if defined NANOVG_GL2
    567 		"#define NANOVG_GL2 1\n"
    568 #elif defined NANOVG_GL3
    569 		"#version 150 core\n"
    570 		"#define NANOVG_GL3 1\n"
    571 #elif defined NANOVG_GLES2
    572 		"#version 100\n"
    573 		"#define NANOVG_GL2 1\n"
    574 #elif defined NANOVG_GLES3
    575 		"#version 300 es\n"
    576 		"#define NANOVG_GL3 1\n"
    577 #endif
    578 
    579 #if NANOVG_GL_USE_UNIFORMBUFFER
    580 	"#define USE_UNIFORMBUFFER 1\n"
    581 #else
    582 	"#define UNIFORMARRAY_SIZE 11\n"
    583 #endif
    584 	"\n";
    585 
    586 	static const char* fillVertShader =
    587 		"#ifdef NANOVG_GL3\n"
    588 		"	uniform vec2 viewSize;\n"
    589 		"	in vec2 vertex;\n"
    590 		"	in vec2 tcoord;\n"
    591 		"	out vec2 ftcoord;\n"
    592 		"	out vec2 fpos;\n"
    593 		"#else\n"
    594 		"	uniform vec2 viewSize;\n"
    595 		"	attribute vec2 vertex;\n"
    596 		"	attribute vec2 tcoord;\n"
    597 		"	varying vec2 ftcoord;\n"
    598 		"	varying vec2 fpos;\n"
    599 		"#endif\n"
    600 		"void main(void) {\n"
    601 		"	ftcoord = tcoord;\n"
    602 		"	fpos = vertex;\n"
    603 		"	gl_Position = vec4(2.0*vertex.x/viewSize.x - 1.0, 1.0 - 2.0*vertex.y/viewSize.y, 0, 1);\n"
    604 		"}\n";
    605 
    606 	static const char* fillFragShader =
    607 		"#ifdef GL_ES\n"
    608 		"#if defined(GL_FRAGMENT_PRECISION_HIGH) || defined(NANOVG_GL3)\n"
    609 		" precision highp float;\n"
    610 		"#else\n"
    611 		" precision mediump float;\n"
    612 		"#endif\n"
    613 		"#endif\n"
    614 		"#ifdef NANOVG_GL3\n"
    615 		"#ifdef USE_UNIFORMBUFFER\n"
    616 		"	layout(std140) uniform frag {\n"
    617 		"		mat3 scissorMat;\n"
    618 		"		mat3 paintMat;\n"
    619 		"		vec4 innerCol;\n"
    620 		"		vec4 outerCol;\n"
    621 		"		vec2 scissorExt;\n"
    622 		"		vec2 scissorScale;\n"
    623 		"		vec2 extent;\n"
    624 		"		float radius;\n"
    625 		"		float feather;\n"
    626 		"		float strokeMult;\n"
    627 		"		float strokeThr;\n"
    628 		"		int texType;\n"
    629 		"		int type;\n"
    630 		"	};\n"
    631 		"#else\n" // NANOVG_GL3 && !USE_UNIFORMBUFFER
    632 		"	uniform vec4 frag[UNIFORMARRAY_SIZE];\n"
    633 		"#endif\n"
    634 		"	uniform sampler2D tex;\n"
    635 		"	in vec2 ftcoord;\n"
    636 		"	in vec2 fpos;\n"
    637 		"	out vec4 outColor;\n"
    638 		"#else\n" // !NANOVG_GL3
    639 		"	uniform vec4 frag[UNIFORMARRAY_SIZE];\n"
    640 		"	uniform sampler2D tex;\n"
    641 		"	varying vec2 ftcoord;\n"
    642 		"	varying vec2 fpos;\n"
    643 		"#endif\n"
    644 		"#ifndef USE_UNIFORMBUFFER\n"
    645 		"	#define scissorMat mat3(frag[0].xyz, frag[1].xyz, frag[2].xyz)\n"
    646 		"	#define paintMat mat3(frag[3].xyz, frag[4].xyz, frag[5].xyz)\n"
    647 		"	#define innerCol frag[6]\n"
    648 		"	#define outerCol frag[7]\n"
    649 		"	#define scissorExt frag[8].xy\n"
    650 		"	#define scissorScale frag[8].zw\n"
    651 		"	#define extent frag[9].xy\n"
    652 		"	#define radius frag[9].z\n"
    653 		"	#define feather frag[9].w\n"
    654 		"	#define strokeMult frag[10].x\n"
    655 		"	#define strokeThr frag[10].y\n"
    656 		"	#define texType int(frag[10].z)\n"
    657 		"	#define type int(frag[10].w)\n"
    658 		"#endif\n"
    659 		"\n"
    660 		"float sdroundrect(vec2 pt, vec2 ext, float rad) {\n"
    661 		"	vec2 ext2 = ext - vec2(rad,rad);\n"
    662 		"	vec2 d = abs(pt) - ext2;\n"
    663 		"	return min(max(d.x,d.y),0.0) + length(max(d,0.0)) - rad;\n"
    664 		"}\n"
    665 		"\n"
    666 		"// Scissoring\n"
    667 		"float scissorMask(vec2 p) {\n"
    668 		"	vec2 sc = (abs((scissorMat * vec3(p,1.0)).xy) - scissorExt);\n"
    669 		"	sc = vec2(0.5,0.5) - sc * scissorScale;\n"
    670 		"	return clamp(sc.x,0.0,1.0) * clamp(sc.y,0.0,1.0);\n"
    671 		"}\n"
    672 		"#ifdef EDGE_AA\n"
    673 		"// Stroke - from [0..1] to clipped pyramid, where the slope is 1px.\n"
    674 		"float strokeMask() {\n"
    675 		"	return min(1.0, (1.0-abs(ftcoord.x*2.0-1.0))*strokeMult) * min(1.0, ftcoord.y);\n"
    676 		"}\n"
    677 		"#endif\n"
    678 		"\n"
    679 		"void main(void) {\n"
    680 		"   vec4 result;\n"
    681 		"	float scissor = scissorMask(fpos);\n"
    682 		"#ifdef EDGE_AA\n"
    683 		"	float strokeAlpha = strokeMask();\n"
    684 		"	if (strokeAlpha < strokeThr) discard;\n"
    685 		"#else\n"
    686 		"	float strokeAlpha = 1.0;\n"
    687 		"#endif\n"
    688 		"	if (type == 0) {			// Gradient\n"
    689 		"		// Calculate gradient color using box gradient\n"
    690 		"		vec2 pt = (paintMat * vec3(fpos,1.0)).xy;\n"
    691 		"		float d = clamp((sdroundrect(pt, extent, radius) + feather*0.5) / feather, 0.0, 1.0);\n"
    692 		"		vec4 color = mix(innerCol,outerCol,d);\n"
    693 		"		// Combine alpha\n"
    694 		"		color *= strokeAlpha * scissor;\n"
    695 		"		result = color;\n"
    696 		"	} else if (type == 1) {		// Image\n"
    697 		"		// Calculate color fron texture\n"
    698 		"		vec2 pt = (paintMat * vec3(fpos,1.0)).xy / extent;\n"
    699 		"#ifdef NANOVG_GL3\n"
    700 		"		vec4 color = texture(tex, pt);\n"
    701 		"#else\n"
    702 		"		vec4 color = texture2D(tex, pt);\n"
    703 		"#endif\n"
    704 		"		if (texType == 1) color = vec4(color.xyz*color.w,color.w);"
    705 		"		if (texType == 2) color = vec4(color.x);"
    706 		"		// Apply color tint and alpha.\n"
    707 		"		color *= innerCol;\n"
    708 		"		// Combine alpha\n"
    709 		"		color *= strokeAlpha * scissor;\n"
    710 		"		result = color;\n"
    711 		"	} else if (type == 2) {		// Stencil fill\n"
    712 		"		result = vec4(1,1,1,1);\n"
    713 		"	} else if (type == 3) {		// Textured tris\n"
    714 		"#ifdef NANOVG_GL3\n"
    715 		"		vec4 color = texture(tex, ftcoord);\n"
    716 		"#else\n"
    717 		"		vec4 color = texture2D(tex, ftcoord);\n"
    718 		"#endif\n"
    719 		"		if (texType == 1) color = vec4(color.xyz*color.w,color.w);"
    720 		"		if (texType == 2) color = vec4(color.x);"
    721 		"		color *= scissor;\n"
    722 		"		result = color * innerCol;\n"
    723 		"	}\n"
    724 		"#ifdef NANOVG_GL3\n"
    725 		"	outColor = result;\n"
    726 		"#else\n"
    727 		"	gl_FragColor = result;\n"
    728 		"#endif\n"
    729 		"}\n";
    730 
    731 	glnvg__checkError(gl, "init");
    732 
    733 	if (gl->flags & NVG_ANTIALIAS) {
    734 		if (glnvg__createShader(&gl->shader, "shader", shaderHeader, "#define EDGE_AA 1\n", fillVertShader, fillFragShader) == 0)
    735 			return 0;
    736 	} else {
    737 		if (glnvg__createShader(&gl->shader, "shader", shaderHeader, NULL, fillVertShader, fillFragShader) == 0)
    738 			return 0;
    739 	}
    740 
    741 	glnvg__checkError(gl, "uniform locations");
    742 	glnvg__getUniforms(&gl->shader);
    743 
    744 	// Create dynamic vertex array
    745 #if defined NANOVG_GL3
    746 	glGenVertexArrays(1, &gl->vertArr);
    747 #endif
    748 	glGenBuffers(1, &gl->vertBuf);
    749 
    750 #if NANOVG_GL_USE_UNIFORMBUFFER
    751 	// Create UBOs
    752 	glUniformBlockBinding(gl->shader.prog, gl->shader.loc[GLNVG_LOC_FRAG], GLNVG_FRAG_BINDING);
    753 	glGenBuffers(1, &gl->fragBuf);
    754 	glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &align);
    755 #endif
    756 	gl->fragSize = sizeof(GLNVGfragUniforms) + align - sizeof(GLNVGfragUniforms) % align;
    757 
    758 	// Some platforms does not allow to have samples to unset textures.
    759 	// Create empty one which is bound when there's no texture specified.
    760 	gl->dummyTex = glnvg__renderCreateTexture(gl, NVG_TEXTURE_ALPHA, 1, 1, 0, NULL);
    761 
    762 	glnvg__checkError(gl, "create done");
    763 
    764 	glFinish();
    765 
    766 	return 1;
    767 }
    768 
    769 static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data)
    770 {
    771 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
    772 	GLNVGtexture* tex = glnvg__allocTexture(gl);
    773 
    774 	if (tex == NULL) return 0;
    775 
    776 #ifdef NANOVG_GLES2
    777 	// Check for non-power of 2.
    778 	if (glnvg__nearestPow2(w) != (unsigned int)w || glnvg__nearestPow2(h) != (unsigned int)h) {
    779 		// No repeat
    780 		if ((imageFlags & NVG_IMAGE_REPEATX) != 0 || (imageFlags & NVG_IMAGE_REPEATY) != 0) {
    781 			printf("Repeat X/Y is not supported for non power-of-two textures (%d x %d)\n", w, h);
    782 			imageFlags &= ~(NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
    783 		}
    784 		// No mips.
    785 		if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) {
    786 			printf("Mip-maps is not supported for non power-of-two textures (%d x %d)\n", w, h);
    787 			imageFlags &= ~NVG_IMAGE_GENERATE_MIPMAPS;
    788 		}
    789 	}
    790 #endif
    791 
    792 	glGenTextures(1, &tex->tex);
    793 	tex->width = w;
    794 	tex->height = h;
    795 	tex->type = type;
    796 	tex->flags = imageFlags;
    797 	glnvg__bindTexture(gl, tex->tex);
    798 
    799 	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    800 #ifndef NANOVG_GLES2
    801 	glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->width);
    802 	glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    803 	glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    804 #endif
    805 
    806 #if defined (NANOVG_GL2)
    807 	// GL 1.4 and later has support for generating mipmaps using a tex parameter.
    808 	if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) {
    809 		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    810 	}
    811 #endif
    812 
    813 	switch (type)
    814 	{
    815 	case NVG_TEXTURE_BGR:
    816 #if NANOVG_GLES2
    817 		// GLES2 cannot handle GL_BGR, do local conversion to GL_RGB
    818 		tex->data = (uint8_t*)malloc(sizeof(uint8_t) * 3 * w * h);
    819 		for (uint32_t i=0; i<w*h; ++i)
    820 		{
    821 			tex->data[i*3+0] = data[i*3+2];
    822 			tex->data[i*3+1] = data[i*3+1];
    823 			tex->data[i*3+2] = data[i*3+0];
    824 		}
    825 		data = tex->data;
    826 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    827 #else
    828 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
    829 #endif
    830 		break;
    831 	case NVG_TEXTURE_BGRA:
    832 #if NANOVG_GLES2
    833 		// GLES2 cannot handle GL_BGRA, do local conversion to GL_RGBA
    834 		tex->data = (uint8_t*)malloc(sizeof(uint8_t) * 4 * w * h);
    835 		for (uint32_t i=0; i<w*h; ++i)
    836 		{
    837 			tex->data[i*3+0] = data[i*3+3];
    838 			tex->data[i*3+1] = data[i*3+2];
    839 			tex->data[i*3+2] = data[i*3+1];
    840 			tex->data[i*3+3] = data[i*3+0];
    841 		}
    842 		data = tex->data;
    843 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
    844 #else
    845 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
    846 #endif
    847 		break;
    848 	case NVG_TEXTURE_RGB:
    849 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    850 		break;
    851 	case NVG_TEXTURE_RGBA:
    852 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    853 		break;
    854 	default:
    855 #if defined(NANOVG_GLES2) || defined (NANOVG_GL2)
    856 		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
    857 #elif defined(NANOVG_GLES3)
    858 		glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data);
    859 #else
    860 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data);
    861 #endif
    862 		break;
    863 	}
    864 
    865 	if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) {
    866 		if (imageFlags & NVG_IMAGE_NEAREST) {
    867 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    868 		} else {
    869 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    870 		}
    871 	} else {
    872 		if (imageFlags & NVG_IMAGE_NEAREST) {
    873 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    874 		} else {
    875 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    876 		}
    877 	}
    878 
    879 	if (imageFlags & NVG_IMAGE_NEAREST) {
    880 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    881 	} else {
    882 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    883 	}
    884 
    885 	if (imageFlags & NVG_IMAGE_REPEATX)
    886 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    887 	else
    888 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    889 
    890 	if (imageFlags & NVG_IMAGE_REPEATY)
    891 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    892 	else
    893 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    894 
    895 	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    896 #ifndef NANOVG_GLES2
    897 	glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    898 	glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    899 	glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    900 #endif
    901 
    902 	// The new way to build mipmaps on GLES and GL3
    903 #if !defined(NANOVG_GL2)
    904 	if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) {
    905 		glGenerateMipmap(GL_TEXTURE_2D);
    906 	}
    907 #endif
    908 
    909 	glnvg__checkError(gl, "create tex");
    910 	glnvg__bindTexture(gl, 0);
    911 
    912 	return tex->id;
    913 }
    914 
    915 
    916 static int glnvg__renderDeleteTexture(void* uptr, int image)
    917 {
    918 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
    919 	return glnvg__deleteTexture(gl, image);
    920 }
    921 
    922 static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data)
    923 {
    924 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
    925 	GLNVGtexture* tex = glnvg__findTexture(gl, image);
    926 
    927 	if (tex == NULL) return 0;
    928 	glnvg__bindTexture(gl, tex->tex);
    929 
    930 	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    931 
    932 #ifndef NANOVG_GLES2
    933 	glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->width);
    934 	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
    935 	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
    936 #else
    937 	// No support for all of skip, need to update a whole row at a time.
    938 	switch (tex->type)
    939 	{
    940 	case NVG_TEXTURE_BGR:
    941 		data += y*tex->width*3;
    942 		break;
    943 	case NVG_TEXTURE_BGRA:
    944 		data += y*tex->width*4;
    945 		break;
    946 	case NVG_TEXTURE_RGB:
    947 		data += y*tex->width*3;
    948 		break;
    949 	case NVG_TEXTURE_RGBA:
    950 		data += y*tex->width*4;
    951 		break;
    952 	default:
    953 		data += y*tex->width;
    954 		break;
    955 	}
    956 	x = 0;
    957 	w = tex->width;
    958 #endif
    959 
    960 	switch (tex->type)
    961 	{
    962 	case NVG_TEXTURE_BGR:
    963 		glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_BGR, GL_UNSIGNED_BYTE, data);
    964 		break;
    965 	case NVG_TEXTURE_BGRA:
    966 		glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_BGRA, GL_UNSIGNED_BYTE, data);
    967 		break;
    968 	case NVG_TEXTURE_RGB:
    969 		glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGB, GL_UNSIGNED_BYTE, data);
    970 		break;
    971 	case NVG_TEXTURE_RGBA:
    972 		glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGBA, GL_UNSIGNED_BYTE, data);
    973 		break;
    974 	default:
    975 #if defined(NANOVG_GLES2) || defined(NANOVG_GL2)
    976 		glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
    977 #else
    978 		glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RED, GL_UNSIGNED_BYTE, data);
    979 #endif
    980 		break;
    981 	}
    982 
    983 	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    984 #ifndef NANOVG_GLES2
    985 	glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    986 	glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    987 	glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    988 #endif
    989 
    990 	glnvg__bindTexture(gl, 0);
    991 
    992 	return 1;
    993 }
    994 
    995 static int glnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h)
    996 {
    997 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
    998 	GLNVGtexture* tex = glnvg__findTexture(gl, image);
    999 	if (tex == NULL) return 0;
   1000 	*w = tex->width;
   1001 	*h = tex->height;
   1002 	return 1;
   1003 }
   1004 
   1005 static void glnvg__xformToMat3x4(float* m3, float* t)
   1006 {
   1007 	m3[0] = t[0];
   1008 	m3[1] = t[1];
   1009 	m3[2] = 0.0f;
   1010 	m3[3] = 0.0f;
   1011 	m3[4] = t[2];
   1012 	m3[5] = t[3];
   1013 	m3[6] = 0.0f;
   1014 	m3[7] = 0.0f;
   1015 	m3[8] = t[4];
   1016 	m3[9] = t[5];
   1017 	m3[10] = 1.0f;
   1018 	m3[11] = 0.0f;
   1019 }
   1020 
   1021 static NVGcolor glnvg__premulColor(NVGcolor c)
   1022 {
   1023 	c.r *= c.a;
   1024 	c.g *= c.a;
   1025 	c.b *= c.a;
   1026 	return c;
   1027 }
   1028 
   1029 static int glnvg__convertPaint(GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGpaint* paint,
   1030 							   NVGscissor* scissor, float width, float fringe, float strokeThr)
   1031 {
   1032 	GLNVGtexture* tex = NULL;
   1033 	float invxform[6];
   1034 
   1035 	memset(frag, 0, sizeof(*frag));
   1036 
   1037 	frag->innerCol = glnvg__premulColor(paint->innerColor);
   1038 	frag->outerCol = glnvg__premulColor(paint->outerColor);
   1039 
   1040 	if (scissor->extent[0] < -0.5f || scissor->extent[1] < -0.5f) {
   1041 		memset(frag->scissorMat, 0, sizeof(frag->scissorMat));
   1042 		frag->scissorExt[0] = 1.0f;
   1043 		frag->scissorExt[1] = 1.0f;
   1044 		frag->scissorScale[0] = 1.0f;
   1045 		frag->scissorScale[1] = 1.0f;
   1046 	} else {
   1047 		nvgTransformInverse(invxform, scissor->xform);
   1048 		glnvg__xformToMat3x4(frag->scissorMat, invxform);
   1049 		frag->scissorExt[0] = scissor->extent[0];
   1050 		frag->scissorExt[1] = scissor->extent[1];
   1051 		frag->scissorScale[0] = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]) / fringe;
   1052 		frag->scissorScale[1] = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]) / fringe;
   1053 	}
   1054 
   1055 	memcpy(frag->extent, paint->extent, sizeof(frag->extent));
   1056 	frag->strokeMult = (width*0.5f + fringe*0.5f) / fringe;
   1057 	frag->strokeThr = strokeThr;
   1058 
   1059 	if (paint->image != 0) {
   1060 		tex = glnvg__findTexture(gl, paint->image);
   1061 		if (tex == NULL) return 0;
   1062 		if ((tex->flags & NVG_IMAGE_FLIPY) != 0) {
   1063 			float m1[6], m2[6];
   1064 			nvgTransformTranslate(m1, 0.0f, frag->extent[1] * 0.5f);
   1065 			nvgTransformMultiply(m1, paint->xform);
   1066 			nvgTransformScale(m2, 1.0f, -1.0f);
   1067 			nvgTransformMultiply(m2, m1);
   1068 			nvgTransformTranslate(m1, 0.0f, -frag->extent[1] * 0.5f);
   1069 			nvgTransformMultiply(m1, m2);
   1070 			nvgTransformInverse(invxform, m1);
   1071 		} else {
   1072 			nvgTransformInverse(invxform, paint->xform);
   1073 		}
   1074 		frag->type = NSVG_SHADER_FILLIMG;
   1075 
   1076 		#if NANOVG_GL_USE_UNIFORMBUFFER
   1077 		switch (tex->type)
   1078 		{
   1079 		case NVG_TEXTURE_BGR:
   1080 		case NVG_TEXTURE_BGRA:
   1081 		case NVG_TEXTURE_RGB:
   1082 		case NVG_TEXTURE_RGBA:
   1083 			frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0 : 1;
   1084 			break;
   1085 		default:
   1086 			frag->texType = 2;
   1087 			break;
   1088 		}
   1089 		#else
   1090 		switch (tex->type)
   1091 		{
   1092 		case NVG_TEXTURE_BGR:
   1093 		case NVG_TEXTURE_BGRA:
   1094 		case NVG_TEXTURE_RGB:
   1095 		case NVG_TEXTURE_RGBA:
   1096 			frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0.0f : 1.0f;
   1097 			break;
   1098 		default:
   1099 			frag->texType = 2.0f;
   1100 			break;
   1101 		}
   1102 		#endif
   1103 //		printf("frag->texType = %d\n", frag->texType);
   1104 	} else {
   1105 		frag->type = NSVG_SHADER_FILLGRAD;
   1106 		frag->radius = paint->radius;
   1107 		frag->feather = paint->feather;
   1108 		nvgTransformInverse(invxform, paint->xform);
   1109 	}
   1110 
   1111 	glnvg__xformToMat3x4(frag->paintMat, invxform);
   1112 
   1113 	return 1;
   1114 }
   1115 
   1116 static GLNVGfragUniforms* nvg__fragUniformPtr(GLNVGcontext* gl, int i);
   1117 
   1118 static void glnvg__setUniforms(GLNVGcontext* gl, int uniformOffset, int image)
   1119 {
   1120 	GLNVGtexture* tex = NULL;
   1121 #if NANOVG_GL_USE_UNIFORMBUFFER
   1122 	glBindBufferRange(GL_UNIFORM_BUFFER, GLNVG_FRAG_BINDING, gl->fragBuf, uniformOffset, sizeof(GLNVGfragUniforms));
   1123 #else
   1124 	GLNVGfragUniforms* frag = nvg__fragUniformPtr(gl, uniformOffset);
   1125 	glUniform4fv(gl->shader.loc[GLNVG_LOC_FRAG], NANOVG_GL_UNIFORMARRAY_SIZE, &(frag->uniformArray[0][0]));
   1126 #endif
   1127 
   1128 	if (image != 0) {
   1129 		tex = glnvg__findTexture(gl, image);
   1130 	}
   1131 	// If no image is set, use empty texture
   1132 	if (tex == NULL) {
   1133 		tex = glnvg__findTexture(gl, gl->dummyTex);
   1134 	}
   1135 	glnvg__bindTexture(gl, tex != NULL ? tex->tex : 0);
   1136 	glnvg__checkError(gl, "tex paint tex");
   1137 }
   1138 
   1139 static void glnvg__renderViewport(void* uptr, float width, float height, float devicePixelRatio)
   1140 {
   1141 	NVG_NOTUSED(devicePixelRatio);
   1142 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
   1143 	gl->view[0] = width;
   1144 	gl->view[1] = height;
   1145 }
   1146 
   1147 static void glnvg__fill(GLNVGcontext* gl, GLNVGcall* call)
   1148 {
   1149 	GLNVGpath* paths = &gl->paths[call->pathOffset];
   1150 	int i, npaths = call->pathCount;
   1151 
   1152 	// Draw shapes
   1153 	glEnable(GL_STENCIL_TEST);
   1154 	glnvg__stencilMask(gl, 0xff);
   1155 	glnvg__stencilFunc(gl, GL_ALWAYS, 0, 0xff);
   1156 	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   1157 
   1158 	// set bindpoint for solid loc
   1159 	glnvg__setUniforms(gl, call->uniformOffset, 0);
   1160 	glnvg__checkError(gl, "fill simple");
   1161 
   1162 	glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
   1163 	glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
   1164 	glDisable(GL_CULL_FACE);
   1165 	for (i = 0; i < npaths; i++)
   1166 		glDrawArrays(GL_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount);
   1167 	glEnable(GL_CULL_FACE);
   1168 
   1169 	// Draw anti-aliased pixels
   1170 	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   1171 
   1172 	glnvg__setUniforms(gl, call->uniformOffset + gl->fragSize, call->image);
   1173 	glnvg__checkError(gl, "fill fill");
   1174 
   1175 	if (gl->flags & NVG_ANTIALIAS) {
   1176 		glnvg__stencilFunc(gl, GL_EQUAL, 0x00, 0xff);
   1177 		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
   1178 		// Draw fringes
   1179 		for (i = 0; i < npaths; i++)
   1180 			glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
   1181 	}
   1182 
   1183 	// Draw fill
   1184 	glnvg__stencilFunc(gl, GL_NOTEQUAL, 0x0, 0xff);
   1185 	glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
   1186 	glDrawArrays(GL_TRIANGLE_STRIP, call->triangleOffset, call->triangleCount);
   1187 
   1188 	glDisable(GL_STENCIL_TEST);
   1189 }
   1190 
   1191 static void glnvg__convexFill(GLNVGcontext* gl, GLNVGcall* call)
   1192 {
   1193 	GLNVGpath* paths = &gl->paths[call->pathOffset];
   1194 	int i, npaths = call->pathCount;
   1195 
   1196 	glnvg__setUniforms(gl, call->uniformOffset, call->image);
   1197 	glnvg__checkError(gl, "convex fill");
   1198 
   1199 	for (i = 0; i < npaths; i++) {
   1200 		glDrawArrays(GL_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount);
   1201 		// Draw fringes
   1202 		if (paths[i].strokeCount > 0) {
   1203 			glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
   1204 		}
   1205 	}
   1206 }
   1207 
   1208 static void glnvg__stroke(GLNVGcontext* gl, GLNVGcall* call)
   1209 {
   1210 	GLNVGpath* paths = &gl->paths[call->pathOffset];
   1211 	int npaths = call->pathCount, i;
   1212 
   1213 	if (gl->flags & NVG_STENCIL_STROKES) {
   1214 
   1215 		glEnable(GL_STENCIL_TEST);
   1216 		glnvg__stencilMask(gl, 0xff);
   1217 
   1218 		// Fill the stroke base without overlap
   1219 		glnvg__stencilFunc(gl, GL_EQUAL, 0x0, 0xff);
   1220 		glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
   1221 		glnvg__setUniforms(gl, call->uniformOffset + gl->fragSize, call->image);
   1222 		glnvg__checkError(gl, "stroke fill 0");
   1223 		for (i = 0; i < npaths; i++)
   1224 			glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
   1225 
   1226 		// Draw anti-aliased pixels.
   1227 		glnvg__setUniforms(gl, call->uniformOffset, call->image);
   1228 		glnvg__stencilFunc(gl, GL_EQUAL, 0x00, 0xff);
   1229 		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
   1230 		for (i = 0; i < npaths; i++)
   1231 			glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
   1232 
   1233 		// Clear stencil buffer.
   1234 		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   1235 		glnvg__stencilFunc(gl, GL_ALWAYS, 0x0, 0xff);
   1236 		glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
   1237 		glnvg__checkError(gl, "stroke fill 1");
   1238 		for (i = 0; i < npaths; i++)
   1239 			glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
   1240 		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   1241 
   1242 		glDisable(GL_STENCIL_TEST);
   1243 
   1244 //		glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset + gl->fragSize), paint, scissor, strokeWidth, fringe, 1.0f - 0.5f/255.0f);
   1245 
   1246 	} else {
   1247 		glnvg__setUniforms(gl, call->uniformOffset, call->image);
   1248 		glnvg__checkError(gl, "stroke fill");
   1249 		// Draw Strokes
   1250 		for (i = 0; i < npaths; i++)
   1251 			glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
   1252 	}
   1253 }
   1254 
   1255 static void glnvg__triangles(GLNVGcontext* gl, GLNVGcall* call)
   1256 {
   1257 	glnvg__setUniforms(gl, call->uniformOffset, call->image);
   1258 	glnvg__checkError(gl, "triangles fill");
   1259 
   1260 	glDrawArrays(GL_TRIANGLES, call->triangleOffset, call->triangleCount);
   1261 }
   1262 
   1263 static void glnvg__renderCancel(void* uptr) {
   1264 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
   1265 	gl->nverts = 0;
   1266 	gl->npaths = 0;
   1267 	gl->ncalls = 0;
   1268 	gl->nuniforms = 0;
   1269 }
   1270 
   1271 static GLenum glnvg_convertBlendFuncFactor(int factor)
   1272 {
   1273 	if (factor == NVG_ZERO)
   1274 		return GL_ZERO;
   1275 	if (factor == NVG_ONE)
   1276 		return GL_ONE;
   1277 	if (factor == NVG_SRC_COLOR)
   1278 		return GL_SRC_COLOR;
   1279 	if (factor == NVG_ONE_MINUS_SRC_COLOR)
   1280 		return GL_ONE_MINUS_SRC_COLOR;
   1281 	if (factor == NVG_DST_COLOR)
   1282 		return GL_DST_COLOR;
   1283 	if (factor == NVG_ONE_MINUS_DST_COLOR)
   1284 		return GL_ONE_MINUS_DST_COLOR;
   1285 	if (factor == NVG_SRC_ALPHA)
   1286 		return GL_SRC_ALPHA;
   1287 	if (factor == NVG_ONE_MINUS_SRC_ALPHA)
   1288 		return GL_ONE_MINUS_SRC_ALPHA;
   1289 	if (factor == NVG_DST_ALPHA)
   1290 		return GL_DST_ALPHA;
   1291 	if (factor == NVG_ONE_MINUS_DST_ALPHA)
   1292 		return GL_ONE_MINUS_DST_ALPHA;
   1293 	if (factor == NVG_SRC_ALPHA_SATURATE)
   1294 		return GL_SRC_ALPHA_SATURATE;
   1295 	return GL_INVALID_ENUM;
   1296 }
   1297 
   1298 static GLNVGblend glnvg__blendCompositeOperation(NVGcompositeOperationState op)
   1299 {
   1300 	GLNVGblend blend;
   1301 	blend.srcRGB = glnvg_convertBlendFuncFactor(op.srcRGB);
   1302 	blend.dstRGB = glnvg_convertBlendFuncFactor(op.dstRGB);
   1303 	blend.srcAlpha = glnvg_convertBlendFuncFactor(op.srcAlpha);
   1304 	blend.dstAlpha = glnvg_convertBlendFuncFactor(op.dstAlpha);
   1305 	if (blend.srcRGB == GL_INVALID_ENUM || blend.dstRGB == GL_INVALID_ENUM || blend.srcAlpha == GL_INVALID_ENUM || blend.dstAlpha == GL_INVALID_ENUM)
   1306 	{
   1307 		blend.srcRGB = GL_ONE;
   1308 		blend.dstRGB = GL_ONE_MINUS_SRC_ALPHA;
   1309 		blend.srcAlpha = GL_ONE;
   1310 		blend.dstAlpha = GL_ONE_MINUS_SRC_ALPHA;
   1311 	}
   1312 	return blend;
   1313 }
   1314 
   1315 static void glnvg__renderFlush(void* uptr)
   1316 {
   1317 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
   1318 	int i;
   1319 
   1320 	if (gl->ncalls > 0) {
   1321 
   1322 		// Setup require GL state.
   1323 		glUseProgram(gl->shader.prog);
   1324 
   1325 		glEnable(GL_CULL_FACE);
   1326 		glCullFace(GL_BACK);
   1327 		glFrontFace(GL_CCW);
   1328 		glEnable(GL_BLEND);
   1329 		glDisable(GL_DEPTH_TEST);
   1330 		glDisable(GL_SCISSOR_TEST);
   1331 		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   1332 		glStencilMask(0xffffffff);
   1333 		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
   1334 		glStencilFunc(GL_ALWAYS, 0, 0xffffffff);
   1335 		glActiveTexture(GL_TEXTURE0);
   1336 		glBindTexture(GL_TEXTURE_2D, 0);
   1337 		#if NANOVG_GL_USE_STATE_FILTER
   1338 		gl->boundTexture = 0;
   1339 		gl->stencilMask = 0xffffffff;
   1340 		gl->stencilFunc = GL_ALWAYS;
   1341 		gl->stencilFuncRef = 0;
   1342 		gl->stencilFuncMask = 0xffffffff;
   1343 		gl->blendFunc.srcRGB = GL_INVALID_ENUM;
   1344 		gl->blendFunc.srcAlpha = GL_INVALID_ENUM;
   1345 		gl->blendFunc.dstRGB = GL_INVALID_ENUM;
   1346 		gl->blendFunc.dstAlpha = GL_INVALID_ENUM;
   1347 		#endif
   1348 
   1349 #if NANOVG_GL_USE_UNIFORMBUFFER
   1350 		// Upload ubo for frag shaders
   1351 		glBindBuffer(GL_UNIFORM_BUFFER, gl->fragBuf);
   1352 		glBufferData(GL_UNIFORM_BUFFER, gl->nuniforms * gl->fragSize, gl->uniforms, GL_STREAM_DRAW);
   1353 #endif
   1354 
   1355 		// Upload vertex data
   1356 #if defined NANOVG_GL3
   1357 		glBindVertexArray(gl->vertArr);
   1358 #endif
   1359 		glBindBuffer(GL_ARRAY_BUFFER, gl->vertBuf);
   1360 		glBufferData(GL_ARRAY_BUFFER, gl->nverts * sizeof(NVGvertex), gl->verts, GL_STREAM_DRAW);
   1361 		glEnableVertexAttribArray(0);
   1362 		glEnableVertexAttribArray(1);
   1363 		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(NVGvertex), (const GLvoid*)(size_t)0);
   1364 		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(NVGvertex), (const GLvoid*)(0 + 2*sizeof(float)));
   1365 
   1366 		// Set view and texture just once per frame.
   1367 		glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0);
   1368 		glUniform2fv(gl->shader.loc[GLNVG_LOC_VIEWSIZE], 1, gl->view);
   1369 
   1370 #if NANOVG_GL_USE_UNIFORMBUFFER
   1371 		glBindBuffer(GL_UNIFORM_BUFFER, gl->fragBuf);
   1372 #endif
   1373 
   1374 		for (i = 0; i < gl->ncalls; i++) {
   1375 			GLNVGcall* call = &gl->calls[i];
   1376 			glnvg__blendFuncSeparate(gl,&call->blendFunc);
   1377 			if (call->type == GLNVG_FILL)
   1378 				glnvg__fill(gl, call);
   1379 			else if (call->type == GLNVG_CONVEXFILL)
   1380 				glnvg__convexFill(gl, call);
   1381 			else if (call->type == GLNVG_STROKE)
   1382 				glnvg__stroke(gl, call);
   1383 			else if (call->type == GLNVG_TRIANGLES)
   1384 				glnvg__triangles(gl, call);
   1385 		}
   1386 
   1387 		glDisableVertexAttribArray(0);
   1388 		glDisableVertexAttribArray(1);
   1389 #if defined NANOVG_GL3
   1390 		glBindVertexArray(0);
   1391 #endif
   1392 		glDisable(GL_CULL_FACE);
   1393 			glBindBuffer(GL_ARRAY_BUFFER, 0);
   1394 		glUseProgram(0);
   1395 		glnvg__bindTexture(gl, 0);
   1396 	}
   1397 
   1398 	// Reset calls
   1399 	gl->nverts = 0;
   1400 	gl->npaths = 0;
   1401 	gl->ncalls = 0;
   1402 	gl->nuniforms = 0;
   1403 }
   1404 
   1405 static int glnvg__maxVertCount(const NVGpath* paths, int npaths)
   1406 {
   1407 	int i, count = 0;
   1408 	for (i = 0; i < npaths; i++) {
   1409 		count += paths[i].nfill;
   1410 		count += paths[i].nstroke;
   1411 	}
   1412 	return count;
   1413 }
   1414 
   1415 static GLNVGcall* glnvg__allocCall(GLNVGcontext* gl)
   1416 {
   1417 	GLNVGcall* ret = NULL;
   1418 	if (gl->ncalls+1 > gl->ccalls) {
   1419 		GLNVGcall* calls;
   1420 		int ccalls = glnvg__maxi(gl->ncalls+1, 128) + gl->ccalls/2; // 1.5x Overallocate
   1421 		calls = (GLNVGcall*)realloc(gl->calls, sizeof(GLNVGcall) * ccalls);
   1422 		if (calls == NULL) return NULL;
   1423 		gl->calls = calls;
   1424 		gl->ccalls = ccalls;
   1425 	}
   1426 	ret = &gl->calls[gl->ncalls++];
   1427 	memset(ret, 0, sizeof(GLNVGcall));
   1428 	return ret;
   1429 }
   1430 
   1431 static int glnvg__allocPaths(GLNVGcontext* gl, int n)
   1432 {
   1433 	int ret = 0;
   1434 	if (gl->npaths+n > gl->cpaths) {
   1435 		GLNVGpath* paths;
   1436 		int cpaths = glnvg__maxi(gl->npaths + n, 128) + gl->cpaths/2; // 1.5x Overallocate
   1437 		paths = (GLNVGpath*)realloc(gl->paths, sizeof(GLNVGpath) * cpaths);
   1438 		if (paths == NULL) return -1;
   1439 		gl->paths = paths;
   1440 		gl->cpaths = cpaths;
   1441 	}
   1442 	ret = gl->npaths;
   1443 	gl->npaths += n;
   1444 	return ret;
   1445 }
   1446 
   1447 static int glnvg__allocVerts(GLNVGcontext* gl, int n)
   1448 {
   1449 	int ret = 0;
   1450 	if (gl->nverts+n > gl->cverts) {
   1451 		NVGvertex* verts;
   1452 		int cverts = glnvg__maxi(gl->nverts + n, 4096) + gl->cverts/2; // 1.5x Overallocate
   1453 		verts = (NVGvertex*)realloc(gl->verts, sizeof(NVGvertex) * cverts);
   1454 		if (verts == NULL) return -1;
   1455 		gl->verts = verts;
   1456 		gl->cverts = cverts;
   1457 	}
   1458 	ret = gl->nverts;
   1459 	gl->nverts += n;
   1460 	return ret;
   1461 }
   1462 
   1463 static int glnvg__allocFragUniforms(GLNVGcontext* gl, int n)
   1464 {
   1465 	int ret = 0, structSize = gl->fragSize;
   1466 	if (gl->nuniforms+n > gl->cuniforms) {
   1467 		unsigned char* uniforms;
   1468 		int cuniforms = glnvg__maxi(gl->nuniforms+n, 128) + gl->cuniforms/2; // 1.5x Overallocate
   1469 		uniforms = (unsigned char*)realloc(gl->uniforms, structSize * cuniforms);
   1470 		if (uniforms == NULL) return -1;
   1471 		gl->uniforms = uniforms;
   1472 		gl->cuniforms = cuniforms;
   1473 	}
   1474 	ret = gl->nuniforms * structSize;
   1475 	gl->nuniforms += n;
   1476 	return ret;
   1477 }
   1478 
   1479 static GLNVGfragUniforms* nvg__fragUniformPtr(GLNVGcontext* gl, int i)
   1480 {
   1481 	return (GLNVGfragUniforms*)&gl->uniforms[i];
   1482 }
   1483 
   1484 static void glnvg__vset(NVGvertex* vtx, float x, float y, float u, float v)
   1485 {
   1486 	vtx->x = x;
   1487 	vtx->y = y;
   1488 	vtx->u = u;
   1489 	vtx->v = v;
   1490 }
   1491 
   1492 static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
   1493 							  const float* bounds, const NVGpath* paths, int npaths)
   1494 {
   1495 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
   1496 	GLNVGcall* call = glnvg__allocCall(gl);
   1497 	NVGvertex* quad;
   1498 	GLNVGfragUniforms* frag;
   1499 	int i, maxverts, offset;
   1500 
   1501 	if (call == NULL) return;
   1502 
   1503 	call->type = GLNVG_FILL;
   1504 	call->triangleCount = 4;
   1505 	call->pathOffset = glnvg__allocPaths(gl, npaths);
   1506 	if (call->pathOffset == -1) goto error;
   1507 	call->pathCount = npaths;
   1508 	call->image = paint->image;
   1509 	call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);
   1510 
   1511 	if (npaths == 1 && paths[0].convex)
   1512 	{
   1513 		call->type = GLNVG_CONVEXFILL;
   1514 		call->triangleCount = 0;	// Bounding box fill quad not needed for convex fill
   1515 	}
   1516 
   1517 	// Allocate vertices for all the paths.
   1518 	maxverts = glnvg__maxVertCount(paths, npaths) + call->triangleCount;
   1519 	offset = glnvg__allocVerts(gl, maxverts);
   1520 	if (offset == -1) goto error;
   1521 
   1522 	for (i = 0; i < npaths; i++) {
   1523 		GLNVGpath* copy = &gl->paths[call->pathOffset + i];
   1524 		const NVGpath* path = &paths[i];
   1525 		memset(copy, 0, sizeof(GLNVGpath));
   1526 		if (path->nfill > 0) {
   1527 			copy->fillOffset = offset;
   1528 			copy->fillCount = path->nfill;
   1529 			memcpy(&gl->verts[offset], path->fill, sizeof(NVGvertex) * path->nfill);
   1530 			offset += path->nfill;
   1531 		}
   1532 		if (path->nstroke > 0) {
   1533 			copy->strokeOffset = offset;
   1534 			copy->strokeCount = path->nstroke;
   1535 			memcpy(&gl->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke);
   1536 			offset += path->nstroke;
   1537 		}
   1538 	}
   1539 
   1540 	// Setup uniforms for draw calls
   1541 	if (call->type == GLNVG_FILL) {
   1542 		// Quad
   1543 		call->triangleOffset = offset;
   1544 		quad = &gl->verts[call->triangleOffset];
   1545 		glnvg__vset(&quad[0], bounds[2], bounds[3], 0.5f, 1.0f);
   1546 		glnvg__vset(&quad[1], bounds[2], bounds[1], 0.5f, 1.0f);
   1547 		glnvg__vset(&quad[2], bounds[0], bounds[3], 0.5f, 1.0f);
   1548 		glnvg__vset(&quad[3], bounds[0], bounds[1], 0.5f, 1.0f);
   1549 
   1550 		call->uniformOffset = glnvg__allocFragUniforms(gl, 2);
   1551 		if (call->uniformOffset == -1) goto error;
   1552 		// Simple shader for stencil
   1553 		frag = nvg__fragUniformPtr(gl, call->uniformOffset);
   1554 		memset(frag, 0, sizeof(*frag));
   1555 		frag->strokeThr = -1.0f;
   1556 		frag->type = NSVG_SHADER_SIMPLE;
   1557 		// Fill shader
   1558 		glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset + gl->fragSize), paint, scissor, fringe, fringe, -1.0f);
   1559 	} else {
   1560 		call->uniformOffset = glnvg__allocFragUniforms(gl, 1);
   1561 		if (call->uniformOffset == -1) goto error;
   1562 		// Fill shader
   1563 		glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, fringe, fringe, -1.0f);
   1564 	}
   1565 
   1566 	return;
   1567 
   1568 error:
   1569 	// We get here if call alloc was ok, but something else is not.
   1570 	// Roll back the last call to prevent drawing it.
   1571 	if (gl->ncalls > 0) gl->ncalls--;
   1572 }
   1573 
   1574 static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
   1575 								float strokeWidth, const NVGpath* paths, int npaths)
   1576 {
   1577 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
   1578 	GLNVGcall* call = glnvg__allocCall(gl);
   1579 	int i, maxverts, offset;
   1580 
   1581 	if (call == NULL) return;
   1582 
   1583 	call->type = GLNVG_STROKE;
   1584 	call->pathOffset = glnvg__allocPaths(gl, npaths);
   1585 	if (call->pathOffset == -1) goto error;
   1586 	call->pathCount = npaths;
   1587 	call->image = paint->image;
   1588 	call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);
   1589 
   1590 	// Allocate vertices for all the paths.
   1591 	maxverts = glnvg__maxVertCount(paths, npaths);
   1592 	offset = glnvg__allocVerts(gl, maxverts);
   1593 	if (offset == -1) goto error;
   1594 
   1595 	for (i = 0; i < npaths; i++) {
   1596 		GLNVGpath* copy = &gl->paths[call->pathOffset + i];
   1597 		const NVGpath* path = &paths[i];
   1598 		memset(copy, 0, sizeof(GLNVGpath));
   1599 		if (path->nstroke) {
   1600 			copy->strokeOffset = offset;
   1601 			copy->strokeCount = path->nstroke;
   1602 			memcpy(&gl->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke);
   1603 			offset += path->nstroke;
   1604 		}
   1605 	}
   1606 
   1607 	if (gl->flags & NVG_STENCIL_STROKES) {
   1608 		// Fill shader
   1609 		call->uniformOffset = glnvg__allocFragUniforms(gl, 2);
   1610 		if (call->uniformOffset == -1) goto error;
   1611 
   1612 		glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, strokeWidth, fringe, -1.0f);
   1613 		glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset + gl->fragSize), paint, scissor, strokeWidth, fringe, 1.0f - 0.5f/255.0f);
   1614 
   1615 	} else {
   1616 		// Fill shader
   1617 		call->uniformOffset = glnvg__allocFragUniforms(gl, 1);
   1618 		if (call->uniformOffset == -1) goto error;
   1619 		glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, strokeWidth, fringe, -1.0f);
   1620 	}
   1621 
   1622 	return;
   1623 
   1624 error:
   1625 	// We get here if call alloc was ok, but something else is not.
   1626 	// Roll back the last call to prevent drawing it.
   1627 	if (gl->ncalls > 0) gl->ncalls--;
   1628 }
   1629 
   1630 static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor,
   1631 								   const NVGvertex* verts, int nverts, float fringe)
   1632 {
   1633 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
   1634 	GLNVGcall* call = glnvg__allocCall(gl);
   1635 	GLNVGfragUniforms* frag;
   1636 
   1637 	if (call == NULL) return;
   1638 
   1639 	call->type = GLNVG_TRIANGLES;
   1640 	call->image = paint->image;
   1641 	call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);
   1642 
   1643 	// Allocate vertices for all the paths.
   1644 	call->triangleOffset = glnvg__allocVerts(gl, nverts);
   1645 	if (call->triangleOffset == -1) goto error;
   1646 	call->triangleCount = nverts;
   1647 
   1648 	memcpy(&gl->verts[call->triangleOffset], verts, sizeof(NVGvertex) * nverts);
   1649 
   1650 	// Fill shader
   1651 	call->uniformOffset = glnvg__allocFragUniforms(gl, 1);
   1652 	if (call->uniformOffset == -1) goto error;
   1653 	frag = nvg__fragUniformPtr(gl, call->uniformOffset);
   1654 	glnvg__convertPaint(gl, frag, paint, scissor, 1.0f, fringe, -1.0f);
   1655 	frag->type = NSVG_SHADER_IMG;
   1656 
   1657 	return;
   1658 
   1659 error:
   1660 	// We get here if call alloc was ok, but something else is not.
   1661 	// Roll back the last call to prevent drawing it.
   1662 	if (gl->ncalls > 0) gl->ncalls--;
   1663 }
   1664 
   1665 static void glnvg__renderDelete(void* uptr)
   1666 {
   1667 	GLNVGcontext* gl = (GLNVGcontext*)uptr;
   1668 	int i;
   1669 	if (gl == NULL) return;
   1670 
   1671 	glnvg__deleteShader(&gl->shader);
   1672 
   1673 #if NANOVG_GL3
   1674 #if NANOVG_GL_USE_UNIFORMBUFFER
   1675 	if (gl->fragBuf != 0)
   1676 		glDeleteBuffers(1, &gl->fragBuf);
   1677 #endif
   1678 	if (gl->vertArr != 0)
   1679 		glDeleteVertexArrays(1, &gl->vertArr);
   1680 #endif
   1681 	if (gl->vertBuf != 0)
   1682 		glDeleteBuffers(1, &gl->vertBuf);
   1683 
   1684 	if (gl->textureContext != NULL && --gl->textureContext->refCount == 0) {
   1685 		for (i = 0; i < gl->textureContext->ntextures; i++) {
   1686 			if (gl->textureContext->textures[i].tex != 0 && (gl->textureContext->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
   1687 				glDeleteTextures(1, &gl->textureContext->textures[i].tex);
   1688 		}
   1689 		free(gl->textureContext->textures);
   1690 		free(gl->textureContext);
   1691 	}
   1692 
   1693 	free(gl->paths);
   1694 	free(gl->verts);
   1695 	free(gl->uniforms);
   1696 	free(gl->calls);
   1697 
   1698 	free(gl);
   1699 }
   1700 
   1701 
   1702 #if defined NANOVG_GL2
   1703 NVGcontext* nvgCreateGL2(int flags)
   1704 #elif defined NANOVG_GL3
   1705 NVGcontext* nvgCreateGL3(int flags)
   1706 #elif defined NANOVG_GLES2
   1707 NVGcontext* nvgCreateGLES2(int flags)
   1708 #elif defined NANOVG_GLES3
   1709 NVGcontext* nvgCreateGLES3(int flags)
   1710 #endif
   1711 {
   1712 #if defined NANOVG_GL2
   1713 	return nvgCreateSharedGL2(NULL, flags);
   1714 #elif defined NANOVG_GL3
   1715 	return nvgCreateSharedGL3(NULL, flags);
   1716 #elif defined NANOVG_GLES2
   1717 	return nvgCreateSharedGLES2(NULL, flags);
   1718 #elif defined NANOVG_GLES3
   1719 	return nvgCreateSharedGLES3(NULL, flags);
   1720 #endif
   1721 }
   1722 
   1723 // Share the fonts and textures of 'other' if it's non-NULL.
   1724 #if defined NANOVG_GL2
   1725 NVGcontext* nvgCreateSharedGL2(NVGcontext* other, int flags)
   1726 #elif defined NANOVG_GL3
   1727 NVGcontext* nvgCreateSharedGL3(NVGcontext* other, int flags)
   1728 #elif defined NANOVG_GLES2
   1729 NVGcontext* nvgCreateSharedGLES2(NVGcontext* other, int flags)
   1730 #elif defined NANOVG_GLES3
   1731 NVGcontext* nvgCreateSharedGLES3(NVGcontext* other, int flags)
   1732 #endif
   1733 {
   1734 	NVGparams params;
   1735 	NVGcontext* ctx = NULL;
   1736 	GLNVGcontext* gl = (GLNVGcontext*)malloc(sizeof(GLNVGcontext));
   1737 	if (gl == NULL) goto error;
   1738 	memset(gl, 0, sizeof(GLNVGcontext));
   1739 
   1740 	memset(&params, 0, sizeof(params));
   1741 	params.renderCreate = glnvg__renderCreate;
   1742 	params.renderCreateTexture = glnvg__renderCreateTexture;
   1743 	params.renderDeleteTexture = glnvg__renderDeleteTexture;
   1744 	params.renderUpdateTexture = glnvg__renderUpdateTexture;
   1745 	params.renderGetTextureSize = glnvg__renderGetTextureSize;
   1746 	params.renderViewport = glnvg__renderViewport;
   1747 	params.renderCancel = glnvg__renderCancel;
   1748 	params.renderFlush = glnvg__renderFlush;
   1749 	params.renderFill = glnvg__renderFill;
   1750 	params.renderStroke = glnvg__renderStroke;
   1751 	params.renderTriangles = glnvg__renderTriangles;
   1752 	params.renderDelete = glnvg__renderDelete;
   1753 	params.userPtr = gl;
   1754 	params.edgeAntiAlias = flags & NVG_ANTIALIAS ? 1 : 0;
   1755 
   1756 	gl->flags = flags;
   1757 
   1758 	ctx = nvgCreateInternal(&params, other);
   1759 	if (ctx == NULL) goto error;
   1760 
   1761 	return ctx;
   1762 
   1763 error:
   1764 	// 'gl' is freed by nvgDeleteInternal.
   1765 	if (ctx != NULL) nvgDeleteInternal(ctx);
   1766 	return NULL;
   1767 }
   1768 
   1769 #if defined NANOVG_GL2
   1770 void nvgDeleteGL2(NVGcontext* ctx)
   1771 #elif defined NANOVG_GL3
   1772 void nvgDeleteGL3(NVGcontext* ctx)
   1773 #elif defined NANOVG_GLES2
   1774 void nvgDeleteGLES2(NVGcontext* ctx)
   1775 #elif defined NANOVG_GLES3
   1776 void nvgDeleteGLES3(NVGcontext* ctx)
   1777 #endif
   1778 {
   1779 	nvgDeleteInternal(ctx);
   1780 }
   1781 
   1782 #if defined NANOVG_GL2
   1783 int nvglCreateImageFromHandleGL2(NVGcontext* ctx, GLuint textureId, int w, int h, int imageFlags)
   1784 #elif defined NANOVG_GL3
   1785 int nvglCreateImageFromHandleGL3(NVGcontext* ctx, GLuint textureId, int w, int h, int imageFlags)
   1786 #elif defined NANOVG_GLES2
   1787 int nvglCreateImageFromHandleGLES2(NVGcontext* ctx, GLuint textureId, int w, int h, int imageFlags)
   1788 #elif defined NANOVG_GLES3
   1789 int nvglCreateImageFromHandleGLES3(NVGcontext* ctx, GLuint textureId, int w, int h, int imageFlags)
   1790 #endif
   1791 {
   1792 	GLNVGcontext* gl = (GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
   1793 	GLNVGtexture* tex = glnvg__allocTexture(gl);
   1794 
   1795 	if (tex == NULL) return 0;
   1796 
   1797 	tex->type = NVG_TEXTURE_RGBA;
   1798 	tex->tex = textureId;
   1799 	tex->flags = imageFlags;
   1800 	tex->width = w;
   1801 	tex->height = h;
   1802 
   1803 	return tex->id;
   1804 }
   1805 
   1806 #if defined NANOVG_GL2
   1807 GLuint nvglImageHandleGL2(NVGcontext* ctx, int image)
   1808 #elif defined NANOVG_GL3
   1809 GLuint nvglImageHandleGL3(NVGcontext* ctx, int image)
   1810 #elif defined NANOVG_GLES2
   1811 GLuint nvglImageHandleGLES2(NVGcontext* ctx, int image)
   1812 #elif defined NANOVG_GLES3
   1813 GLuint nvglImageHandleGLES3(NVGcontext* ctx, int image)
   1814 #endif
   1815 {
   1816 	GLNVGcontext* gl = (GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
   1817 	GLNVGtexture* tex = glnvg__findTexture(gl, image);
   1818 	return tex->tex;
   1819 }
   1820 
   1821 #endif /* NANOVG_GL_IMPLEMENTATION */