Hi
I am looking for example / articles on how to perform updates to an Open GL ES texture (without using low Performing glTexSubImage2D approach) in a zero copy approach.
I am currently focused on odroid XU3 with MALI T628 running ubuntu.
I studied and tried eglcreateImageKHR approach without success (I cannot create an eglImage: error EGL_BAD_PARAMETER is returned when using EGL_NATIVE_PIXMAP_KHRas a target).
I read that MALI driver has support for UMP data transfer, but I still need a reference to the inner buffer in a openGL ES texture.
Any help needed
Andrea
Hi,
There has already been several threads posted about this issue, have you had a chance to search around for a potential solution?
From a brief look at the specification, you need to ensure the device supports these two extensions at least:
KHR_image_base KHR_image_pixmap
KHR_image_base
KHR_image_pixmap
Can you confirm this is the case?
Without more information about your error, for example a code snippet or reproducer, we can only give general advice.
Hope it helps,
Michael McGeagh
Hi Michael
Sorry for my late answer but I had to buy and wait another board.
I looked around a lot but I am not successfull.
I am running on odroid xu3 (MALI T628), ubuntu 15.04, kernel with X11 enabled.
Linux odroid 3.10.72-23 #1 SMP PREEMPT Sat May 23 17:58:14 BRT 2015 armv7l armv7l armv7l GNU/Linux.
I get error 0x300c out of eglCreateImageKHR.
Basically I do the following (I attached complete source code)
1) setup EGL creating an X11 windows as argument of eglCreateWindowSurface
2) create compile and link minimum shaders to perform a texture rendering
3) create a texture
4) allocate a RGBA 8888 buffer filled with some data (vertical white bar)
5) try to create an EGLImage using eglCreateImageKHR and passing a fbdev_pixmap structure
Thanks for your help
====== TestEGLImage.cpp ======
#include "EGL/egl.h"
#define EGL_EGLEXT_PROTOTYPES
#include "EGL/eglext.h"
#include "GLES2/gl2.h"
#define GL_GLEXT_PROTOTYPES
#include "GLES2/gl2ext.h"
#include "assert.h"
#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "AVWindow.h"
#include "string.h"
#define WIDTH 1280
#define HEIGHT 720
#define NCYCLES 1
EGLint g_configAttributes[] =
{
/* DO NOT MODIFY. */
/* These attributes are in a known order and may be re-written at initialization according to application requests. */
EGL_SAMPLES, 4,
EGL_ALPHA_SIZE, 0,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_BUFFER_SIZE, 32,
EGL_STENCIL_SIZE, 0,
EGL_RENDERABLE_TYPE, 0, /* This field will be completed according to application request. */
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_DEPTH_SIZE, 16,
/* MODIFY BELOW HERE. */
/* If you need to add or override EGL attributes from above, do it below here. */
EGL_NONE
};
EGLint g_contextAttributes[] =
EGL_CONTEXT_CLIENT_VERSION, 0, /* This field will be completed according to application request. */
EGL_NONE, EGL_NONE, /* If we use OpenGL ES 3.1, we will have to use EGL_CONTEXT_MINOR_VERSION,
and we overwrite these fields. */
EGLConfig g_config;
EGLint g_windowAttributes[] =
/*
* Uncomment and remove EGL_NONE above to specify EGL_RENDER_BUFFER value to eglCreateWindowSurface.
* EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
* EGL_NONE
*/
EGLConfig findConfig(EGLDisplay display)
bool strictMatch;
#if defined(__arm__)
strictMatch = true;
#else
strictMatch = false;
#endif
EGLConfig *configsArray = NULL;
EGLint numberOfConfigs = 0;
EGLBoolean success = EGL_FALSE;
/* Enumerate available EGL configurations which match or exceed our required attribute list. */
success = eglChooseConfig(display, g_configAttributes, NULL, 0, &numberOfConfigs);
if (success != EGL_TRUE)
printf("Failed to enumerate EGL configs");
exit(1);
}
printf("Number of configs found is %d\n", numberOfConfigs);
if (numberOfConfigs == 0)
printf("Disabling AntiAliasing to try and find a config.\n");
g_configAttributes[1] = EGL_DONT_CARE;
printf("Failed to enumerate EGL configs 2");
printf("No configs found with the requested attributes");
else
printf("Configs found when antialiasing disabled.\n ");
/* Allocate space for all EGL configs available and get them. */
configsArray = (EGLConfig *)calloc(numberOfConfigs, sizeof(EGLConfig));
success = eglChooseConfig(display, g_configAttributes, configsArray, numberOfConfigs, &numberOfConfigs);
printf("Failed to enumerate EGL configs 3");
bool matchFound = false;
int matchingConfig = -1;
if (strictMatch)
* Loop through the EGL configs to find a color depth match.
* Note: This is necessary, since EGL considers a higher color depth than requested to be 'better'
* even though this may force the driver to use a slow color conversion blitting routine.
EGLint redSize = g_configAttributes[5];
EGLint greenSize = g_configAttributes[7];
EGLint blueSize = g_configAttributes[9];
for (int configsIndex = 0; (configsIndex < numberOfConfigs) && !matchFound; configsIndex++)
EGLint attributeValue = 0;
success = eglGetConfigAttrib(display, configsArray[configsIndex], EGL_RED_SIZE, &attributeValue);
printf("Failed to get EGL attribute");
if (attributeValue == redSize)
success = eglGetConfigAttrib(display, configsArray[configsIndex], EGL_GREEN_SIZE, &attributeValue);
printf("Failed to get EGL attribute 2");
if (attributeValue == greenSize)
success = eglGetConfigAttrib(display, configsArray[configsIndex], EGL_BLUE_SIZE, &attributeValue);
printf("Failed to get EGL attribute 3");
if (attributeValue == blueSize)
matchFound = true;
matchingConfig = configsIndex;
/* If not strict we can use any matching config. */
matchingConfig = 0;
if (!matchFound)
printf("Failed to find matching EGL config");
/* Return the matching config. */
EGLConfig configToReturn = configsArray[matchingConfig];
free(configsArray);
configsArray = NULL;
return configToReturn;
#define _GLCheck()\
{\
GLenum glError = glGetError(); \
if(glError != GL_NO_ERROR) \
{ \
printf ("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \
} \
}\
#define VERTEXPOS 1.0f
#define TEXTUREPOS 1.0f
GLfloat vVertices[] = {
-VERTEXPOS, VERTEXPOS, 0.0f, // Position 0
0.0f, 0.0f, // TexCoord 0
-VERTEXPOS, -VERTEXPOS, 0.0f, // Position 1
0.0f, TEXTUREPOS, // TexCoord 1
VERTEXPOS, -VERTEXPOS, 0.0f, // Position 2
TEXTUREPOS, TEXTUREPOS, // TexCoord 2
VERTEXPOS, VERTEXPOS, 0.0f, // Position 3
TEXTUREPOS, 0.0f, // TexCoord 3
const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
const char _VShaderSource_Blender[] =
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
"varying vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
const char _FShaderSource_Blender[] =
"precision mediump float; \n"
"uniform sampler2D InputTex; \n"
" \n"
"void main(void) \n"
" //gl_FragColor=texture2D(InputTex,v_texCoord); \n"
" vec4 col=texture2D(InputTex,v_texCoord); \n"
" gl_FragColor=vec4(col.b, col.g, col.r, col.a); \n"
void UploadTexture_UsingTextSubImage2D(unsigned char *InPicture, GLuint _iTex)
glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, _iTex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, InPicture);
_GLCheck();
typedef enum
FBDEV_PIXMAP_DEFAULT = 0,
FBDEV_PIXMAP_SUPPORTS_UMP = (1 << 0),
FBDEV_PIXMAP_ALPHA_FORMAT_PRE = (1 << 1),
FBDEV_PIXMAP_COLORSPACE_sRGB = (1 << 2),
FBDEV_PIXMAP_EGL_MEMORY = (1 << 3) /* EGL allocates/frees this memory */
} fbdev_pixmap_flags;
typedef struct fbdev_window
unsigned short width;
unsigned short height;
} fbdev_window;
typedef struct fbdev_pixmap
unsigned int height;
unsigned int width;
unsigned int bytes_per_pixel;
unsigned char buffer_size;
unsigned char red_size;
unsigned char green_size;
unsigned char blue_size;
unsigned char alpha_size;
unsigned char luminance_size;
fbdev_pixmap_flags flags;
unsigned short *data;
unsigned int format; /* extra format information in case rgbal is not enough, especially for YUV formats */
} fbdev_pixmap;
void UploadTexture_UsingEGLImage(EGLDisplay sEGLDisplay, EGLContext sEGLContext, unsigned char *InPicture, GLuint _iTex)
fbdev_pixmap pixmap;
pixmap.height = HEIGHT;
pixmap.width = WIDTH;
pixmap.bytes_per_pixel = 4;
pixmap.buffer_size = 32;
pixmap.red_size = 8;
pixmap.green_size = 8;
pixmap.blue_size = 8;
pixmap.alpha_size = 8;
pixmap.luminance_size = 0;
pixmap.flags = FBDEV_PIXMAP_DEFAULT;
pixmap.data = (unsigned short*)InPicture;
pixmap.format = 1;
EGLImageKHR eglImage = eglCreateImageKHR(sEGLDisplay, sEGLContext, EGL_NATIVE_PIXMAP_KHR, &pixmap, NULL);
EGLint eglError = eglGetError();
if (eglError != EGL_SUCCESS)
printf("eglGetError() = %i (0x%.8x) at line %i\n", eglError, eglError, __LINE__);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
int main(int argc, char **argv)
CAVWindow wind;
EGLDisplay m_sEGLDisplay;
EGLSurface m_sEGLSurface;
EGLContext m_sEGLContext;
EGLint major, minor;
GLuint m_iVShader, m_iFShader;
GLuint m_iProgram;
GLint m_iLocPosition;
GLint m_iLocTexCoord;
GLint iStatus;
m_sEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); assert(m_sEGLDisplay != EGL_NO_DISPLAY);
EGLBoolean success = eglInitialize(m_sEGLDisplay, &major, &minor); assert(success == EGL_TRUE);
printf ("major=%d, minor = %d\n", major, minor );
g_configAttributes[15] = EGL_OPENGL_ES2_BIT;
g_contextAttributes[1] = 2;
g_contextAttributes[2] = EGL_NONE;
g_config = findConfig(m_sEGLDisplay);
wind.CreaFinestra(WIDTH, HEIGHT, L"testEGLImage", 0, 0, m_sEGLDisplay, g_config);
m_sEGLSurface = eglCreateWindowSurface(m_sEGLDisplay, g_config, (EGLNativeWindowType)wind.GethWnd(), g_windowAttributes); assert(m_sEGLSurface != EGL_NO_SURFACE);
eglBindAPI(EGL_OPENGL_ES_API);
m_sEGLContext = eglCreateContext(m_sEGLDisplay, g_config, EGL_NO_CONTEXT, g_contextAttributes); assert(m_sEGLContext != EGL_NO_CONTEXT);
eglMakeCurrent(m_sEGLDisplay, m_sEGLSurface, m_sEGLSurface, m_sEGLContext);
printf ("Vendor =%s\n", eglQueryString(m_sEGLDisplay, EGL_VENDOR));
printf ("API =%s\n", eglQueryString(m_sEGLDisplay, EGL_CLIENT_APIS));
printf ("Version=%s\n", eglQueryString(m_sEGLDisplay, EGL_VERSION));
printf ("Extens =%s\n", eglQueryString(m_sEGLDisplay, EGL_EXTENSIONS));
const GLubyte *strExt = glGetString(GL_EXTENSIONS);
printf("GL_EXTENSIONS: %s\n", strExt);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_DITHER);
glDisable(GL_POLYGON_OFFSET_FILL);
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
glDisable(GL_SAMPLE_COVERAGE);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
m_iVShader = glCreateShader(GL_VERTEX_SHADER);
m_iFShader = glCreateShader(GL_FRAGMENT_SHADER);
const char *pVShader = _VShaderSource_Blender;
const char *pFShader = _FShaderSource_Blender;
glShaderSource(m_iVShader, 1, &pVShader, NULL);
glShaderSource(m_iFShader, 1, &pFShader, NULL);
glCompileShader(m_iVShader);
glGetShaderiv(m_iVShader, GL_COMPILE_STATUS, &iStatus); assert(iStatus != GL_FALSE);
glCompileShader(m_iFShader);
glGetShaderiv(m_iFShader, GL_COMPILE_STATUS, &iStatus);assert(iStatus != GL_FALSE);
m_iProgram = glCreateProgram();
glAttachShader(m_iProgram, m_iVShader);
glAttachShader(m_iProgram, m_iFShader);
glLinkProgram(m_iProgram);
m_iLocPosition = glGetAttribLocation(m_iProgram, "a_position");
m_iLocTexCoord = glGetAttribLocation(m_iProgram, "a_texCoord");
GLuint iTex;
glGenTextures(1, &iTex);
glBindTexture(GL_TEXTURE_2D, iTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
unsigned char *TexData = new unsigned char[WIDTH * HEIGHT * 4];
for (int iCycles = 0; iCycles < NCYCLES; iCycles++)
memset(TexData, 0, WIDTH * HEIGHT * 4);
for (int y = 0; y < HEIGHT; y++)
for (int x = iCycles; x < iCycles + 16; x++)
TexData[y * WIDTH * 4 + 4 * x + 0] = 255;
TexData[y * WIDTH * 4 + 4 * x + 1] = 255;
TexData[y * WIDTH * 4 + 4 * x + 2] = 255;
TexData[y * WIDTH * 4 + 4 * x + 3] = 255;
//UploadTexture_UsingTextSubImage2D(TexData, iTex);
UploadTexture_UsingEGLImage(m_sEGLDisplay, m_sEGLContext, TexData, iTex);
//draw
glUseProgram(m_iProgram);
GLint BlenderSamplerLocInput = glGetUniformLocation(m_iProgram, "InputTex");
glVertexAttribPointer(m_iLocTexCoord, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]);
glEnableVertexAttribArray(m_iLocTexCoord);
glUniform1i(BlenderSamplerLocInput, 0);
glVertexAttribPointer(m_iLocPosition, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices);
glEnableVertexAttribArray(m_iLocPosition);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
GLenum glError = glGetError();
if (!eglSwapBuffers(m_sEGLDisplay, m_sEGLSurface))
printf("Failed to swap buffers.\n");
printf("typer enter\n");
getchar();
delete[] TexData;
//glClearColor(1.0, 1.0, 0.0, 1.0);
//glClear(GL_COLOR_BUFFER_BIT);
//glFlush();
//eglSwapBuffers(m_sEGLDisplay, m_sEGLSurface);
return 0;
====== AVWindow.h (create x11 window) =======
#pragma once
#include "os_types.h"
#include <string>
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include "CBaseThread.h"
class IAVWindowCBF
public:
virtual void OnEnd() {};
class CAVWindow : public CBaseThread
int m_cx, m_cy, m_PosX, m_PosY;
std::wstring m_windowName;
HWND m_hwnd;
void OnInit()
const HINSTANCE hInstance = NULL;
WNDCLASS wc;
* set up and register window class
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = m_windowName.c_str();
RegisterClass(&wc);
* create a window
RECT rc = { 0, 0, m_cx, m_cy };
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
m_hwnd = CreateWindowEx(
NULL,
m_windowName.c_str(),
WS_OVERLAPPEDWINDOW,
m_PosX,
m_PosY,
rc.right - rc.left,
rc.bottom - rc.top,
hInstance,
NULL);
assert(m_hwnd);
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG)this);
ShowWindow(m_hwnd, SW_SHOW);
void DoLoop()
MSG Msg;
//here we force queue creation. Very important, this must be done before sending any message...
PeekMessage(&Msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
while (GetMessage(&Msg, NULL, 0, 0))
TranslateMessage(&Msg);
DispatchMessage(&Msg);
void OnEnd()
DestroyWindow(m_hwnd);
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
CAVWindow *pThis = (CAVWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
long r = pThis->MyWindowProc(hWnd, message, wParam, lParam);
return r;
long MyWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
case WM_CLOSE:
//PostQuitMessage(0);
case WM_PAINT:
return 0; //break;
return (long)DefWindowProc(hWnd, message, wParam, lParam);
CAVWindow()
m_hwnd = NULL;
~CAVWindow()
void CreaFinestra(int cx, int cy, const std::wstring &wName, int posx, int posy)
m_cx = cx;
m_cy = cy;
m_windowName = wName;
m_PosX = posx;
m_PosY = posy;
Start();
void ChiudiFinestra()
if (m_bThreadRunning)
PostThreadMessage(m_ThreadId, WM_QUIT, 0, 0);
WaitThreadEnded();
HWND GethWnd()
return m_hwnd;
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
class CAVWindow
Colormap m_colormap;
XVisualInfo *m_visual;
Window m_window;
Display* m_display;
static Bool wait_for_map(Display *display, XEvent *event, char *windowPointer)
return (event->type == MapNotify && event->xmap.window == (*((Window*)windowPointer)));
void CreaFinestra(int windowWidth, int windowHeight, const std::wstring &wName, int posx, int posy, EGLDisplay eglDisplay, EGLConfig config)
XSetWindowAttributes windowAttributes;
XSizeHints sizeHints;
XEvent event;
XVisualInfo visualInfoTemplate;
unsigned long mask;
long screen;
int visualID, numberOfVisuals;
m_display = XOpenDisplay(NULL);
screen = DefaultScreen(m_display);
eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &visualID);
visualInfoTemplate.visualid = visualID;
m_visual = XGetVisualInfo(m_display, VisualIDMask, &visualInfoTemplate, &numberOfVisuals);
if (m_visual == NULL)
printf("Couldn't get X visual info\n");
throw "Couldn't get X visual info";
m_colormap = XCreateColormap(m_display, RootWindow(m_display, screen), m_visual->visual, AllocNone);
windowAttributes.colormap = m_colormap;
windowAttributes.background_pixel = 0xFFFFFFFF;
windowAttributes.border_pixel = 0;
windowAttributes.event_mask = StructureNotifyMask | ExposureMask;
mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
m_window = XCreateWindow(m_display, RootWindow(m_display, screen), 0, 0, windowWidth, windowHeight,
0, m_visual->depth, InputOutput, m_visual->visual, mask, &windowAttributes);
sizeHints.flags = USPosition;
sizeHints.x = 10;
sizeHints.y = 10;
XSetStandardProperties(m_display, m_window, "Mali OpenGL ES SDK", "", None, 0, 0, &sizeHints);
XMapWindow(m_display, m_window);
XIfEvent(m_display, &event, wait_for_map, (char*)(&m_window));
XSetWMColormapWindows(m_display, m_window, &m_window, 1);
XFlush(m_display);
XSelectInput(m_display, m_window, KeyPressMask | ExposureMask | EnterWindowMask
| LeaveWindowMask | PointerMotionMask | VisibilityChangeMask | ButtonPressMask
| ButtonReleaseMask | StructureNotifyMask);
XDestroyWindow(m_display, m_window);
XFreeColormap(m_display, m_colormap);
XFree(m_visual);
XCloseDisplay(m_display);
return (unsigned long)m_window;
I forgot to attach output of the application, where can be seen that extensions required are available on this platform
major=1, minor = 4
Number of configs found is 2
Vendor =ARM
API =OpenGL_ES
Version=1.4 Midgard-"r5p1-00rel1"
Extens =EGL_KHR_config_attribs EGL_KHR_image EGL_KHR_image_base EGL_KHR_fence_sync EGL_KHR_wait_sync EGL_KHR_gl_colorspace EGL_KHR_get_all_proc_addresses EGL_ARM_pixmap_multisample_discard EGL_KHR_gl_texture_2D_image EGL_KHR_gl_renderbuffer_image EGL_KHR_create_context EGL_KHR_surfaceless_context EGL_KHR_gl_texture_cubemap_image EGL_KHR_cl_event2 EGL_KHR_image_pixmap
GL_EXTENSIONS: GL_ARM_rgba8 GL_ARM_mali_shader_binary GL_OES_depth24 GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_EXT_read_format_bgra GL_OES_compressed_paletted_texture GL_OES_compressed_ETC1_RGB8_texture GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_texture_npot GL_OES_vertex_half_float GL_OES_required_internalformat GL_OES_vertex_array_object GL_OES_mapbuffer GL_EXT_texture_format_BGRA8888 GL_EXT_texture_rg GL_EXT_texture_type_2_10_10_10_REV GL_OES_fbo_render_mipmap GL_OES_element_index_uint GL_EXT_shadow_samplers GL_OES_texture_compression_astc GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_KHR_debug GL_EXT_occlusion_query_boolean GL_EXT_disjoint_timer_query GL_EXT_blend_minmax GL_EXT_discard_framebuffer GL_OES_get_program_binary GL_OES_texture_3D GL_EXT_texture_storage GL_EXT_multisampled_render_to_texture GL_OES_surfaceless_context GL_OES_texture_stencil8 GL_EXT_shader_pixel_local_storage GL_ARM_shader_framebuffer_fetch GL_ARM_shader_framebuffer_fetch_depth_stencil GL_ARM_mali_program_binary GL_EXT_sRGB GL_EXT_sRGB_write_control GL_EXT_texture_sRGB_decode GL_KHR_blend_equation_advanced GL_OES_texture_storage_multisample_2d_array GL_OES_shader_image_atomic
eglGetError() = 12300 (0x0000300c) at line 252
glGetError() = 1282 (0x00000502) at line 257
I also tried to use a XPixMap but nope....
instead of performing
UploadTexture_UsingEGLImage
I tried the following