ppsspp/base/BlackberryDisplay.cpp
2013-08-20 20:33:16 +10:00

172 lines
5.6 KiB
C++

/*
* Copyright (c) 2013 Sacha Refshauge
*
*/
// Blackberry implementation of the framework.
#include "BlackberryMain.h"
char* BlackberryMain::displayTypeString(int type)
{
switch (type)
{
case SCREEN_DISPLAY_TYPE_INTERNAL:
return "Internal"; break;
case SCREEN_DISPLAY_TYPE_COMPOSITE:
return "Composite"; break;
case SCREEN_DISPLAY_TYPE_DVI:
return "DVI"; break;
case SCREEN_DISPLAY_TYPE_HDMI:
return "HDMI"; break;
case SCREEN_DISPLAY_TYPE_DISPLAYPORT:
return "DisplayPort"; break;
case SCREEN_DISPLAY_TYPE_OTHER:
default:
break;
}
return "Unknown Port";
}
void BlackberryMain::startDisplays() {
int num_configs;
EGLint attrib_list[]= {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE};
const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
screen_get_context_property_iv(screen_cxt, SCREEN_PROPERTY_DISPLAY_COUNT, &ndisplays);
egl_disp = (EGLDisplay*)calloc(ndisplays, sizeof(EGLDisplay));
egl_surf = (EGLSurface*)calloc(ndisplays, sizeof(EGLSurface));
displays = (dispdata_t*)calloc(ndisplays, sizeof(dispdata_t));
screen_win = (screen_window_t *)calloc(ndisplays, sizeof(screen_window_t ));
screen_dpy = (screen_display_t*)calloc(ndisplays, sizeof(screen_display_t));
screen_get_context_property_pv(screen_cxt, SCREEN_PROPERTY_DISPLAYS, (void **)screen_dpy);
// Common data
int usage = SCREEN_USAGE_ROTATION | SCREEN_USAGE_OPENGL_ES2;
int format = SCREEN_FORMAT_RGBX8888;
int sensitivity = SCREEN_SENSITIVITY_ALWAYS;
// Initialise every display
for (int i = 0; i < ndisplays; i++) {
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_TYPE, &(displays[i].type));
screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_ATTACHED, &(displays[i].attached));
screen_create_window(&screen_win[i], screen_cxt);
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_FORMAT, &format);
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_USAGE, &usage);
screen_set_window_property_iv(screen_win[i], SCREEN_PROPERTY_SENSITIVITY, &sensitivity);
screen_set_window_property_pv(screen_win[i], SCREEN_PROPERTY_DISPLAY, (void **)&screen_dpy[i]);
egl_disp[i] = eglGetDisplay((EGLNativeDisplayType)i);
eglInitialize(egl_disp[i], NULL, NULL);
if (egl_cont == EGL_NO_CONTEXT) {
eglChooseConfig(egl_disp[0], attrib_list, &egl_conf, 1, &num_configs);
egl_cont = eglCreateContext(egl_disp[0], egl_conf, EGL_NO_CONTEXT, attributes);
}
fprintf(stderr, "Display %i: %s, %s\n", i, displayTypeString(displays[i].type), displays[i].attached ? "Attached" : "Detached");
if (displays[i].attached)
realiseDisplay(i);
}
screen_get_display_property_iv(screen_dpy[0], SCREEN_PROPERTY_DPI, &dpi); // Only internal display has DPI
g_dpi_scale = ((pixel_xres == pixel_yres) ? 300.0f : 213.6f) / dpi;
switchDisplay(screen_ui);
}
void BlackberryMain::realiseDisplay(int idx) {
const EGLint egl_surfaceAttr[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
int size[2] = { atoi(getenv("WIDTH")), atoi(getenv("HEIGHT")) };
if (idx != 0)
screen_get_display_property_iv(screen_dpy[idx], SCREEN_PROPERTY_SIZE, size);
displays[idx].width = size[0];
displays[idx].height = size[1];
screen_set_window_property_iv(screen_win[idx], SCREEN_PROPERTY_BUFFER_SIZE, size);
screen_create_window_buffers(screen_win[idx], 2); // Double buffered
fprintf(stderr, "Display %i realised with %ix%i\n", idx, size[0], size[1]);
egl_surf[idx] = eglCreateWindowSurface(egl_disp[idx], egl_conf, screen_win[idx], egl_surfaceAttr);
// Only enable for devices with hardware QWERTY, 1:1 aspect ratio
if ((pixel_xres == pixel_yres) && displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL)
{
screen_emu = idx;
if (emulating)
switchDisplay(idx);
}
displays[idx].realised = true;
}
void BlackberryMain::unrealiseDisplay(int idx) {
if (displays[idx].type != SCREEN_DISPLAY_TYPE_INTERNAL) // Always true, only external can unrealise
{
screen_emu = screen_ui;
if (emulating)
switchDisplay(screen_ui);
}
killDisplay(idx, false);
displays[idx].realised = false;
}
void BlackberryMain::switchDisplay(int idx) {
static int screen_curr = -1;
if (idx != screen_curr) {
pixel_xres = displays[idx].width;
pixel_yres = displays[idx].height;
dp_xres = (int)(pixel_xres * g_dpi_scale);
dp_yres = (int)(pixel_yres * g_dpi_scale);
screen_curr = idx;
eglMakeCurrent(egl_disp[idx], egl_surf[idx], egl_surf[idx], egl_cont);
}
if (emulating) {
PSP_CoreParameter().pixelWidth = pixel_xres;
PSP_CoreParameter().pixelHeight = pixel_yres;
PSP_CoreParameter().outputWidth = dp_xres;
PSP_CoreParameter().outputHeight = dp_yres;
}
}
void BlackberryMain::killDisplays() {
for (int i = 0; i < ndisplays; i++) {
killDisplay(i, true);
}
if (egl_cont != EGL_NO_CONTEXT) {
eglDestroyContext(egl_disp[0], egl_cont);
egl_cont = EGL_NO_CONTEXT;
}
free(egl_disp);
free(egl_surf);
eglReleaseThread();
free(screen_dpy);
}
void BlackberryMain::killDisplay(int idx, bool killContext) {
if (egl_disp[idx] != EGL_NO_DISPLAY) {
if (killContext)
eglMakeCurrent(egl_disp[idx], EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (egl_surf[idx] != EGL_NO_SURFACE) {
eglDestroySurface(egl_disp[idx], egl_surf[idx]);
egl_surf[idx] = EGL_NO_SURFACE;
}
if (killContext)
{
eglTerminate(egl_disp[idx]);
egl_disp[idx] = EGL_NO_DISPLAY;
}
}
if (killContext && screen_win[idx] != NULL) {
screen_destroy_window(screen_win[idx]);
screen_win[idx] = NULL;
}
screen_destroy_window_buffers(screen_win[idx]);
}