Browse Source

Merge pull request #312 from satoren/master

Improve nvgGlobalCompositeOperation with state
shared-context
Mikko Mononen GitHub 8 years ago
parent
commit
47ffd9d0b9
3 changed files with 60 additions and 22 deletions
  1. +4
    -4
      src/nanovg.c
  2. +4
    -4
      src/nanovg.h
  3. +52
    -14
      src/nanovg_gl.h

+ 4
- 4
src/nanovg.c View File

@@ -390,7 +390,7 @@ void nvgCancelFrame(NVGcontext* ctx)
void nvgEndFrame(NVGcontext* ctx)
{
NVGstate* state = nvg__getState(ctx);
ctx->params.renderFlush(ctx->params.userPtr, state->compositeOperation);
ctx->params.renderFlush(ctx->params.userPtr);
if (ctx->fontImageIdx != 0) {
int fontImage = ctx->fontImages[ctx->fontImageIdx];
int i, j, iw, ih;
@@ -2212,7 +2212,7 @@ void nvgFill(NVGcontext* ctx)
fillPaint.innerColor.a *= state->alpha;
fillPaint.outerColor.a *= state->alpha;

ctx->params.renderFill(ctx->params.userPtr, &fillPaint, &state->scissor, ctx->fringeWidth,
ctx->params.renderFill(ctx->params.userPtr, &fillPaint, state->compositeOperation, &state->scissor, ctx->fringeWidth,
ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths);

// Count triangles
@@ -2253,7 +2253,7 @@ void nvgStroke(NVGcontext* ctx)
else
nvg__expandStroke(ctx, strokeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit);

ctx->params.renderStroke(ctx->params.userPtr, &strokePaint, &state->scissor, ctx->fringeWidth,
ctx->params.renderStroke(ctx->params.userPtr, &strokePaint, state->compositeOperation, &state->scissor, ctx->fringeWidth,
strokeWidth, ctx->cache->paths, ctx->cache->npaths);

// Count triangles
@@ -2401,7 +2401,7 @@ static void nvg__renderText(NVGcontext* ctx, NVGvertex* verts, int nverts)
paint.innerColor.a *= state->alpha;
paint.outerColor.a *= state->alpha;

ctx->params.renderTriangles(ctx->params.userPtr, &paint, &state->scissor, verts, nverts);
ctx->params.renderTriangles(ctx->params.userPtr, &paint, state->compositeOperation, &state->scissor, verts, nverts);

ctx->drawCallCount++;
ctx->textTriCount += nverts/3;


+ 4
- 4
src/nanovg.h View File

@@ -652,10 +652,10 @@ struct NVGparams {
int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h);
void (*renderViewport)(void* uptr, int width, int height, float devicePixelRatio);
void (*renderCancel)(void* uptr);
void (*renderFlush)(void* uptr, NVGcompositeOperationState compositeOperation);
void (*renderFill)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths);
void (*renderStroke)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths);
void (*renderTriangles)(void* uptr, NVGpaint* paint, NVGscissor* scissor, const NVGvertex* verts, int nverts);
void (*renderFlush)(void* uptr);
void (*renderFill)(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths);
void (*renderStroke)(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths);
void (*renderTriangles)(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, const NVGvertex* verts, int nverts);
void (*renderDelete)(void* uptr);
};
typedef struct NVGparams NVGparams;


+ 52
- 14
src/nanovg_gl.h View File

@@ -150,6 +150,15 @@ struct GLNVGtexture {
};
typedef struct GLNVGtexture GLNVGtexture;

struct GLNVGblend
{
GLenum srcRGB;
GLenum dstRGB;
GLenum srcAlpha;
GLenum dstAlpha;
};
typedef struct GLNVGblend GLNVGblend;

enum GLNVGcallType {
GLNVG_NONE = 0,
GLNVG_FILL,
@@ -166,6 +175,7 @@ struct GLNVGcall {
int triangleOffset;
int triangleCount;
int uniformOffset;
GLNVGblend blendFunc;
};
typedef struct GLNVGcall GLNVGcall;

@@ -256,6 +266,7 @@ struct GLNVGcontext {
GLenum stencilFunc;
GLint stencilFuncRef;
GLuint stencilFuncMask;
GLNVGblend blendFunc;
#endif
};
typedef struct GLNVGcontext GLNVGcontext;
@@ -316,6 +327,21 @@ static void glnvg__stencilFunc(GLNVGcontext* gl, GLenum func, GLint ref, GLuint
glStencilFunc(func, ref, mask);
#endif
}
static void glnvg__blendFuncSeparate(GLNVGcontext* gl, const GLNVGblend* blend)
{
#if NANOVG_GL_USE_STATE_FILTER
if ((gl->blendFunc.srcRGB != blend->srcRGB) ||
(gl->blendFunc.dstRGB != blend->dstRGB) ||
(gl->blendFunc.srcAlpha != blend->srcAlpha) ||
(gl->blendFunc.dstAlpha != blend->dstAlpha)) {
gl->blendFunc = *blend;
glBlendFuncSeparate(blend->srcRGB, blend->dstRGB, blend->srcAlpha,blend->dstAlpha);
}
#else
glBlendFuncSeparate(blend->srcRGB, blend->dstRGB, blend->srcAlpha,blend->dstAlpha);
#endif
}

static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
{
@@ -1116,19 +1142,24 @@ static GLenum glnvg_convertBlendFuncFactor(int factor)
return GL_INVALID_ENUM;
}

static void glnvg__blendCompositeOperation(NVGcompositeOperationState op)
static GLNVGblend glnvg__blendCompositeOperation(NVGcompositeOperationState op)
{
GLenum srcRGB = glnvg_convertBlendFuncFactor(op.srcRGB);
GLenum dstRGB = glnvg_convertBlendFuncFactor(op.dstRGB);
GLenum srcAlpha = glnvg_convertBlendFuncFactor(op.srcAlpha);
GLenum dstAlpha = glnvg_convertBlendFuncFactor(op.dstAlpha);
if (srcRGB == GL_INVALID_ENUM || dstRGB == GL_INVALID_ENUM || srcAlpha == GL_INVALID_ENUM || dstAlpha == GL_INVALID_ENUM)
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
else
glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
GLNVGblend blend;
blend.srcRGB = glnvg_convertBlendFuncFactor(op.srcRGB);
blend.dstRGB = glnvg_convertBlendFuncFactor(op.dstRGB);
blend.srcAlpha = glnvg_convertBlendFuncFactor(op.srcAlpha);
blend.dstAlpha = glnvg_convertBlendFuncFactor(op.dstAlpha);
if (blend.srcRGB == GL_INVALID_ENUM || blend.dstRGB == GL_INVALID_ENUM || blend.srcAlpha == GL_INVALID_ENUM || blend.dstAlpha == GL_INVALID_ENUM)
{
blend.srcRGB = GL_ONE;
blend.dstRGB = GL_ONE_MINUS_SRC_ALPHA;
blend.srcAlpha = GL_ONE;
blend.dstAlpha = GL_ONE_MINUS_SRC_ALPHA;
}
return blend;
}

static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeOperation)
static void glnvg__renderFlush(void* uptr)
{
GLNVGcontext* gl = (GLNVGcontext*)uptr;
int i;
@@ -1138,7 +1169,6 @@ static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeO
// Setup require GL state.
glUseProgram(gl->shader.prog);

glnvg__blendCompositeOperation(compositeOperation);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
@@ -1157,6 +1187,10 @@ static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeO
gl->stencilFunc = GL_ALWAYS;
gl->stencilFuncRef = 0;
gl->stencilFuncMask = 0xffffffff;
gl->blendFunc.srcRGB = GL_INVALID_ENUM;
gl->blendFunc.srcAlpha = GL_INVALID_ENUM;
gl->blendFunc.dstRGB = GL_INVALID_ENUM;
gl->blendFunc.dstAlpha = GL_INVALID_ENUM;
#endif

#if NANOVG_GL_USE_UNIFORMBUFFER
@@ -1186,6 +1220,7 @@ static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeO

for (i = 0; i < gl->ncalls; i++) {
GLNVGcall* call = &gl->calls[i];
glnvg__blendFuncSeparate(gl,&call->blendFunc);
if (call->type == GLNVG_FILL)
glnvg__fill(gl, call);
else if (call->type == GLNVG_CONVEXFILL)
@@ -1301,7 +1336,7 @@ static void glnvg__vset(NVGvertex* vtx, float x, float y, float u, float v)
vtx->v = v;
}

static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe,
static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
const float* bounds, const NVGpath* paths, int npaths)
{
GLNVGcontext* gl = (GLNVGcontext*)uptr;
@@ -1317,6 +1352,7 @@ static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGscissor* scissor,
if (call->pathOffset == -1) goto error;
call->pathCount = npaths;
call->image = paint->image;
call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);

if (npaths == 1 && paths[0].convex)
call->type = GLNVG_CONVEXFILL;
@@ -1382,7 +1418,7 @@ error:
if (gl->ncalls > 0) gl->ncalls--;
}

static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe,
static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
float strokeWidth, const NVGpath* paths, int npaths)
{
GLNVGcontext* gl = (GLNVGcontext*)uptr;
@@ -1396,6 +1432,7 @@ static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGscissor* scissor
if (call->pathOffset == -1) goto error;
call->pathCount = npaths;
call->image = paint->image;
call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);

// Allocate vertices for all the paths.
maxverts = glnvg__maxVertCount(paths, npaths);
@@ -1437,7 +1474,7 @@ error:
if (gl->ncalls > 0) gl->ncalls--;
}

static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGscissor* scissor,
static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor,
const NVGvertex* verts, int nverts)
{
GLNVGcontext* gl = (GLNVGcontext*)uptr;
@@ -1448,6 +1485,7 @@ static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGscissor* scis

call->type = GLNVG_TRIANGLES;
call->image = paint->image;
call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);

// Allocate vertices for all the paths.
call->triangleOffset = glnvg__allocVerts(gl, nverts);


Loading…
Cancel
Save