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 }