canvas renderer: Use clip rects to cull tiles/pixels in tiling and drawing passes
This commit is contained in:
parent
e6e674ee04
commit
7fbc4ba270
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
6
todo.txt
6
todo.txt
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue