bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions) { #if defined(TARGET_RASPBERRY_PI) resolutions.clear(); if(!m_DllBcmHost) return false; /* read initial desktop resolution before probe resolutions. * probing will replace the desktop resolution when it finds the same one. * we raplace it because probing will generate more detailed * resolution flags we don't get with vc_tv_get_state. */ if(m_initDesktopRes) { TV_DISPLAY_STATE_T tv_state; // get current display settings state memset(&tv_state, 0, sizeof(TV_DISPLAY_STATE_T)); m_DllBcmHost->vc_tv_get_display_state(&tv_state); if ((tv_state.state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) != 0) // hdtv { m_desktopRes.iScreen = 0; m_desktopRes.bFullScreen = true; m_desktopRes.iWidth = tv_state.display.hdmi.width; m_desktopRes.iHeight = tv_state.display.hdmi.height; m_desktopRes.iScreenWidth = tv_state.display.hdmi.width; m_desktopRes.iScreenHeight= tv_state.display.hdmi.height; m_desktopRes.dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); HDMI_PROPERTY_PARAM_T property; property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE; vc_tv_hdmi_get_property(&property); m_desktopRes.fRefreshRate = property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tv_state.display.hdmi.frame_rate * (1000.0f/1001.0f) : tv_state.display.hdmi.frame_rate; } else if ((tv_state.state & ( VC_SDTV_NTSC | VC_SDTV_PAL )) != 0) // sdtv { m_desktopRes.iScreen = 0; m_desktopRes.bFullScreen = true; m_desktopRes.iWidth = tv_state.display.sdtv.width; m_desktopRes.iHeight = tv_state.display.sdtv.height; m_desktopRes.iScreenWidth = tv_state.display.sdtv.width; m_desktopRes.iScreenHeight= tv_state.display.sdtv.height; m_desktopRes.dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, tv_state.display.sdtv.mode, 1); m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate; m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); } else if ((tv_state.state & VC_LCD_ATTACHED_DEFAULT) != 0) // lcd { m_desktopRes.iScreen = 0; m_desktopRes.bFullScreen = true; m_desktopRes.iWidth = tv_state.display.sdtv.width; m_desktopRes.iHeight = tv_state.display.sdtv.height; m_desktopRes.iScreenWidth = tv_state.display.sdtv.width; m_desktopRes.iScreenHeight= tv_state.display.sdtv.height; m_desktopRes.dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, 0, 0); m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate; m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); } SetResolutionString(m_desktopRes); m_initDesktopRes = false; m_desktopRes.iSubtitles = (int)(0.965 * m_desktopRes.iHeight); CLog::Log(LOGDEBUG, "EGL initial desktop resolution %s (%.2f)\n", m_desktopRes.strMode.c_str(), m_desktopRes.fPixelRatio); } if(GETFLAGS_GROUP(m_desktopRes.dwFlags) && GETFLAGS_MODE(m_desktopRes.dwFlags)) { GetSupportedModes(HDMI_RES_GROUP_DMT, resolutions); GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions); } { AddUniqueResolution(m_desktopRes, resolutions, true); CLog::Log(LOGDEBUG, "EGL probe resolution %s:%x\n", m_desktopRes.strMode.c_str(), m_desktopRes.dwFlags); } DLOG("CEGLNativeTypeRaspberryPI::ProbeResolutions\n"); return true; #else return false; #endif }
bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) { #if defined(TARGET_RASPBERRY_PI) if(!m_DllBcmHost || !m_nativeWindow) return false; while (proc_find("hello_video.bin") >= 0) Sleep(100); DestroyDispmaxWindow(); RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode(); if(GETFLAGS_GROUP(res.dwFlags) && GETFLAGS_MODE(res.dwFlags)) { uint32_t mode3d = HDMI_3D_FORMAT_NONE; sem_init(&m_tv_synced, 0, 0); m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this); if (stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL || stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL) { /* inform TV of any 3D settings. Note this property just applies to next hdmi mode change, so no need to call for 2D modes */ HDMI_PROPERTY_PARAM_T property; property.property = HDMI_PROPERTY_3D_STRUCTURE; if (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOSCREEN_FRAMEPACKING) && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_SUPPORTMVC) && res.fRefreshRate <= 30.0f) property.param1 = HDMI_3D_FORMAT_FRAME_PACKING; else if (stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL) property.param1 = HDMI_3D_FORMAT_SBS_HALF; else if (stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) property.param1 = HDMI_3D_FORMAT_TB_HALF; else property.param1 = HDMI_3D_FORMAT_NONE; property.param2 = 0; mode3d = property.param1; vc_tv_hdmi_set_property(&property); } HDMI_PROPERTY_PARAM_T property; property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE; // if we are closer to ntsc version of framerate, let gpu know int iFrameRate = (int)(res.fRefreshRate + 0.5f); if (fabsf(res.fRefreshRate * (1001.0f / 1000.0f) - iFrameRate) < fabsf(res.fRefreshRate - iFrameRate)) property.param1 = HDMI_PIXEL_CLOCK_TYPE_NTSC; else property.param1 = HDMI_PIXEL_CLOCK_TYPE_PAL; property.param2 = 0; vc_tv_hdmi_set_property(&property); int success = m_DllBcmHost->vc_tv_hdmi_power_on_explicit_new(HDMI_MODE_HDMI, GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags)); if (success == 0) { CLog::Log(LOGDEBUG, "EGL set HDMI mode (%d,%d)=%d %s%s\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success, CStereoscopicsManager::GetInstance().ConvertGuiStereoModeToString(stereo_mode), mode3d==HDMI_3D_FORMAT_FRAME_PACKING ? " FP" : mode3d==HDMI_3D_FORMAT_SBS_HALF ? " SBS" : mode3d==HDMI_3D_FORMAT_TB_HALF ? " TB" : ""); sem_wait(&m_tv_synced); } else { CLog::Log(LOGERROR, "EGL failed to set HDMI mode (%d,%d)=%d %s%s\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success, CStereoscopicsManager::GetInstance().ConvertGuiStereoModeToString(stereo_mode), mode3d==HDMI_3D_FORMAT_FRAME_PACKING ? " FP" : mode3d==HDMI_3D_FORMAT_SBS_HALF ? " SBS" : mode3d==HDMI_3D_FORMAT_TB_HALF ? " TB" : ""); } m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback); sem_destroy(&m_tv_synced); m_desktopRes = res; } else if(!GETFLAGS_GROUP(res.dwFlags) && GETFLAGS_MODE(res.dwFlags)) { sem_init(&m_tv_synced, 0, 0); m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this); SDTV_OPTIONS_T options; options.aspect = get_sdtv_aspect_from_display_aspect((float)res.iScreenWidth / (float)res.iScreenHeight); int success = m_DllBcmHost->vc_tv_sdtv_power_on((SDTV_MODE_T)GETFLAGS_MODE(res.dwFlags), &options); if (success == 0) { CLog::Log(LOGDEBUG, "EGL set SDTV mode (%d,%d)=%d\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success); sem_wait(&m_tv_synced); } else { CLog::Log(LOGERROR, "EGL failed to set SDTV mode (%d,%d)=%d\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success); } m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback); sem_destroy(&m_tv_synced); m_desktopRes = res; } m_dispman_display = g_RBP.OpenDisplay(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); if (stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL) transform = DISPMANX_STEREOSCOPIC_SBS; else if (stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) transform = DISPMANX_STEREOSCOPIC_TB; else transform = DISPMANX_STEREOSCOPIC_MONO; CLog::Log(LOGDEBUG, "EGL set resolution %dx%d -> %dx%d @ %.2f fps (%d,%d) flags:%x aspect:%.2f\n", m_width, m_height, dst_rect.width, dst_rect.height, res.fRefreshRate, GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), (int)res.dwFlags, res.fPixelRatio); 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 }
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) if(!m_DllBcmHost || !m_nativeWindow) return false; DestroyDispmaxWindow(); if(!m_fixedMode && GETFLAGS_GROUP(res.dwFlags) && GETFLAGS_MODE(res.dwFlags)) { sem_init(&m_tv_synced, 0, 0); m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this); if (res.dwFlags & (D3DPRESENTFLAG_MODE3DSBS|D3DPRESENTFLAG_MODE3DTB)) { /* inform TV of any 3D settings. Note this property just applies to next hdmi mode change, so no need to call for 2D modes */ HDMI_PROPERTY_PARAM_T property; property.property = HDMI_PROPERTY_3D_STRUCTURE; if (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS) property.param1 = HDMI_3D_FORMAT_SBS_HALF; else if (res.dwFlags & D3DPRESENTFLAG_MODE3DTB) property.param1 = HDMI_3D_FORMAT_TB_HALF; else property.param1 = HDMI_3D_FORMAT_NONE; property.param2 = 0; vc_tv_hdmi_set_property(&property); } int success = m_DllBcmHost->vc_tv_hdmi_power_on_explicit_new(HDMI_MODE_HDMI, GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags)); if (success == 0) { CLog::Log(LOGDEBUG, "EGL set HDMI mode (%d,%d)=%d%s%s\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success, (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS) ? " SBS":"", (res.dwFlags & D3DPRESENTFLAG_MODE3DTB) ? " TB":""); sem_wait(&m_tv_synced); } else { CLog::Log(LOGERROR, "EGL failed to set HDMI mode (%d,%d)=%d%s%s\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success, (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS) ? " SBS":"", (res.dwFlags & D3DPRESENTFLAG_MODE3DTB) ? " TB":""); } m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback); sem_destroy(&m_tv_synced); m_desktopRes = res; } 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 (%d,%d) flags:%x aspect:%.2f\n", m_width, m_height, dst_rect.width, dst_rect.height, res.fRefreshRate, GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), (int)res.dwFlags, res.fPixelRatio); // The trick for SBS is that we stick two dispman elements together // and the PI firmware knows that we are in SBS/TAB mode and it renders the gui in SBS/TAB if(res.dwFlags & (D3DPRESENTFLAG_MODE3DSBS|D3DPRESENTFLAG_MODE3DTB)) { if (res.dwFlags & D3DPRESENTFLAG_MODE3DTB) { // bottom half dst_rect.y = res.iScreenHeight; } else { // right side dst_rect.x = 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); if (res.dwFlags & D3DPRESENTFLAG_MODE3DTB) { // top half - fall through dst_rect.y = 0; } else { // left side - fall through dst_rect.x = 0; } } 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 }
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 }