[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