Skip to content

Commit 614cb2d

Browse files
committed
Merge remote-tracking branch 'upstream/master' into iosbackend
# Conflicts: # jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java # jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
2 parents b00143c + 9f5b4bb commit 614cb2d

6 files changed

Lines changed: 255 additions & 91 deletions

File tree

jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java

Lines changed: 112 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,62 @@ private static int getLimitCount(Buffer buffer, int elementSize) {
8181
return buffer.limit() / elementSize;
8282
}
8383

84+
private static int getRemainingBytes(ByteBuffer buffer) {
85+
checkLimit(buffer);
86+
return buffer.remaining();
87+
}
88+
89+
private static int getRemainingBytes(IntBuffer buffer) {
90+
checkLimit(buffer);
91+
return checkedLongToInt((long) buffer.remaining() * 4L, "buffer size");
92+
}
93+
94+
private static int checkedLongToInt(long value, String name) {
95+
if (value < 0 || value > Integer.MAX_VALUE) {
96+
throw new RendererException(name + " exceeds the range supported by Android GLES bindings: " + value);
97+
}
98+
return (int) value;
99+
}
100+
101+
private static long getSyncHandle(Object sync) {
102+
if (!(sync instanceof Long)) {
103+
throw new IllegalArgumentException("Expected a sync object returned by glFenceSync");
104+
}
105+
return (Long) sync;
106+
}
107+
108+
private static int getBooleanValueCount(int pname) {
109+
if (pname == GLES20.GL_COLOR_WRITEMASK) {
110+
return 4;
111+
}
112+
return 1;
113+
}
114+
115+
private static String joinShaderSource(String[] strings, IntBuffer lengths) {
116+
StringBuilder builder = new StringBuilder();
117+
int lengthPosition = lengths == null ? 0 : lengths.position();
118+
119+
for (int i = 0; i < strings.length; i++) {
120+
String source = strings[i];
121+
if (lengths != null) {
122+
int length = lengths.get(lengthPosition + i);
123+
if (length >= 0 && length < source.length()) {
124+
builder.append(source, 0, length);
125+
continue;
126+
}
127+
}
128+
builder.append(source);
129+
}
130+
131+
return builder.toString();
132+
}
133+
134+
private static void unmapBufferAfterRead(int target) {
135+
if (!GLES30.glUnmapBuffer(target)) {
136+
throw new RendererException("Mapped buffer data became corrupted while reading");
137+
}
138+
}
139+
84140
private static void checkLimit(Buffer buffer) {
85141
if (buffer == null) {
86142
return;
@@ -148,32 +204,57 @@ public void glBufferData(int target, ByteBuffer data, int usage) {
148204

149205
@Override
150206
public void glBufferData(int target, long dataSize, int usage) {
151-
GLES20.glBufferData(target, (int) dataSize, null, usage);
207+
GLES20.glBufferData(target, checkedLongToInt(dataSize, "data size"), null, usage);
152208
}
153209

154210
@Override
155211
public void glBufferSubData(int target, long offset, FloatBuffer data) {
156-
GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data);
212+
GLES20.glBufferSubData(target, checkedLongToInt(offset, "offset"), getLimitBytes(data), data);
157213
}
158214

159215
@Override
160216
public void glBufferSubData(int target, long offset, ShortBuffer data) {
161-
GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data);
217+
GLES20.glBufferSubData(target, checkedLongToInt(offset, "offset"), getLimitBytes(data), data);
162218
}
163219

164220
@Override
165221
public void glBufferSubData(int target, long offset, ByteBuffer data) {
166-
GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data);
222+
GLES20.glBufferSubData(target, checkedLongToInt(offset, "offset"), getLimitBytes(data), data);
167223
}
168224

169225
@Override
170226
public void glGetBufferSubData(int target, long offset, ByteBuffer data) {
171-
throw new UnsupportedOperationException("OpenGL ES 2 does not support glGetBufferSubData");
227+
int byteCount = getRemainingBytes(data);
228+
Buffer mapped = GLES30.glMapBufferRange(target, checkedLongToInt(offset, "offset"), byteCount, GLES30.GL_MAP_READ_BIT);
229+
if (!(mapped instanceof ByteBuffer)) {
230+
throw new RendererException("Unable to map buffer for reading");
231+
}
232+
233+
try {
234+
ByteBuffer source = (ByteBuffer) mapped;
235+
source.limit(byteCount);
236+
data.duplicate().put(source);
237+
} finally {
238+
unmapBufferAfterRead(target);
239+
}
172240
}
173241

174242
@Override
175243
public void glGetBufferSubData(int target, long offset, IntBuffer data) {
176-
throw new UnsupportedOperationException("OpenGL ES 2 does not support glGetBufferSubData");
244+
int byteCount = getRemainingBytes(data);
245+
Buffer mapped = GLES30.glMapBufferRange(target, checkedLongToInt(offset, "offset"), byteCount, GLES30.GL_MAP_READ_BIT);
246+
if (!(mapped instanceof ByteBuffer)) {
247+
throw new RendererException("Unable to map buffer for reading");
248+
}
249+
250+
try {
251+
ByteBuffer source = (ByteBuffer) mapped;
252+
source.limit(byteCount);
253+
source.order(data.order());
254+
data.duplicate().put(source.asIntBuffer());
255+
} finally {
256+
unmapBufferAfterRead(target);
257+
}
177258
}
178259

179260
@Override
@@ -280,7 +361,7 @@ public void glDrawArrays(int mode, int first, int count) {
280361

281362
@Override
282363
public void glDrawRangeElements(int mode, int start, int end, int count, int type, long indices) {
283-
GLES20.glDrawElements(mode, count, type, (int)indices);
364+
GLES30.glDrawRangeElements(mode, start, end, count, type, checkedLongToInt(indices, "indices offset"));
284365
}
285366

286367
@Override
@@ -325,8 +406,18 @@ public int glGetAttribLocation(int program, String name) {
325406

326407
@Override
327408
public void glGetBoolean(int pname, ByteBuffer params) {
328-
// GLES20.glGetBoolean(pname, params);
329-
throw new UnsupportedOperationException("Today is not a good day for this");
409+
checkLimit(params);
410+
int count = getBooleanValueCount(pname);
411+
if (params.remaining() < count) {
412+
throw new RendererException("Insufficient buffer space for boolean query result");
413+
}
414+
boolean[] values = new boolean[count];
415+
GLES20.glGetBooleanv(pname, values, 0);
416+
417+
ByteBuffer destination = params.duplicate();
418+
for (boolean value : values) {
419+
destination.put((byte) (value ? GLES20.GL_TRUE : GLES20.GL_FALSE));
420+
}
330421
}
331422

332423
@Override
@@ -427,10 +518,7 @@ public void glScissor(int x, int y, int width, int height) {
427518

428519
@Override
429520
public void glShaderSource(int shader, String[] string, IntBuffer length) {
430-
if (string.length != 1) {
431-
throw new UnsupportedOperationException("Today is not a good day");
432-
}
433-
GLES20.glShaderSource(shader, string[0]);
521+
GLES20.glShaderSource(shader, joinShaderSource(string, length));
434522
}
435523

436524
@Override
@@ -545,7 +633,7 @@ public void glUseProgram(int program) {
545633

546634
@Override
547635
public void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer) {
548-
GLES20.glVertexAttribPointer(index, size, type, normalized, stride, (int)pointer);
636+
GLES20.glVertexAttribPointer(index, size, type, normalized, stride, checkedLongToInt(pointer, "pointer offset"));
549637
}
550638

551639
@Override
@@ -565,7 +653,7 @@ public void glBufferData(int target, IntBuffer data, int usage) {
565653

566654
@Override
567655
public void glBufferSubData(int target, long offset, IntBuffer data) {
568-
GLES20.glBufferSubData(target, (int)offset, getLimitBytes(data), data);
656+
GLES20.glBufferSubData(target, checkedLongToInt(offset, "offset"), getLimitBytes(data), data);
569657
}
570658

571659
@Override
@@ -580,12 +668,12 @@ public void glDrawBuffers(IntBuffer bufs) {
580668

581669
@Override
582670
public void glDrawElementsInstancedARB(int mode, int indicesCount, int type, long indicesBufferOffset, int primcount) {
583-
GLES30.glDrawElementsInstanced(mode, indicesCount, type, (int)indicesBufferOffset, primcount);
671+
GLES30.glDrawElementsInstanced(mode, indicesCount, type, checkedLongToInt(indicesBufferOffset, "indices offset"), primcount);
584672
}
585673

586674
@Override
587675
public void glGetMultisample(int pname, int index, FloatBuffer val) {
588-
GLES31.glGetMultisamplefv(pname, index, val);
676+
throw new UnsupportedOperationException("Multisample textures require OpenGL ES 3.1");
589677
}
590678

591679
@Override
@@ -595,7 +683,7 @@ public void glRenderbufferStorageMultisampleEXT(int target, int samples, int int
595683

596684
@Override
597685
public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedSampleLocations) {
598-
GLES31.glTexStorage2DMultisample(target, samples, internalformat, width, height, fixedSampleLocations);
686+
throw new UnsupportedOperationException("Multisample textures require OpenGL ES 3.1");
599687
}
600688

601689
@Override
@@ -620,15 +708,12 @@ public void glUniformBlockBinding(int program, int uniformBlockIndex, int unifor
620708

621709
@Override
622710
public int glGetProgramResourceIndex(int program, int programInterface, String name) {
623-
return GLES31.glGetProgramResourceIndex(program, programInterface, name);
711+
throw new UnsupportedOperationException("Shader storage buffer objects require OpenGL ES 3.1");
624712
}
625713

626714
@Override
627715
public void glShaderStorageBlockBinding(int program, int storageBlockIndex, int storageBlockBinding) {
628-
/*
629-
* GLES 3.1 exposes shader storage block binding through GLSL layout(binding = N).
630-
* Android's GLES31 Java bindings do not expose glShaderStorageBlockBinding.
631-
*/
716+
throw new UnsupportedOperationException("Shader storage buffer objects require OpenGL ES 3.1");
632717
}
633718

634719
@Override
@@ -692,23 +777,22 @@ public void glRenderbufferStorageEXT(int param1, int param2, int param3, int par
692777

693778
@Override
694779
public void glReadPixels(int x, int y, int width, int height, int format, int type, long offset) {
695-
// TODO: no offset???
696-
GLES20.glReadPixels(x, y, width, height, format, type, null);
780+
GLES30.glReadPixels(x, y, width, height, format, type, checkedLongToInt(offset, "offset"));
697781
}
698782

699783
@Override
700784
public int glClientWaitSync(Object sync, int flags, long timeout) {
701-
throw new UnsupportedOperationException("OpenGL ES 2 does not support sync fences");
785+
return GLES30.glClientWaitSync(getSyncHandle(sync), flags, timeout);
702786
}
703787

704788
@Override
705789
public void glDeleteSync(Object sync) {
706-
throw new UnsupportedOperationException("OpenGL ES 2 does not support sync fences");
790+
GLES30.glDeleteSync(getSyncHandle(sync));
707791
}
708792

709793
@Override
710794
public Object glFenceSync(int condition, int flags) {
711-
throw new UnsupportedOperationException("OpenGL ES 2 does not support sync fences");
795+
return GLES30.glFenceSync(condition, flags);
712796
}
713797

714798
@Override

jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -686,10 +686,6 @@ private boolean renderFrameWithBlitSrgbConversion() {
686686
renderer.setMainFrameBufferOverride(linearFrameBuffer);
687687
try {
688688
listener.update();
689-
FrameBuffer currentMainFramebuffer = renderer.getCurrentFrameBuffer();
690-
if (currentMainFramebuffer != linearFrameBuffer) {
691-
restoreMainFramebuffer = currentMainFramebuffer;
692-
}
693689
} finally {
694690
renderer.setMainFrameBufferOverride(restoreMainFramebuffer);
695691
}
@@ -705,8 +701,10 @@ private boolean renderFrameWithBlitSrgbConversion() {
705701
blitCamera.resize(blitWidth, blitHeight, true);
706702
}
707703
renderManager.setCamera(blitCamera, true);
708-
blitGeometry.setWidth(blitWidth);
709-
blitGeometry.setHeight(blitHeight);
704+
if (blitGeometry.getWidth() != blitWidth || blitGeometry.getHeight() != blitHeight) {
705+
blitGeometry.setWidth(blitWidth);
706+
blitGeometry.setHeight(blitHeight);
707+
}
710708
blitGeometry.updateGeometricState();
711709
renderManager.renderGeometry(blitGeometry);
712710
} finally {

0 commit comments

Comments
 (0)