Exemple #1
0
static void opengl_swap_synchronous(void)
{
    if (g_sync_method == SYNC_SWAP) {
        swap_opengl_buffers();
    } else if (g_sync_method == SYNC_SWAP_FINISH) {
        swap_opengl_buffers();
        gl_finish();
    } else if (g_sync_method == SYNC_FINISH_SWAP_FINISH) {
        gl_finish();
        swap_opengl_buffers();
        gl_finish();
    } else if (g_sync_method == SYNC_SLEEP_SWAP_FINISH) {
        sleep_until_vsync();
        swap_opengl_buffers();
        gl_finish();
    } else if (g_sync_method == SYNC_FINISH_SLEEP_SWAP_FINISH) {
        gl_finish();
        sleep_until_vsync();
        swap_opengl_buffers();
        gl_finish();
    } else if (g_sync_method == SYNC_SWAP_FENCE) {
        swap_opengl_buffers();
        opengl_fence(FENCE_SET);
        glFlush();
        opengl_fence(FENCE_WAIT);
    } else if (g_sync_method == SYNC_SWAP_SLEEP_FENCE) {
        swap_opengl_buffers();
        sleep_until_vsync();
        opengl_fence(FENCE_SET);
        glFlush();
        opengl_fence(FENCE_WAIT);
    }
}
void plat_sdl_finish(void)
{
  if (plat_sdl_overlay != NULL) {
    SDL_FreeYUVOverlay(plat_sdl_overlay);
    plat_sdl_overlay = NULL;
  }
  if (plat_sdl_gl_active) {
    gl_finish();
    plat_sdl_gl_active = 0;
  }
  // restore back to initial resolution
  // resolves black screen issue on R-Pi
  if (strcmp(vid_drv_name, "x11") != 0)
    SDL_SetVideoMode(fs_w, fs_h, 16, SDL_SWSURFACE);
  SDL_Quit();
}
void plat_sdl_event_handler(void *event_)
{
  static int was_active;
  SDL_Event *event = event_;

  switch (event->type) {
  case SDL_VIDEORESIZE:
    //printf("resize %dx%d\n", event->resize.w, event->resize.h);
    if (plat_target.vout_method != 0
        && !plat_target.vout_fullscreen && !old_fullscreen)
    {
      window_w = event->resize.w;
      window_h = event->resize.h;
      plat_sdl_change_video_mode(0, 0, 1);
    }
    break;
  case SDL_ACTIVEEVENT:
    if (event->active.gain && !was_active) {
      if (plat_sdl_overlay != NULL) {
        SDL_Rect dstrect = { 0, 0, plat_sdl_screen->w, plat_sdl_screen->h };
        SDL_DisplayYUVOverlay(plat_sdl_overlay, &dstrect);
      }
      else if (plat_sdl_gl_active) {
        if (gl_quirks & GL_QUIRK_ACTIVATE_RECREATE) {
          gl_finish();
          plat_sdl_gl_active = (gl_init(display, window, &gl_quirks) == 0);
        }
        gl_flip(NULL, 0, 0);
      }
      // else SDL takes care of it
    }
    was_active = event->active.gain;
    break;
  case SDL_QUIT:
    if (plat_sdl_quit_cb != NULL)
      plat_sdl_quit_cb();
    break;
  }
}
/* w, h is layer resolution */
int plat_sdl_change_video_mode(int w, int h, int force)
{
  static int prev_w, prev_h;

  if (w == 0)
    w = prev_w;
  else
    prev_w = w;
  if (h == 0)
    h = prev_h;
  else
    prev_h = h;
plat_target.vout_method=vout_mode_overlay;
  // invalid method might come from config..
  if (plat_target.vout_method != 0
      && plat_target.vout_method != vout_mode_overlay
      && plat_target.vout_method != vout_mode_gl)
  {
    fprintf(stderr, "invalid vout_method: %d\n", plat_target.vout_method);
    plat_target.vout_method = 0;
  }

  // skip GL recreation if window doesn't change - avoids flicker
  if (plat_target.vout_method == vout_mode_gl && plat_sdl_gl_active
      && plat_target.vout_fullscreen == old_fullscreen && !force)
  {
    return 0;
  }

  if (plat_sdl_overlay != NULL) {
    SDL_FreeYUVOverlay(plat_sdl_overlay);
    plat_sdl_overlay = NULL;
  }
  if (plat_sdl_gl_active) {
    gl_finish();
    plat_sdl_gl_active = 0;
  }

  if (plat_target.vout_method != 0) {
    Uint32 flags = SDL_RESIZABLE | SDL_SWSURFACE;
    int win_w = window_w;
    int win_h = window_h;

    if (plat_target.vout_fullscreen) {
      flags |= SDL_FULLSCREEN;
      win_w = fs_w;
      win_h = fs_h;
    }

    // XXX: workaround some occasional mysterious deadlock in SDL_SetVideoMode
    // (seen on r-pi)
    SDL_PumpEvents();

unsigned int user_width = 0;
sscanf(getenv("PCSX_WIDTH"), "%d", &user_width);
if(user_width == 0)
	user_width=win_h;
    plat_sdl_screen = SDL_SetVideoMode(/*win_w*/ /*win_h*4/3*/ /*640*/ user_width*4/3, /*win_h*/ /*512*/ user_width, 0, flags);
    if (plat_sdl_screen == NULL) {
      fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
      plat_target.vout_method = 0;
    }
  }

  if (plat_target.vout_method == vout_mode_overlay) {
    plat_sdl_overlay = SDL_CreateYUVOverlay(w, h, SDL_UYVY_OVERLAY, plat_sdl_screen);
    if (plat_sdl_overlay != NULL) {
      if ((long)plat_sdl_overlay->pixels[0] & 3)
        fprintf(stderr, "warning: overlay pointer is unaligned\n");

      plat_sdl_overlay_clear();
    }
    else {
      fprintf(stderr, "warning: could not create overlay.\n");
      plat_target.vout_method = 0;
    }
  }
  else if (plat_target.vout_method == vout_mode_gl) {
    plat_sdl_gl_active = (gl_init(display, window, &gl_quirks) == 0);
    if (!plat_sdl_gl_active) {
      fprintf(stderr, "warning: could not init GL.\n");
      plat_target.vout_method = 0;
    }
  }

  if (plat_target.vout_method == 0) {
    SDL_PumpEvents();

    plat_sdl_screen = SDL_SetVideoMode(w, h, 16, SDL_SWSURFACE);
    if (plat_sdl_screen == NULL) {
      fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
      return -1;
    }
  }

  old_fullscreen = plat_target.vout_fullscreen;
  if (plat_sdl_resize_cb != NULL)
    plat_sdl_resize_cb(plat_sdl_screen->w, plat_sdl_screen->h);

  return 0;
}
int plat_sdl_init(void)
{
  static const char *vout_list[] = { NULL, NULL, NULL, NULL };
  const SDL_VideoInfo *info;
  SDL_SysWMinfo wminfo;
  int overlay_works = 0;
  int gl_works = 0;
  int i, ret, h;

  ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
  if (ret != 0) {
    fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
    return -1;
  }

  info = SDL_GetVideoInfo();
  if (info != NULL) {
    fs_w = info->current_w;
    fs_h = info->current_h;
    printf("plat_sdl: using %dx%d as fullscreen resolution\n", fs_w, fs_h);
  }

  g_menuscreen_w = 640;
  if (fs_w != 0 && g_menuscreen_w > fs_w)
    g_menuscreen_w = fs_w;
  g_menuscreen_h = 480;
  if (fs_h != 0) {
    h = fs_h;
    if (info && info->wm_available && h > WM_DECORATION_H)
      h -= WM_DECORATION_H;
    if (g_menuscreen_h > h)
      g_menuscreen_h = h;
  }

  ret = plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, 1);
  if (ret != 0) {
    plat_sdl_screen = SDL_SetVideoMode(0, 0, 16, SDL_SWSURFACE);
    if (plat_sdl_screen == NULL) {
      fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
      goto fail;
    }

    if (plat_sdl_screen->w < 320 || plat_sdl_screen->h < 240) {
      fprintf(stderr, "resolution %dx%d is too small, sorry.\n",
              plat_sdl_screen->w, plat_sdl_screen->h);
      goto fail;
    }
  }
  g_menuscreen_w = window_w = plat_sdl_screen->w;
  g_menuscreen_h = window_h = plat_sdl_screen->h;

  // overlay/gl require native bpp in some cases..
  plat_sdl_screen = SDL_SetVideoMode(g_menuscreen_w, g_menuscreen_h,
    0, SDL_SWSURFACE);
  if (plat_sdl_screen == NULL) {
    fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
    goto fail;
  }

  plat_sdl_overlay = SDL_CreateYUVOverlay(plat_sdl_screen->w, plat_sdl_screen->h,
    SDL_UYVY_OVERLAY, plat_sdl_screen);
  if (plat_sdl_overlay != NULL) {
    printf("plat_sdl: overlay: fmt %x, planes: %d, pitch: %d, hw: %d\n",
      plat_sdl_overlay->format, plat_sdl_overlay->planes, *plat_sdl_overlay->pitches,
      plat_sdl_overlay->hw_overlay);

    if (plat_sdl_overlay->hw_overlay)
      overlay_works = 1;
    else
      fprintf(stderr, "warning: video overlay is not hardware accelerated, "
                      "not going to use it.\n");
    SDL_FreeYUVOverlay(plat_sdl_overlay);
    plat_sdl_overlay = NULL;
  }
  else
    fprintf(stderr, "overlay is not available.\n");

  // get x11 display/window for GL
  SDL_VideoDriverName(vid_drv_name, sizeof(vid_drv_name));
#ifdef SDL_VIDEO_DRIVER_X11
  if (strcmp(vid_drv_name, "x11") == 0) {
    SDL_VERSION(&wminfo.version);
    ret = SDL_GetWMInfo(&wminfo);
    if (ret > 0) {
      display = wminfo.info.x11.display;
      window = (void *)wminfo.info.x11.window;
    }
  }
#endif

  ret = gl_init(display, window, &gl_quirks);
  if (ret == 0) {
    gl_works = 1;
    gl_finish();
  }

  i = 0;
  vout_list[i++] = "SDL Window";
  if (overlay_works) {
    plat_target.vout_method = vout_mode_overlay = i;
    vout_list[i++] = "Video Overlay";
  }
  if (gl_works) {
    plat_target.vout_method = vout_mode_gl = i;
    vout_list[i++] = "OpenGL";
  }
  plat_target.vout_methods = vout_list;

  return 0;

fail:
  SDL_Quit();
  return -1;
}
/*!
	To set a valid raster position outside the viewport, first set a valid
    raster position inside the viewport, then call glBitmap with NULL
    as the bitmap parameter and with xmove and ymove set to
    the offsets of the new raster position. This technique is useful when
    panning an image around the viewport.
	(see http://www.opengl.org/sdk/docs/man/xhtml/glBitmap.xml and
	http://www.opengl.org/sdk/docs/man/xhtml/glDrawPixels.xml)
*/
void ImageView::GLDraw()
{	
#ifdef USE_OPEN_GL_WINDOW
	if (!valid())
		GLViewSetup();
#else
	gl_start();
#endif

	// Invert image
	//glPixelZoom(1.0f, -1.0f);
	glPixelZoom((float) m_scaling, (float) -m_scaling);

	// Set image origin
	glRasterPos2i(0, h());

	// Check that the raster position is valid
	GLboolean rasVal;

	glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &rasVal);

	if (!rasVal)
	{
		ShowError("Invalid raster position. No image will be shown");
	}

	// If image is scaled down, the view needs to be fully erased
	//if (m_zoom < 1)
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	
	m_mutex.Lock();

	if (m_curByteImage.is_contiguous() && m_curByteImage.size() > 0)
		glDrawPixels(m_curByteImage.ni(), m_curByteImage.nj(), GL_LUMINANCE,
			GL_UNSIGNED_BYTE, m_curByteImage.top_left_ptr());
	else if (m_curRGBImage.is_contiguous())
		glDrawPixels(m_curRGBImage.ni(), m_curRGBImage.nj(), GL_RGB,
			GL_UNSIGNED_BYTE, m_curRGBImage.top_left_ptr());
	else
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	m_mutex.Release();

	// Call the current vision system component (if there is one)
	// to draw over the current image
	if (m_pPainter)
	{
		glPushMatrix();
		glTranslated(m_offset.x, m_offset.y + h(), 0);
		glScaled(m_zoom, -m_zoom, 1);
		glColor4f(0, 0, 0, 1.0);
		m_pPainter->DrawWithMutex(m_painterInfo);
		glPopMatrix();
	}

#ifdef USE_OPEN_GL_WINDOW
	glFlush();
#else
	gl_finish();
#endif
}