×
Namespaces

Variants
Actions

如何通过直接访问屏幕内存来直接绘制屏幕并更新

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

文章
翻译:
hoolee
最后由 hamishwillee 在 22 Dec 2011 编辑

有三个方法可以跳过window server来直接绘制屏幕(这里称为Direct drawing),这通常用在游戏程序中使得屏幕绘制更加快速。其中一个直接访问的方法就是直接访问屏幕内存,并通过编辑内存来绘制屏幕。

这里可以使用UserSvr::ScreenInfo()这个API来获取屏幕地址,结果放在TScreenInfoV01包中,下面的代码片段可以获得内存地址,并绘制一个简单的矩形到屏幕上:

           TPckgBuf<TScreenInfoV01> infoPckg;
TScreenInfoV01& screenInfo = infoPckg();
UserSvr::ScreenInfo(infoPckg);
TUint16* screenMemory = (TUint16*) screenInfo.iScreenAddress + 16;
for (int j = 80; j < 140; j++)
{
for (int i = 0; i < 176; i++)
{
*(screenMemory + 2*(16 + i + j*176)) = i/8 + j;
}
}

当绘制完成后,屏幕将会被更新,变化后的内容直接反映在屏幕上,我们可以通过向系统队列增加一个重绘事件来完成TRawEvent::ERedraw(通过UserSvr::AddEvent()),它将立刻更新屏幕,下列代码演示了如何处理:

          TRawEvent redraw;
          redraw.Set(TRawEvent::ERedraw);
          UserSvr::AddEvent(redraw);


但TRawEvent::ERedraw是由主机系统生成的,如模拟器环境的WM_PAINT事件。S60第二版中,屏幕更新可以通过增加系统队列完成,但第三版中却无法立刻展现系统队列中重绘指令的效果。屏幕只能通过手机屏幕关于超出数据区域的通知事件才能更新。

所以通过UserSvr::ScreenInfo()来修改显示内存的方法在S60第三版后是不建议使用的。

作为一个解决方案,可以通过使用老的绘制方法强制屏幕更新,通过使用CFbsScreenDevice的Update()方法来指明超出数据区域,这个代码示例如下:

          CFbsScreenDevice* iMyScreenDev = CFbsScreenDevice::NewL(0 ,EColor64K); 
          // the screennumber will be 0 if phone supports single screen where as the 
          // displaymode can be as per your choice
          RRegion iMyregion;
          iMyregion.AddRect(TRect(0,0,240,320)); // the out of date rect region.
          iMyScreenDev->Update(iMyregion);
          iMyregion.Close();
This page was last modified on 22 December 2011, at 07:58.
31 page views in the last 30 days.
×