`
totoxian
  • 浏览: 1074062 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

Symbian屏幕双缓冲&&DSA

阅读更多

参考网上一篇文章重新整理了下屏幕双缓冲和DSA的知识!

⑴图形设置和图形上下文

应用程序绘制图形时,必须要使用图形设备和图形上下文。

图形设备是绘制操作的对象(如屏幕、打印机等),图形设备上下文提供了一种设备的抽象机制从而完全屏蔽了具体的图形设备,应用程序在使用这些图形设备时只需要和这些抽象的图形设备类交互即可,而不必考虑其具体的设备。

图形上下文是绘画平台及绘画所需要工具的集合体,它还包括平台的尺寸、方向、颜色和所有能实现绘画想象力的附件。

下面为Symbian中使用的图形设备及其功能,它们是实现绘画的基础。

图形设备 描述
CGraphicsDevice 图形设备的基类
CBitmapDevice 位图化图形设备的基类
CFbsDevice 使用字体位图服务器的图形设备基类
CPrinterDevice 具有打印功能的设备基类
CWsScreenDevice 使用窗口服务器的屏幕设备
CFbsBitmapDevice 使用字体位图服务器的设备具体实现
CFbsScreenDevice 使用直接屏幕访问(DSA),而不通过窗口服务器

这些设备类的继承关系如下:

CWindowsGc用于屏幕绘制,CFbsBitGc则用于内存绘制!

⑵双缓冲

应用程序在屏幕上的描画一般是使用CWsScreenDevice图形设备来完成,与CWindowGc图形上下文相关联。CONE提供了一个CWindowGc实例作为描画控件的标准图形上下文。它被CCoeEnv创建并且可以使用CCoeControls::SystemGc()方法访问。 CWindowGc的描画方法在客户端窗口服务器缓冲区上进行缓冲。

void CExampleControl::Draw( const TRect& /*aRect*/ ) const
{
 // Get the system graphics context
 CWindowGc& gc = SystemGc();
 // Set drawing settings
 gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
 gc.SetBrushColor( KRgbRed );
 // Draw
 gc.DrawLine( TPoint(10,10), TPoint(30,10) );
}

DrawNow()强制控件立即重画自己,而DrawDeferred()导致一个重画事件使用低优先级操作!

如果一个游戏的图形由多个需要被经常更新的运动对象组成,窗口服务器的客户端缓冲可能被充满并且可能会在所有对象都更新的时候溢出,用户可能会发现屏幕出现闪烁。如果一个视图仍然在更新的时候,可能会出现闪烁或者其他不希望的效果。这些问题的解决方案是双缓冲,图形先被画在一个屏外位图上,然后被画到屏幕上作为一个单一窗口服务器操作。尤其是对于那种在一秒钟内重画几次屏幕的游戏,使用屏外位图可以改善它们的性能。

  一个屏外位图可以使用位图化的图形上下文和图形设备类来创建:CFbsBitGc和CFbsBitmapDevice。它们使用其他的上下文和设备类来创建和使用。为了获得额外的性能,位图自己就应该是一个CWsBitmap位图。在屏外位图更新之后,它可以使用正常的窗口服务器的描画方法画在窗口中。

  当一个应用程序在一个窗口画位图时,它转化为和窗口相同的显示模式。这是一个很消耗时间的操作,实质上可能降低描画的速度。因此把位图用于动画的游戏应该在动画开始之前就完成转化。转化可以通过使用一个屏外位图来执行,如下面的示例方法演示:

CFbsBitmap* CExampleControl::LoadAndConvertBitmapL( Const TDesC& aFileName, TInt aBitmapId )
{
 // Load the bitmap
 CFbsBitmap* originalBitmap = new ( ELeave ) CFbsBitmap();
 CleanupStack::PushL( originalBitmap );
 User::LeaveIfError( originalBitmap->Load( aFileName, aBitmapId, EFalse ) );


 // Create a new bitmap, graphics device and context
 CFbsBitmap* newBitmap = new ( ELeave ) CFbsBitmap();
 CleanupStack::PushL( newBitmap );
 newBitmap->Create( originalBitmap->SizeInPixels(), Window()->DisplayMode() );
 CFbsBitmapDevice* graphicsDevice = CFbsBitmapDevice::NewL(newBitmap);
 CleanupStack::PushL( graphicsDevice );
 CFbsBitGc* graphicsContext;
 User::LeaveIfError( graphicsDevice->CreateContext( graphicsContext ) );
 TPoint zero(0,0);

 // Blit the loaded bitmap to the new bitmap
 graphicsContext->BitBlt( zero, originalBitmap );
 CleanupStack::Pop(3);
 delete graphicsContext;
 delete graphicsDevice ;
 delete originalBitmap;
 return newBitmap;
}

  示例方法使用一个文件名和位图ID作为参数,并且从一个MBM文件中装载相应的位图。如果一个游戏有许多位图应该转化,那么应该在游戏或者等级的初始化阶段转化,因此用户就不会看到这个操作了。

⑵直接屏幕访问(DSA)

  使用窗口服务器在屏幕上描画需要一个上下文转换,这会减慢描画速度。为了绕过窗口服务器省去繁琐的上下文转换,可以直接访问屏幕。这被称作直接屏幕访问。

在Symbian OS中有两种方法来直接在屏幕上描画:

  ①CFbsScreenDevice是一个可以被发送到屏幕驱动程序SCDV.DLL的图形设备。在创建一个CFbsBitGc图形上下文之后,它能像任何其他的图形设备一样使用。然而,可以直接在屏幕上描画,而不需要使用窗口服务器。

直接在屏幕上描画的另一种方法是从系统中查询屏幕内存地址,这可以使用UserSrv类来实现:

TPckgBuf<TScreenInfoV01> infoPckg;
TScreenInfoV01& screenInfo = infoPckg();
UserSvr::ScreenInfo(infoPckg);
TUint16* screenMemory = screenInfo.iScreenAddress + 16;
  屏幕内存有一个32字节的头。

  即使在屏幕内存内写数据比CFbsScreenDevice稍微快一点,但是功能可能根据硬件和屏幕的设备驱动程序的不同而有差异。在一些基于Symbian OS的终端中,屏幕在内存变化的时候自动从屏幕内存中更新,而在其他的终端中描画需要明确的激活。屏幕内存地址只对目标硬件有效,因此描画代码需要分为硬件和模拟器两部分。在模拟器环境中,可以描画到一个屏外位图中,而不是屏幕内存中,然后使用正常的窗口服务器描画方法位块传送到屏幕上。环境可以通过使用__WINS__定义来检测出来。

#ifdef __WINS__ // Emulator environment
// Draw to an off-screen bitmap
#else // Hardware environment
// Draw directly to the screen memory
#endif

  这两种直接描画方法的一个共同的问题是窗口服务器不了解描画,因此它不能通知应用程序是否出现另一个窗口或者窗口组。 即使当应用程序失去焦点的时候得到一个事件,它们也不能停止直接描画,因为直接描画实在太快了,并且屏幕内容有可能被弄乱。 这可能发生在玩游戏的时候,突然有电话打进来的情况下。


新近的GT 6.1版本提供了一个应用编程接口用于直接描画,将能解决前面提到的问题。

这个应用编程接口由两个类组成:一个MDirectScreenAccess类,提供用于应用程序的回调方法,还有一个CDirectScreenAccess类处理与窗口服务器的通讯。 下面的代码说明CDirectScreenAccess实例是如何构造的,以及直接描画支持是如何激活的。

iDrawer = CDirectScreenAccess::NewL(iEikonEnv->WsSession(), *iEikonEnv->ScreenDevice(), Window(), *this);
iEikonEnv->WsSession().Flush();
iDrawer->StartL();
iDrawer->ScreenDevice()->SetAutoUpdate(ETrue);

  CDirectScreenAccess的NewL方法获得一个窗口服务器会话CONE的图形设备应用程序窗口一个到MDirectedScreenAccess导出类的指针作为参数。 在CDirectScreenAccess::StartL被调用来激活直接描画支持之前,客户端窗口服务器缓冲应该溢出。 为了能自动更新屏幕,屏幕设备的SetAutoUpdate方法需要使用ETrue参数,否则gc draw指令不会在模拟器中立即显示,而是在下一次冲刷(Flush)视窗服务器时才显示。 当直接描画支持激活的时候,CDirectScreenAccess产生一个CFbsBitGc图形上下文,可以被应用程序用来在屏幕上绘画。

iDrawer->Gc()->BitBlt( TPoint(0,0), iBitmap );

  当另一个窗口出现在应用程序窗口上时,CDirectScreenAccess从窗口服务器取得一个事件来中断描画。 CDirectScreenAccess然后调用MDirectScreenAccess派生类的AbortNow方法,这个方法必须被应用程序重载以便中断描画。 为了防止屏幕被弄乱,窗口服务器直到中断描画事件被处理的时候才画重叠窗口。

分享到:
评论

相关推荐

    DSA数字签名 DSA数字签名

    DSA数字签 DSA数字签DSA数字签名 DSA数字签名

    DSA签名算法的C#实现

    DSA(Digital Signature Algorithm)是一种基于离散对数问题的公钥密码学算法,常用于数字签名,以确保数据的完整性和发送者的身份。在C#中实现DSA签名算法,主要涉及以下几个关键步骤和知识点: 1. **密钥生成**:...

    DSA2013专业版

    4. **语音导航**:为了保证驾驶安全,DSA2013提供了语音导航功能,让驾驶员可以专注于道路,而不必频繁查看屏幕。语音提示清晰,易于理解。 5. **用户界面**:专业版的用户界面设计友好,操作直观,方便用户快速...

    liuzhigao.rar_DSA实现_DSA算法_dsa_dsa用C实现

    标题"liuzhigao.rar_DSA实现_DSA算法_dsa_dsa用C实现"中,核心关键词是“DSA实现”、“DSA算法”以及“C实现”,这表明这是一个关于使用C语言实现数字签名算法(Digital Signature Algorithm,简称DSA)的项目。DSA...

    DSA自动运行

    在这种情况下,`autohide=0`的作用是取消自动隐藏的功能,使得DSA电子狗能够在特定条件下自动启动并显示在屏幕上。 #### 六、注意事项 - **兼容性问题**:在进行上述设置前,请确保您的DSA电子狗和凯立德地图版本...

    安卓DSA无蓝牙提示修改版

    Android DSA 官方使用说明 (转自网络,不完整,只是一个简单说明). p z9 I: h `8 X$ S: x* f 说明:Android DSA是由惠州善领科技有限公司独立开发,软件主要基于Android 2.1及以上平台的手机及MID上使用,支持320...

    DSA标准通信协议(philips)

    根据提供的文档信息,本文将对“DSA标准通信协议(Philips)”进行详细的解析与扩展,以便深入了解该协议的背景、架构及其应用场景。 ### 一、简介 #### 1.1 目的 本文旨在详细介绍Philips公司开发的DSA(Data ...

    最新 DSA 数据 tag

    DSA,全称Digital Signature Algorithm(数字签名算法),是公钥密码学中的一种标准签名方案,主要应用于数据的完整性验证和身份认证。在这个压缩包文件中,"最新 DSA 数据"可能包含了一些关于DSA算法的最新研究、...

    2010DSA -P46

    描述中的“善领”可能是指DSA的一个品牌或开发者,专注于提供适合低内存设备和清晰度较低屏幕的解决方案。这意味着该软件在资源有限的硬件上也能运行良好,这对于那些不希望升级硬件但又想提升导航体验的用户来说...

    DSA201黄金版

    5. **语音播报**:为了保证驾驶安全,DSA201采用语音播报方式,避免驾驶员在驾驶过程中分心查看屏幕。语音提示清晰,能及时提醒用户注意即将遇到的测速点或红绿灯。 6. **节能模式**:软件具备节能模式,可以在车辆...

    善领DSA最新电子眼数据

    【善领DSA最新电子眼数据】是针对驾驶安全预警系统的一种升级数据,主要包含全国范围内的交通监控设备信息,如测速摄像头、红绿灯、违章拍照点等位置信息。这些数据对于驾驶员来说至关重要,可以帮助他们遵守交通...

    IBM服务器硬件检测工具DSA

    IBM服务器硬件检测工具DSA,全称为Diagnostics Support Assistant,是IBM提供的一款专业工具,用于对IBM服务器的硬件状态进行全面的检查和诊断。该工具能够帮助系统管理员快速识别和解决可能出现的硬件问题,确保...

    DSA_fmodce_UploadError:493_DSASOUND_dsa最后版本_dsa最后版_

    在IT领域,DSA通常指的是Digital Signature Algorithm(数字签名算法),这是一种用于确保数据完整性和来源真实性的加密技术。在本场景中,“DSA最后版”可能是指一个软件或程序的最终版本,其中包含了对DSA算法的...

    DSA全分辨480X272-800X480

    在这个压缩包文件"DSA全分辨480X272-800X480"中,我们可以推测这是一款适用于不同分辨率显示器的DSA软件版本,分别适应480x272像素和800x480像素的屏幕。 DSA系统的核心在于其数据库,包含了各种交通标志、地标的...

    dsa皮肤制作

    ### DSA皮肤制作详解 #### 一、引言 随着技术的发展与个性化需求的增长,越来越多的用户希望对自己的设备进行定制化设置,以更好地满足个人喜好和功能需求。善领(DSA)电子狗作为一款广受好评的产品,不仅因其...

    2014年DSA最新数据大全

    标题中的“2014年DSA最新数据大全”指的是2014年度关于DSA(Dynamic Signature Algorithm,动态签名算法)的全面数据集合。DSA是一种基于公钥密码学的数字签名算法,广泛应用于软件验证、安全通信等领域。在2014年的...

    DSA速度变色版

    "DSA速度变色版"是基于数据结构与算法(DSA)的一个特定实现,可能是某个软件或游戏的版本,其中包含了速度变化和颜色变换的特性。这个版本可能专注于优化算法执行效率,或者在视觉呈现上增加了动态色彩效果。下面将...

    DSA.rar_DSA算法,matlab_dsa

    动态模拟退火算法(Dynamic Simulated Annealing,DSA)是一种基于物理退火原理的全局优化算法,主要用于寻找复杂问题的全局最优解。该算法源于固体物理学中的退火过程,通过模拟物质冷却过程中能量逐渐降低的过程,...

    dsa专业版220数据

    标题中的“dsa专业版220数据”指的是一个特定版本的DSA(可能是一个软件或数据库)的专业级更新,编号为220。DSA通常代表Data Storage and Retrieval,这是一个广泛的概念,可以涉及到数据管理和检索系统,尤其是在...

    dsa_CODE.rar_dsa_dsa code_dsa 通信_dsa_CODE_dsa通信

    在这个压缩包文件“dsa_CODE.rar_dsa_dsa code_dsa 通信_dsa_CODE_dsa通信”中,包含的是DSA协议的源代码,可能是一个实现或解释该协议的实例。以下将详细介绍DSA协议及其相关的编程知识点。 **DSA协议详解** DSA...

Global site tag (gtag.js) - Google Analytics