WINCE6下动态修改分辨率的问题

[问题求助] 进来讨论一下WINCE如何动态改变分辨率?

RT,最近小弟我在做WINCE(WINCE6)下动态改变分辨率的功能,起源于本公司的WINCE6平台支持HDMI输出,当HDMI以不同分辨率(1280*720,1920*1080,720*480。。。)输出时,希望wince能动态的改变分辨率,以使UI层能够在HDMI TV上全屏显示。 ' B9 |# m$ ~2 R0 V: C
工作了一天,添加了一个驱动,在应用层使用DeviceIoControl要求底层驱动根据新的分辨率对LCD控制器重新配置,这段代码验证没有问题。但是结果是花屏,我在想修改完LCD控制器的配置后,如何通知WINCE内核(或者说GDI),要求其重载重绘?如果能让WINCE重绘重载显示驱动,那么估计我就能成功了。。。。请问该如何操作呀?不知道哪位哥们做过类似的开发?一起分享一下经验吧。。。。。

==================================================================================

动态改变分辨率在CE6上面是没问题的(CE5不行),但是不是让应用层调用IOControl,应用层应该调用ChangeDisplaySettingsEx,然后由display driver去处理。
) /- Q4 b4 }: m) Idisplay driver那边要报多个分辨率,然后在GPE::SetMode处理一下。

SCODE ANYKADISP::SetMode (INT modeId, HPALETTE *palette)
{
 RETAILMSG(HAL_ZONE_INIT, (TEXT("++ANYKADISP::SetMode/r/n")));
 
 if (modeId != 0)
 {
  RETAILMSG(HAL_ZONE_INIT, (TEXT("ANYKADISP::SetMode Want mode %d, only have mode 0/r/n"),modeId));
  return E_INVALIDARG;
 }
 
 if (palette)
 {
  *palette = EngCreatePalette (PAL_BITFIELDS, 0, NULL, gBitMasks[0], gBitMasks[1], gBitMasks[2]);
 }

    m_dwPhysicalModeID = m_pMode->modeId;

    m_CursorHotspot.x = 0;
    m_CursorHotspot.y = 0;      
 
 RETAILMSG(HAL_ZONE_INIT, (TEXT("--ANYKADISP::SetMode/r/n")));
 
 return S_OK;
}

==================================================================================

我见过有做成动态设置分辨率的,不过设置完以后,都要重新启动一下才可以,不知道不重新启动有没有办法做到。

==================================================================================

如果你直接用IOCTL,花屏基本上是免不了的,因为你没有通知系统,而系统的gwes负责了很大一块UI和消息的处理。

==================================================================================

如果你是通过ChangeDisplaySettingsEx通知驱动的,那么系统就会知道,它会帮你调整界面. 2 I/ d4 ~1 P  s. w2 H1 O
我记得怎么改不繁的,还是直接用ChangeDisplaySettingsEx吧,大概就做这么几步:
GetModeInfo里面返回多个分辨率
NumModes返回可供切换的分辨率的数目。 , A6 Z" L8 _9 w- I
SetMode运行前系统应该已经把当前primary surface删除了,你需要在SetMode中重新分配primary surface。

==================================================================================

貌似飞凌的网站上看到过,不过俺不懂,建议楼主去咨询一下。

==================================================================================

Display驱动里面,GetModeInfo;NumModes等函数需要告诉OS有两种显示模式,例如一个是320*240 16bpp,另一个是320*240 24bpp。然后调用ChangeDisplaySettingsEx,上层应该就会调用驱动的SetMode来切换显示模式。完全不用重新启动。可以参考微软的例子wince500/public/common/oak/csp/x86/geode/gxvideo/base/Misc.cpp

 http://topic.csdn.net/u/20090407/16/878b6cb7-32b4-428e-ab37-0617301bdccd.html

==================================================================================

你说的是设备重起么?如果设备重起叫什么动态设置分辨率啊
不过display driver里面是要重新reset一下的

==================================================================================

ruritanian,

能否提供实现GetModeInfo,NumModes和SetMode这三个函数的参考代码。我在我的display驱动中找到了这三个函数,但是实现挺简单的:

SCODE
TCCDISP::GetModeInfo(GPEMode *mode, int modeNo)
{
//RETAILMSG(TC_LOG_LEVEL(TC_DEBUG), (TEXT("[DISPLAY ] TCCDISP::GetModeInfo()/n/r")));

if (modeNo != 0)
{
RETAILMSG(TC_LOG_LEVEL(TC_ERROR), (TEXT("[DISPDRV:ERR] GetModeInfo() : modeNo = %d, Driver Support Only Mode 0/n/r"), modeNo));
return E_INVALIDARG;
}

*mode = *m_pMode;

return S_OK;
}

int
TCCDISP::NumModes()
{
RETAILMSG(TC_LOG_LEVEL(TC_DEBUG), (TEXT("[DISPLAY ] TCCDISP::NumModes()/n/r")));
return 1;
}

SCODE
TCCDISP::SetMode (INT modeId, HPALETTE *palette)
{
SCODE scRet = S_OK;

RETAILMSG(TC_LOG_LEVEL(TC_LOG), (TEXT("[DISPLAY ] ++TCCDISP::SetMode(%d)/n/r"), modeId));

if (modeId == 0)
{
m_dwPhysicalModeID = m_pMode->modeId;

// Create Palette
if (palette)
{
*palette = EngCreatePalette(PAL_BITFIELDS, 0, NULL, gBitMasks[0], gBitMasks[1], gBitMasks[2]);
}

//Allocate Primary Surface
if (NULL == m_pPrimarySurface)
{
if (FAILED(AllocSurface((DDGPESurf **)&m_pPrimarySurface,
m_nScreenWidthSave, m_nScreenHeightSave,
m_pMode->format, m_pModeEx->ePixelFormat,
GPE_REQUIRE_VIDEO_MEMORY)))
{
RETAILMSG(TC_LOG_LEVEL(TC_ERROR), (TEXT("[DISPLAY ] SetMode() : m_pPrimarySurface AllocSurface() Fail/n/r")));
scRet = E_INVALIDARG;
}
else
{
m_pVisibleSurface = (TCCDISPSurf*)m_pPrimarySurface;
}
}

m_pPrimarySurface->SetRotation(m_nScreenWidth, m_nScreenHeight, m_iRotate);

}
else
{
RETAILMSG(TC_LOG_LEVEL(TC_ERROR), (TEXT("[DISPLAY ] SetMode() : modeId = %d, Driver Support Only Mode 0/n/r"), modeId));
scRet = E_INVALIDARG;
}

#ifdef _USING_HW_ACCELETE_
//reserved for H/W Accelerate Dump Memory
pHWTempHeap = m_pVideoMemoryHeap->Alloc(800*480*4);
#endif
RETAILMSG(TC_LOG_LEVEL(TC_LOG), (TEXT("[DISPLAY ] --TCCDISP::SetMode()/n/r")));

return scRet;
}

=================================================================================

你先把GetModeInfo和NumModes按照我说的实现了,然后再调一下SetMode,看上去你的代码里SetMode已经分配Primary surface了。SetMode里面的代码各家都不一样,需要调试一下。

=================================================================================

哪个API会调用SetMode?还有加入我准备好几套分辨率的参数,应该在哪里初始化呢?
http://www.intelligraphics.com/introduction-wince-driver-development

=================================================================================

ruritanian,
能给我讲讲display驱动中实现DDGPE继承类的各个成员函数或者GDI函数的调用流程吧?

=================================================================================

这周非常爽,我已经在TCC8900 WINCE平台做出了动态改变WINCE分辨率。如同ruritanian群友所说的,

1.需要DISP驱动中准备好自己需要的分辨率模式,比如说800*480和1280*720两种模式。放在一个GPEModeEx m_ModeInfoEx[2];数组中 其中m_ModeInfoEx中每个元素的modeId为0和1,以此类推

2.然后可以在TCCDISP::TCCDISP()构造函数中适当对m_ModeInfoEx进行初始化;

3.TCCDISP::NumModes()中必须返回2,也就是数组m_ModeInfoEx的元素大小;TCCDISP::GetModeInfo(GPEMode *mode, int modeNo)函数根据modeNo来判断是否支持;TCCDISP::SetMode就是根据modeId要求来新建m_pPrimarySurface,然后分配给m_pVisibleSurface;

4.应用程序部分我是用以下代码调用的:

case ID_RESOLUTION_1280:
MessageBox(hWnd, TEXT("ID_RESOLUTION_1280"),TEXT("Resolution"),MB_OK);
while (TRUE == EnumDisplaySettings(NULL, maxModeIndex, &DevMode)) 

/*检索显示模式列表,取出该结构体的地址赋给&DevMode,即&DevMode指向等待切换的显示模式

   该结构体定义时,需要对其2个属性进行设置如下:

   devmode.dmSize=sizeof(DEVMODE);
   devmode.dmDriverExtra=0;

*/
{
maxModeIndex++;
if((DevMode.dmPelsWidth == 1280)&&(DevMode.dmPelsHeight == 720)) //确认显示模式是否正确
{
SaveLCDStatus( 1280,720);//修改注册表键值,存入将要切换的分辨率
Ret = ChangeDisplaySettingsEx(NULL,&DevMode,NULL,CDS_RESET,NULL) ;//进行切换
if(Ret != DISP_CHANGE_SUCCESSFUL) //判断是否切换成功
{
printf("Mode %d: Display mode resolution test failed.", maxModeIndex));
}else{
printf("ChangeDisplaySettingsEx dwRet = %d /r/n", Ret);
break;
}

}

}
break;

case ID_RESOLUTION_480:
while (TRUE == EnumDisplaySettings(NULL, maxModeIndex, &DevMode))
{
maxModeIndex++;
if((DevMode.dmPelsWidth == 800)&&(DevMode.dmPelsHeight == 480))
{
  SaveLCDStatus( 800,480);
  Ret = ChangeDisplaySettingsEx(NULL,&DevMode,NULL,CDS_RESET,NULL) ;
  if(Ret != DISP_CHANGE_SUCCESSFUL)
  {
  printf("Mode %d: Display mode resolution test failed."), maxModeIndex);
  }else{
  printf("ChangeDisplaySettingsEx dwRet = %d /r/n", Ret);
  break;
  }
}
}
break;

================================================================================

http://topic.csdn.net/u/20091207/19/29c03a48-7616-4e1a-bbbe-b45a5e887c2d.html

仔细阅读安凯BSP与显示Mode相关的代码,位于anykaDisp.cpp

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值