예제 #1
0
파일: EGL.cpp 프로젝트: Alceris/ppsspp
bool cInterfaceEGL::ChooseAndCreate(void *window_handle, bool core, bool use565) {
	int attribs32[] = {
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  // Keep this first!
		EGL_RED_SIZE, 8,
		EGL_GREEN_SIZE, 8,
		EGL_BLUE_SIZE, 8,
		EGL_ALPHA_SIZE, 8,
		EGL_DEPTH_SIZE, 16,
		EGL_STENCIL_SIZE, 8,
		EGL_TRANSPARENT_TYPE, EGL_NONE,
		EGL_NONE, 0
	};
	int attribs16[] = {
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  // Keep this first!
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_DEPTH_SIZE, 16,
		EGL_STENCIL_SIZE, 8,
		EGL_TRANSPARENT_TYPE, EGL_NONE,
		EGL_NONE, 0
	};
	int attribsFallback32[] = {
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  // Keep this first!
		EGL_RED_SIZE, 8,
		EGL_GREEN_SIZE, 8,
		EGL_BLUE_SIZE, 8,
		EGL_ALPHA_SIZE, 8,
		EGL_DEPTH_SIZE, 16,
		EGL_NONE, 0
	};
	int attribsFallback16[] = {
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  // Keep this first!
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_DEPTH_SIZE, 16,
		EGL_NONE, 0
	};

	int *attribs = attribs32;
	int *attribsFallback = attribsFallback32;
	if (use565) {
		attribs = attribs16;
		attribsFallback = attribsFallback16;
	}

	EGLint ctx_attribs[] = {
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE, 0
	};

	switch (s_opengl_mode) {
	case MODE_OPENGL:
		EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_BIT");
		attribs[1] = EGL_OPENGL_BIT;
		ctx_attribs[0] = EGL_NONE;
		break;
	case MODE_OPENGLES2:
		EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_ES2_BIT");
		attribs[1] = EGL_OPENGL_ES2_BIT;
		ctx_attribs[1] = 2;
		break;
	case MODE_OPENGLES3:
		EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_ES3_BIT_KHR");
		attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
		ctx_attribs[1] = 3;
		break;
	default:
		EGL_ELOG("Unknown OpenGL mode set\n");
		return false;
		break;
	}

	EGL_ILOG("Calling eglChooseConfig to get number of configs (use16bit=%d)...", (int)use565);

	EGLConfig *configs;
	EGLint num_configs;
	if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) {
		EGL_ILOG("Error: couldn't get a number of configs. Trying with fallback config (no stencil, not specifying transparent:none)\n");
		attribsFallback[1] = attribs[1];
		attribs = attribsFallback;
		if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) {
			eglTerminate(egl_dpy);
			return false;
		}
	}

	EGL_ILOG("Got %d configs. Now choosing...", num_configs);
	configs = new EGLConfig[num_configs];

	if (!eglChooseConfig(egl_dpy, attribs, configs, num_configs, &num_configs)) {
		EGL_ELOG("Error: couldn't get an EGL visual config (num_configs=%d)! Terminating EGL.\n", num_configs);
		eglTerminate(egl_dpy);
		return false;
	}

	int chosenConfig = -1;
	// Find our ideal config in the list. If it's there, use it, otherwise pick whatever the device wanted (#0)
	int wantedAlpha = 8;
	// Requiring alpha seems to be a problem on older devices. Let's see if this helps...
	if (attribs[1] == EGL_OPENGL_ES2_BIT)
		wantedAlpha = 0;
	for (int i = 0; i < num_configs; i++) {
		EGL_ILOG("Config %d:", i);
		LogEGLConfig(egl_dpy, configs[i]);
		int red, green, blue, alpha, depth, stencil;
		eglGetConfigAttrib(egl_dpy, configs[i], EGL_RED_SIZE, &red);
		eglGetConfigAttrib(egl_dpy, configs[i], EGL_GREEN_SIZE, &green);
		eglGetConfigAttrib(egl_dpy, configs[i], EGL_BLUE_SIZE, &blue);
		eglGetConfigAttrib(egl_dpy, configs[i], EGL_ALPHA_SIZE, &alpha);
		eglGetConfigAttrib(egl_dpy, configs[i], EGL_DEPTH_SIZE, &depth);
		eglGetConfigAttrib(egl_dpy, configs[i], EGL_STENCIL_SIZE, &stencil);
		if (chosenConfig == -1 && red == 8 && green == 8 && blue == 8 && alpha == wantedAlpha && depth == 24 && stencil == 8) {
			chosenConfig = i;
		}
	}
	if (chosenConfig == -1)
		chosenConfig = 0;

	EGL_ILOG("eglChooseConfig successful: num_configs=%d, choosing config %d", num_configs, chosenConfig);

	if (s_opengl_mode == MODE_OPENGL) {
		EGL_ILOG("eglBindAPI(OPENGL)");
		eglBindAPI(EGL_OPENGL_API);
	} else {
		EGL_ILOG("eglBindAPI(OPENGL_ES)");
		eglBindAPI(EGL_OPENGL_ES_API);
	}

	EGLNativeWindowType host_window = (EGLNativeWindowType)window_handle;
	EGLNativeWindowType native_window = InitializePlatform(host_window, configs[chosenConfig]);

	const char *s = eglQueryString(egl_dpy, EGL_VERSION);
	EGL_ILOG("EGL_VERSION = %s\n", s);

	s = eglQueryString(egl_dpy, EGL_VENDOR);
	EGL_ILOG("EGL_VENDOR = %s\n", s);

	s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
	EGL_ILOG("EGL_EXTENSIONS = %s\n", s);

	s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
	EGL_ILOG("EGL_CLIENT_APIS = %s\n", s);

	egl_ctx = eglCreateContext(egl_dpy, configs[chosenConfig], EGL_NO_CONTEXT, ctx_attribs);
	if (!egl_ctx) {
		EGL_ILOG("Error: eglCreateContext failed: %s\n", EGLGetErrorString(eglGetError()));
		delete[] configs;
		return false;
	}
	EGL_ILOG("Successfully created EGL context.\n");

	egl_surf = eglCreateWindowSurface(egl_dpy, configs[chosenConfig], native_window, nullptr);
	if (!egl_surf) {
		EGL_ILOG("Error: eglCreateWindowSurface failed: native_window=%p error=%s ctx_attribs[1]==%d\n", native_window, EGLGetErrorString(eglGetError()), ctx_attribs[1]);
		eglDestroyContext(egl_dpy, egl_ctx);
		delete[] configs;
		return false;
	}
	EGL_ILOG("Successfully created EGL window surface (window=%p).\n", native_window);

	delete[] configs;
	return true;
}
예제 #2
0
// Create rendering window.
bool cInterfaceEGL::Create(void *window_handle, bool core, bool use16bit)
{
	const char *s;
	EGLint egl_major, egl_minor;

	egl_dpy = OpenDisplay();

	if (!egl_dpy)
	{
		INFO_LOG(G3D, "Error: eglGetDisplay() failed\n");
		return false;
	}

	if (!eglInitialize(egl_dpy, &egl_major, &egl_minor))
	{
		INFO_LOG(G3D, "Error: eglInitialize() failed\n");
		return false;
	}
	INFO_LOG(G3D, "eglInitialize() succeeded\n");

	if (s_opengl_mode == MODE_DETECT || s_opengl_mode == MODE_DETECT_ES)
		DetectMode();

	int attribs32[] = {
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  // Keep this first!
		EGL_RED_SIZE, 8,
		EGL_GREEN_SIZE, 8,
		EGL_BLUE_SIZE, 8,
		EGL_ALPHA_SIZE, 8,
		EGL_DEPTH_SIZE, 16,
		EGL_STENCIL_SIZE, 8,
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_TRANSPARENT_TYPE, EGL_NONE,
		EGL_SAMPLES, 0,
		EGL_NONE, 0
	};
	int attribs16[] = {
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  // Keep this first!
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_DEPTH_SIZE, 16,
		EGL_STENCIL_SIZE, 8,
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_TRANSPARENT_TYPE, EGL_NONE,
		EGL_SAMPLES, 0,
		EGL_NONE, 0
	};
	int *attribs = attribs32;
	if (use16bit) {
		attribs = attribs16;
	}

	EGLint ctx_attribs[] = {
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE, 0
	};

	switch (s_opengl_mode) {
		case MODE_OPENGL:
			attribs[1] = EGL_OPENGL_BIT;
			ctx_attribs[0] = EGL_NONE;
		break;
		case MODE_OPENGLES2:
			attribs[1] = EGL_OPENGL_ES2_BIT;
			ctx_attribs[1] = 2;
		break;
		case MODE_OPENGLES3:
			attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
			ctx_attribs[1] = 3;
		break;
		default:
			ERROR_LOG(G3D, "Unknown OpenGL mode set\n");
			return false;
		break;
	}

	EGLConfig *configs;
	EGLint num_configs;
	if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) {
		INFO_LOG(G3D, "Error: couldn't get a number of configs\n");
		eglTerminate(egl_dpy);
		return false;
	}

	configs = new EGLConfig[num_configs];

	if (!eglChooseConfig(egl_dpy, attribs, configs, num_configs, &num_configs)) {
		INFO_LOG(G3D, "Error: couldn't get an EGL visual config\n");
		eglTerminate(egl_dpy);
		return false;
	}

	INFO_LOG(G3D, "eglChooseConfig successful: num_configs=%d, choosing config 0", num_configs);
	for (int i = 0; i < num_configs; i++) {
		INFO_LOG(G3D, "Config %d:", i);
		LogEGLConfig(egl_dpy, configs[i]);
	}

	if (s_opengl_mode == MODE_OPENGL)
		eglBindAPI(EGL_OPENGL_API);
	else
		eglBindAPI(EGL_OPENGL_ES_API);

	EGLNativeWindowType host_window = (EGLNativeWindowType) window_handle;
	EGLNativeWindowType native_window = InitializePlatform(host_window, configs[0]);

	s = eglQueryString(egl_dpy, EGL_VERSION);
	INFO_LOG(G3D, "EGL_VERSION = %s\n", s);

	s = eglQueryString(egl_dpy, EGL_VENDOR);
	INFO_LOG(G3D, "EGL_VENDOR = %s\n", s);

	s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
	INFO_LOG(G3D, "EGL_EXTENSIONS = %s\n", s);

	s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
	INFO_LOG(G3D, "EGL_CLIENT_APIS = %s\n", s);

	egl_ctx = eglCreateContext(egl_dpy, configs[0], EGL_NO_CONTEXT, ctx_attribs);
	if (!egl_ctx) {
		INFO_LOG(G3D, "Error: eglCreateContext failed: %s\n", EGLGetErrorString(eglGetError()));
		eglTerminate(egl_dpy);
		delete[] configs;
		return false;
	}

	egl_surf = eglCreateWindowSurface(egl_dpy, configs[0], native_window, nullptr);
	if (!egl_surf) {
		INFO_LOG(G3D, "Error: eglCreateWindowSurface failed: native_window=%p error=%s ctx_attribs[1]==%d\n", native_window, EGLGetErrorString(eglGetError()), ctx_attribs[1]);

		eglDestroyContext(egl_dpy, egl_ctx);
		eglTerminate(egl_dpy);
		delete[] configs;
		return false;
	}

	delete[] configs;
	return true;
}