canvas renderer: Use clip rects to cull tiles/pixels in tiling and drawing passes

This commit is contained in:
martinfouilleul 2023-02-08 12:59:31 +01:00
parent e6e674ee04
commit 7fbc4ba270
6 changed files with 44 additions and 13 deletions

View File

@ -178,10 +178,16 @@ int main()
mg_set_color_rgba(0, 1, 1, 1); mg_set_color_rgba(0, 1, 1, 1);
mg_clear(); mg_clear();
// mg_clip_push(100, 100, contentRect.w - 200, contentRect.h - 200);
// head // head
mg_set_color_rgba(1, 1, 0, 1); mg_set_color_rgba(1, 1, 0, 1);
mg_circle_fill(x, y, 200); mg_circle_fill(x, y, 200);
/*
mg_clip_pop();
mg_set_width(2);
mg_set_color_rgba(1, 0, 0, 1);
mg_rectangle_stroke(100, 100, contentRect.w - 200, contentRect.h - 200);
*/
// smile // smile
f32 frown = frameTime > 0.033 ? 100 : 0; f32 frown = frameTime > 0.033 ? 100 : 0;

View File

@ -64,7 +64,7 @@ void main()
uint tileCounter = tileCounterBuffer.elements[tileIndex]; uint tileCounter = tileCounterBuffer.elements[tileIndex];
const float subPixelFactor = 16.; const float subPixelFactor = 16.;
ivec2 centerPoint = ivec2(round((vec2(pixelCoord) + vec2(0.5, 0.5)) * subPixelFactor)); ivec2 centerPoint = ivec2((vec2(pixelCoord) + vec2(0.5, 0.5)) * subPixelFactor);
//* //*
const int sampleCount = 8; const int sampleCount = 8;
@ -132,12 +132,13 @@ void main()
uint i1 = indexBuffer.elements[triangleIndex+1u]; uint i1 = indexBuffer.elements[triangleIndex+1u];
uint i2 = indexBuffer.elements[triangleIndex+2u]; uint i2 = indexBuffer.elements[triangleIndex+2u];
ivec2 p0 = ivec2(vertexBuffer.elements[i0].pos * subPixelFactor + vec2(0.5, 0.5)); ivec2 p0 = ivec2((vertexBuffer.elements[i0].pos) * subPixelFactor);
ivec2 p1 = ivec2(vertexBuffer.elements[i1].pos * subPixelFactor + vec2(0.5, 0.5)); ivec2 p1 = ivec2((vertexBuffer.elements[i1].pos) * subPixelFactor);
ivec2 p2 = ivec2(vertexBuffer.elements[i2].pos * subPixelFactor + vec2(0.5, 0.5)); ivec2 p2 = ivec2((vertexBuffer.elements[i2].pos) * subPixelFactor);
int zIndex = vertexBuffer.elements[i0].zIndex; int zIndex = vertexBuffer.elements[i0].zIndex;
vec4 color = shapeBuffer.elements[zIndex].color; vec4 color = shapeBuffer.elements[zIndex].color;
ivec4 clip = ivec4(round((shapeBuffer.elements[zIndex].clip + vec4(0.5, 0.5, 0.5, 0.5)) * subPixelFactor));
//NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge //NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge
int cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x; int cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x;
@ -164,6 +165,14 @@ void main()
{ {
ivec2 samplePoint = samplePoints[sampleIndex]; ivec2 samplePoint = samplePoints[sampleIndex];
if( samplePoint.x < clip.x
|| samplePoint.x > clip.z
|| samplePoint.y < clip.y
|| samplePoint.y > clip.w)
{
continue;
}
int w0 = orient2d(p1, p2, samplePoint); int w0 = orient2d(p1, p2, samplePoint);
int w1 = orient2d(p2, p0, samplePoint); int w1 = orient2d(p2, p0, samplePoint);
int w2 = orient2d(p0, p1, samplePoint); int w2 = orient2d(p0, p1, samplePoint);

View File

@ -57,11 +57,18 @@ void main()
vec2 p1 = vertexBuffer.elements[i1].pos; vec2 p1 = vertexBuffer.elements[i1].pos;
vec2 p2 = vertexBuffer.elements[i2].pos; vec2 p2 = vertexBuffer.elements[i2].pos;
vec4 fbox = vec4(min(min(p0.x, p1.x), p2.x), int shapeIndex = vertexBuffer.elements[i0].zIndex;
min(min(p0.y, p1.y), p2.y), vec4 clip = shapeBuffer.elements[shapeIndex].clip;
max(max(p0.x, p1.x), p2.x),
max(max(p0.y, p1.y), p2.y));
vec4 fbox = vec4(max(min(min(p0.x, p1.x), p2.x), clip.x),
max(min(min(p0.y, p1.y), p2.y), clip.y),
min(max(max(p0.x, p1.x), p2.x), clip.z),
min(max(max(p0.y, p1.y), p2.y), clip.w));
/*
fbox.xy = min(fbox.xy, clip.xy);
fbox.zw = max(fbox.zw, clip.zw);
*/
uvec4 box = uvec4(floor(fbox))/tileSize; uvec4 box = uvec4(floor(fbox))/tileSize;
uint xMin = max(0u, box.x); uint xMin = max(0u, box.x);

View File

@ -446,11 +446,16 @@ u32 mg_next_shape_textured(mg_canvas_data* canvas, vec2 uv, mg_color color)
int index = canvas->nextZIndex; int index = canvas->nextZIndex;
canvas->nextZIndex++; canvas->nextZIndex++;
mp_rect clip = {canvas->clip.x,
canvas->clip.y,
canvas->clip.x + canvas->clip.w - 1,
canvas->clip.y + canvas->clip.h - 1};
mg_vertex_layout* layout = &canvas->backend->vertexLayout; mg_vertex_layout* layout = &canvas->backend->vertexLayout;
*(vec2*)(((char*)layout->uvBuffer) + index*layout->uvStride) = uv; *(vec2*)(((char*)layout->uvBuffer) + index*layout->uvStride) = uv;
*(mg_color*)(((char*)layout->colorBuffer) + index*layout->colorStride) = color; *(mg_color*)(((char*)layout->colorBuffer) + index*layout->colorStride) = color;
*(mp_rect*)(((char*)layout->clipBuffer) + index*layout->clipStride) = canvas->clip; *(mp_rect*)(((char*)layout->clipBuffer) + index*layout->clipStride) = clip;
return(index); return(index);
} }

View File

@ -64,8 +64,8 @@ kernel void BoundingBoxKernel(constant mg_vertex* vertexBuffer [[buffer(0)]],
float2 clipMax(clip.x + clip.z-1, clip.y + clip.w-1); float2 clipMax(clip.x + clip.z-1, clip.y + clip.w-1);
//NOTE(martin): intersect with current clip //NOTE(martin): intersect with current clip
boxMin = max(boxMin, clipMin); boxMin = max(boxMin, clip.xy);
boxMax = min(boxMax, clipMax); boxMax = min(boxMax, clip.zw);
//NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge //NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge
float cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x; float cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x;

View File

@ -6,12 +6,16 @@ Canvas renderer perf
[?] use half-floats or short fixed-point for pos and uv, packing them in two ints [?] use half-floats or short fixed-point for pos and uv, packing them in two ints
[?] pre-compute triangle edges/bounding boxes? [?] pre-compute triangle edges/bounding boxes?
[!] Investigate artifact when shifting positions of vertices by (0.5, 0.5) before multiplying
by subpixel precision and truncating... -> ie sampling at the middle of pixels vs at integer coordinates...
[ ] What alignment gives crisp-ier lines?
[>] Add surface scaling for high dpi surfaces [>] Add surface scaling for high dpi surfaces
[x] Allow setting swap interval [x] Allow setting swap interval
[!] Allow swap interval of 0 on macos [!] Allow swap interval of 0 on macos
[>] Use clip rects in tiling/drawing pass [x] Use clip rects in tiling/drawing pass
[ ] Clean canvas code [ ] Clean canvas code
[ ] make zIndex implicit when calling push_vertex [ ] make zIndex implicit when calling push_vertex