Create and initialize a pbuffer.

I’m working on my Xperia X1 (WinCE 6.1, MSM7200a, OpenGL ES 1.1) and I’m trying to setup a pbuffer in order to perform offline rendering.
Here’s the code I’m using:


// EGL variables
EGLDisplay eglDisplay = 0;
EGLConfig eglConfigWindow = 0;
EGLConfig eglConfigPbuffer = 0;
EGLSurface eglSurfaceWindow = 0;
EGLSurface eglSurfacePbuffer = 0;
EGLContext eglContext = 0;

unsigned int testEGLError(HWND hWnd, char* pszLocation) {

	EGLint iErr = eglGetError();

	if (iErr != EGL_SUCCESS) {
		TCHAR pszStr[256];
		TCHAR tmsg[256];
		int i;

		i = 0;
		while (pszLocation[i] != '\0' && i < 255) {
			tmsg[i] = (TCHAR)(pszLocation[i]);
			i++;
		}
		tmsg[i] = (TCHAR)('\0');

		_stprintf(pszStr, _T("%s failed (%d).
"), tmsg, iErr);
		MessageBox(hWnd, pszStr, _T("Error"), MB_OK | MB_ICONEXCLAMATION);
		return 0;
	}
	return 1;
}

unsigned int initEGL(void) {

	EGLint iMajorVersion, iMinorVersion;
	int iConfigs;
	const EGLint attribListWindow[] = {
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_DEPTH_SIZE, 16,
		EGL_STENCIL_SIZE, 0,
		EGL_NONE
	};
	const EGLint attribListPbuffer[] = {
		EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_DEPTH_SIZE, 16,
		EGL_STENCIL_SIZE, 0,
		EGL_NONE
	};
	const EGLint srfPbufferAttr[] = {
		EGL_WIDTH, 256,
		EGL_HEIGHT, 256,
		// if enabled, the following lines result in a EGL_BAD_ATTRIBUTE error on the eglCreatePbufferSurface
		// EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
		// EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
		EGL_NONE
	};

	eglDisplay = eglGetDisplay((NativeDisplayType)hDC);
	if (eglDisplay == EGL_NO_DISPLAY)
		eglDisplay = eglGetDisplay((NativeDisplayType)EGL_DEFAULT_DISPLAY);

	if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
		goto cleanup;

	// choose a config valid for window surfaces
	if (!eglChooseConfig(eglDisplay, attribListWindow, &eglConfigWindow, 1, &iConfigs) || (iConfigs != 1))
		goto cleanup;

	// create a window surface
	eglSurfaceWindow = eglCreateWindowSurface(eglDisplay, eglConfigWindow, hWnd, NULL);
	if (eglSurfaceWindow == EGL_NO_SURFACE) {
		eglGetError();
		eglSurfaceWindow = eglCreateWindowSurface(eglDisplay, eglConfigWindow, NULL, NULL);
	}
	if (!testEGLError(hWnd, "eglCreateWindowSurface"))
		goto cleanup;

	// create a rendering context
	eglContext = eglCreateContext(eglDisplay, eglConfigWindow, NULL, NULL);
	if (!testEGLError(hWnd, "eglCreateContext"))
		goto cleanup;

	// try to make window the current surface
	eglMakeCurrent(eglDisplay, eglSurfaceWindow, eglSurfaceWindow, eglContext);
	if (!testEGLError(hWnd, "eglMakeCurrent(eglSurfaceWindow)"))
		goto cleanup;

	// choose a config valid for pbuffer surfaces
	if (!eglChooseConfig(eglDisplay, attribListPbuffer, &eglConfigPbuffer, 1, &iConfigs) || (iConfigs != 1))
		goto cleanup;

	// create a pbuffer surface
	eglSurfacePbuffer = eglCreatePbufferSurface(eglDisplay, eglConfigPbuffer, srfPbufferAttr);
	if (!testEGLError(hWnd, "eglCreatePbufferSurface"))
		goto cleanup;

	// try to make pbuffer the current surface
	eglMakeCurrent(eglDisplay, eglSurfacePbuffer, eglSurfacePbuffer, eglContext);
	if (!testEGLError(hWnd, "eglMakeCurrent(eglSurfacePbuffer)"))
		goto cleanup;

	return 1;

cleanup:
	eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
	if (eglSurfaceWindow != EGL_NO_SURFACE)
		eglDestroySurface(eglDisplay, eglSurfaceWindow);
	if (eglSurfacePbuffer != EGL_NO_SURFACE)
		eglDestroySurface(eglDisplay, eglSurfacePbuffer);
	if (eglContext != EGL_NO_CONTEXT)
		eglDestroyContext(eglDisplay, eglContext);
	eglTerminate(eglDisplay);
	return 0;
}

When the application run the eglMakeCurrent(eglDisplay, eglSurfacePbuffer, eglSurfacePbuffer, eglContext) command, it crashes and exits. Then, the device must be restarted in order to have other OpenGL ES applications running.
Could someone point me to a possible solution? Is my EGL initialization code wrong/incomplete?

Many thanks in advance.
Matteo.

Needless to say it probably shouldn’t crash, but you could try explicitly specify GLES by binding the API with eglBindAPI() and specifying the rendering bit in the config attributes for both surfaces. It’s possible the implementation isn’t completely to spec, and you can only hope the less ambiguous cases are more likely to work. Regardless it looks fair game for EGL1.4, so you might have more luck with the GLES vendor.