diff --git a/android/core/src/processing/core/PGL.java b/android/core/src/processing/core/PGL.java index f42f5905b..f2bc047ad 100644 --- a/android/core/src/processing/core/PGL.java +++ b/android/core/src/processing/core/PGL.java @@ -33,6 +33,8 @@ import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.opengles.*; + +import android.opengl.GLES20; import android.opengl.GLSurfaceView.EGLConfigChooser; import android.opengl.GLSurfaceView.Renderer; import android.opengl.GLSurfaceView; @@ -79,7 +81,7 @@ public class PGL { public static final int DEFAULT_TESS_INDICES = 32; /** Initial sizes for vertex cache used in PShape3D. */ - public static final int DEFAULT_VERTEX_CACHE_SIZE = 128; + public static final int DEFAULT_VERTEX_CACHE_SIZE = 512; /** Maximum lights by default is 8, the minimum defined by OpenGL. */ public static final int MAX_LIGHTS = 8; @@ -93,6 +95,9 @@ public class PGL { * vertices to have good room for vertex reuse. */ public static final int MAX_TESS_INDICES = 2 * MAX_TESS_VERTICES; + /** Maximum dimension of a texture used to hold font data. **/ + public static final int MAX_FONT_TEX_SIZE = 256; + public static final int LESS = GL10.GL_LESS; public static final int LESS_OR_EQUAL = GL10.GL_LEQUAL; public static final int COUNTER_CLOCKWISE = GL10.GL_CCW; @@ -817,14 +822,17 @@ public class PGL { } public void copyVertexBufferSubData(float[] data, int offset, int size, int mode) { + //GLES20.glBufferSubData(GL11.GL_ARRAY_BUFFER, offset * SIZEOF_FLOAT, size * SIZEOF_FLOAT, FloatBuffer.wrap(data, 0, size)); gl11.glBufferSubData(GL11.GL_ARRAY_BUFFER, offset * SIZEOF_FLOAT, size * SIZEOF_FLOAT, FloatBuffer.wrap(data, 0, size)); } public void setVertexFormat(int size, int offset) { + //GLES20.glVertexAttribPointer(vertAttribIdx, size, GL11.GL_FLOAT, false, stride, (just an int buffer with a single element contaning the offset?)); gl11.glVertexPointer(size, GL11.GL_FLOAT, 0, size * offset * SIZEOF_FLOAT); } public void setColorFormat(int size, int offset) { + //GLES20.glVertexAttribPointer(colorAttribIdx, size, GL11.GL_FLOAT, false, stride, null); gl11.glColorPointer(size, GL11.GL_FLOAT, 0, size * offset* SIZEOF_FLOAT); } diff --git a/android/core/src/processing/core/PGraphicsAndroid3D.java b/android/core/src/processing/core/PGraphicsAndroid3D.java index 626104ad0..554787fcc 100644 --- a/android/core/src/processing/core/PGraphicsAndroid3D.java +++ b/android/core/src/processing/core/PGraphicsAndroid3D.java @@ -3147,7 +3147,8 @@ public class PGraphicsAndroid3D extends PGraphics { textTex.textures[i].glID = 0; // To avoid finalization (texture objects were already deleted when context changed). textTex.textures[i] = null; } - textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize); + textTex = new PFontTexture(parent, textFont, PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize), + PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize)); textFont.setCache(this, textTex); } } diff --git a/android/core/src/processing/core/PTexture.java b/android/core/src/processing/core/PTexture.java index 6e80858d0..c8f169c56 100644 --- a/android/core/src/processing/core/PTexture.java +++ b/android/core/src/processing/core/PTexture.java @@ -783,9 +783,18 @@ public class PTexture implements PConstants { pgl.initTex(glTarget, glFormat, glWidth, glHeight); // Once OpenGL knows the size of the new texture, we make sure it doesn't - // contain any garbage in the region of interest (0, 0, width, height): - int[] texels = new int[width * height]; - setTexels(texels, 0, 0, width, height); + // contain any garbage in the region of interest (0, 0, width, height): + // Doing in patches of 16x16 pixels to avoid creating a (potentially) + // very large transient array which in certain situations (memory- + // constrained android devices) might lead to an out-of-memory error. + int[] texels = new int[16 * 16]; + for (int y = 0; y < height + 16; y += 16) { + int h = PApplet.min(16, height - y); + for (int x = 0; x < width + 16; x += 16) { + int w = PApplet.min(16, width - x); + setTexels(texels, x, y, w, h); + } + } texels = null; pgl.unbindTexture(glTarget); diff --git a/java/libraries/opengl/src/processing/opengl/PGL.java b/java/libraries/opengl/src/processing/opengl/PGL.java index b3cbc82c6..c029f6ed9 100644 --- a/java/libraries/opengl/src/processing/opengl/PGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGL.java @@ -108,6 +108,9 @@ public class PGL { * vertices to have good room for vertex reuse. */ public static final int MAX_TESS_INDICES = 2 * MAX_TESS_VERTICES; + /** Maximum dimension of a texture used to hold font data. **/ + public static final int MAX_FONT_TEX_SIZE = 2048; + public static final int LESS = GL.GL_LESS; public static final int LESS_OR_EQUAL = GL.GL_LEQUAL; public static final int COUNTER_CLOCKWISE = GL.GL_CCW; diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index c846bbefc..3f7f4afa0 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -3146,7 +3146,8 @@ public class PGraphicsOpenGL extends PGraphics { protected void textLineImpl(char buffer[], int start, int stop, float x, float y) { textTex = (PFontTexture)textFont.getCache(pg); if (textTex == null) { - textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize); + textTex = new PFontTexture(parent, textFont, PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize), + PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize)); textFont.setCache(this, textTex); } else { if (!pgl.contextIsCurrent(textTex.context)) { diff --git a/java/libraries/opengl/src/processing/opengl/PTexture.java b/java/libraries/opengl/src/processing/opengl/PTexture.java index 19c5689ec..25fd5619c 100644 --- a/java/libraries/opengl/src/processing/opengl/PTexture.java +++ b/java/libraries/opengl/src/processing/opengl/PTexture.java @@ -788,9 +788,18 @@ public class PTexture implements PConstants { pgl.initTex(glTarget, glFormat, glWidth, glHeight); // Once OpenGL knows the size of the new texture, we make sure it doesn't - // contain any garbage in the region of interest (0, 0, width, height): - int[] texels = new int[width * height]; - setTexels(texels, 0, 0, width, height); + // contain any garbage in the region of interest (0, 0, width, height): + // Doing in patches of 16x16 pixels to avoid creating a (potentially) + // very large transient array which in certain situations (memory- + // constrained android devices) might lead to an out-of-memory error. + int[] texels = new int[16 * 16]; + for (int y = 0; y < height + 16; y += 16) { + int h = PApplet.min(16, height - y); + for (int x = 0; x < width + 16; x += 16) { + int w = PApplet.min(16, width - x); + setTexels(texels, x, y, w, h); + } + } texels = null; pgl.unbindTexture(glTarget);