Exemple #1
0
bool CWinEGLPlatformRaspberryPI::SetDisplayResolution(RESOLUTION_INFO& res)
{
  EGL_DISPMANX_WINDOW_T *nativeWindow = (EGL_DISPMANX_WINDOW_T *)m_nativeWindow;

  DestroyWindow();

  bool bFound = false;

  RESOLUTION_INFO resSearch;

  int best_score = 0;

  for (size_t i = 0; i < m_res.size(); i++)
  {
    if(m_res[i].iWidth == res.iWidth && m_res[i].iHeight == res.iHeight && m_res[i].fRefreshRate == res.fRefreshRate)
    {
      int score = 0;

      /* prefere progressive over interlaced */
      if(!GETFLAGS_INTERLACE(m_res[i].dwFlags))
        score = 1;

      if(score >= best_score)
      {
        resSearch = m_res[i];
        bFound = true;
      }
    }
  }

  if(bFound)
  {
    sem_init(&m_tv_synced, 0, 0);
    m_DllBcmHost.vc_tv_register_callback(CallbackTvServiceCallback, this);
  
    int success = m_DllBcmHost.vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, GETFLAGS_GROUP(resSearch.dwFlags), GETFLAGS_MODE(resSearch.dwFlags));

    if (success == 0) 
    {
      CLog::Log(LOGINFO, "CWinEGLPlatformRaspberryPI::SetDisplayResolution set HDMI mode (%d,%d,%d)=%d\n", 
                          GETFLAGS_MODE3D(resSearch.dwFlags) ? HDMI_MODE_3D:HDMI_MODE_HDMI, GETFLAGS_GROUP(resSearch.dwFlags), 
                          GETFLAGS_MODE(resSearch.dwFlags), success);
      sem_wait(&m_tv_synced);
    } 
    else 
    {
      CLog::Log(LOGERROR, "CWinEGLPlatformRaspberryPI::SetDisplayResolution failed to set HDMI mode (%d,%d,%d)=%d\n", 
                          GETFLAGS_MODE3D(resSearch.dwFlags) ? HDMI_MODE_3D:HDMI_MODE_HDMI, GETFLAGS_GROUP(resSearch.dwFlags), 
                          GETFLAGS_MODE(resSearch.dwFlags), success);
    }
    m_DllBcmHost.vc_tv_unregister_callback(CallbackTvServiceCallback);
    sem_destroy(&m_tv_synced);
  }

  m_dispman_display = m_DllBcmHostDisplay.vc_dispmanx_display_open(0);

  OVERSCAN &overscan = res.Overscan;

  m_width   = res.iWidth;
  m_height  = res.iHeight;
  //m_bFullScreen = fullScreen;
  m_fb_width  = res.iWidth;
  m_fb_height = res.iHeight;

  m_fb_bpp    = 8;

  VC_RECT_T dst_rect;
  VC_RECT_T src_rect;

  dst_rect.x = overscan.left;
  dst_rect.y = overscan.top;
  dst_rect.width = overscan.right-overscan.left;
  dst_rect.height = overscan.bottom-overscan.top;

  src_rect.x = 0;
  src_rect.y = 0;
  src_rect.width = m_fb_width << 16;
  src_rect.height = m_fb_height << 16;

  VC_DISPMANX_ALPHA_T alpha;
  memset(&alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T));
  alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;

  DISPMANX_CLAMP_T clamp;
  memset(&clamp, 0x0, sizeof(DISPMANX_CLAMP_T));

  DISPMANX_TRANSFORM_T transform = DISPMANX_NO_ROTATE;
  DISPMANX_UPDATE_HANDLE_T dispman_update = m_DllBcmHostDisplay.vc_dispmanx_update_start(0);
  CLog::Log(LOGDEBUG, "CWinEGLPlatformRaspberryPI::SetDisplayResolution %dx%d->%dx%d\n", m_fb_width, m_fb_height, dst_rect.width, dst_rect.height);

  // width < height => half SBS
  if (src_rect.width < src_rect.height)
  {
    // right side
    /*
    dst_rect.x = m_width;
    dst_rect.width = m_width;
    */
    dst_rect.x = res.iWidth;
    dst_rect.width >>= overscan.right - dst_rect.x;
    m_dispman_element2 = m_DllBcmHostDisplay.vc_dispmanx_element_add(dispman_update,
      m_dispman_display,
      1,                              // layer
      &dst_rect,
      (DISPMANX_RESOURCE_HANDLE_T)0,  // src
      &src_rect,
      DISPMANX_PROTECTION_NONE,
      //(VC_DISPMANX_ALPHA_T*)0,        // alpha
      &alpha,
      //(DISPMANX_CLAMP_T*)0,           // clamp
      &clamp,
      //(DISPMANX_TRANSFORM_T)0);       // transform
      transform);       // transform
      assert(m_dispman_element2 != DISPMANX_NO_HANDLE);
      assert(m_dispman_element2 != (unsigned)DISPMANX_INVALID);
    // left side - fall through
    /*
    dst_rect.x = 0;
    dst_rect.width = m_width;
    */
    dst_rect.x = overscan.left;
    dst_rect.width = res.iWidth - dst_rect.x;
  }
bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res)
{
#if defined(TARGET_RASPBERRY_PI)
  bool bFound = false;

  if(!m_DllBcmHost || !m_nativeWindow)
    return false;

  DestroyDispmaxWindow();

  RESOLUTION_INFO resSearch;

  int best_score = 0;

  for (size_t i = 0; i < m_res.size(); i++)
  {
    if(m_res[i].iScreenWidth == res.iScreenWidth && m_res[i].iScreenHeight == res.iScreenHeight && m_res[i].fRefreshRate == res.fRefreshRate)
    {
      int score = 0;

      /* prefere progressive over interlaced */
      if(!GETFLAGS_INTERLACE(m_res[i].dwFlags))
        score = 1;

      if(score >= best_score)
      {
        resSearch = m_res[i];
        bFound = true;
      }
    }
  }

  if(bFound && !m_fixedMode)
  {
    sem_init(&m_tv_synced, 0, 0);
    m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this);

    int success = m_DllBcmHost->vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, GETFLAGS_GROUP(resSearch.dwFlags), GETFLAGS_MODE(resSearch.dwFlags));

    if (success == 0)
    {
      CLog::Log(LOGDEBUG, "EGL set HDMI mode (%d,%d,%d)=%d\n",
                          GETFLAGS_MODE3D(resSearch.dwFlags) ? HDMI_MODE_3D:HDMI_MODE_HDMI, GETFLAGS_GROUP(resSearch.dwFlags),
                          GETFLAGS_MODE(resSearch.dwFlags), success);
      sem_wait(&m_tv_synced);
    }
    else
    {
      CLog::Log(LOGERROR, "EGL failed to set HDMI mode (%d,%d,%d)=%d\n",
                          GETFLAGS_MODE3D(resSearch.dwFlags) ? HDMI_MODE_3D:HDMI_MODE_HDMI, GETFLAGS_GROUP(resSearch.dwFlags),
                          GETFLAGS_MODE(resSearch.dwFlags), success);
    }
    m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback);
    sem_destroy(&m_tv_synced);

    m_desktopRes = resSearch;
  }

  m_dispman_display = m_DllBcmHost->vc_dispmanx_display_open(0);

  m_width   = res.iWidth;
  m_height  = res.iHeight;

  VC_RECT_T dst_rect;
  VC_RECT_T src_rect;

  dst_rect.x      = 0;
  dst_rect.y      = 0;
  dst_rect.width  = res.iScreenWidth;
  dst_rect.height = res.iScreenHeight;

  src_rect.x      = 0;
  src_rect.y      = 0;
  src_rect.width  = m_width << 16;
  src_rect.height = m_height << 16;

  VC_DISPMANX_ALPHA_T alpha;
  memset(&alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T));
  alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;

  DISPMANX_CLAMP_T clamp;
  memset(&clamp, 0x0, sizeof(DISPMANX_CLAMP_T));

  DISPMANX_TRANSFORM_T transform = DISPMANX_NO_ROTATE;
  DISPMANX_UPDATE_HANDLE_T dispman_update = m_DllBcmHost->vc_dispmanx_update_start(0);

  CLog::Log(LOGDEBUG, "EGL set resolution %dx%d -> %dx%d @ %.2f fps\n",
      m_width, m_height, dst_rect.width, dst_rect.height, bFound ? resSearch.fRefreshRate : res.fRefreshRate);

  // The trick for SBS is that we stick two dispman elements together 
  // and the PI firmware knows that we are in SBS mode and it renders the gui in SBS
  if(bFound && (resSearch.dwFlags & D3DPRESENTFLAG_MODE3DSBS))
  {
    // right side
    dst_rect.x = res.iScreenWidth;
    dst_rect.width = res.iScreenWidth;

    m_dispman_element2 = m_DllBcmHost->vc_dispmanx_element_add(dispman_update,
      m_dispman_display,
      1,                              // layer
      &dst_rect,
      (DISPMANX_RESOURCE_HANDLE_T)0,  // src
      &src_rect,
      DISPMANX_PROTECTION_NONE,
      &alpha,                         // alpha
      &clamp,                         // clamp
      transform);                     // transform
      assert(m_dispman_element2 != DISPMANX_NO_HANDLE);
      assert(m_dispman_element2 != (unsigned)DISPMANX_INVALID);

    // left side - fall through
    dst_rect.x = 0;
    dst_rect.width = res.iScreenWidth;
  }

  m_dispman_element = m_DllBcmHost->vc_dispmanx_element_add(dispman_update,
    m_dispman_display,
    1,                              // layer
    &dst_rect,
    (DISPMANX_RESOURCE_HANDLE_T)0,  // src
    &src_rect,
    DISPMANX_PROTECTION_NONE,
    &alpha,                         //alphe
    &clamp,                         //clamp
    transform);                     // transform

  assert(m_dispman_element != DISPMANX_NO_HANDLE);
  assert(m_dispman_element != (unsigned)DISPMANX_INVALID);

  memset(m_nativeWindow, 0, sizeof(EGL_DISPMANX_WINDOW_T));

  EGL_DISPMANX_WINDOW_T *nativeWindow = (EGL_DISPMANX_WINDOW_T *)m_nativeWindow;

  nativeWindow->element = m_dispman_element;
  nativeWindow->width   = m_width;
  nativeWindow->height  = m_height;

  m_DllBcmHost->vc_dispmanx_display_set_background(dispman_update, m_dispman_display, 0x00, 0x00, 0x00);
  m_DllBcmHost->vc_dispmanx_update_submit_sync(dispman_update);

  DLOG("CEGLNativeTypeRaspberryPI::SetNativeResolution\n");

  return true;
#else
  return false;
#endif
}