Skip to content

Commit b29cadf

Browse files
committed
Fix glTexImage3D and glTexSubImage3D to pass correct type of arraybuffer to their entrypoints. Fix GL_PIXEL_PACK_BUFFER and GL_PIXEL_UNPACK_BUFFER to be taken into account when operating with texture functions. Use fast garbage free WebGL 2 entry points for texture functions.
1 parent 61a592a commit b29cadf

File tree

1 file changed

+124
-6
lines changed

1 file changed

+124
-6
lines changed

src/library_gl.js

Lines changed: 124 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,9 +1224,82 @@ var LibraryGL = {
12241224
}
12251225
},
12261226

1227+
#if USE_WEBGL2
1228+
$emscriptenWebGLGetHeapForType: function(type) {
1229+
switch(type) {
1230+
case 0x1400 /* GL_BYTE */:
1231+
return HEAP8;
1232+
case 0x1401 /* GL_UNSIGNED_BYTE */:
1233+
return HEAPU8;
1234+
case 0x1402 /* GL_SHORT */:
1235+
return HEAP16;
1236+
case 0x1403 /* GL_UNSIGNED_SHORT */:
1237+
case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */:
1238+
case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */:
1239+
case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */:
1240+
case 0x8D61 /* GL_HALF_FLOAT_OES */:
1241+
case 0x140B /* GL_HALF_FLOAT */:
1242+
return HEAPU16;
1243+
case 0x1404 /* GL_INT */:
1244+
return HEAP32;
1245+
case 0x1405 /* GL_UNSIGNED_INT */:
1246+
case 0x84FA /* GL_UNSIGNED_INT_24_8_WEBGL/GL_UNSIGNED_INT_24_8 */:
1247+
case 0x8C3E /* GL_UNSIGNED_INT_5_9_9_9_REV */:
1248+
case 0x8368 /* GL_UNSIGNED_INT_2_10_10_10_REV */:
1249+
case 0x8C3B /* GL_UNSIGNED_INT_10F_11F_11F_REV */:
1250+
case 0x84FA /* GL_UNSIGNED_INT_24_8 */:
1251+
return HEAPU32;
1252+
case 0x1406 /* GL_FLOAT */:
1253+
return HEAPF32;
1254+
default:
1255+
return null;
1256+
}
1257+
},
1258+
1259+
$emscriptenWebGLGetShiftForType: function(type) {
1260+
switch(type) {
1261+
case 0x1400 /* GL_BYTE */:
1262+
case 0x1401 /* GL_UNSIGNED_BYTE */:
1263+
return 0;
1264+
case 0x1402 /* GL_SHORT */:
1265+
case 0x1403 /* GL_UNSIGNED_SHORT */:
1266+
case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */:
1267+
case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */:
1268+
case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */:
1269+
case 0x8D61 /* GL_HALF_FLOAT_OES */:
1270+
case 0x140B /* GL_HALF_FLOAT */:
1271+
return 1;
1272+
case 0x1404 /* GL_INT */:
1273+
case 0x1406 /* GL_FLOAT */:
1274+
case 0x1405 /* GL_UNSIGNED_INT */:
1275+
case 0x84FA /* GL_UNSIGNED_INT_24_8_WEBGL/GL_UNSIGNED_INT_24_8 */:
1276+
case 0x8C3E /* GL_UNSIGNED_INT_5_9_9_9_REV */:
1277+
case 0x8368 /* GL_UNSIGNED_INT_2_10_10_10_REV */:
1278+
case 0x8C3B /* GL_UNSIGNED_INT_10F_11F_11F_REV */:
1279+
case 0x84FA /* GL_UNSIGNED_INT_24_8 */:
1280+
return 2;
1281+
default:
1282+
return 0;
1283+
}
1284+
},
1285+
#endif
1286+
12271287
glTexImage2D__sig: 'viiiiiiiii',
12281288
glTexImage2D__deps: ['$emscriptenWebGLGetTexPixelData'],
12291289
glTexImage2D: function(target, level, internalFormat, width, height, border, format, type, pixels) {
1290+
#if USE_WEBGL2
1291+
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1292+
if (GLctx.currentPixelUnpackBufferBinding) {
1293+
GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
1294+
} else if (pixels != 0) {
1295+
GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, emscriptenWebGLGetHeapForType(type), pixels >> emscriptenWebGLGetShiftForType(type));
1296+
} else {
1297+
GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, null);
1298+
}
1299+
return;
1300+
}
1301+
#endif
1302+
12301303
var pixelData = null;
12311304
if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat);
12321305
GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData);
@@ -1235,6 +1308,18 @@ var LibraryGL = {
12351308
glTexSubImage2D__sig: 'viiiiiiiii',
12361309
glTexSubImage2D__deps: ['$emscriptenWebGLGetTexPixelData'],
12371310
glTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, type, pixels) {
1311+
#if USE_WEBGL2
1312+
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1313+
if (GLctx.currentPixelUnpackBufferBinding) {
1314+
GLctx.texSubImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
1315+
} else if (pixels != 0) {
1316+
GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, emscriptenWebGLGetHeapForType(type), pixels >> emscriptenWebGLGetShiftForType(type));
1317+
} else {
1318+
GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, null);
1319+
}
1320+
return;
1321+
}
1322+
#endif
12381323
var pixelData = null;
12391324
if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0);
12401325
GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData);
@@ -1243,6 +1328,16 @@ var LibraryGL = {
12431328
glReadPixels__sig: 'viiiiiii',
12441329
glReadPixels__deps: ['$emscriptenWebGLGetTexPixelData'],
12451330
glReadPixels: function(x, y, width, height, format, type, pixels) {
1331+
#if USE_WEBGL2
1332+
if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
1333+
if (GLctx.currentPixelPackBufferBinding) {
1334+
GLctx.readPixels(x, y, width, height, format, type, pixels);
1335+
} else {
1336+
GLctx.readPixels(x, y, width, height, format, type, emscriptenWebGLGetHeapForType(type), pixels >> emscriptenWebGLGetShiftForType(type));
1337+
}
1338+
return;
1339+
}
1340+
#endif
12461341
var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format);
12471342
if (!pixelData) {
12481343
GL.recordError(0x0500/*GL_INVALID_ENUM*/);
@@ -1691,15 +1786,25 @@ var LibraryGL = {
16911786
},
16921787

16931788
glTexImage3D__sig: 'viiiiiiiiii',
1694-
glTexImage3D: function(target, level, internalFormat, width, height, depth, border, format, type, data) {
1695-
GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type,
1696-
HEAPU8.subarray(data));
1789+
glTexImage3D: function(target, level, internalFormat, width, height, depth, border, format, type, pixels) {
1790+
if (GLctx.currentPixelUnpackBufferBinding) {
1791+
GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type, pixels);
1792+
} else if (pixels != 0) {
1793+
GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type, emscriptenWebGLGetHeapForType(type), pixels >> emscriptenWebGLGetShiftForType(type));
1794+
} else {
1795+
GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type, null);
1796+
}
16971797
},
16981798

16991799
glTexSubImage3D__sig: 'viiiiiiiiiii',
1700-
glTexSubImage3D: function(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data) {
1701-
GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type,
1702-
HEAPU8.subarray(data));
1800+
glTexSubImage3D: function(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) {
1801+
if (GLctx.currentPixelUnpackBufferBinding) {
1802+
GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
1803+
} else if (pixels != 0) {
1804+
GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, emscriptenWebGLGetHeapForType(type), pixels >> emscriptenWebGLGetShiftForType(type));
1805+
} else {
1806+
GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, null);
1807+
}
17031808
},
17041809

17051810
// Queries
@@ -3113,6 +3218,19 @@ var LibraryGL = {
31133218
}
31143219
#endif
31153220

3221+
#if USE_WEBGL2
3222+
if (target == 0x88EB /*GL_PIXEL_PACK_BUFFER*/) {
3223+
// In WebGL 2 glReadPixels entry point, we need to use a different WebGL 2 API function call when a buffer is bound to
3224+
// GL_PIXEL_PACK_BUFFER_BINDING point, so must keep track whether that binding point is non-null to know what is
3225+
// the proper API function to call.
3226+
GLctx.currentPixelPackBufferBinding = buffer;
3227+
} else if (target == 0x88EC /*GL_PIXEL_UNPACK_BUFFER*/) {
3228+
// In WebGL 2 glTexImage2D, glTexSubImage2D, glTexImage3D and glTexSubImage3D entry points, we need to use a different WebGL 2 API function
3229+
// call when a buffer is bound to GL_PIXEL_UNPACK_BUFFER_BINDING point, so must keep track whether that binding point is non-null to know what
3230+
// is the proper API function to call.
3231+
GLctx.currentPixelUnpackBufferBinding = buffer;
3232+
}
3233+
#endif
31163234
GLctx.bindBuffer(target, bufferObj);
31173235
},
31183236

0 commit comments

Comments
 (0)