[gl, canvas]
- Haul path color and texture sampling outside of per-sample loop - Pack gl input structs a bit - Set correct hint flags for glBufferData()
This commit is contained in:
parent
9bfae2c4e8
commit
59fdc27ac6
|
@ -44,9 +44,8 @@ typedef struct mg_gl_path_elt
|
||||||
{
|
{
|
||||||
vec2 p[4];
|
vec2 p[4];
|
||||||
int pathIndex;
|
int pathIndex;
|
||||||
int localEltIndex;
|
|
||||||
mg_gl_seg_kind kind;
|
mg_gl_seg_kind kind;
|
||||||
u8 pad[4];
|
|
||||||
} mg_gl_path_elt;
|
} mg_gl_path_elt;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -105,7 +104,6 @@ typedef struct mg_gl_encoding_context
|
||||||
mg_gl_path* pathBufferData;
|
mg_gl_path* pathBufferData;
|
||||||
mg_gl_path_elt* elementBufferData;
|
mg_gl_path_elt* elementBufferData;
|
||||||
int pathIndex;
|
int pathIndex;
|
||||||
int localEltIndex;
|
|
||||||
mg_primitive* primitive;
|
mg_primitive* primitive;
|
||||||
vec4 pathScreenExtents;
|
vec4 pathScreenExtents;
|
||||||
vec4 pathUserExtents;
|
vec4 pathUserExtents;
|
||||||
|
@ -195,8 +193,6 @@ void mg_gl_canvas_encode_element(mg_gl_encoding_context* context, mg_path_elt_ty
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
glElt->localEltIndex = context->localEltIndex;
|
|
||||||
|
|
||||||
for(int i=0; i<count; i++)
|
for(int i=0; i<count; i++)
|
||||||
{
|
{
|
||||||
mg_update_path_extents(&context->pathUserExtents, p[i]);
|
mg_update_path_extents(&context->pathUserExtents, p[i]);
|
||||||
|
@ -998,10 +994,9 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend,
|
||||||
glUseProgram(backend->raster);
|
glUseProgram(backend->raster);
|
||||||
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentCountBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentBuffer);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileOpBuffer);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->tileOpBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->screenTilesBuffer);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->screenTilesBuffer);
|
|
||||||
|
|
||||||
glUniform1f(0, scale);
|
glUniform1f(0, scale);
|
||||||
glUniform1i(1, backend->msaaCount);
|
glUniform1i(1, backend->msaaCount);
|
||||||
|
@ -1126,8 +1121,6 @@ void mg_gl_canvas_render(mg_canvas_backend* interface,
|
||||||
(eltIndex < primitive->path.count) && (primitive->path.startIndex + eltIndex < eltCount);
|
(eltIndex < primitive->path.count) && (primitive->path.startIndex + eltIndex < eltCount);
|
||||||
eltIndex++)
|
eltIndex++)
|
||||||
{
|
{
|
||||||
context.localEltIndex = segCount;
|
|
||||||
|
|
||||||
mg_path_elt* elt = &pathElements[primitive->path.startIndex + eltIndex];
|
mg_path_elt* elt = &pathElements[primitive->path.startIndex + eltIndex];
|
||||||
|
|
||||||
if(elt->type != MG_PATH_MOVE)
|
if(elt->type != MG_PATH_MOVE)
|
||||||
|
@ -1453,12 +1446,12 @@ mg_canvas_backend* gl_canvas_backend_create(mg_wgl_surface* surface)
|
||||||
|
|
||||||
glGenBuffers(1, &backend->pathBuffer);
|
glGenBuffers(1, &backend->pathBuffer);
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->pathBuffer);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->pathBuffer);
|
||||||
glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_PATH_BUFFER_SIZE, 0, GL_DYNAMIC_COPY);
|
glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_PATH_BUFFER_SIZE, 0, GL_STREAM_DRAW);
|
||||||
|
|
||||||
//TODO change flags
|
//TODO change flags
|
||||||
glGenBuffers(1, &backend->elementBuffer);
|
glGenBuffers(1, &backend->elementBuffer);
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->elementBuffer);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->elementBuffer);
|
||||||
glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_ELEMENT_BUFFER_SIZE, 0, GL_DYNAMIC_COPY);
|
glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_ELEMENT_BUFFER_SIZE, 0, GL_STREAM_DRAW);
|
||||||
|
|
||||||
glGenBuffers(1, &backend->segmentBuffer);
|
glGenBuffers(1, &backend->segmentBuffer);
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentBuffer);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentBuffer);
|
||||||
|
|
|
@ -36,7 +36,6 @@ struct mg_gl_path_elt
|
||||||
{
|
{
|
||||||
vec2 p[4];
|
vec2 p[4];
|
||||||
int pathIndex;
|
int pathIndex;
|
||||||
int localEltIndex;
|
|
||||||
int kind;
|
int kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,13 +43,12 @@ struct mg_gl_segment
|
||||||
{
|
{
|
||||||
int kind;
|
int kind;
|
||||||
int pathIndex;
|
int pathIndex;
|
||||||
int config; //TODO pack these
|
int config;
|
||||||
int windingIncrement;
|
int windingIncrement;
|
||||||
vec4 box;
|
vec4 box;
|
||||||
mat3 implicitMatrix;
|
mat3 implicitMatrix;
|
||||||
float sign;
|
|
||||||
vec2 hullVertex;
|
vec2 hullVertex;
|
||||||
int debugID;
|
float sign;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mg_gl_path_queue
|
struct mg_gl_path_queue
|
||||||
|
@ -62,10 +60,9 @@ struct mg_gl_path_queue
|
||||||
struct mg_gl_tile_op
|
struct mg_gl_tile_op
|
||||||
{
|
{
|
||||||
int kind;
|
int kind;
|
||||||
int index;
|
|
||||||
int next;
|
int next;
|
||||||
bool crossRight;
|
int index;
|
||||||
int windingOffset;
|
int windingOffsetOrCrossRight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mg_gl_tile_queue
|
struct mg_gl_tile_queue
|
||||||
|
@ -75,7 +72,6 @@ struct mg_gl_tile_queue
|
||||||
int last;
|
int last;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
float ccw(vec2 a, vec2 b, vec2 c)
|
float ccw(vec2 a, vec2 b, vec2 c)
|
||||||
{
|
{
|
||||||
return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
|
return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
|
||||||
|
|
|
@ -82,7 +82,7 @@ void main()
|
||||||
tileOpBuffer.elements[pathOpIndex].kind = MG_GL_OP_START;
|
tileOpBuffer.elements[pathOpIndex].kind = MG_GL_OP_START;
|
||||||
tileOpBuffer.elements[pathOpIndex].next = -1;
|
tileOpBuffer.elements[pathOpIndex].next = -1;
|
||||||
tileOpBuffer.elements[pathOpIndex].index = pathIndex;
|
tileOpBuffer.elements[pathOpIndex].index = pathIndex;
|
||||||
tileOpBuffer.elements[pathOpIndex].windingOffset = windingOffset;
|
tileOpBuffer.elements[pathOpIndex].windingOffsetOrCrossRight = windingOffset;
|
||||||
|
|
||||||
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
||||||
vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x+1, tileCoord.y+1);
|
vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x+1, tileCoord.y+1);
|
||||||
|
@ -114,7 +114,7 @@ void main()
|
||||||
tileOpBuffer.elements[pathOpIndex].kind = MG_GL_OP_START;
|
tileOpBuffer.elements[pathOpIndex].kind = MG_GL_OP_START;
|
||||||
tileOpBuffer.elements[pathOpIndex].next = -1;
|
tileOpBuffer.elements[pathOpIndex].next = -1;
|
||||||
tileOpBuffer.elements[pathOpIndex].index = pathIndex;
|
tileOpBuffer.elements[pathOpIndex].index = pathIndex;
|
||||||
tileOpBuffer.elements[pathOpIndex].windingOffset = windingOffset;
|
tileOpBuffer.elements[pathOpIndex].windingOffsetOrCrossRight = windingOffset;
|
||||||
|
|
||||||
if(lastOpIndex < 0)
|
if(lastOpIndex < 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,22 +9,17 @@ layout(binding = 0) restrict readonly buffer pathBufferSSBO
|
||||||
mg_gl_path elements[];
|
mg_gl_path elements[];
|
||||||
} pathBuffer;
|
} pathBuffer;
|
||||||
|
|
||||||
layout(binding = 1) restrict readonly buffer segmentCountBufferSSBO
|
layout(binding = 1) restrict readonly buffer segmentBufferSSBO
|
||||||
{
|
|
||||||
int elements[];
|
|
||||||
} segmentCountBuffer;
|
|
||||||
|
|
||||||
layout(binding = 2) restrict readonly buffer segmentBufferSSBO
|
|
||||||
{
|
{
|
||||||
mg_gl_segment elements[];
|
mg_gl_segment elements[];
|
||||||
} segmentBuffer;
|
} segmentBuffer;
|
||||||
|
|
||||||
layout(binding = 3) restrict readonly buffer tileOpBufferSSBO
|
layout(binding = 2) restrict readonly buffer tileOpBufferSSBO
|
||||||
{
|
{
|
||||||
mg_gl_tile_op elements[];
|
mg_gl_tile_op elements[];
|
||||||
} tileOpBuffer;
|
} tileOpBuffer;
|
||||||
|
|
||||||
layout(binding = 4) restrict readonly buffer screenTilesBufferSSBO
|
layout(binding = 3) restrict readonly buffer screenTilesBufferSSBO
|
||||||
{
|
{
|
||||||
int elements[];
|
int elements[];
|
||||||
} screenTilesBuffer;
|
} screenTilesBuffer;
|
||||||
|
@ -91,8 +86,17 @@ void main()
|
||||||
if(op.kind == MG_GL_OP_START)
|
if(op.kind == MG_GL_OP_START)
|
||||||
{
|
{
|
||||||
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
||||||
vec4 pathColor = pathBuffer.elements[pathIndex].color;
|
vec4 nextColor = pathBuffer.elements[pathIndex].color;
|
||||||
pathColor.rgb *= pathColor.a;
|
nextColor.rgb *= nextColor.a;
|
||||||
|
|
||||||
|
if(useTexture != 0)
|
||||||
|
{
|
||||||
|
vec3 ph = vec3(centerCoord.xy, 1);
|
||||||
|
vec2 uv = (pathBuffer.elements[pathIndex].uvTransform * ph).xy;
|
||||||
|
vec4 texColor = texture(srcTexture, uv);
|
||||||
|
texColor.rgb *= texColor.a;
|
||||||
|
nextColor *= texColor;
|
||||||
|
}
|
||||||
|
|
||||||
for(int sampleIndex = 0; sampleIndex<sampleCount; sampleIndex++)
|
for(int sampleIndex = 0; sampleIndex<sampleCount; sampleIndex++)
|
||||||
{
|
{
|
||||||
|
@ -107,19 +111,10 @@ void main()
|
||||||
||(pathBuffer.elements[pathIndex].cmd == MG_GL_STROKE && (winding[sampleIndex] != 0));
|
||(pathBuffer.elements[pathIndex].cmd == MG_GL_STROKE && (winding[sampleIndex] != 0));
|
||||||
if(filled)
|
if(filled)
|
||||||
{
|
{
|
||||||
vec4 nextColor = pathColor;
|
|
||||||
if(useTexture != 0)
|
|
||||||
{
|
|
||||||
vec3 ph = vec3(sampleCoord.xy, 1);
|
|
||||||
vec2 uv = (pathBuffer.elements[pathIndex].uvTransform * ph).xy;
|
|
||||||
vec4 texColor = texture(srcTexture, uv);
|
|
||||||
texColor.rgb *= texColor.a;
|
|
||||||
nextColor *= texColor;
|
|
||||||
}
|
|
||||||
color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor;
|
color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
winding[sampleIndex] = op.windingOffset;
|
winding[sampleIndex] = op.windingOffsetOrCrossRight;
|
||||||
}
|
}
|
||||||
pathIndex = op.index;
|
pathIndex = op.index;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +134,7 @@ void main()
|
||||||
winding[sampleIndex] += seg.windingIncrement;
|
winding[sampleIndex] += seg.windingIncrement;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(op.crossRight)
|
if(op.windingOffsetOrCrossRight != 0)
|
||||||
{
|
{
|
||||||
if( (seg.config == MG_GL_BR || seg.config == MG_GL_TL)
|
if( (seg.config == MG_GL_BR || seg.config == MG_GL_TL)
|
||||||
&&(sampleCoord.y > seg.box.w))
|
&&(sampleCoord.y > seg.box.w))
|
||||||
|
@ -159,8 +154,17 @@ void main()
|
||||||
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
||||||
|
|
||||||
vec4 pixelColor = vec4(0);
|
vec4 pixelColor = vec4(0);
|
||||||
vec4 pathColor = pathBuffer.elements[pathIndex].color;
|
vec4 nextColor = pathBuffer.elements[pathIndex].color;
|
||||||
pathColor.rgb *= pathColor.a;
|
nextColor.rgb *= nextColor.a;
|
||||||
|
|
||||||
|
if(useTexture != 0)
|
||||||
|
{
|
||||||
|
vec3 ph = vec3(centerCoord.xy, 1);
|
||||||
|
vec2 uv = (pathBuffer.elements[pathIndex].uvTransform * ph).xy;
|
||||||
|
vec4 texColor = texture(srcTexture, uv);
|
||||||
|
texColor.rgb *= texColor.a;
|
||||||
|
nextColor *= texColor;
|
||||||
|
}
|
||||||
|
|
||||||
for(int sampleIndex=0; sampleIndex<sampleCount; sampleIndex++)
|
for(int sampleIndex=0; sampleIndex<sampleCount; sampleIndex++)
|
||||||
{
|
{
|
||||||
|
@ -175,15 +179,6 @@ void main()
|
||||||
||(pathBuffer.elements[pathIndex].cmd == MG_GL_STROKE && (winding[sampleIndex] != 0));
|
||(pathBuffer.elements[pathIndex].cmd == MG_GL_STROKE && (winding[sampleIndex] != 0));
|
||||||
if(filled)
|
if(filled)
|
||||||
{
|
{
|
||||||
vec4 nextColor = pathColor;
|
|
||||||
if(useTexture != 0)
|
|
||||||
{
|
|
||||||
vec3 ph = vec3(sampleCoord.xy, 1);
|
|
||||||
vec2 uv = (pathBuffer.elements[pathIndex].uvTransform * ph).xy;
|
|
||||||
vec4 texColor = texture(srcTexture, uv);
|
|
||||||
texColor.rgb *= texColor.a;
|
|
||||||
nextColor *= texColor;
|
|
||||||
}
|
|
||||||
color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor;
|
color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ void bin_to_tiles(int segIndex)
|
||||||
|
|
||||||
tileOpBuffer.elements[tileOpIndex].kind = MG_GL_OP_SEGMENT;
|
tileOpBuffer.elements[tileOpIndex].kind = MG_GL_OP_SEGMENT;
|
||||||
tileOpBuffer.elements[tileOpIndex].index = segIndex;
|
tileOpBuffer.elements[tileOpIndex].index = segIndex;
|
||||||
tileOpBuffer.elements[tileOpIndex].crossRight = false;
|
tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 0;
|
||||||
tileOpBuffer.elements[tileOpIndex].next = -1;
|
tileOpBuffer.elements[tileOpIndex].next = -1;
|
||||||
|
|
||||||
int tileQueueIndex = pathQueue.tileQueues + y*pathArea.z + x;
|
int tileQueueIndex = pathQueue.tileQueues + y*pathArea.z + x;
|
||||||
|
@ -126,7 +126,7 @@ void bin_to_tiles(int segIndex)
|
||||||
//NOTE: if the segment crosses the right boundary, mark it.
|
//NOTE: if the segment crosses the right boundary, mark it.
|
||||||
if(crossR)
|
if(crossR)
|
||||||
{
|
{
|
||||||
tileOpBuffer.elements[tileOpIndex].crossRight = true;
|
tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue