Duilib的双缓冲实现,附带GDI、WTL的双缓冲实现
前言:
闪烁问题,之前的经验是使用双缓冲,借此机会,把双缓冲的研究心得总结下。
双缓冲的含义:
缓冲这个词,相信大家都不陌生,Cache。主要是为了解决上下游(或者模块、或者系统)等性能不匹配问题。如果把上游看成“生产者”,下游看成“消费者”,当“生产者”与“消费者”的处理速度不同时,为了避免干等,中间会加一些缓冲区。
无缓冲,双方都容易阻塞。
最常用的生产者-消费者模型,增加弹性缓冲,缺点是每生产+每消费都需要加锁
双缓冲,等消费者队列为空时加锁,执行exchange(如swap方法),大大减少了加锁次数。
双缓冲在界面的使用:
GDI双缓冲:
WM_ERASEBKGND : 返回1,禁止背景重绘
HDC hDc = ::GetDC( m_hWnd) ;
RECT rcDest;
HDC hMemDc = CreateCompatibleDC(hDc);
HBITMAP hMemBitmap = CreateCompatibleBitmap(hDc); //内存画布,放到内存DC中就可以在内存中画图了
HBITMAP hOldBitmap = ::SelectObject (hDC, hBitmap);
//....hMemDc作画
::BitBlt (m_hDestDC, rc.left, rc.top, rc.Width(), rc.Height(), hDC, rc.left, rc.top, SRCCOPY); //拷贝到显示器缓冲 //资源释放与还原
::SelectObject (hDC, hOldBitmap);
DeleteObject(hMemBitmap);
DeleteDC(hMemDc);
ReleaseDC(m_hWnd,hDc);
WTL双缓冲:
CDoubleBufferImpl 在AtlFrame.h中。
1.首先继承自CDoubleBufferImpl
class TCtrl:
public CWindowImpl< TCtrl>,
public WTL::CDoubleBufferImpl<TCtrl> // 继承双缓冲类
2.由于双缓冲类中已经处理了WM_ERASEBKGND 和WM_PAINT消息,所以需要从你的代码中删除对这些消息的处理。然后加上双缓冲的消息处理即可。
BEGIN_MSG_MAP(TCtrl)
// MESSAGE_HANDLER(WM_PAINT, OnPaint)
CHAIN_MSG_MAP( WTL::CDoubleBufferImpl<TCtrl>)
END_MSG_MAP()
3.增加一个DoPaint函数,函数声明如下:
void DoPaint(CDCHandle dc);
4.将原来OnPaint函数中的代码移到DoPaint中,注意原来的CPaintDC需要改用参数中的CDCHandler
void TCtrl::DoPaint( CDCHandle dc )
{
//CPaintDC dc(m_hWnd);
dc.MoveTo( xx… )
}
Duilib双缓冲:
Duilib使用的GDI+引擎,也已经支持双缓冲,这里简单介绍下它的实现过程
1、Duilib也默认处理了WM_REASEBKGND 并返回1;
2、IRenderContext 类负责渲染。
目前由RenderContext_GdiPlus来实现。
1)构造函数中,创建内存DC
2) 获取绘图区域后,创建内存Bitmap
然后作画,细节暂时略,后续源码剖析会补充,敬请期待。
最后,拷贝到显示器缓冲。
Duilib的双缓冲实现,附带GDI、WTL的双缓冲实现的更多相关文章
- js 实现动态key value(JSON字符串注意事项:key和value都要用双引号,官网指定用双引号)
1.JSON字符串注意事项:key和value都要用双引号,官网指定用双引号,如下: var mapStr='{"a":"a","b":&q ...
- WTL使用双缓冲避免重绘闪烁
1.继承自CDoubleBufferImpl template <class T> class CDoubleBufferImpl { public: // Overrideables v ...
- 做双网卡绑定_______物理机在双网卡的情况下做多IP绑定
公司的环境是这样的: 一台物理机需要做双网卡绑定,同时呢,在双网卡绑定的同时还要做多IP. 其实整个过程可以分为两个步骤: 第一个,物理机先做双网卡. 第二个,在bond上做多IP实例. 双网卡绑定的 ...
- JAVA中”单引号”,“双引号”,“没有单引号和双引号”区别:
单引号引的数据 是char类型的——>单引号只能引一个字符(表示单个字符)双引号引的数据 是String类型的——>而双引号可以引0个及其以上(引用字符串) char类型的值用单引号引起来 ...
- linux中配置双网卡的目的?如何实现双网卡绑定,以实现负载均衡?
配置双网卡的目的:========================== 1.你想做路由器,网关 2.实现冗余 3.负载均衡 linux 主机安装双网卡,共享一个IP地址,对外提供访问,实际 同 ...
- 缓冲流的原理和BufferedOutputStream字节缓冲输出流
缓冲流的原理 BufferedOutputStream字节缓冲输出流 package com.yang.Test.BufferedStudy; import java.io.BufferedOutpu ...
- C#如何消除绘制图形缩放时抖动,总结
一.手动双缓冲 首先定义一个BitmapBitmap backBuffer = new Bitmap(画布宽度, 画布高度);然后获取这个Bitmap的GraphicsGraphics graphic ...
- GDI+ 双缓冲实现
早前曾为此问题在CSDN发帖求助(GDI+ 如何使用双缓冲绘制图像),得到了一个GDI+下较可行的方法,虽然绘制效果比直接绘制要好一些,不过还不能跟GDI的双缓冲方式比肩. 现在,我终于找到了一个 ...
- 陈灯WGF双缓冲绘图框架
“木丸子童屋”,专售各类儿童玩具,价格优惠,请大家多多支持:http://shop65552598.taobao.com/ WGF(windows graphic foundation)为window ...
随机推荐
- 『居善地』接口测试 — 6、Httpbin服务介绍
目录 1.Httpbin服务介绍 2.在Windows系统中部署Httpbin服务 3.在Linux系统中部署Httpbin服务 4.Httpbin访问方式 5.Httpbin常用调试接口 6.总结: ...
- C++ primer plus读书笔记——第14章 C++中的代码重用
第14章 C++中的代码重用 1. 使用公有继承时,类可以继承接口,可能还有实现(基类的纯虚函数提供接口,但不提供实现).获得接口是is-a关系的组成部分.而使用组合,类可以获得实现,但不能获得接口. ...
- computed和watch的区别
严格上来说,计算属性能够实现的效果,watch都可以实现.只是有时候watch写起来比较麻烦. 但是watch能够实现的效果computed不一定能够实现. 1:watch内部可以包含异步操作,com ...
- traefik ingress Controller使用
Kubernetes Ingress Kubernetes Ingress是路由规则的集合,这些规则控制外部用户如何访问Kubernetes集群中运行的服务. 在Kubernetes中,有三种方式可以 ...
- XSF /如何使用xrandr
XSF /如何使用xrandr 西里尔·布鲁莱布瓦<kibi@debian.org> 目录 入门 什么是xrandr? xrandr是与XRandR 扩展名交互的命令行工具[请参阅x.or ...
- CentOS 7磁盘寻找不到,卡在sulogin,造成的开机失败问题--Error getting authority...
今天早上使用内网gitlab仓库的时候,发现页面无法打开,ssh也无法连接. 到机房接上显示器,发现如下错误: Error getting authority: Error initializing ...
- 012.Python的字典和集合的相关函数
一 字典的相关函数 1.1 增函数 dictvar = {"a":1,"b":2} dictvar["c"] = 3 print(dictv ...
- C语言函数sscanf()的用法-(转自Walter L)
在我的学习过程中,从文件读取数据是一件很麻烦的事,所幸有sscanf()函数. C语言函数sscanf()的用法sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: int ss ...
- Centos7 vsftpd虚拟用户权限控制(vsftpd虚拟用户限制IP访问)
实验目标:(新增限制虚拟机用户登陆的IP) 实现在同一跟目录下对admin,upload,download三个虚拟用户的不同权限的控制.具体权限控制列表如下: 用户名 权限说明 admin 管理员,可 ...
- 『动善时』JMeter基础 — 31、JMeter中BeanShell断言详解
目录 1.BeanShell简介 2.Beanshell的内置变量和方法 3.BeanShell断言界面详解 4.BeanShell断言的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 ...