From 430027cd788e3c387cf42742a0ccb20df73121e4 Mon Sep 17 00:00:00 2001 From: dayllenger Date: Fri, 26 Jan 2018 01:11:32 +0300 Subject: [PATCH 1/2] use Appender for GL queue buffer --- src/dlangui/graphics/glsupport.d | 133 ++++++++++++++----------------- src/dlangui/widgets/editors.d | 1 + 2 files changed, 61 insertions(+), 73 deletions(-) diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index 37d6dce9..019ffdc2 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -866,10 +866,10 @@ final class GLSupport { static if (SUPPORT_LEGACY_OPENGL) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, cast(void*)_queue._vertices.ptr); - glColorPointer(4, GL_FLOAT, 0, cast(void*)_queue._colors.ptr); + glVertexPointer(3, GL_FLOAT, 0, cast(void*)_queue._vertices.data.ptr); + glColorPointer(4, GL_FLOAT, 0, cast(void*)_queue._colors.data.ptr); - checkgl!glDrawElements(GL_LINES, cast(int)length, GL_UNSIGNED_INT, cast(void*)(_queue._indices[start .. start + length].ptr)); + checkgl!glDrawElements(GL_LINES, cast(int)length, GL_UNSIGNED_INT, cast(void*)(_queue._indices.data[start .. start + length].ptr)); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); @@ -887,10 +887,10 @@ final class GLSupport { static if (SUPPORT_LEGACY_OPENGL) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, cast(void*)_queue._vertices.ptr); - glColorPointer(4, GL_FLOAT, 0, cast(void*)_queue._colors.ptr); + glVertexPointer(3, GL_FLOAT, 0, cast(void*)_queue._vertices.data.ptr); + glColorPointer(4, GL_FLOAT, 0, cast(void*)_queue._colors.data.ptr); - checkgl!glDrawElements(GL_TRIANGLES, cast(int)length, GL_UNSIGNED_INT, cast(void*)(_queue._indices[start .. start + length].ptr)); + checkgl!glDrawElements(GL_TRIANGLES, cast(int)length, GL_UNSIGNED_INT, cast(void*)(_queue._indices.data[start .. start + length].ptr)); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); @@ -913,11 +913,11 @@ final class GLSupport { glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, cast(void*)_queue._vertices.ptr); - glTexCoordPointer(2, GL_FLOAT, 0, cast(void*)_queue._texCoords.ptr); - glColorPointer(4, GL_FLOAT, 0, cast(void*)_queue._colors.ptr); + glVertexPointer(3, GL_FLOAT, 0, cast(void*)_queue._vertices.data.ptr); + glTexCoordPointer(2, GL_FLOAT, 0, cast(void*)_queue._texCoords.data.ptr); + glColorPointer(4, GL_FLOAT, 0, cast(void*)_queue._colors.data.ptr); - checkgl!glDrawElements(GL_TRIANGLES, cast(int)length, GL_UNSIGNED_INT, cast(void*)(_queue._indices[start .. start + length].ptr)); + checkgl!glDrawElements(GL_TRIANGLES, cast(int)length, GL_UNSIGNED_INT, cast(void*)(_queue._indices.data[start .. start + length].ptr)); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); @@ -1464,16 +1464,16 @@ private final class OpenGLQueue { int start; } + import std.array: Appender; // a big buffer - float[] _vertices; - float[] _colors; - float[] _texCoords; - int[] _indices; - + Appender!(float[]) _vertices; + Appender!(float[]) _colors; + Appender!(float[]) _texCoords; + Appender!(int[]) _indices; /// draw all void flush() { - glSupport.fillBuffers(_vertices, _colors, _texCoords, _indices); + glSupport.fillBuffers(_vertices.data, _colors.data, _texCoords.data, _indices.data); foreach(b; batches) { switch(b.type) with(OpenGLBatch.BatchType) { @@ -1484,18 +1484,14 @@ private final class OpenGLQueue { default: break; } } - //Log.d(batches.length, " ", _vertices.length, " ", _colors.length, " ", _texCoords.length, " ", _indices.length); + //Log.d(batches.length, " ", _vertices.data.length, " ", _colors.data.length, " ", _texCoords.data.length, " ", _indices.data.length); glSupport.destroyBuffers(); destroy(batches); - destroy(_vertices); - destroy(_colors); - destroy(_texCoords); - destroy(_indices); batches = null; - _vertices = null; - _colors = null; - _texCoords = null; - _indices = null; + _vertices.clear; + _colors.clear; + _texCoords.clear; + _indices.clear; } static immutable float Z_2D = -2.0f; @@ -1537,9 +1533,8 @@ private final class OpenGLQueue { float[2 * 4] texCoords = [srcx0,srcy0, srcx0,srcy1, srcx1,srcy0, srcx1,srcy1]; - int[] indices = makeRectangleIndicesArray(cast(int)_vertices.length / 3); - - mixin(calcLengthAndAppendAllToBuffer); + enum verts = 4; + mixin(add); } /// add solid rectangle to queue @@ -1571,9 +1566,8 @@ private final class OpenGLQueue { // fill texture coords buffer with zeros float[2 * 4] texCoords = 0; - int[] indices = makeRectangleIndicesArray(cast(int)_vertices.length / 3); - - mixin(calcLengthAndAppendAllToBuffer); + enum verts = 4; + mixin(add); } /// add triangle to queue @@ -1601,9 +1595,8 @@ private final class OpenGLQueue { // fill texture coords buffer with zeros float[2 * 3] texCoords = 0; - int[] indices = makeTriangleIndicesArray(cast(int)_vertices.length / 3); - - mixin(calcLengthAndAppendAllToBuffer); + enum verts = 3; + mixin(add); } /// add line to queue @@ -1629,48 +1622,42 @@ private final class OpenGLQueue { // fill texture coords buffer with zeros float[2 * 2] texCoords = 0; - int[] indices = makeLineIndicesArray(cast(int)_vertices.length / 3); - - mixin(calcLengthAndAppendAllToBuffer); + enum verts = 2; + mixin(add); } - enum calcLengthAndAppendAllToBuffer = q{ + enum add = q{ + int offset = cast(int)_vertices.data.length / 3; + static if(verts == 4) { + // make indices for rectangle (2 triangles == 6 vertexes per rect) + int[6] indices = [ + offset + 0, + offset + 1, + offset + 2, + offset + 1, + offset + 2, + offset + 3 ]; + } else + static if(verts == 3) { + // make indices for triangles + int[3] indices = [ + offset + 0, + offset + 1, + offset + 2 ]; + } else + static if(verts == 2) { + // make indices for lines + int[2] indices = [ + offset + 0, + offset + 1 ]; + } else + static assert(0); + batches[$-1].length += cast(int)indices.length; - _vertices ~= vertices; - _colors ~= colors; - _texCoords ~= texCoords; - _indices ~= indices; + _vertices ~= cast(float[])vertices; + _colors ~= cast(float[])colors; + _texCoords ~= cast(float[])texCoords; + _indices ~= cast(int[])indices; }; - - /// make indices for rectangle (2 triangles == 6 vertexes per rect) - int[6] makeRectangleIndicesArray(int offset) pure nothrow { - int[6] indices; - indices[0] = offset + 0; - indices[1] = offset + 1; - indices[2] = offset + 2; - indices[3] = offset + 1; - indices[4] = offset + 2; - indices[5] = offset + 3; - - return indices; - } - - /// make indices for triangles - int[3] makeTriangleIndicesArray(int offset) pure nothrow { - int[3] indices; - indices[0] = offset + 0; - indices[1] = offset + 1; - indices[2] = offset + 2; - return indices; - } - - /// make indices for lines - int[2] makeLineIndicesArray(int offset) pure nothrow { - int[2] indices; - indices[0] = offset + 0; - indices[1] = offset + 1; - - return indices; - } } diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d index 5236eaf4..28e83c24 100644 --- a/src/dlangui/widgets/editors.d +++ b/src/dlangui/widgets/editors.d @@ -37,6 +37,7 @@ import dlangui.graphics.colors; public import dlangui.core.editable; import std.algorithm; +import std.conv : to; import dlangui.core.streams; /// Modified state change listener From 66468a216798f5ce24ac3776b421afe5b8356b2c Mon Sep 17 00:00:00 2001 From: dayllenger Date: Sun, 28 Jan 2018 18:40:27 +0300 Subject: [PATCH 2/2] use appender also for batches --- src/dlangui/graphics/glsupport.d | 68 ++++++++++++++++---------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index 019ffdc2..7f6ee6a8 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -1445,8 +1445,6 @@ GLenum primitiveTypeToGL(PrimitiveType type) { /// OpenGL GUI rendering queue. It collects gui draw calls, fills a big buffer for vertex data and draws everything private final class OpenGLQueue { - OpenGLBatch[] batches; - /// OpenGL batch structure - to draw several triangles in single OpenGL call private struct OpenGLBatch { @@ -1465,6 +1463,7 @@ private final class OpenGLQueue { } import std.array: Appender; + Appender!(OpenGLBatch[]) batches; // a big buffer Appender!(float[]) _vertices; Appender!(float[]) _colors; @@ -1474,7 +1473,7 @@ private final class OpenGLQueue { /// draw all void flush() { glSupport.fillBuffers(_vertices.data, _colors.data, _texCoords.data, _indices.data); - foreach(b; batches) { + foreach(b; batches.data) { switch(b.type) with(OpenGLBatch.BatchType) { case Line: glSupport.drawLines(b.length, b.start); break; @@ -1486,8 +1485,7 @@ private final class OpenGLQueue { } //Log.d(batches.length, " ", _vertices.data.length, " ", _colors.data.length, " ", _texCoords.data.length, " ", _indices.data.length); glSupport.destroyBuffers(); - destroy(batches); - batches = null; + batches.clear; _vertices.clear; _colors.clear; _texCoords.clear; @@ -1498,22 +1496,23 @@ private final class OpenGLQueue { /// add textured rectangle to queue void addTexturedRect(Tex2D texture, int textureDx, int textureDy, uint color1, uint color2, uint color3, uint color4, Rect srcrc, Rect dstrc, bool linear) { - if (batches is null - || batches[$-1].type != OpenGLBatch.BatchType.TexturedRect - || batches[$-1].texture.ID != texture.ID - || batches[$-1].textureLinear != linear) + if (batches.data.length == 0 + || batches.data[$-1].type != OpenGLBatch.BatchType.TexturedRect + || batches.data[$-1].texture.ID != texture.ID + || batches.data[$-1].textureLinear != linear) { batches ~= OpenGLBatch(); - batches[$-1].type = OpenGLBatch.BatchType.TexturedRect; - batches[$-1].texture = texture; - batches[$-1].textureDx = textureDx; - batches[$-1].textureDy = textureDy; - batches[$-1].textureLinear = linear; - if(batches.length > 1) - batches[$-1].start = batches[$-2].start + batches[$-2].length; + batches.data[$-1].type = OpenGLBatch.BatchType.TexturedRect; + batches.data[$-1].texture = texture; + batches.data[$-1].textureDx = textureDx; + batches.data[$-1].textureDy = textureDy; + batches.data[$-1].textureLinear = linear; + if(batches.data.length > 1) + batches.data[$-1].start = batches.data[$-2].start + batches.data[$-2].length; } - float[] colors = convertColors([color1, color2, color3, color4]); + uint[4] colorsARGB = [color1, color2, color3, color4]; + float[] colors = convertColors(colorsARGB); float dstx0 = cast(float)dstrc.left; float dsty0 = cast(float)(glSupport.currentFBO ? dstrc.top : (glSupport.bufferDy - dstrc.top)); @@ -1544,14 +1543,15 @@ private final class OpenGLQueue { /// add gradient rectangle to queue void addGradientRect(Rect rc, uint color1, uint color2, uint color3, uint color4) { - if (batches is null || batches[$-1].type != OpenGLBatch.BatchType.Rect) { + if (batches.data.length == 0 || batches.data[$-1].type != OpenGLBatch.BatchType.Rect) { batches ~= OpenGLBatch(); - batches[$-1].type = OpenGLBatch.BatchType.Rect; - if(batches.length > 1) - batches[$-1].start = batches[$-2].start + batches[$-2].length; + batches.data[$-1].type = OpenGLBatch.BatchType.Rect; + if(batches.data.length > 1) + batches.data[$-1].start = batches.data[$-2].start + batches.data[$-2].length; } - float[] colors = convertColors([color1, color2, color3, color4]); + uint[4] colorsARGB = [color1, color2, color3, color4]; + float[] colors = convertColors(colorsARGB); float x0 = cast(float)(rc.left); float y0 = cast(float)(glSupport.currentFBO ? rc.top : (glSupport.bufferDy - rc.top)); @@ -1572,14 +1572,15 @@ private final class OpenGLQueue { /// add triangle to queue void addTriangle(PointF p1, PointF p2, PointF p3, uint color1, uint color2, uint color3) { - if (batches is null || batches[$-1].type != OpenGLBatch.BatchType.Triangle) { + if (batches.data.length == 0 || batches.data[$-1].type != OpenGLBatch.BatchType.Triangle) { batches ~= OpenGLBatch(); - batches[$-1].type = OpenGLBatch.BatchType.Triangle; - if(batches.length > 1) - batches[$-1].start = batches[$-2].start + batches[$-2].length; + batches.data[$-1].type = OpenGLBatch.BatchType.Triangle; + if(batches.data.length > 1) + batches.data[$-1].start = batches.data[$-2].start + batches.data[$-2].length; } - float[] colors = convertColors([color1, color2, color3]); + uint[3] colorsARGB = [color1, color2, color3]; + float[] colors = convertColors(colorsARGB); float x0 = p1.x; float y0 = glSupport.currentFBO ? p1.y : (glSupport.bufferDy - p1.y); @@ -1602,14 +1603,15 @@ private final class OpenGLQueue { /// add line to queue /// rc is a line (left, top) - (right, bottom) void addLine(Rect rc, uint color1, uint color2) { - if (batches is null || batches[$-1].type != OpenGLBatch.BatchType.Line) { + if (batches.data.length == 0 || batches.data[$-1].type != OpenGLBatch.BatchType.Line) { batches ~= OpenGLBatch(); - batches[$-1].type = OpenGLBatch.BatchType.Line; - if(batches.length > 1) - batches[$-1].start = batches[$-2].start + batches[$-2].length; + batches.data[$-1].type = OpenGLBatch.BatchType.Line; + if(batches.data.length > 1) + batches.data[$-1].start = batches.data[$-2].start + batches.data[$-2].length; } - float[] colors = convertColors([color1, color2]); + uint[2] colorsARGB = [color1, color2]; + float[] colors = convertColors(colorsARGB); float x0 = cast(float)(rc.left); float y0 = cast(float)(glSupport.currentFBO ? rc.top : (glSupport.bufferDy - rc.top)); @@ -1653,7 +1655,7 @@ private final class OpenGLQueue { } else static assert(0); - batches[$-1].length += cast(int)indices.length; + batches.data[$-1].length += cast(int)indices.length; _vertices ~= cast(float[])vertices; _colors ~= cast(float[])colors;