Exemplo n.º 1
0
static void gl_free(void *data)
{
#ifdef RARCH_CONSOLE
   if (driver.video_data)
      return;
#endif

   gl_t *gl = (gl_t*)data;

   gl_deinit_font(gl);
   gl_shader_deinit();
   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   glDisableClientState(GL_COLOR_ARRAY);
   glDeleteTextures(TEXTURES, gl->texture);

#ifdef HAVE_OPENGL_TEXREF
   glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
   glDeleteBuffers(1, &gl->pbo);
#endif

#ifdef HAVE_FBO
   gl_deinit_fbo(gl);
#endif

   gfx_ctx_destroy();

   if (gl->empty_buf)
      free(gl->empty_buf);

   free(gl);
}
Exemplo n.º 2
0
static bool gfx_ctx_init(void)
{
   if (g_inited)
      return false;

   static const int visual_attribs[] = {
      GLX_X_RENDERABLE     , True,
      GLX_DRAWABLE_TYPE    , GLX_WINDOW_BIT,
      GLX_RENDER_TYPE      , GLX_RGBA_BIT,
      GLX_DOUBLEBUFFER     , True,
      GLX_RED_SIZE         , 8,
      GLX_GREEN_SIZE       , 8,
      GLX_BLUE_SIZE        , 8,
      GLX_ALPHA_SIZE       , 8,
      GLX_DEPTH_SIZE       , 0,
      GLX_STENCIL_SIZE     , 0,
      None
   };

   GLXFBConfig *fbcs = NULL;

   g_quit = 0;

   init_lut();

   g_dpy = XOpenDisplay(NULL);
   if (!g_dpy)
      goto error;

   // GLX 1.3+ required.
   int major, minor;
   glXQueryVersion(g_dpy, &major, &minor);
   if (major < 1 || (major == 1 && minor < 3))
      goto error;

   int nelements;
   fbcs = glXChooseFBConfig(g_dpy, DefaultScreen(g_dpy),
         visual_attribs, &nelements);

   if (!fbcs)
      goto error;

   if (!nelements)
   {
      XFree(fbcs);
      goto error;
   }

   g_fbc = fbcs[0];
   XFree(fbcs);

   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 3
0
static bool gfx_ctx_set_video_mode(
      unsigned width, unsigned height,
      bool fullscreen)
{
   if (g_inited)
      return false;

   int ret = 0;
   struct drm_fb *fb = NULL;

   struct sigaction sa = {{0}};
   sa.sa_handler = sighandler;
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);

#define EGL_ATTRIBS_BASE \
   EGL_SURFACE_TYPE,    EGL_WINDOW_BIT, \
   EGL_RED_SIZE,        1, \
   EGL_GREEN_SIZE,      1, \
   EGL_BLUE_SIZE,       1, \
   EGL_ALPHA_SIZE,      0, \
   EGL_DEPTH_SIZE,      0

   static const EGLint egl_attribs_gl[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_vg[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   // GLES 2.0. Don't use for any other API.
   static const EGLint gles_context_attribs[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };

   const EGLint *attrib_ptr;
   switch (g_api)
   {
      case GFX_CTX_OPENGL_API:
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
         attrib_ptr = egl_attribs_gles;
         break;
      case GFX_CTX_OPENVG_API:
         attrib_ptr = egl_attribs_vg;
         break;
      default:
         attrib_ptr = NULL;
   }

   g_egl_dpy = eglGetDisplay((EGLNativeDisplayType)g_gbm_dev);
   if (!g_egl_dpy)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get EGL display.\n");
      goto error;
   }

   EGLint major, minor;
   if (!eglInitialize(g_egl_dpy, &major, &minor))
      goto error;

   EGLint n;
   if (!eglChooseConfig(g_egl_dpy, attrib_ptr, &g_config, 1, &n) || n != 1)
      goto error;

   g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, (g_api == GFX_CTX_OPENGL_ES_API) ? gles_context_attribs : NULL);
   if (!g_egl_ctx)
      goto error;

   g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_gbm_surface, NULL);
   if (!g_egl_surf)
      goto error;

   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
      goto error;

   glClear(GL_COLOR_BUFFER_BIT);
   eglSwapBuffers(g_egl_dpy, g_egl_surf);

   g_bo = gbm_surface_lock_front_buffer(g_gbm_surface);
   fb = drm_fb_get_from_bo(g_bo);

   ret = drmModeSetCrtc(g_drm_fd, g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, g_drm_mode);
   if (ret < 0)
      goto error;

   g_inited = true;
   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 4
0
static bool gfx_ctx_init(void)
{
   if (g_inited)
      return false;

   g_drm_fd = open("/dev/dri/card0", O_RDWR);
   if (g_drm_fd < 0)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't open DRM device.\n");
      goto error;
   }

   g_resources = drmModeGetResources(g_drm_fd);
   if (!g_resources)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get device resources.\n");
      goto error;
   }

   for (int i = 0; i < g_resources->count_connectors; i++)
   {
      g_connector = drmModeGetConnector(g_drm_fd, g_resources->connectors[i]);

      if (!g_connector)
         continue;
      if (g_connector->connection == DRM_MODE_CONNECTED && g_connector->count_modes > 0)
         break;

      drmModeFreeConnector(g_connector);
      g_connector = NULL;
   }

   if (!g_connector)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get device connector.\n");
      goto error;
   }

   for (int i = 0; i < g_resources->count_encoders; i++)
   {
      g_encoder = drmModeGetEncoder(g_drm_fd, g_resources->encoders[i]);

      if (!g_encoder)
         continue;
      if (g_encoder->encoder_id == g_connector->encoder_id)
         break;

      drmModeFreeEncoder(g_encoder);
      g_encoder = NULL;
   }

   if (!g_encoder)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find DRM encoder.\n");
      goto error;
   }

   g_drm_mode = &g_connector->modes[0];

   g_crtc_id   = g_encoder->crtc_id;
   g_orig_crtc = drmModeGetCrtc(g_drm_fd, g_crtc_id);
   if (!g_orig_crtc)
      RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");

   g_connector_id = g_connector->connector_id;

   g_fb_width  = g_drm_mode->hdisplay;
   g_fb_height = g_drm_mode->vdisplay;

   g_gbm_dev     = gbm_create_device(g_drm_fd);
   g_gbm_surface = gbm_surface_create(g_gbm_dev,
         g_fb_width, g_fb_height,
         GBM_FORMAT_XRGB8888,
         GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

   if (!g_gbm_surface)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't create GBM surface.\n");
      goto error;
   }

   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 5
0
static bool gfx_ctx_init(void)
{
   const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_NONE
   };
   EGLint num_config;
   EGLint egl_version_major, egl_version_minor;
   int format = SCREEN_FORMAT_RGBX8888;

   EGLint context_attributes[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
   int usage;

   usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION;

   RARCH_LOG("Initializing context\n");

   if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY)
   {
      RARCH_ERR("eglGetDisplay failed.\n");
      goto error;
   }

   if (!eglInitialize(g_egl_dpy, &egl_version_major, &egl_version_minor))
   {
      RARCH_ERR("eglInitialize failed.\n");
      goto error;
   }

   if (!eglBindAPI(EGL_OPENGL_ES_API))
   {
      RARCH_ERR("eglBindAPI failed.\n");
      goto error;
   }

   RARCH_LOG("[BLACKBERRY QNX/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor);

   if (!eglChooseConfig(g_egl_dpy, attribs, &egl_config, 1, &num_config))
   {
      RARCH_ERR("eglChooseConfig failed.\n");
      goto error;
   }

   if ((g_egl_ctx = eglCreateContext(g_egl_dpy, egl_config, 0, context_attributes)) == EGL_NO_CONTEXT)
   {
      RARCH_ERR("eglCreateContext failed.\n");
      goto error;
   }

   if (screen_create_window(&screen_win, screen_ctx))
   {
      RARCH_ERR("screen_create_window failed:.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_FORMAT] failed.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_USAGE] failed.\n");
      goto error;
   }

   if (screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp))
   {
      RARCH_ERR("screen_get_window_property_pv [SCREEN_PROPERTY_DISPLAY] failed.\n");
      goto error;
   }

   int screen_resolution[2];

   if (screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution))
   {
      RARCH_ERR("screen_get_window_property_iv [SCREEN_PROPERTY_SIZE] failed.\n");
      goto error;
   }

   int angle = atoi(getenv("ORIENTATION"));

   screen_display_mode_t screen_mode;
   if (screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode))
   {
      RARCH_ERR("screen_get_display_property_pv [SCREEN_PROPERTY_MODE] failed.\n");
      goto error;
   }

   int size[2];
   if (screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size)) {
      RARCH_ERR("screen_get_window_property_iv [SCREEN_PROPERTY_BUFFER_SIZE] failed.\n");
      goto error;
   }

   int buffer_size[2] = {size[0], size[1]};

   if ((angle == 0) || (angle == 180)) {
      if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
            ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) {
         buffer_size[1] = size[0];
         buffer_size[0] = size[1];
      }
   } else if ((angle == 90) || (angle == 270)){
      if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
            ((screen_mode.width < screen_mode.height && size[0] < size[1]))) {
         buffer_size[1] = size[0];
         buffer_size[0] = size[1];
      }
   } else {
      RARCH_ERR("Navigator returned an unexpected orientation angle.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_BUFFER_SIZE] failed.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_ROTATION] failed.\n");
      goto error;
   }

   if (screen_create_window_buffers(screen_win, WINDOW_BUFFERS))
   {
      RARCH_ERR("screen_create_window_buffers failed.\n");
      goto error;
   }

   if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, egl_config, screen_win, 0)))
   {
      RARCH_ERR("eglCreateWindowSurface failed.\n");
      goto error;
   }


   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
   {
      RARCH_ERR("eglMakeCurrent failed.\n");
      goto error;
   }

   return true;

error:
   RARCH_ERR("EGL error: %d.\n", eglGetError());
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 6
0
static bool gfx_ctx_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   if (g_inited)
      return false;

   int i;
   int ret = 0;
   struct drm_fb *fb = NULL;

   struct sigaction sa = {{0}};
   sa.sa_handler = sighandler;
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);

#define EGL_ATTRIBS_BASE \
   EGL_SURFACE_TYPE,    EGL_WINDOW_BIT, \
   EGL_RED_SIZE,        1, \
   EGL_GREEN_SIZE,      1, \
   EGL_BLUE_SIZE,       1, \
   EGL_ALPHA_SIZE,      0, \
   EGL_DEPTH_SIZE,      0

   static const EGLint egl_attribs_gl[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif

   static const EGLint egl_attribs_vg[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   const EGLint *attrib_ptr;
   switch (g_api)
   {
      case GFX_CTX_OPENGL_API:
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef EGL_KHR_create_context
         if (g_major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
         attrib_ptr = egl_attribs_gles;
         break;
      case GFX_CTX_OPENVG_API:
         attrib_ptr = egl_attribs_vg;
         break;
      default:
         attrib_ptr = NULL;
   }

   // Find desired video mode, and use that.
   // If not fullscreen, we get desired windowed size, which is not appropriate.
   if ((width == 0 && height == 0) || !fullscreen)
      g_drm_mode = &g_connector->modes[0];
   else
   {
      // Try to match g_settings.video.refresh_rate as closely as possible.
      // Lower resolutions tend to have multiple supported refresh rates as well.
      float minimum_fps_diff = 0.0f;

      // Find best match.
      for (i = 0; i < g_connector->count_modes; i++)
      {
         if (width != g_connector->modes[i].hdisplay || height != g_connector->modes[i].vdisplay)
            continue;

         if (!g_drm_mode)
         {
            g_drm_mode = &g_connector->modes[i];
            minimum_fps_diff = g_drm_mode->vrefresh - g_settings.video.refresh_rate;
         }
         else
         {
            float diff = g_connector->modes[i].vrefresh - g_settings.video.refresh_rate;
            if (diff < minimum_fps_diff)
            {
               g_drm_mode = &g_connector->modes[i];
               minimum_fps_diff = diff;
            }
         }
      }
   }

   if (!g_drm_mode)
   {
      RARCH_ERR("[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", width, height);
      goto error;
   }

   g_fb_width = g_drm_mode->hdisplay;
   g_fb_height = g_drm_mode->vdisplay;

   // Create GBM surface.
   g_gbm_surface = gbm_surface_create(g_gbm_dev,
         g_fb_width, g_fb_height,
         GBM_FORMAT_XRGB8888,
         GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

   if (!g_gbm_surface)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't create GBM surface.\n");
      goto error;
   }

   g_egl_dpy = eglGetDisplay((EGLNativeDisplayType)g_gbm_dev);
   if (!g_egl_dpy)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get EGL display.\n");
      goto error;
   }

   EGLint major, minor;
   if (!eglInitialize(g_egl_dpy, &major, &minor))
      goto error;

   EGLint n;
   if (!eglChooseConfig(g_egl_dpy, attrib_ptr, &g_config, 1, &n) || n != 1)
      goto error;

   EGLint egl_attribs[16];
   EGLint *attr = egl_attribs;
   attr = egl_fill_attribs(attr);

   g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT,
         attr != egl_attribs ? egl_attribs : NULL);

   if (g_egl_ctx == EGL_NO_CONTEXT)
      goto error;

   if (g_use_hw_ctx)
   {
      g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_config, g_egl_ctx,
            attr != egl_attribs ? egl_attribs : NULL);
      RARCH_LOG("[KMS/EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx);

      if (g_egl_hw_ctx == EGL_NO_CONTEXT)
         goto error;
   }

   g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_gbm_surface, NULL);
   if (!g_egl_surf)
      goto error;

   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
      goto error;

   glClear(GL_COLOR_BUFFER_BIT);
   eglSwapBuffers(g_egl_dpy, g_egl_surf);

   g_bo = gbm_surface_lock_front_buffer(g_gbm_surface);
   fb = drm_fb_get_from_bo(g_bo);

   ret = drmModeSetCrtc(g_drm_fd, g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, g_drm_mode);
   if (ret < 0)
      goto error;

   g_inited = true;
   return true;

error:
   gfx_ctx_destroy(data);
   return false;
}
Exemplo n.º 7
0
static bool gfx_ctx_set_video_mode(
      unsigned width, unsigned height,
      bool fullscreen)
{
   DWORD style;
   RECT rect   = {0};

   HMONITOR hm_to_use = NULL;
   MONITORINFOEX current_mon;

   monitor_info(&current_mon, &hm_to_use);
   RECT mon_rect = current_mon.rcMonitor;

   g_resize_width  = width;
   g_resize_height = height;

   bool windowed_full = g_settings.video.windowed_fullscreen;
   if (fullscreen)
   {
      if (windowed_full)
      {
         style = WS_EX_TOPMOST | WS_POPUP;
         g_resize_width  = width  = mon_rect.right - mon_rect.left;
         g_resize_height = height = mon_rect.bottom - mon_rect.top;
      }
      else
      {
         style = WS_POPUP | WS_VISIBLE;

         if (!set_fullscreen(width, height, current_mon.szDevice))
            goto error;

         // display settings might have changed, get new coordinates
         GetMonitorInfo(hm_to_use, (MONITORINFO*)&current_mon);
         mon_rect = current_mon.rcMonitor;
         g_restore_desktop = true;
      }
   }
   else
   {
      style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
      rect.right  = width;
      rect.bottom = height;
      AdjustWindowRect(&rect, style, FALSE);
      width  = rect.right - rect.left;
      height = rect.bottom - rect.top;
   }

   g_hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", style,
         fullscreen ? mon_rect.left : g_pos_x,
         fullscreen ? mon_rect.top  : g_pos_y,
         width, height,
         NULL, NULL, NULL, NULL);

   if (!g_hwnd)
      goto error;

   if (!fullscreen)
   {
      SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU)));
      RECT rcTemp = {0, 0, g_resize_height, 0x7FFF}; // 0x7FFF="Infinite" height
      SendMessage(g_hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rcTemp); // recalculate margin, taking possible menu wrap into account
      g_resize_height += rcTemp.top + rect.top; // extend by new top margin and substract previous margin
      SetWindowPos(g_hwnd, NULL, 0, 0, g_resize_width, g_resize_height, SWP_NOMOVE);
   }

   if (!fullscreen || windowed_full)
   {
      ShowWindow(g_hwnd, SW_RESTORE);
      UpdateWindow(g_hwnd);
      SetForegroundWindow(g_hwnd);
      SetFocus(g_hwnd);
   }

   show_cursor(!fullscreen);

   // Wait until GL context is created (or failed to do so ...)
   MSG msg;
   while (!g_inited && !g_quit && GetMessage(&msg, g_hwnd, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   if (g_quit)
      goto error;

   p_swap_interval = (BOOL (APIENTRY *)(int))wglGetProcAddress("wglSwapIntervalEXT");

   gfx_ctx_swap_interval(g_interval);

   driver.display_type  = RARCH_DISPLAY_WIN32;
   driver.video_display = 0;
   driver.video_window  = (uintptr_t)g_hwnd;

   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 8
0
static bool gfx_ctx_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   struct sigaction sa = {{0}};
   sa.sa_handler = sighandler;
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);
   int x_off = 0;
   int y_off = 0;

   bool windowed_full = g_settings.video.windowed_fullscreen;
   bool true_full = false;
   int (*old_handler)(Display*, XErrorEvent*) = NULL;

   XSetWindowAttributes swa = {0};

   XVisualInfo *vi = glXGetVisualFromFBConfig(g_dpy, g_fbc);
   if (!vi)
      goto error;

   swa.colormap = g_cmap = XCreateColormap(g_dpy, RootWindow(g_dpy, vi->screen),
         vi->visual, AllocNone);
   swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask;
   swa.override_redirect = fullscreen ? True : False;

   if (fullscreen && !windowed_full)
   {
      if (x11_enter_fullscreen(g_dpy, width, height, &g_desktop_mode))
      {
         g_should_reset_mode = true;
         true_full = true;
      }
      else
         RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n");
   }

   if (g_settings.video.monitor_index)
      g_screen = g_settings.video.monitor_index - 1;

#ifdef HAVE_XINERAMA
   if (fullscreen || g_screen != 0)
   {
      unsigned new_width  = width;
      unsigned new_height = height;
      if (x11_get_xinerama_coord(g_dpy, g_screen, &x_off, &y_off, &new_width, &new_height))
         RARCH_LOG("[GLX]: Using Xinerama on screen #%u.\n", g_screen);
      else
         RARCH_LOG("[GLX]: Xinerama is not active on screen.\n");

      if (fullscreen)
      {
         width  = new_width;
         height = new_height;
      }
   }
#endif

   RARCH_LOG("[GLX]: X = %d, Y = %d, W = %u, H = %u.\n",
         x_off, y_off, width, height);

   g_win = XCreateWindow(g_dpy, RootWindow(g_dpy, vi->screen),
         x_off, y_off, width, height, 0,
         vi->depth, InputOutput, vi->visual, 
         CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa);
   XSetWindowBackground(g_dpy, g_win, 0);

   g_glx_win = glXCreateWindow(g_dpy, g_fbc, g_win, 0);

   x11_set_window_attr(g_dpy, g_win);

   if (fullscreen)
      x11_show_mouse(g_dpy, g_win, false);

   if (true_full)
   {
      RARCH_LOG("[GLX]: Using true fullscreen.\n");
      XMapRaised(g_dpy, g_win);
   }
   else if (fullscreen) // We attempted true fullscreen, but failed. Attempt using windowed fullscreen.
   {
      XMapRaised(g_dpy, g_win);
      RARCH_LOG("[GLX]: Using windowed fullscreen.\n");
      // We have to move the window to the screen we want to go fullscreen on first.
      // x_off and y_off usually get ignored in XCreateWindow().
      x11_move_window(g_dpy, g_win, x_off, y_off, width, height);
      x11_windowed_fullscreen(g_dpy, g_win);
   }
   else
   {
      XMapWindow(g_dpy, g_win);
      // If we want to map the window on a different screen, we'll have to do it by force.
      // Otherwise, we should try to let the window manager sort it out.
      // x_off and y_off usually get ignored in XCreateWindow().
      if (g_screen)
         x11_move_window(g_dpy, g_win, x_off, y_off, width, height);
   }

   XEvent event;
   XIfEvent(g_dpy, &event, glx_wait_notify, NULL);

   if (!g_ctx)
   {
      if (g_core || g_debug)
      {
         int attribs[16];
         int *aptr = attribs;

         if (g_core)
         {
            *aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB;
            *aptr++ = g_major;
            *aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB;
            *aptr++ = g_minor;

            // Technically, we don't have core/compat until 3.2.
            // Version 3.1 is either compat or not depending on GL_ARB_compatibility.
            if ((g_major * 1000 + g_minor) >= 3002)
            {
               *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB;
               *aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
            }
         }

         if (g_debug)
         {
            *aptr++ = GLX_CONTEXT_FLAGS_ARB;
            *aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB;
         }

         *aptr = None;
         g_ctx = glx_create_context_attribs(g_dpy, g_fbc, NULL, True, attribs);
         if (g_use_hw_ctx)
         {
            RARCH_LOG("[GLX]: Creating shared HW context.\n");
            g_hw_ctx = glx_create_context_attribs(g_dpy, g_fbc, g_ctx, True, attribs);
            if (!g_hw_ctx)
               RARCH_ERR("[GLX]: Failed to create new shared context.\n");
         }
      }
      else
      {
         g_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, 0, True);
         if (g_use_hw_ctx)
         {
            g_hw_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, g_ctx, True);
            if (!g_hw_ctx)
               RARCH_ERR("[GLX]: Failed to create new shared context.\n");
         }
      }

      if (!g_ctx)
      {
         RARCH_ERR("[GLX]: Failed to create new context.\n");
         goto error;
      }
   }
   else
   {
      driver.video_cache_context_ack = true;
      RARCH_LOG("[GLX]: Using cached GL context.\n");
   }

   glXMakeContextCurrent(g_dpy, g_glx_win, g_glx_win, g_ctx);
   XSync(g_dpy, False);

   g_quit_atom = XInternAtom(g_dpy, "WM_DELETE_WINDOW", False);
   if (g_quit_atom)
      XSetWMProtocols(g_dpy, g_win, &g_quit_atom, 1);

   int val;
   glXGetConfig(g_dpy, vi, GLX_DOUBLEBUFFER, &val);
   g_is_double = val;
   if (g_is_double)
   {
      const char *swap_func = NULL;

      g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
      g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA");

      if (g_pglSwapIntervalEXT)
         swap_func = "glXSwapIntervalEXT";
      else if (g_pglSwapInterval)
         swap_func = "glXSwapIntervalMESA";

      if (!g_pglSwapInterval && !g_pglSwapIntervalEXT)
         RARCH_WARN("[GLX]: Cannot find swap interval call.\n");
      else
         RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func);
   }
   else
      RARCH_WARN("[GLX]: Context is not double buffered!.\n");

   gfx_ctx_swap_interval(data, g_interval);

   // This can blow up on some drivers. It's not fatal, so override errors for this call.
   old_handler = XSetErrorHandler(nul_handler);
   XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime);
   XSync(g_dpy, False);
   XSetErrorHandler(old_handler);

   XFree(vi);
   g_has_focus = true;
   g_inited    = true;

   if (!x11_create_input_context(g_dpy, g_win, &g_xim, &g_xic))
      goto error;

   driver.display_type  = RARCH_DISPLAY_X11;
   driver.video_display = (uintptr_t)g_dpy;
   driver.video_window  = (uintptr_t)g_win;
   g_true_full = true_full;

   return true;

error:
   if (vi)
      XFree(vi);

   gfx_ctx_destroy(data);
   return false;
}
Exemplo n.º 9
0
static bool gfx_ctx_set_video_mode(
      unsigned width, unsigned height,
      bool fullscreen)
{
   struct sigaction sa = {{0}};
   sa.sa_handler = sighandler;
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);

   XVisualInfo temp = {0};
   XSetWindowAttributes swa = {0};
   XVisualInfo *vi = NULL;
   bool windowed_full = g_settings.video.windowed_fullscreen;
   bool true_full = false;
   int x_off = 0;
   int y_off = 0;

   int (*old_handler)(Display*, XErrorEvent*) = NULL;

   EGLint vid;
   if (!eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &vid))
      goto error;

   temp.visualid = vid;

   EGLint num_visuals;
   vi = XGetVisualInfo(g_dpy, VisualIDMask, &temp, &num_visuals);
   if (!vi)
      goto error;

   swa.colormap = g_cmap = XCreateColormap(g_dpy, RootWindow(g_dpy, vi->screen),
         vi->visual, AllocNone);
   swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask;
   swa.override_redirect = fullscreen ? True : False;

   if (fullscreen && !windowed_full)
   {
      if (x11_enter_fullscreen(g_dpy, width, height, &g_desktop_mode))
      {
         g_should_reset_mode = true;
         true_full = true;
      }
      else
         RARCH_ERR("[X/EGL]: Entering true fullscreen failed. Will attempt windowed mode.\n");
   }

   if (g_settings.video.monitor_index)
      g_screen = g_settings.video.monitor_index - 1;

#ifdef HAVE_XINERAMA
   if (fullscreen || g_screen != 0)
   {
      unsigned new_width  = width;
      unsigned new_height = height;
      if (x11_get_xinerama_coord(g_dpy, g_screen, &x_off, &y_off, &new_width, &new_height))
         RARCH_LOG("[X/EGL]: Using Xinerama on screen #%u.\n", g_screen);
      else
         RARCH_LOG("[X/EGL]: Xinerama is not active on screen.\n");

      if (fullscreen)
      {
         width  = new_width;
         height = new_height;
      }
   }
#endif

   RARCH_LOG("[X/EGL]: X = %d, Y = %d, W = %u, H = %u.\n",
         x_off, y_off, width, height);

   g_win = XCreateWindow(g_dpy, RootWindow(g_dpy, vi->screen),
         x_off, y_off, width, height, 0,
         vi->depth, InputOutput, vi->visual, 
         CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa);
   XSetWindowBackground(g_dpy, g_win, 0);

   // GLES 2.0. Don't use for any other API.
   static const EGLint egl_ctx_gles_attribs[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE,
   };

   g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT,
         (g_api == GFX_CTX_OPENGL_ES_API) ? egl_ctx_gles_attribs : NULL);

   RARCH_LOG("[X/EGL]: Created context: %p.\n", (void*)g_egl_ctx);

   if (!g_egl_ctx)
      goto error;

   g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_win, NULL);
   if (!g_egl_surf)
      goto error;

   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
      goto error;

   RARCH_LOG("[X/EGL]: Current context: %p.\n", (void*)eglGetCurrentContext());

   x11_set_window_attr(g_dpy, g_win);

   if (fullscreen)
      x11_show_mouse(g_dpy, g_win, false);

   if (true_full)
   {
      RARCH_LOG("[X/EGL]: Using true fullscreen.\n");
      XMapRaised(g_dpy, g_win);
   }
   else if (fullscreen) // We attempted true fullscreen, but failed. Attempt using windowed fullscreen.
   {
      XMapRaised(g_dpy, g_win);
      RARCH_LOG("[X/EGL]: Using windowed fullscreen.\n");
      // We have to move the window to the screen we want to go fullscreen on first.
      // x_off and y_off usually get ignored in XCreateWindow().
      x11_move_window(g_dpy, g_win, x_off, y_off, width, height);
      x11_windowed_fullscreen(g_dpy, g_win);
   }
   else
   {
      XMapWindow(g_dpy, g_win);
      // If we want to map the window on a different screen, we'll have to do it by force.
      // Otherwise, we should try to let the window manager sort it out.
      // x_off and y_off usually get ignored in XCreateWindow().
      if (g_screen)
         x11_move_window(g_dpy, g_win, x_off, y_off, width, height);
   }

   XEvent event;
   XIfEvent(g_dpy, &event, egl_wait_notify, NULL);

   g_quit_atom = XInternAtom(g_dpy, "WM_DELETE_WINDOW", False);
   if (g_quit_atom)
      XSetWMProtocols(g_dpy, g_win, &g_quit_atom, 1);

   gfx_ctx_swap_interval(g_interval);

   // This can blow up on some drivers. It's not fatal, so override errors for this call.
   old_handler = XSetErrorHandler(nul_handler);
   XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime);
   XSync(g_dpy, False);
   XSetErrorHandler(old_handler);

   XFree(vi);
   g_has_focus = true;
   g_inited    = true;

   driver.display_type  = RARCH_DISPLAY_X11;
   driver.video_display = (uintptr_t)g_dpy;
   driver.video_window  = (uintptr_t)g_win;
   g_true_full = true_full;

   return true;

error:
   if (vi)
      XFree(vi);

   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 10
0
static bool gfx_ctx_init(void)
{
   RARCH_LOG("gfx_ctx_init().\n");
   const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_NONE
   };
   EGLint num_config;
   EGLint egl_version_major, egl_version_minor;
   EGLint format;
   EGLint width;
   EGLint height;
   GLfloat ratio;

   EGLint context_attributes[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };

   RARCH_LOG("Initializing context\n");

   if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY)
   {
      RARCH_ERR("eglGetDisplay failed.\n");
      goto error;
   }

   if (!eglInitialize(g_egl_dpy, &egl_version_major, &egl_version_minor))
   {
      RARCH_ERR("eglInitialize failed.\n");
      goto error;
   }

   RARCH_LOG("[ANDROID/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor);

   if (!eglChooseConfig(g_egl_dpy, attribs, &g_config, 1, &num_config))
   {
      RARCH_ERR("eglChooseConfig failed.\n");
      goto error;
   }

   int var = eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &format);

   if (!var)
   {
      RARCH_ERR("eglGetConfigAttrib failed: %d.\n", var);
      goto error;
   }

   ANativeWindow_setBuffersGeometry(g_android.app->window, 0, 0, format);

   if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, g_android.app->window, 0)))
   {
      RARCH_ERR("eglCreateWindowSurface failed.\n");
      goto error;
   }

   if (!(g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, 0, context_attributes)))
   {
      RARCH_ERR("eglCreateContext failed.\n");
      goto error;
   }

   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
   {
      RARCH_ERR("eglMakeCurrent failed.\n");
      goto error;
   }

   if (!eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &width) ||
         !eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height))
   {
      RARCH_ERR("eglQuerySurface failed.\n");
      goto error;
   }

   if (g_extern.lifecycle_state & (1ULL << RARCH_REENTRANT))
   {
      RARCH_LOG("[ANDROID/EGL]: Setting up reentrant state.\n");
      gfx_ctx_orientation_update();
   }

   return true;

error:
   RARCH_ERR("EGL error: %d.\n", eglGetError());
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 11
0
static bool gfx_ctx_init(void)
{
   if (g_inited)
      return false;

   XInitThreads();

#define EGL_ATTRIBS_BASE \
   EGL_SURFACE_TYPE,    EGL_WINDOW_BIT, \
   EGL_RED_SIZE,        1, \
   EGL_GREEN_SIZE,      1, \
   EGL_BLUE_SIZE,       1, \
   EGL_ALPHA_SIZE,      0, \
   EGL_DEPTH_SIZE,      0

   static const EGLint egl_attribs_gl[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_vg[] = {
      EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   const EGLint *attrib_ptr;
   switch (g_api)
   {
      case GFX_CTX_OPENGL_API:
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
         attrib_ptr = egl_attribs_gles;
         break;
      case GFX_CTX_OPENVG_API:
         attrib_ptr = egl_attribs_vg;
         break;
      default:
         attrib_ptr = NULL;
   }

   g_quit = 0;

   g_dpy = XOpenDisplay(NULL);
   if (!g_dpy)
      goto error;

   g_egl_dpy = eglGetDisplay((EGLNativeDisplayType)g_dpy);
   if (!g_egl_dpy)
   {
      RARCH_ERR("[X/EGL]: EGL display not available.\n");
      goto error;
   }

   EGLint egl_major, egl_minor;
   if (!eglInitialize(g_egl_dpy, &egl_major, &egl_minor))
   {
      RARCH_ERR("[X/EGL]: Unable to initialize EGL.\n");
      goto error;
   }

   RARCH_LOG("[X/EGL]: EGL version: %d.%d\n", egl_major, egl_minor);

   EGLint num_configs;
   if (!eglChooseConfig(g_egl_dpy, attrib_ptr, &g_config, 1, &num_configs))
   {
      RARCH_ERR("[X/EGL]: eglChooseConfig failed with %x.\n", eglGetError());
      goto error;
   }

   if (num_configs == 0 || !g_config)
   {
      RARCH_ERR("[X/EGL]: No EGL configurations available.\n");
      goto error;
   }

   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 12
0
static bool gfx_ctx_init(void)
{
   RARCH_LOG("[VC/EGL]: Initializing...\n");
   if (g_inited)
   {
      RARCH_ERR("[VC/EGL]: Attempted to re-initialize driver.\n");
      return false;
   }

   EGLint num_config;
   static EGL_DISPMANX_WINDOW_T nativewindow;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   DISPMANX_MODEINFO_T dispman_modeinfo;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

   static const EGLint attribute_list[] =
   {
      EGL_RED_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_BLUE_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_NONE
   };

   static const EGLint context_attributes[] =
   {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };

   bcm_host_init();

   // get an EGL display connection
   g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
   if (!g_egl_dpy)
      goto error;

   // initialize the EGL display connection
   if (!eglInitialize(g_egl_dpy, NULL, NULL))
      goto error;

   // get an appropriate EGL frame buffer configuration
   if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_config, 1, &num_config))
      goto error;

   // create an EGL rendering context
   g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, (g_api == GFX_CTX_OPENGL_ES_API) ? context_attributes : NULL);
   if (!g_egl_ctx)
      goto error;

   // create an EGL window surface
   if (graphics_get_display_size(0 /* LCD */, &g_fb_width, &g_fb_height) < 0)
      goto error;

   dst_rect.x = 0;
   dst_rect.y = 0;
   dst_rect.width = g_fb_width;
   dst_rect.height = g_fb_height;

   src_rect.x = 0;
   src_rect.y = 0;
   src_rect.width = g_fb_width << 16;
   src_rect.height = g_fb_height << 16;

   dispman_display = vc_dispmanx_display_open(0 /* LCD */);
   vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);
   dispman_update = vc_dispmanx_update_start(0);

   VC_DISPMANX_ALPHA_T alpha;
   alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
   alpha.opacity = 255;
   alpha.mask = 0;

   dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display,
      0 /*layer*/, &dst_rect, 0 /*src*/,
      &src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0 /*clamp*/, DISPMANX_NO_ROTATE);

   nativewindow.element = dispman_element;
   nativewindow.width = g_fb_width;
   nativewindow.height = g_fb_height;
   vc_dispmanx_update_submit_sync(dispman_update);

   g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, &nativewindow, NULL);
   if (!g_egl_surf)
      goto error;

   // connect the context to the surface
   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
      goto error;

   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 13
0
static void *vg_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
   unsigned temp_width = 0, temp_height = 0;
   VGfloat clearColor[4] = {0, 0, 0, 1};
   settings_t        *settings = config_get_ptr();
   const gfx_ctx_driver_t *ctx = NULL;
   vg_t                    *vg = (vg_t*)calloc(1, sizeof(vg_t));

   if (!vg)
      goto error;

   ctx = gfx_ctx_init_first(vg, settings->video.context_driver,
         GFX_CTX_OPENVG_API, 0, 0, false);

   if (!ctx)
      goto error;

   gfx_ctx_set(ctx);

   gfx_ctx_get_video_size(&temp_width, &temp_height);
   RARCH_LOG("Detecting screen resolution %ux%u.\n", temp_width, temp_height);

   if (temp_width != 0 && temp_height != 0)
      video_driver_set_size(&temp_width, &temp_height);

   gfx_ctx_swap_interval(video->vsync ? 1 : 0);

   gfx_ctx_update_window_title();

   vg->mTexType    = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565;
   vg->keep_aspect = video->force_aspect;

   unsigned win_width  = video->width;
   unsigned win_height = video->height;
   if (video->fullscreen && (win_width == 0) && (win_height == 0))
   {
      video_driver_get_size(&temp_width, &temp_height);

      win_width  = temp_width;
      win_height = temp_height;
   }

   if (!gfx_ctx_set_video_mode(win_width, win_height, video->fullscreen))
      goto error;

   video_driver_get_size(&temp_width, &temp_height);

   temp_width  = 0;
   temp_height = 0;
   gfx_ctx_get_video_size(&temp_width, &temp_height);
   vg->should_resize = true;

   if (temp_width != 0 && temp_height != 0)
   {
      RARCH_LOG("Verified window resolution %ux%u.\n", temp_width, temp_height);
      video_driver_set_size(&temp_width, &temp_height);
   }

   video_driver_get_size(&temp_width, &temp_height);

   vg->mScreenAspect = (float)temp_width / temp_height;

   gfx_ctx_translate_aspect(&vg->mScreenAspect, temp_width, temp_height);

   vgSetfv(VG_CLEAR_COLOR, 4, clearColor);

   vg->mTextureWidth = vg->mTextureHeight = video->input_scale * RARCH_SCALE_BASE;
   vg->mImage = vgCreateImage(vg->mTexType, vg->mTextureWidth, vg->mTextureHeight,
         video->smooth ? VG_IMAGE_QUALITY_BETTER : VG_IMAGE_QUALITY_NONANTIALIASED);
   vg_set_nonblock_state(vg, !video->vsync);

   gfx_ctx_input_driver(input, input_data);

   if (settings->video.font_enable && font_renderer_create_default(&vg->font_driver, &vg->mFontRenderer,
            *settings->video.font_path ? settings->video.font_path : NULL, settings->video.font_size))
   {
      vg->mFont            = vgCreateFont(0);

      if (vg->mFont != VG_INVALID_HANDLE)
      {
         vg->mFontsOn      = true;
         vg->mFontHeight   = settings->video.font_size;
         vg->mPaintFg      = vgCreatePaint();
         vg->mPaintBg      = vgCreatePaint();
         VGfloat paintFg[] = { settings->video.msg_color_r, settings->video.msg_color_g, settings->video.msg_color_b, 1.0f };
         VGfloat paintBg[] = { settings->video.msg_color_r / 2.0f, settings->video.msg_color_g / 2.0f, settings->video.msg_color_b / 2.0f, 0.5f };

         vgSetParameteri(vg->mPaintFg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(vg->mPaintFg, VG_PAINT_COLOR, 4, paintFg);

         vgSetParameteri(vg->mPaintBg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(vg->mPaintBg, VG_PAINT_COLOR, 4, paintBg);
      }
   }

   if (vg_query_extension("KHR_EGL_image") && gfx_ctx_image_buffer_init(video))
   {
      pvgCreateEGLImageTargetKHR = (PFNVGCREATEEGLIMAGETARGETKHRPROC)gfx_ctx_get_proc_address("vgCreateEGLImageTargetKHR");

      if (pvgCreateEGLImageTargetKHR)
      {
         RARCH_LOG("[VG] Using EGLImage buffer\n");
         vg->mEglImageBuf = true;
      }
   }

#if 0
   const char *ext = (const char*)vgGetString(VG_EXTENSIONS);
   if (ext)
      RARCH_LOG("[VG] Supported extensions: %s\n", ext);
#endif

   return vg;

error:
   if (vg)
      free(vg);
   gfx_ctx_destroy(ctx);
   return NULL;
}
Exemplo n.º 14
0
static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
#ifdef _WIN32
   gfx_set_dwm();
#endif

#ifdef RARCH_CONSOLE
   if (driver.video_data)
      return driver.video_data;
#endif

   gl_t *gl = (gl_t*)calloc(1, sizeof(gl_t));
   if (!gl)
      return NULL;

   if (!gfx_ctx_init())
   {
      free(gl);
      return NULL;
   }

   unsigned full_x = 0, full_y = 0;
   gfx_ctx_get_video_size(&full_x, &full_y);
   RARCH_LOG("Detecting resolution %ux%u.\n", full_x, full_y);

   gfx_ctx_set_swap_interval(video->vsync ? 1 : 0, false);

   unsigned win_width = video->width;
   unsigned win_height = video->height;
   if (video->fullscreen && (win_width == 0) && (win_height == 0))
   {
      win_width = full_x;
      win_height = full_y;
   }

   if (!gfx_ctx_set_video_mode(win_width, win_height,
            g_settings.video.force_16bit ? 15 : 0, video->fullscreen))
   {
      free(gl);
      return NULL;
   }

#ifndef RARCH_CONSOLE
   gfx_ctx_update_window_title(true);

   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif

#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32)
   // Win32 GL lib doesn't have some functions needed for XML shaders.
   // Need to load dynamically :(
   if (!load_gl_proc())
   {
      gfx_ctx_destroy();
      free(gl);
      return NULL;
   }
#endif

   gl->vsync = video->vsync;
   gl->fullscreen = video->fullscreen;
   
   gl->full_x = full_x;
   gl->full_y = full_y;
   gl->win_width = win_width;
   gl->win_height = win_height;

   RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);

#if defined(HAVE_CG_MENU) && defined(RARCH_CONSOLE)
   RARCH_LOG("Initializing menu shader ...\n");
   gl_cg_set_menu_shader(default_paths.menu_shader_file);
#endif

   if (!gl_shader_init())
   {
      RARCH_ERR("Shader init failed.\n");
      gfx_ctx_destroy();
      free(gl);
      return NULL;
   }

   RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num());

#ifdef HAVE_FBO
   // Set up render to texture.
   gl_init_fbo(gl, RARCH_SCALE_BASE * video->input_scale,
         RARCH_SCALE_BASE * video->input_scale);
#endif
   
   gl->keep_aspect = video->force_aspect;

   // Apparently need to set viewport for passes when we aren't using FBOs.
   gl_shader_use(0);
   gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);
   gl_shader_use(1);
   gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);

   bool force_smooth = false;
   if (gl_shader_filter_type(1, &force_smooth))
      gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST;
   else
      gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST;

   gl->texture_type = RARCH_GL_TEXTURE_TYPE;
   gl->texture_fmt = video->rgb32 ? RARCH_GL_FORMAT32 : RARCH_GL_FORMAT16;
   gl->base_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t);

   glEnable(GL_TEXTURE_2D);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_DITHER);
   glClearColor(0, 0, 0, 1);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glEnableClientState(GL_COLOR_ARRAY);
   glVertexPointer(2, GL_FLOAT, 0, vertex_ptr);

   memcpy(gl->tex_coords, tex_coords, sizeof(tex_coords));
   glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords);
   glColorPointer(4, GL_FLOAT, 0, white_color);

   set_lut_texture_coords(tex_coords);

   gl->tex_w = RARCH_SCALE_BASE * video->input_scale;
   gl->tex_h = RARCH_SCALE_BASE * video->input_scale;

#ifdef HAVE_OPENGL_TEXREF
   glGenBuffers(1, &gl->pbo);
   glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, gl->pbo);
   glBufferData(GL_TEXTURE_REFERENCE_BUFFER_SCE,
         gl->tex_w * gl->tex_h * gl->base_size * TEXTURES, NULL, GL_STREAM_DRAW);
#endif

   // Empty buffer that we use to clear out the texture with on res change.
   gl->empty_buf = calloc(gl->tex_w * gl->tex_h, gl->base_size);
   gl_init_textures(gl);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->last_width[i] = gl->tex_w;
      gl->last_height[i] = gl->tex_h;
   }

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->prev_info[i].tex = gl->texture[(gl->tex_index - (i + 1)) & TEXTURES_MASK];
      gl->prev_info[i].input_size[0] = gl->tex_w;
      gl->prev_info[i].tex_size[0] = gl->tex_w;
      gl->prev_info[i].input_size[1] = gl->tex_h;
      gl->prev_info[i].tex_size[1] = gl->tex_h;
      memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords)); 
   }

   gfx_ctx_input_driver(input, input_data);
   gl_init_font(gl, g_settings.video.font_path, g_settings.video.font_size);
      
   if (!gl_check_error())
   {
      gfx_ctx_destroy();
      free(gl);
      return NULL;
   }

   return gl;
}
Exemplo n.º 15
0
static bool gfx_ctx_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   DWORD style;
   RECT rect   = {0};

   HMONITOR hm_to_use = NULL;
   MONITORINFOEX current_mon;

   monitor_info(&current_mon, &hm_to_use);
   RECT mon_rect = current_mon.rcMonitor;

   g_resize_width  = width;
   g_resize_height = height;

   bool windowed_full = g_settings.video.windowed_fullscreen;
   if (fullscreen)
   {
      if (windowed_full)
      {
         style = WS_EX_TOPMOST | WS_POPUP;
         g_resize_width  = width  = mon_rect.right - mon_rect.left;
         g_resize_height = height = mon_rect.bottom - mon_rect.top;
      }
      else
      {
         style = WS_POPUP | WS_VISIBLE;

         if (!set_fullscreen(width, height, current_mon.szDevice))
            goto error;

         // display settings might have changed, get new coordinates
         GetMonitorInfo(hm_to_use, (MONITORINFO*)&current_mon);
         mon_rect = current_mon.rcMonitor;
         g_restore_desktop = true;
      }
   }
   else
   {
      style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
      rect.right  = width;
      rect.bottom = height;
      AdjustWindowRect(&rect, style, FALSE);
      width  = rect.right - rect.left;
      height = rect.bottom - rect.top;
   }

   g_hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", style,
         fullscreen ? mon_rect.left : g_pos_x,
         fullscreen ? mon_rect.top  : g_pos_y,
         width, height,
         NULL, NULL, NULL, NULL);

   if (!g_hwnd)
      goto error;

   if (!fullscreen || windowed_full)
   {
      ShowWindow(g_hwnd, SW_RESTORE);
      UpdateWindow(g_hwnd);
      SetForegroundWindow(g_hwnd);
      SetFocus(g_hwnd);
   }

   show_cursor(!fullscreen);

   // Wait until GL context is created (or failed to do so ...)
   MSG msg;
   while (!g_inited && !g_quit && GetMessage(&msg, g_hwnd, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   if (g_quit)
      goto error;

   p_swap_interval = (BOOL (APIENTRY *)(int))wglGetProcAddress("wglSwapIntervalEXT");

   gfx_ctx_swap_interval(data, g_interval);

   driver.display_type  = RARCH_DISPLAY_WIN32;
   driver.video_display = 0;
   driver.video_window  = (uintptr_t)g_hwnd;

   return true;

error:
   gfx_ctx_destroy(data);
   return false;
}
Exemplo n.º 16
0
static bool gfx_ctx_set_video_mode(
      unsigned width, unsigned height,
      bool fullscreen)
{
   struct sigaction sa = {{0}};
   sa.sa_handler = sighandler;
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);
   int x_off = 0;
   int y_off = 0;

   bool windowed_full = g_settings.video.windowed_fullscreen;
   bool true_full = false;

   XSetWindowAttributes swa = {0};

   XVisualInfo *vi = glXGetVisualFromFBConfig(g_dpy, g_fbc);
   if (!vi)
      goto error;

   swa.colormap = g_cmap = XCreateColormap(g_dpy, RootWindow(g_dpy, vi->screen),
         vi->visual, AllocNone);
   swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask;
   swa.override_redirect = fullscreen ? True : False;

   if (fullscreen && !windowed_full)
   {
      if (x11_enter_fullscreen(g_dpy, width, height, &g_desktop_mode))
      {
         g_should_reset_mode = true;
         true_full = true;
      }
      else
         RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n");
   }

   if (g_settings.video.monitor_index)
      g_screen = g_settings.video.monitor_index - 1;

#ifdef HAVE_XINERAMA
   if (fullscreen || g_screen != 0)
   {
      unsigned new_width  = width;
      unsigned new_height = height;
      if (x11_get_xinerama_coord(g_dpy, g_screen, &x_off, &y_off, &new_width, &new_height))
         RARCH_LOG("[GLX]: Using Xinerama on screen #%u.\n", g_screen);
      else
         RARCH_LOG("[GLX]: Xinerama is not active on screen.\n");

      if (fullscreen)
      {
         width  = new_width;
         height = new_height;
      }
   }
#endif

   RARCH_LOG("[GLX]: X = %d, Y = %d, W = %u, H = %u.\n",
         x_off, y_off, width, height);

   g_win = XCreateWindow(g_dpy, RootWindow(g_dpy, vi->screen),
         x_off, y_off, width, height, 0,
         vi->depth, InputOutput, vi->visual, 
         CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa);
   XSetWindowBackground(g_dpy, g_win, 0);

   gfx_ctx_update_window_title(true);
   x11_set_window_attr(g_dpy, g_win);

   if (fullscreen)
      x11_hide_mouse(g_dpy, g_win);

   if (true_full)
   {
      RARCH_LOG("[GLX]: Using true fullscreen.\n");
      XMapRaised(g_dpy, g_win);
   }
   else if (fullscreen) // We attempted true fullscreen, but failed. Attempt using windowed fullscreen.
   {
      XMapRaised(g_dpy, g_win);
      RARCH_LOG("[GLX]: Using windowed fullscreen.\n");
      // We have to move the window to the screen we want to go fullscreen on first.
      // x_off and y_off usually get ignored in XCreateWindow().
      x11_move_window(g_dpy, g_win, x_off, y_off, width, height);
      x11_windowed_fullscreen(g_dpy, g_win);
   }
   else
   {
      XMapWindow(g_dpy, g_win);
      // If we want to map the window on a different screen, we'll have to do it by force.
      // Otherwise, we should try to let the window manager sort it out.
      // x_off and y_off usually get ignored in XCreateWindow().
      if (g_screen)
         x11_move_window(g_dpy, g_win, x_off, y_off, width, height);
   }

   XEvent event;
   XIfEvent(g_dpy, &event, glx_wait_notify, NULL);

   XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime);

   g_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, 0, True);
   if (!g_ctx)
   {
      RARCH_ERR("[GLX]: Failed to create new context.\n");
      goto error;
   }

   glXMakeCurrent(g_dpy, g_win, g_ctx);
   XSync(g_dpy, False);

   g_quit_atom = XInternAtom(g_dpy, "WM_DELETE_WINDOW", False);
   if (g_quit_atom)
      XSetWMProtocols(g_dpy, g_win, &g_quit_atom, 1);

   int val;
   glXGetConfig(g_dpy, vi, GLX_DOUBLEBUFFER, &val);
   g_is_double = val;
   if (g_is_double)
   {
      if (!g_pglSwapInterval)
         g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapInterval");
      if (!g_pglSwapInterval)
         g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA");
      if (!g_pglSwapInterval)
         g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI");
      if (!g_pglSwapInterval)
         RARCH_WARN("[GLX]: Cannot find swap interval call.\n");
   }
   else
      RARCH_WARN("[GLX]: Context is not double buffered!.\n");

   gfx_ctx_swap_interval(g_interval);

   XFree(vi);
   g_has_focus = true;
   g_inited    = true;

   driver.display_type  = RARCH_DISPLAY_X11;
   driver.video_display = (uintptr_t)g_dpy;
   driver.video_window  = (uintptr_t)g_win;
   g_true_full = true_full;

   return true;

error:
   if (vi)
      XFree(vi);

   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 17
0
static bool gfx_ctx_init(void *data)
{
   if (g_inited)
      return false;

   XInitThreads();

   static const int visual_attribs[] = {
      GLX_X_RENDERABLE     , True,
      GLX_DRAWABLE_TYPE    , GLX_WINDOW_BIT,
      GLX_RENDER_TYPE      , GLX_RGBA_BIT,
      GLX_DOUBLEBUFFER     , True,
      GLX_RED_SIZE         , 8,
      GLX_GREEN_SIZE       , 8,
      GLX_BLUE_SIZE        , 8,
      GLX_ALPHA_SIZE       , 8,
      GLX_DEPTH_SIZE       , 0,
      GLX_STENCIL_SIZE     , 0,
      None
   };

   GLXFBConfig *fbcs = NULL;
   g_quit = 0;

   if (!g_dpy)
      g_dpy = XOpenDisplay(NULL);

   if (!g_dpy)
      goto error;

   int major, minor;
   glXQueryVersion(g_dpy, &major, &minor);

   // GLX 1.3+ minimum required.
   if ((major * 1000 + minor) < 1003)
      goto error;

   glx_create_context_attribs = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");

#ifdef GL_DEBUG
   g_debug = true;
#else
   g_debug = g_extern.system.hw_render_callback.debug_context;
#endif

   g_core = (g_major * 1000 + g_minor) >= 3001; // Have to use ContextAttribs
   if ((g_core || g_debug) && !glx_create_context_attribs)
      goto error;

   int nelements;
   fbcs = glXChooseFBConfig(g_dpy, DefaultScreen(g_dpy),
         visual_attribs, &nelements);

   if (!fbcs)
      goto error;

   if (!nelements)
   {
      XFree(fbcs);
      goto error;
   }

   g_fbc = fbcs[0];
   XFree(fbcs);

   return true;

error:
   gfx_ctx_destroy(data);
   return false;
}
Exemplo n.º 18
0
static bool gfx_ctx_init(void)
{
   if (g_inited)
      return false;

   static const char *modules[] = {
      "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", NULL
   };

   for (int i = 0; modules[i]; i++)
   {
      RARCH_LOG("[KMS/EGL]: Trying to load module %s ...\n", modules[i]);
      g_drm_fd = drmOpen(modules[i], NULL);
      if (g_drm_fd >= 0)
      {
         RARCH_LOG("[KMS/EGL]: Found module %s.\n", modules[i]);
         break;
      }
   }

   if (g_drm_fd < 0)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't open DRM device.\n");
      goto error;
   }

   g_resources = drmModeGetResources(g_drm_fd);
   if (!g_resources)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get device resources.\n");
      goto error;
   }

   for (int i = 0; i < g_resources->count_connectors; i++)
   {
      g_connector = drmModeGetConnector(g_drm_fd, g_resources->connectors[i]);
      if (g_connector->connection == DRM_MODE_CONNECTED)
         break;

      drmModeFreeConnector(g_connector);
      g_connector = NULL;
   }

   // TODO: Figure out what index for crtcs to use ...
   g_orig_crtc = drmModeGetCrtc(g_drm_fd, g_resources->crtcs[0]);
   if (!g_orig_crtc)
      RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");

   if (!g_connector)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get device connector.\n");
      goto error;
   }

   for (int i = 0, area = 0; i < g_connector->count_modes; i++)
   {
      drmModeModeInfo *current_mode = &g_connector->modes[i];
      int current_area = current_mode->hdisplay * current_mode->vdisplay;
      if (current_area > area)
      {
         g_drm_mode = current_mode;
         area       = current_area;
      }
   }

   if (!g_drm_mode)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find DRM mode.\n");
      goto error;
   }

	for (int i = 0; i < g_resources->count_encoders; i++)
   {
		g_encoder = drmModeGetEncoder(g_drm_fd, g_resources->encoders[i]);
		if (g_encoder->encoder_id == g_connector->encoder_id)
			break;

		drmModeFreeEncoder(g_encoder);
		g_encoder = NULL;
	}

	if (!g_encoder)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find DRM encoder.\n");
      goto error;
   }

   g_crtc_id      = g_encoder->crtc_id;
   g_connector_id = g_connector->connector_id;

   g_fb_width  = g_drm_mode->hdisplay;
   g_fb_height = g_drm_mode->vdisplay;

   g_gbm_dev     = gbm_create_device(g_drm_fd);
   g_gbm_surface = gbm_surface_create(g_gbm_dev,
         g_fb_width, g_fb_height,
         GBM_FORMAT_XRGB8888,
         GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

   if (!g_gbm_surface)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't create GBM surface.\n");
      goto error;
   }

   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 19
0
static bool gfx_ctx_init(void)
{
   struct android_app *android_app = (struct android_app*)g_android;
   const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_NONE
   };
   EGLint num_config;
   EGLint egl_version_major, egl_version_minor;
   EGLint format;

   EGLint context_attributes[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };

   RARCH_LOG("Initializing context\n");

   if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY)
   {
      RARCH_ERR("eglGetDisplay failed.\n");
      goto error;
   }

   if (!eglInitialize(g_egl_dpy, &egl_version_major, &egl_version_minor))
   {
      RARCH_ERR("eglInitialize failed.\n");
      goto error;
   }

   RARCH_LOG("[ANDROID/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor);

   if (!eglChooseConfig(g_egl_dpy, attribs, &g_config, 1, &num_config))
   {
      RARCH_ERR("eglChooseConfig failed.\n");
      goto error;
   }

   int var = eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &format);

   if (!var)
   {
      RARCH_ERR("eglGetConfigAttrib failed: %d.\n", var);
      goto error;
   }

   ANativeWindow_setBuffersGeometry(android_app->window, 0, 0, format);

   if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, android_app->window, 0)))
   {
      RARCH_ERR("eglCreateWindowSurface failed.\n");
      goto error;
   }

   if (!(g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, 0, context_attributes)))
   {
      RARCH_ERR("eglCreateContext failed.\n");
      goto error;
   }

   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
   {
      RARCH_ERR("eglMakeCurrent failed.\n");
      goto error;
   }

   return true;

error:
   RARCH_ERR("EGL error: %d.\n", eglGetError());
   gfx_ctx_destroy();
   return false;
}
Exemplo n.º 20
0
static bool gfx_ctx_init(void *data)
{
   int i;
   unsigned monitor_index;
   unsigned gpu_index = 0;
   unsigned monitor = max(g_settings.video.monitor_index, 1);

   const char *gpu;
   if (g_inited)
      return false;

   g_drm_fd = -1;
   struct string_list *gpu_descriptors = dir_list_new("/dev/dri", NULL, false);

nextgpu:
   free_drm_resources();

   if (!gpu_descriptors || gpu_index == gpu_descriptors->size)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find a suitable DRM device.\n");
      goto error;
   }
   gpu = gpu_descriptors->elems[gpu_index++].data;

   g_drm_fd = open(gpu, O_RDWR);
   if (g_drm_fd < 0)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't open DRM device.\n");
      goto nextgpu;
   }

   g_resources = drmModeGetResources(g_drm_fd);
   if (!g_resources)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device resources.\n");
      goto nextgpu;
   }

   // Enumerate all connectors.
   monitor_index = 0;
   RARCH_LOG("[KMS/EGL]: Found %d connectors.\n", g_resources->count_connectors);
   for (i = 0; i < g_resources->count_connectors; i++)
   {
      drmModeConnectorPtr conn = drmModeGetConnector(g_drm_fd, g_resources->connectors[i]);
      if (conn)
      {
         bool connected = conn->connection == DRM_MODE_CONNECTED;
         RARCH_LOG("[KMS/EGL]: Connector %d connected: %s\n", i, connected ? "yes" : "no");
         RARCH_LOG("[KMS/EGL]: Connector %d has %d modes.\n", i, conn->count_modes);
         if (connected && conn->count_modes > 0)
         {
            monitor_index++;
            RARCH_LOG("[KMS/EGL]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index);
         }
         drmModeFreeConnector(conn);
      }
   }

   monitor_index = 0;
   for (i = 0; i < g_resources->count_connectors; i++)
   {
      g_connector = drmModeGetConnector(g_drm_fd, g_resources->connectors[i]);

      if (!g_connector)
         continue;
      if (g_connector->connection == DRM_MODE_CONNECTED && g_connector->count_modes > 0)
      {
         monitor_index++;
         if (monitor_index == monitor)
            break;
      }

      drmModeFreeConnector(g_connector);
      g_connector = NULL;
   }

   if (!g_connector)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device connector.\n");
      goto nextgpu;
   }

   for (i = 0; i < g_resources->count_encoders; i++)
   {
      g_encoder = drmModeGetEncoder(g_drm_fd, g_resources->encoders[i]);

      if (!g_encoder)
         continue;
      if (g_encoder->encoder_id == g_connector->encoder_id)
         break;

      drmModeFreeEncoder(g_encoder);
      g_encoder = NULL;
   }

   if (!g_encoder)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't find DRM encoder.\n");
      goto nextgpu;
   }

   for (i = 0; i < g_connector->count_modes; i++)
   {
      RARCH_LOG("[KMS/EGL]: Mode %d: (%s) %d x %d, %u Hz\n", i,
            g_connector->modes[i].name,
            g_connector->modes[i].hdisplay, g_connector->modes[i].vdisplay,
            g_connector->modes[i].vrefresh);
   }

   g_crtc_id   = g_encoder->crtc_id;
   g_orig_crtc = drmModeGetCrtc(g_drm_fd, g_crtc_id);
   if (!g_orig_crtc)
      RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");

   g_connector_id = g_connector->connector_id;

   // First mode is assumed to be the "optimal" one for get_video_size() purposes.
   g_fb_width  = g_connector->modes[0].hdisplay;
   g_fb_height = g_connector->modes[0].vdisplay;

   g_gbm_dev = gbm_create_device(g_drm_fd);
   if (!g_gbm_dev)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't create GBM device.\n");
      goto nextgpu;
   }

   dir_list_free(gpu_descriptors);
   return true;

error:
   dir_list_free(gpu_descriptors);
   gfx_ctx_destroy(data);
   return false;
}
Exemplo n.º 21
0
static void *d3d_init(const video_info_t *info,
      const input_driver_t **input, void **input_data)
{
   d3d_video_t            *d3d        = NULL;
   const gfx_ctx_driver_t *ctx_driver = NULL;

#ifdef _XBOX
   if (video_driver_get_ptr(false))
   {
      d3d = (d3d_video_t*)video_driver_get_ptr(false);

      /* Reinitialize renderchain as we
       * might have changed pixel formats.*/
      if (d3d->renderchain_driver->reinit(d3d, (const void*)info))
      {
         d3d_deinit_chain(d3d);
         d3d_init_chain(d3d, info);

         input_driver_set(input, input_data);

         video_driver_ctl(RARCH_DISPLAY_CTL_SET_OWN_DRIVER, NULL);
         return d3d;
      }
   }
#endif

   d3d = new d3d_video_t();
   if (!d3d)
      goto error;

   ctx_driver = d3d_get_context(d3d);
   if (!ctx_driver)
      goto error;

   /* Default values */
   d3d->dev                  = NULL;
   d3d->dev_rotation         = 0;
   d3d->needs_restore        = false;
#ifdef HAVE_OVERLAY
   d3d->overlays_enabled     = false;
#endif
#ifdef _XBOX
   d3d->should_resize        = false;
#else
#ifdef HAVE_MENU
   d3d->menu                 = NULL;
#endif
#endif

   gfx_ctx_set(ctx_driver);

   if (!d3d_construct(d3d, info, input, input_data))
   {
      RARCH_ERR("[D3D]: Failed to init D3D.\n");
      goto error;
   }

   d3d->keep_aspect       = info->force_aspect;
#ifdef _XBOX
   video_driver_ctl(RARCH_DISPLAY_CTL_SET_OWN_DRIVER, NULL);
   video_driver_ctl(RARCH_INPUT_CTL_SET_OWN_DRIVER, NULL);
#endif

   return d3d;

error:
   gfx_ctx_destroy(ctx_driver);
   if (d3d)
      delete d3d;
   return NULL;
}
Exemplo n.º 22
0
static bool gfx_ctx_init(void)
{
    EGLint width;
    EGLint height;

    RARCH_LOG("[EMSCRIPTEN/EGL]: Initializing...\n");
    if (g_inited)
    {
        RARCH_LOG("[EMSCRIPTEN/EGL]: Attempted to re-initialize driver.\n");
        return true;
    }

    EGLint num_config;

    static const EGLint attribute_list[] =
    {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] =
    {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    // get an EGL display connection
    g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (!g_egl_dpy)
        goto error;

    // initialize the EGL display connection
    if (!eglInitialize(g_egl_dpy, NULL, NULL))
        goto error;

    // get an appropriate EGL frame buffer configuration
    if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_config, 1, &num_config))
        goto error;

    // create an EGL rendering context
    g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, context_attributes);
    if (!g_egl_ctx)
        goto error;

    // create an EGL window surface
    g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, 0, NULL);
    if (!g_egl_surf)
        goto error;

    // connect the context to the surface
    if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
        goto error;

    eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &width);
    eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height);
    g_fb_width = width;
    g_fb_height = height;
    RARCH_LOG("[EMSCRIPTEN/EGL]: Dimensions: %ux%u\n", width, height);

    return true;

error:
    gfx_ctx_destroy();
    return false;
}