20 #include <CoreFoundation/CoreFoundation.h>
22 #include <IOSurface/IOSurfaceAPI.h>
24 #include <OpenGL/OpenGL.h>
25 #include <OpenGL/CGLMacro.h>
37 "description" :
"An image residing in GPU memory (GL Texture Object).",
51 "CoreFoundation.framework",
76 GLenum format = GL_BGRA;
78 format = GL_DEPTH_COMPONENT;
92 json_object_object_foreach(t->
cpuData, key, value)
96 json_object_object_get_ex(value,
"buffer", &o);
97 void *buffer = (
void *)json_object_get_int64(o);
99 json_object_object_get_ex(value,
"freeCallback", &o);
100 void (^freeCallback)(
void *) = (
void (^)(
void *))json_object_get_int64(o);
102 freeCallback(buffer);
104 Block_release(freeCallback);
156 VuoImage VuoImage_make(
unsigned int glTextureName,
unsigned int glInternalFormat,
unsigned long int pixelsWide,
unsigned long int pixelsHigh)
158 if (!glTextureName || !pixelsWide || !pixelsHigh)
191 VUserLog(
"Error: freeCallback may not be NULL.");
195 if (!glTextureName || !pixelsWide || !pixelsHigh)
198 return VuoImage_make_internal(glTextureName, glInternalFormat, pixelsWide, pixelsHigh, freeCallback, freeCallbackContext);
269 if (!pixels || !pixelsWide || !pixelsHigh)
274 static bool freeCallbackWarningEmitted =
false;
275 if (!freeCallbackWarningEmitted)
277 freeCallbackWarningEmitted =
true;
278 VUserLog(
"VuoImage_makeFromBuffer() and VuoImage_makeFromBufferWithStride() now take ownership of `pixels`, and therefore `freeCallback` is required. Since there's no `freeCallback`, I'm giving up and outputting an empty image. Please update the plugin listed in the backtrace below.");
284 __block GLenum internalformat;
285 __block GLuint glTextureName;
286 __block
int alignment = 1;
287 __block
bool customRowLength =
false;
292 glTextureName =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, internalformat, pixelsWide, pixelsHigh, format, NULL);
298 if (colorDepth == VuoImageColorDepth_8)
300 else if (colorDepth == VuoImageColorDepth_16)
302 glType = GL_HALF_FLOAT_ARB;
312 || bytesPerRow == bytesPerPixel * pixelsWide)
317 if (bytesPerRow % 4 == 0)
319 else if (bytesPerRow % 8 == 0)
321 else if (bytesPerRow % 2 == 0)
323 else if (bytesPerRow % bytesPerPixel == 0)
325 GLuint rowPixels = bytesPerRow / bytesPerPixel;
326 glPixelStorei(GL_UNPACK_ROW_LENGTH, rowPixels);
327 customRowLength =
true;
331 VUserLog(
"Not sure how to handle this stride:");
332 VUserLog(
" %dx%d",pixelsWide,pixelsHigh);
333 VUserLog(
" bytesPerRow = %d",bytesPerRow);
334 VUserLog(
" bytesPerPixel = %d",bytesPerPixel);
335 GLint leftoverBytes = bytesPerRow - bytesPerPixel*pixelsWide;
336 VUserLog(
" leftoverBytes = %d",leftoverBytes);
341 glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
343 glBindTexture(GL_TEXTURE_2D, glTextureName);
344 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
346 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, pixelsWide, pixelsHigh, 0, format, glType, (GLvoid *)pixels);
347 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
348 glBindTexture(GL_TEXTURE_2D, 0);
351 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
353 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
358 glFlushRenderAPPLE();
368 image->
cpuQueue = dispatch_queue_create(
"org.vuo.image.cpu", NULL);
369 image->
cpuData = json_object_new_object();
373 char *keyWithAlignment;
374 asprintf(&keyWithAlignment,
"%s alignment=%d", key, alignment);
376 key = keyWithAlignment;
380 char *keyWithRowLength;
381 asprintf(&keyWithRowLength,
"%s rowLength=%d", key, bytesPerRow);
383 key = keyWithRowLength;
386 json_object_object_add(cpuEntry,
"buffer", json_object_new_int64((
long long)pixels));
387 json_object_object_add(cpuEntry,
"freeCallback", json_object_new_int64((
long long)Block_copy(freeCallback)));
388 json_object_object_add(image->
cpuData, key, cpuEntry);
424 if (image->
glInternalFormat == GL_DEPTH_COMPONENT && requestedFormat != GL_DEPTH_COMPONENT16)
426 VUserLog(
"Error: Image has format GL_DEPTH_COMPONENT, which must be fetched as GL_DEPTH_COMPONENT16.");
431 image->cpuQueue = dispatch_queue_create(
"org.vuo.image.cpu", NULL);
432 image->cpuData = json_object_new_object();
435 __block
unsigned char *pixels = NULL;
437 char *key = VuoGl_stringForConstant(requestedFormat);
438 struct json_object *value;
439 if (json_object_object_get_ex(image->cpuData, key, &value))
442 json_object_object_get_ex(value,
"buffer", &o);
443 pixels = (unsigned char *)json_object_get_int64(o);
447 unsigned int channels;
448 if (requestedFormat == GL_LUMINANCE
449 || requestedFormat == GL_R16
450 || requestedFormat == GL_DEPTH_COMPONENT16)
452 else if (requestedFormat == GL_LUMINANCE_ALPHA)
454 else if (requestedFormat == GL_RGB
455 || requestedFormat == GL_BGR)
457 else if (requestedFormat == GL_RGBA
458 || requestedFormat == GL_BGRA
459 || requestedFormat == GL_RGBA16I_EXT
460 || requestedFormat == GL_RGBA16F_ARB
461 || requestedFormat == GL_RGBA32F_ARB)
465 VUserLog(
"Error: Unknown format %s.", VuoGl_stringForConstant(requestedFormat));
469 unsigned int bytesPerChannel = 1;
470 GLuint type = GL_UNSIGNED_BYTE;
471 if (requestedFormat == GL_RGBA16I_EXT
472 || requestedFormat == GL_R16
473 || requestedFormat == GL_DEPTH_COMPONENT16)
476 type = GL_UNSIGNED_SHORT;
478 else if (requestedFormat == GL_RGBA16F_ARB)
481 type = GL_HALF_FLOAT_ARB;
483 else if (requestedFormat == GL_RGBA32F_ARB)
489 GLuint actualFormat = requestedFormat;
490 if (requestedFormat == GL_RGBA16I_EXT
491 || requestedFormat == GL_RGBA16F_ARB
492 || requestedFormat == GL_RGBA32F_ARB)
493 actualFormat = GL_BGRA;
494 else if (requestedFormat == GL_DEPTH_COMPONENT16)
495 actualFormat = GL_DEPTH_COMPONENT;
496 else if (requestedFormat == GL_R16)
497 actualFormat = GL_RED;
500 pixels = (
unsigned char *)malloc(pixelBufferSize);
504 const char *tamperEvidentSeal =
"Vuo\0Ima\0ge_\0get\0Buf\0fer\0()\0";
505 int tamperEvidentSealLength = strlen(tamperEvidentSeal);
506 if (pixelBufferSize > tamperEvidentSealLength)
507 strlcpy((
char *)pixels, tamperEvidentSeal, pixelBufferSize);
512 bool openGLAddsPadding = ((image->
pixelsWide * channels * bytesPerChannel) % 4 != 0);
513 if (openGLAddsPadding)
515 glPixelStorei(GL_PACK_ALIGNMENT, 1);
519 glGetTexImage(image->
glTextureTarget, 0, actualFormat, type, (GLvoid *)pixels);
522 if (openGLAddsPadding)
524 glPixelStorei(GL_PACK_ALIGNMENT, 4);
526 if (pixelBufferSize > tamperEvidentSealLength && strncmp((
char *)pixels, tamperEvidentSeal, strlen(tamperEvidentSeal)) == 0)
528 GLenum error = glGetError();
529 if (error == GL_NO_ERROR)
533 VUserLog(
"Warning: glGetTexImage() says it was successful, but it didn't actually copy any data. This might happen if the input texture has an IOSurface bound to it.");
535 VUserLog(
"OpenGL Error: %d", error);
546 json_object_object_add(cpuEntry,
"buffer", json_object_new_int64((
long long)pixels));
547 json_object_object_add(cpuEntry,
"freeCallback", json_object_new_int64((
long long)Block_copy( ^(
void *buffer){ free(buffer); } )));
548 json_object_object_add(image->
cpuData, key, cpuEntry);
562 __block GLint wrapModeGL;
567 glGetTexParameteriv(image->
glTextureTarget, GL_TEXTURE_WRAP_S, &wrapModeGL);
574 if (wrapModeGL == GL_CLAMP_TO_EDGE)
575 return VuoImageWrapMode_ClampEdge;
576 else if (wrapModeGL == GL_REPEAT)
577 return VuoImageWrapMode_Repeat;
578 else if (wrapModeGL == GL_MIRRORED_REPEAT)
579 return VuoImageWrapMode_MirroredRepeat;
581 return VuoImageWrapMode_None;
593 GLint wrapModeGL = GL_CLAMP_TO_BORDER;
594 if (wrapMode == VuoImageWrapMode_ClampEdge)
595 wrapModeGL = GL_CLAMP_TO_EDGE;
596 else if (wrapMode == VuoImageWrapMode_Repeat)
597 wrapModeGL = GL_REPEAT;
598 else if (wrapMode == VuoImageWrapMode_MirroredRepeat)
599 wrapModeGL = GL_MIRRORED_REPEAT;
601 glTexParameteri(image->
glTextureTarget, GL_TEXTURE_WRAP_S, wrapModeGL);
602 glTexParameteri(image->
glTextureTarget, GL_TEXTURE_WRAP_T, wrapModeGL);
608 glFlushRenderAPPLE();
618 if (!pixelsWide || !pixelsHigh)
657 forcePixelsWide ? forcePixelsWide : image->
pixelsWide,
658 forcePixelsHigh ? forcePixelsHigh : image->
pixelsHigh,
708 if (aChannels == 4 && bChannels == 1)
712 if (abs(aPixels[i*4+0] - bPixels[i*4+2]) > tolerance
713 || abs(aPixels[i*4+1] - bPixels[i*4+2]) > tolerance
714 || abs(aPixels[i*4+2] - bPixels[i*4+2]) > tolerance
715 || abs(aPixels[i*4+3] - bPixels[i*4+3]) > tolerance)
717 VDebugLog(
"Difference found at pixel coordinate (%ld,%ld): RGBA %d,%d,%d,%d vs %d,%d,%d,%d",
719 aPixels[i*4+2],aPixels[i*4+1],aPixels[i*4+0],aPixels[i*4+3],
720 bPixels[i*4+2],bPixels[i*4+2],bPixels[i*4+2],bPixels[i*4+3]);
725 else if (aChannels == 1 && bChannels == 4)
729 if (abs(aPixels[i*4+2] - bPixels[i*4+0]) > tolerance
730 || abs(aPixels[i*4+2] - bPixels[i*4+1]) > tolerance
731 || abs(aPixels[i*4+2] - bPixels[i*4+2]) > tolerance
732 || abs(aPixels[i*4+3] - bPixels[i*4+3]) > tolerance)
734 VDebugLog(
"Difference found at pixel coordinate (%ld,%ld): RGBA %d,%d,%d,%d vs %d,%d,%d,%d",
736 aPixels[i*4+2],aPixels[i*4+2],aPixels[i*4+2],aPixels[i*4+3],
737 bPixels[i*4+2],bPixels[i*4+1],bPixels[i*4+0],bPixels[i*4+3]);
744 if (abs(aPixels[i] - bPixels[i]) > tolerance)
746 unsigned int p = (i/4)*4;
747 VDebugLog(
"Difference found at pixel coordinate (%ld,%ld): abs(%d - %d) > %d (RGBA %d,%d,%d,%d vs %d,%d,%d,%d)",
749 aPixels[i], bPixels[i], tolerance,
750 aPixels[p+2],aPixels[p+1],aPixels[p+0],aPixels[p+3],
751 bPixels[p+2],bPixels[p+1],bPixels[p+0],bPixels[p+3]);
804 bool foundSubstantialPixel =
false;
808 foundSubstantialPixel =
true;
811 return !foundSubstantialPixel;
838 return VuoImageColorDepth_8;
848 return VuoImageColorDepth_8;
856 return VuoImageColorDepth_16;
861 return VuoImageColorDepth_32;
866 return VuoImageColorDepth_8;
937 if (json_object_object_get_ex(js,
"pointer", &o))
940 if ((requestedPixelsWide == 0 && requestedPixelsHigh == 0)
953 __block
unsigned int glInternalFormat = 0;
954 unsigned long int pixelsWide;
955 unsigned long int pixelsHigh;
956 float scaleFactor = 1;
960 if (json_object_object_get_ex(js,
"pixelsWide", &o))
961 pixelsWide = json_object_get_int64(o);
967 if (json_object_object_get_ex(js,
"pixelsHigh", &o))
968 pixelsHigh = json_object_get_int64(o);
972 if (pixelsWide == 0 || pixelsHigh == 0)
977 if (json_object_object_get_ex(js,
"scaleFactor", &o))
978 scaleFactor = json_object_get_double(o);
983 if (json_object_object_get_ex(js,
"color", &o))
989 if (json_object_object_get_ex(js,
"ioSurface", &o))
991 IOSurfaceID surfID = json_object_get_int(o);
995 __block IOSurfaceRef surf = NULL;
996 __block GLuint textureRect;
998 glInternalFormat = GL_RGBA;
999 surf = IOSurfaceLookup(surfID);
1002 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1005 textureRect =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, glInternalFormat, pixelsWide, pixelsHigh, GL_BGRA, surf);
1006 glFlushRenderAPPLE();
1023 requestedPixelsWide ? requestedPixelsWide : pixelsWide,
1024 requestedPixelsHigh ? requestedPixelsHigh : pixelsHigh,
1064 if (!json_object_object_get_ex(js,
"pixelsWide", &o))
1066 *outputPixelsWide = json_object_get_int64(o);
1068 if (!json_object_object_get_ex(js,
"pixelsHigh", &o))
1070 *outputPixelsHigh = json_object_get_int64(o);
1072 if (!json_object_object_get_ex(js,
"ioSurface", &o))
1074 IOSurfaceID surfID = json_object_get_int(o);
1076 GLuint textureRect = provider(*outputPixelsWide, *outputPixelsHigh);
1081 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureRect);
1083 IOSurfaceRef *surf = outputIOSurface;
1084 *surf = IOSurfaceLookup(surfID);
1087 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1091 CGLError err = CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, (GLsizei)*outputPixelsWide, (GLsizei)*outputPixelsHigh, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, *surf, 0);
1092 if(err != kCGLNoError)
1094 VUserLog(
"Error in CGLTexImageIOSurface2D(): %s", CGLErrorString(err));
1097 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1098 glFlushRenderAPPLE();
1129 if (!clientTextureName)
1134 if (!json_object_object_get_ex(js,
"pixelsWide", &o))
1136 unsigned long inputPixelsWide = json_object_get_int64(o);
1138 if (!json_object_object_get_ex(js,
"pixelsHigh", &o))
1140 unsigned long inputPixelsHigh = json_object_get_int64(o);
1142 if (!json_object_object_get_ex(js,
"ioSurface", &o))
1144 IOSurfaceID surfID = json_object_get_int(o);
1146 __block
bool success =
true;
1148 IOSurfaceRef *surf = outputIOSurface;
1149 *surf = IOSurfaceLookup(surfID);
1152 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1157 bool shouldResize = (inputPixelsWide != pixelsWide
1158 || inputPixelsHigh != pixelsHigh);
1163 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, clientTextureName);
1164 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, pixelsWide, pixelsHigh, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1165 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1167 GLuint outputFramebuffer;
1168 glGenFramebuffers(1, &outputFramebuffer);
1169 glBindFramebuffer(GL_FRAMEBUFFER, outputFramebuffer);
1170 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, clientTextureName, 0);
1172 glViewport(0, 0, pixelsWide, pixelsHigh);
1176 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
1177 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1178 glDeleteFramebuffers(1, &outputFramebuffer);
1182 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, clientTextureName);
1184 CGLError err = CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, (GLsizei)inputPixelsWide, (GLsizei)inputPixelsHigh, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, *surf, 0);
1185 if (err != kCGLNoError)
1187 VUserLog(
"Error in CGLTexImageIOSurface2D(): %s", CGLErrorString(err));
1192 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1195 glFlushRenderAPPLE();
1216 if (!json_object_object_get_ex(js,
"pixelsWide", &o))
1218 GLsizei pixelsWide = json_object_get_int64(o);
1220 if (!json_object_object_get_ex(js,
"pixelsHigh", &o))
1222 GLsizei pixelsHigh = json_object_get_int64(o);
1224 if (!json_object_object_get_ex(js,
"ioSurface", &o))
1226 IOSurfaceID surfID = json_object_get_int(o);
1227 IOSurfaceRef surf = IOSurfaceLookup(surfID);
1230 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1244 static GLuint
CompileShader(CGLContextObj cgl_ctx, GLenum type,
const char *source)
1246 GLint length = (GLint)strlen(source);
1247 GLuint shader = glCreateShader(type);
1248 glShaderSource(shader, 1, (
const GLchar**)&source, &length);
1249 glCompileShader(shader);
1251 int infologLength = 0;
1252 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
1253 if (infologLength > 0)
1255 char *infoLog = (
char *)malloc(infologLength);
1256 int charsWritten = 0;
1257 glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog);
1272 CGLContextObj cgl_ctx = (CGLContextObj)context;
1274 static bool openGL32Core;
1275 static GLuint vertexArray;
1276 static GLuint program;
1277 static GLuint receiveTextureOffsetAndSizeUniform;
1281 char *vertexShaderSource;
1282 char *fragmentShaderSource;
1286 CGLSetCurrentContext(cgl_ctx);
1293 in vec2 textureCoordinate;
1294 out vec2 fragmentTextureCoordinate;
1297 fragmentTextureCoordinate = textureCoordinate;
1298 gl_Position = vec4(position.x, position.y, 0., 1.);
1302 uniform sampler2DRect receiveTexture;
1303 uniform vec4 receiveTextureOffsetAndSize;
1304 in vec2 fragmentTextureCoordinate;
1308 FragColor = texture(receiveTexture, receiveTextureOffsetAndSize.xy + fragmentTextureCoordinate * receiveTextureOffsetAndSize.zw);
1316 glGenVertexArraysAPPLE(1, &vertexArray);
1317 glBindVertexArrayAPPLE(vertexArray);
1320 attribute vec2 position;
1321 attribute vec2 textureCoordinate;
1322 varying vec2 fragmentTextureCoordinate;
1325 fragmentTextureCoordinate = textureCoordinate;
1326 gl_Position = vec4(position.x, position.y, 0., 1.);
1330 uniform sampler2DRect receiveTexture;
1331 uniform vec4 receiveTextureOffsetAndSize;
1332 varying vec2 fragmentTextureCoordinate;
1335 gl_FragColor = texture2DRect(receiveTexture, receiveTextureOffsetAndSize.xy + fragmentTextureCoordinate * receiveTextureOffsetAndSize.zw);
1341 const GLfloat quadPositionsAndTextureCoordinates[] = {
1351 GLuint quadPTCBuffer;
1352 glGenBuffers(1, &quadPTCBuffer);
1353 glBindBuffer(GL_ARRAY_BUFFER, quadPTCBuffer);
1354 glBufferData(GL_ARRAY_BUFFER,
sizeof(quadPositionsAndTextureCoordinates), quadPositionsAndTextureCoordinates, GL_STATIC_DRAW);
1357 GLuint vertexShader =
CompileShader(context, GL_VERTEX_SHADER, vertexShaderSource);
1358 GLuint fragmentShader =
CompileShader(context, GL_FRAGMENT_SHADER, fragmentShaderSource);
1359 program = glCreateProgram();
1360 glAttachShader(program, vertexShader);
1361 glAttachShader(program, fragmentShader);
1362 glLinkProgram(program);
1363 GLuint positionAttribute = glGetAttribLocation(program,
"position");
1364 GLuint textureCoordinateAttribute = glGetAttribLocation(program,
"textureCoordinate");
1365 GLuint receiveTextureUniform = glGetUniformLocation(program,
"receiveTexture");
1366 receiveTextureOffsetAndSizeUniform = glGetUniformLocation(program,
"receiveTextureOffsetAndSize");
1368 glUseProgram(program);
1370 glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, GL_FALSE,
sizeof(GLfloat)*4, (
void*)0);
1371 glEnableVertexAttribArray(positionAttribute);
1373 glVertexAttribPointer(textureCoordinateAttribute, 2, GL_FLOAT, GL_FALSE,
sizeof(GLfloat)*4, (
void*)(
sizeof(GLfloat)*2));
1374 glEnableVertexAttribArray(textureCoordinateAttribute);
1376 glUniform1i(receiveTextureUniform, 0);
1382 CGLSetCurrentContext(cgl_ctx);
1386 glBindVertexArrayAPPLE(vertexArray);
1388 GLuint textureRect =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, pixelsWide, pixelsHigh, GL_BGRA, surf);
1391 VUserLog(
"Error: Couldn't allocate texture.");
1397 glActiveTexture(GL_TEXTURE0);
1398 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureRect);
1400 glUseProgram(program);
1404 glGetIntegerv(GL_VIEWPORT, viewport);
1406 glUniform4f(receiveTextureOffsetAndSizeUniform,
1407 ((
float)pixelsWide - viewport[2]) / 2,
1408 flip ? viewport[3] : 0,
1410 viewport[3] * (flip ? -1 : 1));
1412 glDrawArrays(GL_TRIANGLES, 0, 6);
1414 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1415 VuoGlTexture_release(VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, pixelsWide, pixelsHigh, textureRect);
1420 glBindVertexArrayAPPLE(0);
1422 glBindBuffer(GL_ARRAY_BUFFER, 0);
1439 json_object_object_add(js,
"pointer", json_object_new_int64((int64_t)value));
1457 __block IOSurfaceID surfID = 0;
1472 glFlushRenderAPPLE();
1480 json_object_object_add(js,
"ioSurface", o);
1485 json_object_object_add(js,
"pixelsWide", o);
1489 json_object_object_add(js,
"pixelsHigh", o);
1493 json_object_object_add(js,
"scaleFactor", o);
1514 return strdup(
"No image");
1519 case GL_RGB: type =
"RGB, each channel 8-bit unsigned integer";
break;
1520 case GL_RGB16F_ARB: type =
"RGB, each channel 16-bit signed float";
break;
1521 case GL_RGB32F_ARB: type =
"RGB, each channel 32-bit signed float";
break;
1522 case GL_RGBA: type =
"RGBA, each channel 8-bit unsigned integer";
break;
1523 case GL_RGBA16F_ARB: type =
"RGBA, each channel 16-bit signed float";
break;
1524 case GL_RGBA32F_ARB: type =
"RGBA, each channel 32-bit signed float";
break;
1525 case GL_LUMINANCE8: type =
"intensity, 8-bit unsigned integer";
break;
1526 case GL_LUMINANCE16F_ARB: type =
"intensity, 16-bit signed float";
break;
1527 case GL_LUMINANCE32F_ARB: type =
"intensity, 32-bit signed float";
break;
1528 case GL_LUMINANCE8_ALPHA8: type =
"intensity+alpha, each channel 8-bit unsigned integer";
break;
1529 case GL_LUMINANCE_ALPHA16F_ARB: type =
"intensity+alpha, each channel 16-bit signed float";
break;
1530 case GL_LUMINANCE_ALPHA32F_ARB: type =
"intensity+alpha, each channel 32-bit signed float";
break;
1531 case GL_DEPTH_COMPONENT: type =
"intensity, 16-bit signed float";
break;
1532 default: type =
"(unknown)";
1538 char *summary =
VuoText_format(
"<div>%luĂ—%lu pixels @ %gx</div><div>%s</div><div>OpenGL: %s, %s, ID %u</div>",
1546 free(internalformat);