GUI刷新机制研究(二) 渲染部分
在大家最期待的Update环节,调用栈依次是
CoreRoot_UpdateGE20
CoreRoot_UpdateCanvas
CoreGroup_drawContent
ViewsRectangle_Draw
对于ViewsRectangle_Draw, 其定义在生成的Views.c
其中最主要的部分是调用了GraphicsCanvas_FillRectangle去填充一个矩形
这个函数的定义在Graphics.c中,找到其定义,发现该函数调用了EwFillRectangle
这个函数就是EW package中的RGBA8888 图形引擎的部分,定义在ewgfx.c中
然后我们观察到了一个有趣的事情,也就是说真正的绘制还是不在ewgfx.c中,可以看到EwFillRectangle中通过一个叫做XTask的结构来描述要进行的绘制操作,把task封装到issue内,然后提交
task = EwAllocTask(issue, 0)
task->Token = EW_TASK_FILL_RECTANGLE;
task->Data = ...
task-> X1 = ...
task->flag |= EW_TASK_SOLID
然后通过EwDoneIssue 提交该任务,EwDoneIssue调用EwFlushTasks, 然后是通过ProcessIssues的
EwExecuteTasks来执行,在ewgfxtask.c中有该函数的定义。这个函数就是一个比较有趣的环节了
首先是取出issue的task, 这里注意各个task也是用链表管理的
所以在这里是一个遍历的操作,会完成所有的绘制操作。
好的,依次分析一下:
首先是根据task->Flags & EW_TASK_MODE_MASK 来确定当前的绘制模式是基于solid,还是gradient, 还是alpha blended
与的结果就是一个funcNo, 用来查表用。然后就是根据task->Token去匹配具体的task id, 比如这里匹配到EW_TASKID_FILL_RECTANGLE
然后从FillDrivers[funcNo] 查一个函数。FillDrivers的定义在ewgfxlinks.h中
static const XFillDriver FillDriver[] = {
0, 0, EwGfxFillSolid, EwGfxFillSolidBlend, EwGfxFillGradient, EwGfxFillGradientBlend, EwGfxFillLinearGradient, ....
}
可以看到这些都是用于填充矩形的方法,只不过是有着不同的填充效果。对应的具体效果,应该也是在上位机中选定,然后生成到C文件中
EwGfxFillSolid是个宏,也是在ewgfxlinks.h中有关于这一切的声明。
注意一个地方,也就是ewgfxlinks.h中有static的数组,这就说明,这个头文件只能最多被一个C文件所包含,而且这个ewgfxlinks.h中有许多ifdef的语句,这就说明,在那个c文件中,include “ewgfxlinks.h”之前一定还有别的头文件声明了一些宏。
果然,在ewgfxtask.c中,头文件的包含顺序如下:
#include "ewrte.h"
#include "ewgfxdriver.h"
#include "ewgfxcore.h"
#include "ewgfxtask.h"
#include "ewextgfx.h"
#include "ewgfxdef.h"
#include "ewgfxlinks.h"
那么继续分析
#ifndef EWGfxFillSolid
#define EwGfxFillSolid EwGfxFillLinearGradient
#endif
一通分析下来,发现这个表里好像全是0,那就说明走的是FillRectanle2
通过打log, 确认了FillRectangle走的的确是FillRectanle2这个函数:
里面调用EwEmulateFill这个方法,传了一个FillWorkers.
在ewgfxdriver.c中(soft版本),可以看到EwEmulateFill是在一个for循环中,按高度处理每一行,每一行的处理通过fillworker完成
FillWorkers[] 也是定义在ewgfxlinks.h中,里面的成员是
EwFillRowSolid, EwFillSolidBlend, ... , 这几个都是我们比较熟悉的ewextpxl_RGBA8888.c中的函数,这里都是真正干活的函数
至此,完成了对soft版本gfx调用栈的初步分析。现在,来分析一下,openGL的版本,是如何兼容的。
对于opengl的版本,在ewgfxtask.c这一层次,和soft没有任何区别,区别在于绘制任务的提交后,具体由什么硬件完成操作
沿着这个思路,很容易就会发现:
还是在刚才的FillDrivers[]中,EwGfxFillSolid 等一系列的函数簇,都在ewextgfx.h中被宏定义redirect到了OpenGLFillDriver中了
OpenGLFillDriver的实现就在ewextgfx.c中。
因此,可以粗略的认为, 除去公共部分外,ewextgfx.c主要是给opengl用的,ewextpxl_RGBA8888是纯soft渲染用的。