Nuklear渲染机制分析

最近打算用C写个东西,想找个轻量的UI库,想起以前star过的一个repo,只有一个头文件约15000行的ANSI C代码,没有任何标准库以外的依赖。就是这个:https://github.com/vurtun/nuklear 。嗯,Nuklear,核动力。
看效果真心不错,让我想起另一个UI库zebkit,HTML5 canvas的。事实上这两个还真有点像,就是都是命令式绘制的。本来想照着demo用SDL做一个简单的界面出来,结果久别重逢C语言,一不小心把源码review了一遍(张全蛋:silly B stupid Chinglish。不不不,只是觉得说代码审查不对味儿...)。下面是简单的分析。

Nuklear用一个nk_context结构维护输入,风格,内存,剪贴板,命令队列,鼠标合成,窗口管理。对于一个nk_context实例,基本渲染流程为:

  1. 应用程序初始化后开始如下帧循环逻辑。

  2. 应用程序从平台相关接口获取输入事件,根据事件类型对nk_context调用nk_input_*等api,Nuklear将各类事件参数记录在nk_context中。注意前后要调用nk_input_begin和nk_input_end以初始化和再处理一些数据。
  3. 应用程序对nk_context调用nk_begin绘制窗口,Nuklear用窗口名和标题计算hash并在nk_context的窗口链表中查找,如果窗口不存在则创建并加入链表,否则只更新窗口的参数(如位置大小样式等)。同时,Nuklear还会在此时根据上一步骤中记录的输入事件处理窗口响应行为。
  4. 应用程序调用nk_layout_*、nk_button_*等api绘制布局和控件,Nuklear判断控件可见性并“绘制”控件,这里的绘制实际上是向nk_context的命令队列插入绘制命令。同时,Nuklear根据上一步骤中记录的输入事件处理控件响应行为。
  5. 应用程序对nk_context调用nk_end结束绘制窗口。
  6. 应用程序对nk_context调用nk_foreach宏,循环取出上一步骤中“绘制”控件时加入的绘制命令,并根据命令类型调用平台相关接口进行实际的绘制。
  7. 开始下一帧的循环。

总结起来,这个库实现轻巧,代码也用了一些技巧,看起来很干净。以个人的看法评价下优缺点:

首先,整个UI的驱动机制,从事件到渲染都是命令式的,nk_context只管理窗口并不维护控件的数据结构,应用程序需要自己维护数据,在绘制控件时传入。这样的好处是内存占用小,数据甚至可以只存在于栈中,而且命令式渲染可以很方便灵活地定制效果。

但是,控件的绘制和响应输入事件耦合在了一起,缺少独立数据结构导致应用程序需要协助维护控件状态,并在绘制控件时通过nk_context传入,比如last_widget_state表示控件一系列响应鼠标等输入事件的状态,这些本应该是应用程序不关心的。

其次,命令式绘制导致每帧都需要重复绘制,即使界面并没有发生变化。在源码开头的注释中提到定义NK_ZERO_COMMAND_MEMORY的宏可以在加入绘制命令到队列之前memset清零命令结构体,从而利用memcmp快速检查命令队列是否变化从而避免实际绘制(不清零会有随机数据无法比较)。然而找遍了源码也没有找到实际的使用,也没有提供相关的utils,如果需要自己实现的话感觉有点侵入式了。

最后,不得不说乍一看single header file的ANSI C代码似乎很好看,但是细看发现一些符号命名真是随意,创建窗口的api是nk_begin,源码中还有nk__begin(两个下划线),nk_start,nk_draw_begin,nk__draw_begin,虽然明白意图是私有符号,但是阅读起来真容易马虎。还有api动词名词就不说了,但是大括号换行和不换行两种风格夹杂,赋值语句对齐和不对齐交替,if语句不加花括号一会写在一行一会写两行。

自从当兵几年没用C还以为都忘干净了,重新拾起来吧。

时间: 2024-10-29 00:32:59

Nuklear渲染机制分析的相关文章

深入理解Android渲染机制

基础知识 CPU: 中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps.Drawables等都是一起打包到统一的纹理). GPU:一个类似于CPU的专门用来处理Graphics的处理器, 作用用来帮助加快格栅化操作,当然,也有相应的缓存数据(例如缓存已经光栅化过的bitmap等)机制. OpenGL ES:是手持嵌入式设备的3DAPI,跨平台的.功能完善的2D和3D图形应用程序接口API,有一套固定渲染管线流程. OpenGL ES详解 D

深入Android渲染机制

1.知识储备 CPU: 中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps.Drawables等都是一起打包到统一的纹理). GPU:一个类似于CPU的专门用来处理Graphics的处理器, 作用用来帮助加快格栅化操作,当然,也有相应的缓存数据(例如缓存已经光栅化过的bitmap等)机制. OpenGL ES是手持嵌入式设备的3DAPI,跨平台的.功能完善的2D和3D图形应用程序接口API,有一套固定渲染管线流程. 附相关OpenGL渲染流

Android渲染机制和丢帧分析

http://blog.csdn.net/bd_zengxinxin/article/details/52525781 自己编写App的时候,有时会感觉界面卡顿,尤其是自定义View的时候,大多数是因为布局的层次过多,存在不必要的绘制, 或者onDraw等方法中过于耗时.那么究竟需要多快,才能给用户一个流畅的体验呢?那么就需要简单了解下Android的渲染机制: Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,那么整个过程如果保证在16ms以内就能达到一个流畅的画面. 那么

webkit 渲染机制

最近看了< webkit技术内幕 >,虽然并不能完全看懂,但是对浏览器的渲染机制也算是有了一个比较完整的认识. 我们从浏览器地址栏输入网址开始到web页面被完整的呈现在眼前,大概的经过了这样一个过程:网址被DNS解析为IP地址 -> 通过IP地址建立TCP连接 -> 发送HTTP请求 -> 服务器处理请求并返回响应 ->  浏览器解析渲染页面 -> 断开TCP连接 可是浏览器是怎么去解析渲染页面的呢?这里就要涉及到浏览器的内核,也就是浏览器的渲染引擎(严格来说应该

Chromium网页渲染机制简要介绍和学习计划

作为一个浏览器,快速地将网页渲染出来是最重要的工作.Chromium为了做到这一点,费尽了心机,做了大量优化工作.这些优化工作是卓有成效的,代表了当今最先进的网页渲染技术.值得一提的是,这些渲染技术不仅适用于网页渲染,也可以应用在原生系统的UI渲染上.例如,在Android系统上,我们就可以看到两者在渲染技术上的相似之处.本文接下来就对Chromium的网页渲染机制进行简要介绍,并且制定学习计划. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! Chrom

Android4.4 fence机制分析

Android4.4 fence机制分析 在任何一个系统中,无可避免的都会跟各种buffers打交道,最经典的模式就是消费-生产者模式,一个独立的buffer在它们之间的交换等操作都需要一个机制来控制每个buffer的"生命周期",即ALLOCATION 和 RELEASE ,此外还要考虑到同步性问题,什么时候可以read buffer和write buffer都需要听从调遣. 在android中的fence就是这样一个为了解决同步性而出现的机制.首先从fence的语义角度来分析一下它

QT开发(六十三)——QT事件机制分析

QT开发(六十三)--QT事件机制分析 一.事件机制 事件是由系统或者QT平台本身在不同的时刻发出的.当用户按下鼠标.敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件.一些事件在对用户操作做出响应时发出,如键盘事件等:另一些事件则是由系统自动发出,如计时器事件. 事件的出现,使得程序代码不会按照原始的线性顺序执行.线性顺序的程序设计风格不适合处理复杂的用户交互,如用户交互过程中,用户点击"打开文件"将开始执行打开文件的操作,用户点击"保存文件"将开始执

Linux通信之poll机制分析

poll机制分析 韦东山 2009.12.10 所有的系统调用,基于都可以在它的名字前加上"sys_"前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open.sys_read.sys_write.sys_poll. 一.内核框架: 对于系统调用poll或select,它们对应的内核函数都是sys_poll.分析sys_poll,即可理解poll机制. sys_poll函数位于fs/select.c文件中,代码如下:

浏览器的渲染机制

Google Web Fundamentals 是一个非常优秀的文档,里面讲到了跟web.浏览器.前端的方方面面.我总结一下其中的 Ilya Grigorik 写的 Critical rendering path 浏览器渲染机制部分的内容如下: 几个概念 1.DOM:Document Object Model,浏览器将HTML解析成树形的数据结构,简称DOM. 2.CSSOM:CSS Object Model,浏览器将CSS代码解析成树形的数据结构. 3.DOM 和 CSSOM 都是以 Byte