Using Vertex Buffer Object method to speed up the rendering

This commit is contained in:
Andrea Cavalli 2017-09-23 23:23:26 +02:00
parent 30512b143d
commit 209109d75c
12 changed files with 230 additions and 116 deletions

View File

@ -58,15 +58,15 @@ public class Main {
if (arg.contains("headless")) {
Utils.headlessOverride = true;
}
if (arg.contains("console-8")) {
if (arg.contains("headless-8")) {
Utils.headlessOverride = true;
Utils.forceEngine = "console-8";
}
if (arg.contains("console-256")) {
if (arg.contains("headless-256")) {
Utils.headlessOverride = true;
Utils.forceEngine = "console-256";
}
if (arg.contains("console-24bit")) {
if (arg.contains("headless-24bit")) {
Utils.headlessOverride = true;
Utils.forceEngine = "console-24bit";
}
@ -81,7 +81,8 @@ public class Main {
Utils.msDosMode = true;
}
}
DisplayManager.setBrightness(0.5f);
DisplayManager.preInitialization();
DisplayManager.setBrightness(0.2f);
Keyboard.startKeyboard();
}

View File

@ -1,6 +1,9 @@
package org.warp.picalculator.gui;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.Semaphore;
import org.warp.picalculator.Main;
@ -26,21 +29,33 @@ public final class DisplayManager implements RenderingLoop {
public static DisplayManager INSTANCE;
private static float brightness;
public static final GraphicEngine engine = chooseGraphicEngine();
public static final boolean supportsPauses = engine.doesRefreshPauses();
public static final GraphicEngine engine;
public static final boolean supportsPauses;
public static Renderer renderer;
public static Skin guiSkin;
public static BinaryFont[] fonts;
public static String error = null;
public String[] errorStackTrace = null;
public final static int[] glyphsHeight = new int[] { 9, 6, 12, 9 };
public static String error;
public String[] errorStackTrace;
public final static int[] glyphsHeight;
public static Screen screen;
public static String displayDebugString = "";
public static ObjectArrayList<GUIErrorMessage> errorMessages = new ObjectArrayList<>();
public static String displayDebugString;
public static ObjectArrayList<GUIErrorMessage> errorMessages;
static {
engine = chooseGraphicEngine();
supportsPauses = engine.doesRefreshPauses();
glyphsHeight = new int[] { 9, 6, 12, 9 };
displayDebugString = "";
errorMessages = new ObjectArrayList<>();
}
public static void preInitialization() {
//Nothing. When called for the first time the static methods will be loaded
}
public DisplayManager(Screen screen) {
setScreen(screen);
INSTANCE = this;
@ -236,7 +251,8 @@ public final class DisplayManager implements RenderingLoop {
private void draw_init() {
if (engine.supportsFontRegistering()) {
for (BinaryFont f : engine.getRegisteredFonts()) {
List<BinaryFont> fontsIterator = engine.getRegisteredFonts();
for (BinaryFont f : fontsIterator) {
if (!f.isInitialized()) {
f.initialize(engine);
}

View File

@ -28,7 +28,7 @@ public class GraphicUtils {
RAD = (float) Math.PI / 180.0f;
DEG = 180.0f / (float) Math.PI;
SIN_BITS = 12;
SIN_BITS = 8;
SIN_MASK = ~(-1 << SIN_BITS);
SIN_COUNT = SIN_MASK + 1;

View File

@ -1,7 +1,8 @@
package org.warp.picalculator.gui.graphicengine;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
public interface GraphicEngine {
@ -43,7 +44,11 @@ public interface GraphicEngine {
public boolean doesRefreshPauses();
public boolean supportsFontRegistering();
public default boolean supportsFontRegistering() {
return false;
}
public ArrayList<BinaryFont> getRegisteredFonts();
public default List<BinaryFont> getRegisteredFonts() {
return null;
}
}

View File

@ -193,16 +193,4 @@ public class CPUEngine implements GraphicEngine {
public boolean doesRefreshPauses() {
return true;
}
@Override
public boolean supportsFontRegistering() {
// TODO Auto-generated method stub
return false;
}
@Override
public ArrayList<BinaryFont> getRegisteredFonts() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -2,6 +2,10 @@ package org.warp.picalculator.gui.graphicengine.gpu;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;
import org.warp.picalculator.Main;
import org.warp.picalculator.Utils;
@ -12,7 +16,7 @@ import org.warp.picalculator.gui.graphicengine.Skin;
import com.jogamp.opengl.GLProfile;
public class GPUEngine implements org.warp.picalculator.gui.graphicengine.GraphicEngine {
public class GPUEngine implements GraphicEngine {
private volatile boolean initialized = false;
private volatile boolean created = false;
@ -20,7 +24,7 @@ public class GPUEngine implements org.warp.picalculator.gui.graphicengine.Graphi
private RenderingLoop d;
private GPURenderer r;
int[] size = new int[] { Main.screenSize[0], Main.screenSize[1] };
private final ArrayList<BinaryFont> registeredFonts = new ArrayList<BinaryFont>();
private final CopyOnWriteArrayList<BinaryFont> registeredFonts = new CopyOnWriteArrayList<BinaryFont>();
@Override
public int[] getSize() {
@ -165,7 +169,7 @@ public class GPUEngine implements org.warp.picalculator.gui.graphicengine.Graphi
}
@Override
public ArrayList<BinaryFont> getRegisteredFonts() {
public CopyOnWriteArrayList<BinaryFont> getRegisteredFonts() {
return registeredFonts;
}

View File

@ -27,13 +27,16 @@ public class GPURenderer implements Renderer {
public static GL2ES1 gl;
private static final int ELEMENT_VERTICES_COUNT = 6;
private static final int ELEMENTS_MAX_COUNT_PER_BUFFER = 128;
private final DeallocationHelper deallocationHelper = new DeallocationHelper();
FloatBuffer fbVertices;
FloatBuffer txVertices;
FloatBuffer colVertices;
int fbElements;
float[] currentColor = new float[16];
float[] currentColor = new float[24];
float[] currentClearColorARGBf = new float[] { 1f, 197f / 255f, 194f / 255f, 175f / 255f };
boolean currentTexEnabled;
Texture currentTex;
@ -47,17 +50,42 @@ public class GPURenderer implements Renderer {
final float red = (r) / 255f;
final float gre = (gg) / 255f;
final float blu = (b) / 255f;
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
//currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
currentColor = new float[] {
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
}; //OK
}
@Override
public void glColor3f(float red, float gre, float blu) {
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
// currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
currentColor = new float[] {
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
red, gre, blu, 1.0f,
};//OK
}
@Override
public void glColor4f(float red, float gre, float blu, float alp) {
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
// currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
currentColor = new float[] {
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
};//ok
}
@Override
@ -89,7 +117,15 @@ public class GPURenderer implements Renderer {
final float gre = (g) / 255f;
final float blu = (b) / 255f;
final float alp = (a) / 255f;
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
//currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
currentColor = new float[] {
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
red, gre, blu, alp,
};//OK
}
@Override
@ -125,8 +161,37 @@ public class GPURenderer implements Renderer {
uvX /= currentTexWidth;
uvHeight /= currentTexHeight;
uvY = 1 - uvY / currentTexHeight - uvHeight;
final float[] vertices = { x, y, 0.0f, x, y + height, 0.0f, x + width, y, 0.0f, x + width, y + height, 0.0f, };
final float[] tex_vertices = { uvX, uvY + uvHeight, uvX, uvY, uvX + uvWidth, uvY + uvHeight, uvX + uvWidth, uvY, };
// final float[] vertices = { x, y, 0.0f, x, y + height, 0.0f, x + width, y, 0.0f, x + width, y + height, 0.0f, };
// final float[] tex_vertices = { uvX, uvY + uvHeight, uvX, uvY, uvX + uvWidth, uvY + uvHeight, uvX + uvWidth, uvY, };
//V0 x, y, 0.0f
//V1 x, y + height, 0.0f
//V2 x + width, y, 0.0f
//V3 x + width, y + height, 0.0f
//NV0 = V1
//NV1 = V3
//NV2 = V0
//NV3 = V0
//NV4 = V3
//NV5 = V2
final float[] vertices = {
x, y + height, 0.0f,
x + width, y + height, 0.0f,
x, y, 0.0f,
x, y, 0.0f,
x + width, y + height, 0.0f,
x + width, y, 0.0f
};
final float[] tex_vertices = {
uvX, uvY,
uvX + uvWidth, uvY,
uvX, uvY + uvHeight,
uvX, uvY + uvHeight,
uvX + uvWidth, uvY,
uvX + uvWidth, uvY + uvHeight
};
fbElements++;
fbVertices.put(vertices);
txVertices.put(tex_vertices);
@ -136,8 +201,37 @@ public class GPURenderer implements Renderer {
@Override
public void glFillColor(float x0, float y0, float w1, float h1) {
disableTexture();
final float[] vertices = { x0, y0, 0.0f, x0, y0 + h1, 0.0f, x0 + w1, y0, 0.0f, x0 + w1, y0 + h1, 0.0f, };
final float[] tex_vertices = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, };
// final float[] vertices = { x0, y0, 0.0f, x0, y0 + h1, 0.0f, x0 + w1, y0, 0.0f, x0 + w1, y0 + h1, 0.0f, };
// final float[] tex_vertices = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, };
//V0 x0, y0, 0.0f
//V1 x0, y0 + h1, 0.0f
//V2 x0 + w1, y0, 0.0f
//V3 x0 + w1, y0 + h1, 0.0f
//NV0 = V1
//NV1 = V3
//NV2 = V0
//NV3 = V0
//NV4 = V3
//NV5 = V2
final float[] vertices = {
x0, y0 + h1, 0.0f,
x0 + w1, y0 + h1, 0.0f,
x0, y0, 0.0f,
x0, y0, 0.0f,
x0 + w1, y0 + h1, 0.0f,
x0 + w1, y0, 0.0f,
};
final float[] tex_vertices = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
};
fbElements++;
fbVertices.put(vertices);
txVertices.put(tex_vertices);
@ -215,37 +309,39 @@ public class GPURenderer implements Renderer {
return tex;
}
@Override
public void glClearSkin() {
if (currentTex != null) {
currentTex = null;
endDrawCycle();
startDrawCycle();
}
}
public void startDrawCycle() {
public void startDrawCycle(boolean first) {
if (fbVertices == null) {
fbVertices = Buffers.newDirectFloatBuffer(3 * 4);
txVertices = Buffers.newDirectFloatBuffer(2 * 4);
colVertices = Buffers.newDirectFloatBuffer(4 * 4);
fbVertices = Buffers.newDirectFloatBuffer(3 * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER);
txVertices = Buffers.newDirectFloatBuffer(2 * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER);
colVertices = Buffers.newDirectFloatBuffer(4 * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER);
}
fbElements = 0;
if (first || fbVertices == null || cycleEnded) {
fbElements = 0;
}
cycleEnded = false;
}
private boolean precTexEnabled;
private Texture precTex;
private boolean cycleEnded = true;
public void endDrawCycle() {
fbVertices.rewind();
txVertices.rewind();
colVertices.rewind();
gl.glColorPointer(4, GL.GL_FLOAT, 0, colVertices);
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, txVertices);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, fbVertices);
if (precTexEnabled != currentTexEnabled | precTex != currentTex) {
public void updateDrawCycle() {
updateDrawCycle(false, false);
}
public void updateDrawCycle(boolean first, boolean last) {
final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex;
final boolean changeRequired = last || fbElements >= ELEMENTS_MAX_COUNT_PER_BUFFER;
if (first) {
startDrawCycle(true);
}
if (textureChange) {
if (!first && fbElements > 0) {
endDrawCycle();
if (!last) {
startDrawCycle(true);
}
}
precTexEnabled = currentTexEnabled;
precTex = currentTex;
if (currentTexEnabled) {
@ -254,9 +350,34 @@ public class GPURenderer implements Renderer {
} else {
gl.glDisable(GL.GL_TEXTURE_2D);
}
} else if (!first) {
if (fbElements > 0 && changeRequired) {
endDrawCycle();
if (!last) {
startDrawCycle(false);
}
}
}
}
public void endDrawCycle() {
fbVertices.limit(fbVertices.position());
txVertices.limit(txVertices.position());
colVertices.limit(colVertices.position());
fbVertices.rewind();
txVertices.rewind();
colVertices.rewind();
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, fbElements * 4);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, fbVertices);
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, txVertices);
gl.glColorPointer(4, GL.GL_FLOAT, 0, colVertices);
fbVertices.limit(fbVertices.capacity());
txVertices.limit(txVertices.capacity());
colVertices.limit(colVertices.capacity());
gl.glDrawArrays(GL.GL_TRIANGLES, 0, fbElements * ELEMENT_VERTICES_COUNT);
//gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, fbElements * ELEMENT_VERTICES_COUNT);
cycleEnded = true;
// deleteBuffer(fbVertices);
// deleteBuffer(txVertices);
@ -272,22 +393,28 @@ public class GPURenderer implements Renderer {
}
}
@Override
public void glClearSkin() {
if (currentTex != null) {
currentTex = null;
updateDrawCycle();
}
}
void disableTexture() {
endDrawCycle();
startDrawCycle();
currentTexEnabled = false;
updateDrawCycle();
}
void enableTexture() {
endDrawCycle();
startDrawCycle();
currentTexEnabled = true;
updateDrawCycle();
}
void useTexture(Texture t, float w, float h) {
enableTexture();
currentTex = t;
currentTexWidth = w;
currentTexHeight = h;
enableTexture();
}
}

View File

@ -342,11 +342,11 @@ class NEWTWindow implements GLEventListener {
gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
renderer.startDrawCycle();
renderer.updateDrawCycle(true, false);
disp.repaint();
renderer.endDrawCycle();
renderer.updateDrawCycle(false, true);
GPURenderer.gl = null;

View File

@ -330,14 +330,4 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng
public boolean doesRefreshPauses() {
return true;
}
@Override
public boolean supportsFontRegistering() {
return false;
}
@Override
public ArrayList<BinaryFont> getRegisteredFonts() {
return null;
}
}

View File

@ -280,16 +280,4 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin
public boolean doesRefreshPauses() {
return true;
}
@Override
public boolean supportsFontRegistering() {
// TODO Auto-generated method stub
return false;
}
@Override
public ArrayList<BinaryFont> getRegisteredFonts() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -281,16 +281,4 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine.
public boolean doesRefreshPauses() {
return true;
}
@Override
public boolean supportsFontRegistering() {
// TODO Auto-generated method stub
return false;
}
@Override
public ArrayList<BinaryFont> getRegisteredFonts() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -82,14 +82,18 @@ public class MathParser {
boolean lastLoopDidSomething;
Function lastElement;
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: ");
for (Function f : functionsList) {
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, f.toString());
if (Utils.debugOn) {
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: ");
for (Function f : functionsList) {
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, f.toString());
}
Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MAX);
}
Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MAX);
for (MathParserStep step : steps) {
Utils.out.println(2, "Stack fixing step \""+step.getStepName()+"\"");
if (Utils.debugOn) {
Utils.out.println(2, "Stack fixing step \""+step.getStepName()+"\"");
}
int stepQty = step.requiresReversedIteration()?-1:1, initialIndex = step.requiresReversedIteration()?functionsList.size()-1:0;
do {
lastLoopDidSomething = false;
@ -107,11 +111,14 @@ public class MathParser {
curIndex.i += stepQty;
}
} while (lastLoopDidSomething);
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: ");
for (Function f : functionsList) {
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, f.toString());
if (Utils.debugOn) {
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: ");
for (Function f : functionsList) {
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, f.toString());
}
Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MAX);
}
Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MAX);
}
// //Phase 4