Improve efficiency in Graphics rendering.

We don't copy as many arrays now.
This commit is contained in:
Ben Richards 2024-06-25 16:39:17 +12:00
parent f6d71c32cc
commit 8f34a894a7
6 changed files with 79 additions and 178 deletions

View file

@ -163,9 +163,10 @@ var BatchHandlerTriFlat = new Class({
* @since 3.90.0
* @param {Phaser.Types.Renderer.WebGL.DrawingContext} currentContext - The current drawing context.
* @param {number[]} indexes - The index data. Each triangle is defined by three indices into the vertices array, so the length of this should be a multiple of 3.
* @param {number[]} vertices - The vertices data. Each vertex is defined by an x-coordinate, a y-coordinate, a tint color, a pass ID (initially -1), and an index ID (initially -1).
* @param {number[]} vertices - The vertices data. Each vertex is defined by an x-coordinate and a y-coordinate.
* @param {number[]} colors - The color data. Each vertex has a color as a Uint32 value.
*/
batch: function (currentContext, indexes, vertices)
batch: function (currentContext, indexes, vertices, colors)
{
if (this.instanceCount === 0)
{
@ -189,26 +190,33 @@ var BatchHandlerTriFlat = new Class({
var vertexViewU32 = vertexBuffer.viewU32;
var vertexOffset32 = this.vertexCount * stride / vertexViewF32.BYTES_PER_ELEMENT;
// Track vertex usage.
var passes = [];
var passOffset = 0;
var vertexIndices = [];
var vertexIndicesOffset = 0;
for (var i = 0; i < indexes.length; i++)
{
var index = indexes[i] * 5;
var index = indexes[i];
var vertexIndex = index * 2;
if (vertices[index + 3] !== passID)
if (passes[i] !== passID)
{
// Update the vertex buffer.
vertexViewF32[vertexOffset32++] = vertices[index];
vertexViewF32[vertexOffset32++] = vertices[index + 1];
vertexViewU32[vertexOffset32++] = vertices[index + 2];
vertexViewF32[vertexOffset32++] = vertices[vertexIndex];
vertexViewF32[vertexOffset32++] = vertices[vertexIndex + 1];
vertexViewU32[vertexOffset32++] = colors[index];
// Assign the vertex to the current pass.
vertices[index + 3] = passID;
passes[passOffset++] = passID;
// Record the index where the vertex was stored.
vertices[index + 4] = this.vertexCount;
vertexIndices[vertexIndicesOffset++] = this.vertexCount;
this.vertexCount++;
}
var id = vertices[index + 4];
var id = vertexIndices[vertexIndicesOffset - 1];
// Update the index buffer.
// There is always at least one index per vertex,
@ -238,6 +246,8 @@ var BatchHandlerTriFlat = new Class({
indexOffset16 = this.instanceCount * this.indicesPerInstance;
vertexOffset32 = this.vertexCount * stride / vertexViewF32.BYTES_PER_ELEMENT;
passOffset = 0;
vertexIndicesOffset = 0;
// Now the batch is empty.
}

View file

@ -24,34 +24,11 @@ var DrawLine = new Class({
initialize: function DrawLine (manager)
{
RenderNode.call(this, 'DrawLine', manager);
/**
* The vertices of the line segment as a quad.
* These values have been transformed.
* They should be used before the next call to `run`,
* whereupon they will be overridden.
*
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#quad
* @type {{ xTL: number, yTL: number, xTR: number, yTR: number, xBL: number, yBL: number, xBR: number, yBR: number }}
* @since 3.90.0
*/
this.quad = {
xTL: 0,
yTL: 0,
xTR: 0,
yTR: 0,
xBL: 0,
yBL: 0,
xBR: 0,
yBR: 0
};
},
/**
* Get the transformed vertices of a line segment as a quad.
* The values are stored in the `quad` property.
* Access the values directly or copy them to another object,
* before the next call to `run`, whereupon they will be overridden.
* The values are pushed to a `vertices` list in the order TL, BL, BR, TR.
*
* @method Phaser.Renderer.WebGL.RenderNodes.DrawLine#run
* @since 3.90.0
@ -63,8 +40,9 @@ var DrawLine = new Class({
* @param {number} by - The y coordinate of the end of the line.
* @param {number} aLineWidth - The width of the line at the start.
* @param {number} bLineWidth - The width of the line at the end.
* @param {number[]} vertices - The list to which the vertices are assigned.
*/
run: function (drawingContext, currentMatrix, ax, ay, bx, by, aLineWidth, bLineWidth)
run: function (drawingContext, currentMatrix, ax, ay, bx, by, aLineWidth, bLineWidth, vertices)
{
this.onRunBegin(drawingContext);
@ -89,29 +67,29 @@ var DrawLine = new Class({
var lx3 = ax + al0;
var ly3 = ay + al1;
var quad = this.quad;
var offset = vertices.length;
if (currentMatrix)
{
quad.xTL = currentMatrix.getX(lx3, ly3);
quad.yTL = currentMatrix.getY(lx3, ly3);
quad.xBL = currentMatrix.getX(lx1, ly1);
quad.yBL = currentMatrix.getY(lx1, ly1);
quad.xTR = currentMatrix.getX(lx2, ly2);
quad.yTR = currentMatrix.getY(lx2, ly2);
quad.xBR = currentMatrix.getX(lx0, ly0);
quad.yBR = currentMatrix.getY(lx0, ly0);
vertices[offset + 0] = currentMatrix.getX(lx3, ly3);
vertices[offset + 1] = currentMatrix.getY(lx3, ly3);
vertices[offset + 2] = currentMatrix.getX(lx1, ly1);
vertices[offset + 3] = currentMatrix.getY(lx1, ly1);
vertices[offset + 4] = currentMatrix.getX(lx0, ly0);
vertices[offset + 5] = currentMatrix.getY(lx0, ly0);
vertices[offset + 6] = currentMatrix.getX(lx2, ly2);
vertices[offset + 7] = currentMatrix.getY(lx2, ly2);
}
else
{
quad.xTL = lx3;
quad.yTL = ly3;
quad.xBL = lx1;
quad.yBL = ly1;
quad.xTR = lx2;
quad.yTR = ly2;
quad.xBR = lx0;
quad.yBR = ly0;
vertices[offset + 0] = lx3;
vertices[offset + 1] = ly3;
vertices[offset + 2] = lx1;
vertices[offset + 3] = ly1;
vertices[offset + 4] = lx0;
vertices[offset + 5] = ly0;
vertices[offset + 6] = lx2;
vertices[offset + 7] = ly2;
}
this.onRunEnd(drawingContext);

View file

@ -57,11 +57,11 @@ var FillPath = new Class({
var index, pathIndex, point, polygonIndexArray, x, y;
var polygonCacheIndex = 0;
var verticesIndex = 0;
var indexedTrianglesIndex = 0;
var polygonCache = [];
var vertices = [];
var colors = [];
var colorsIndex = 0;
for (pathIndex = 0; pathIndex < length; pathIndex++)
{
@ -98,80 +98,21 @@ var FillPath = new Class({
for (index = 0; index < polygonCacheLength; index += 2)
{
vertices[verticesIndex++] = polygonCache[index];
vertices[verticesIndex++] = polygonCache[index + 1];
vertices[verticesIndex++] = tintTL;
vertices[verticesIndex++] = -1;
vertices[verticesIndex++] = -1;
colors[colorsIndex++] = tintTL;
}
// for (pathIndex = 0; pathIndex < length; pathIndex++)
// {
// point = path[pathIndex];
// // Transform the point.
// x = currentMatrix.getX(point.x, point.y);
// y = currentMatrix.getY(point.x, point.y);
// if (
// pathIndex > 0 &&
// pathIndex < length - 1 &&
// Math.abs(x - polygonCache[polygonCacheIndex - 2]) <= detail &&
// Math.abs(y - polygonCache[polygonCacheIndex - 1]) <= detail
// )
// {
// // Skip this point if it's too close to the previous point
// // and is not the first or last point in the path.
// continue;
// }
// polygonCache[polygonCacheIndex++] = x;
// polygonCache[polygonCacheIndex++] = y;
// vertices[verticesIndex++] = x;
// vertices[verticesIndex++] = y;
// vertices[verticesIndex++] = tintTL;
// vertices[verticesIndex++] = -1;
// vertices[verticesIndex++] = -1;
// }
// polygonIndexArray = Earcut(polygonCache);
submitterNode.batch(drawingContext, polygonIndexArray, vertices);
submitterNode.batch(drawingContext, polygonIndexArray, polygonCache, colors);
}
else
{
// If the tint colors are different,
// then we need to create a new vertex for each triangle.
// for (pathIndex = 0; pathIndex < length; pathIndex++)
// {
// point = path[pathIndex];
// // Transform the point.
// x = currentMatrix.getX(point.x, point.y);
// y = currentMatrix.getY(point.x, point.y);
// if (
// pathIndex > 0 &&
// pathIndex < length - 1 &&
// Math.abs(x - polygonCache[polygonCacheIndex - 2]) <= detail &&
// Math.abs(y - polygonCache[polygonCacheIndex - 1]) <= detail
// )
// {
// // Skip this point if it's too close to the previous point
// // and is not the first or last point in the path.
// continue;
// }
// polygonCache[polygonCacheIndex++] = x;
// polygonCache[polygonCacheIndex++] = y;
// }
// polygonIndexArray = Earcut(polygonCache);
var indexLength = polygonIndexArray.length;
var indexedTriangles = Array(indexLength);
var vertices = Array(indexLength * 2);
var verticesIndex = 0;
for (index = 0; index < indexLength; index += 3)
{
@ -182,9 +123,6 @@ var FillPath = new Class({
vertices[verticesIndex++] = x;
vertices[verticesIndex++] = y;
vertices[verticesIndex++] = tintTL;
vertices[verticesIndex++] = -1;
vertices[verticesIndex++] = -1;
// Vertex B
p = polygonIndexArray[index + 1] * 2;
@ -193,9 +131,6 @@ var FillPath = new Class({
vertices[verticesIndex++] = x;
vertices[verticesIndex++] = y;
vertices[verticesIndex++] = tintTR;
vertices[verticesIndex++] = -1;
vertices[verticesIndex++] = -1;
// Vertex C
p = polygonIndexArray[index + 2] * 2;
@ -204,9 +139,10 @@ var FillPath = new Class({
vertices[verticesIndex++] = x;
vertices[verticesIndex++] = y;
vertices[verticesIndex++] = tintBL;
vertices[verticesIndex++] = -1;
vertices[verticesIndex++] = -1;
colors[colorsIndex++] = tintTL;
colors[colorsIndex++] = tintTR;
colors[colorsIndex++] = tintBL;
// Add new indices for the triangle.
indexedTriangles[indexedTrianglesIndex++] = index + 0;
@ -214,7 +150,7 @@ var FillPath = new Class({
indexedTriangles[indexedTrianglesIndex++] = index + 2;
}
submitterNode.batch(drawingContext, indexedTriangles, vertices);
submitterNode.batch(drawingContext, indexedTriangles, vertices, colors);
}
this.onRunEnd(drawingContext);

View file

@ -100,11 +100,9 @@ var FillRect = new Class({
submitterNode.batch(
drawingContext,
this._indexedTriangles,
quad,
[
quad[0], quad[1], tintTL, -1, -1,
quad[2], quad[3], tintBL, -1, -1,
quad[4], quad[5], tintBR, -1, -1,
quad[6], quad[7], tintTR, -1, -1
tintTL, tintBL, tintBR, tintTR
]
);

View file

@ -70,19 +70,15 @@ var FillTri = new Class({
[
currentMatrix.getX(xA, yA),
currentMatrix.getY(xA, yA),
tintA,
-1,
-1,
currentMatrix.getX(xB, yB),
currentMatrix.getY(xB, yB),
tintB,
-1,
-1,
currentMatrix.getX(xC, yC),
currentMatrix.getY(xC, yC),
tintC,
-1,
-1
currentMatrix.getY(xC, yC)
],
[
tintA,
tintB,
tintC
]
);
}
@ -94,19 +90,15 @@ var FillTri = new Class({
[
xA,
yA,
tintA,
-1,
-1,
xB,
yB,
tintB,
-1,
-1,
xC,
yC,
tintC,
-1,
-1
yC
],
[
tintA,
tintB,
tintC
]
);
}

View file

@ -85,6 +85,9 @@ var StrokePath = new Class({
var vertexOffset = 0;
var vertexCount;
var colors = [];
var colorOffset = 0;
var dx, dy, tdx, tdy;
var detailSquared = detail * detail;
@ -120,6 +123,7 @@ var StrokePath = new Class({
}
}
// Compute and add the vertices for the line segment.
drawLineNode.run(
drawingContext,
currentMatrix,
@ -128,36 +132,19 @@ var StrokePath = new Class({
nextPoint.x,
nextPoint.y,
point.width / 2,
nextPoint.width / 2
nextPoint.width / 2,
vertices
);
var quad = drawLineNode.quad;
// The previous operation added 4 vertices.
vertexOffset += 8;
vertices[vertexOffset++] = quad.xTL;
vertices[vertexOffset++] = quad.yTL;
vertices[vertexOffset++] = tintTL;
vertices[vertexOffset++] = -1;
vertices[vertexOffset++] = -1;
vertexCount = vertexOffset / 2;
vertices[vertexOffset++] = quad.xBL;
vertices[vertexOffset++] = quad.yBL;
vertices[vertexOffset++] = tintBL;
vertices[vertexOffset++] = -1;
vertices[vertexOffset++] = -1;
vertices[vertexOffset++] = quad.xBR;
vertices[vertexOffset++] = quad.yBR;
vertices[vertexOffset++] = tintBR;
vertices[vertexOffset++] = -1;
vertices[vertexOffset++] = -1;
vertices[vertexOffset++] = quad.xTR;
vertices[vertexOffset++] = quad.yTR;
vertices[vertexOffset++] = tintTR;
vertices[vertexOffset++] = -1;
vertices[vertexOffset++] = -1;
vertexCount = vertexOffset / 5;
colors[colorOffset++] = tintTL;
colors[colorOffset++] = tintBL;
colors[colorOffset++] = tintBR;
colors[colorOffset++] = tintTR;
// Draw two triangles.
// The vertices are in the order: TL, BL, BR, TR
@ -201,7 +188,7 @@ var StrokePath = new Class({
}
}
submitterNode.batch(drawingContext, indices, vertices);
submitterNode.batch(drawingContext, indices, vertices, colors);
this.onRunEnd(drawingContext);
}