ReactOS 图形系统分析(29):DIB 引擎与 DIB 库 — gdi/dib/ + gdi/diblib/
1. 概述
gdi/dib/与gdi/diblib/是引擎软件渲染的像素级实现层——前面《分析_4~27》里Eng*/IntEng*软件路径最终都汇入这里:按位深做逐像素/逐行/整块的位图操作。当显示驱动没有硬件加速(framebuf 等)时,这就是写入帧缓冲的最终执行者。
引擎软件路径(eng/:EngBitBlt/EngStretchBlt/EngAlphaBlend/EngLineTo ...) ↓ DibFunctionsForBitmapFormat[位深].XXX(函数表分发,dib/dib.c 或 dib_new.c) ├─ 旧实现 dib/:手写各位深 dib1bpp.c ~ dib32bpp.c + 通用 stretchblt/alphablend/floodfill └─ 新实现 diblib/(USE_DIBLIB 可选编译):宏模板生成全位深组合 + 16 种 ROP 优化 ↓ │ 位深格式:BMF_1/4/8/16/24/32BPP(4RLE/8RLE/JPEG/PNG 为 Dummy 桩) ↓ pvScan0 + y×lDelta 直接读写像素内存(或 i386 汇编加速 hline/colorfill)两套实现并存([win32ss/CMakeLists.txt](file:///d:/reactos/win32ss/CMakeLists.txt#L210-L220)):
| 配置 | 使用的文件 | 特点 |
|---|---|---|
USE_DIBLIB(开) | dib/dib_new.c+eng/bitblt_new.c(BitBlt 走 DibLib) | 宏模板生成,位深组合全覆盖,16 个 BitBlt_*.c 各优化一个 ROP |
| 默认(关) | dib/dib.c+eng/copybits.c+dib8/16/32gen.c | 手写各位深实现 + gendib 生成 |
2. 核心机制 — DibFunctionsForBitmapFormat 函数表
2.1 DIB_FUNCTIONS([dib.h](file:///d:/reactos/win32ss/gdi/dib/dib.h#L44-L56))
typedefstruct{PFN_DIB_PutPixel DIB_PutPixel;// 单像素写PFN_DIB_GetPixel DIB_GetPixel;// 单像素读PFN_DIB_HLine DIB_HLine;// 水平线(x1..x2, y)PFN_DIB_VLine DIB_VLine;// 垂直线(x, y1..y2)PFN_DIB_BitBlt DIB_BitBlt;// 通用位块(旧实现)PFN_DIB_BitBlt DIB_BitBltSrcCopy;// SRCCOPY 快路径PFN_DIB_StretchBlt DIB_StretchBlt;// 拉伸(全位深共用 XXBPP)PFN_DIB_TransparentBlt DIB_TransparentBlt;// 透明色PFN_DIB_ColorFill DIB_ColorFill;// 纯色填充PFN_DIB_AlphaBlend DIB_AlphaBlend;// alpha 混合(16/24/32 专用,其余共用 XXBPP)}DIB_FUNCTIONS;externDIB_FUNCTIONS DibFunctionsForBitmapFormat[];// 按 BMF_* 索引索引 = 位图格式([dib.c](file:///d:/reactos/win32ss/gdi/dib/dib.c#L20-L88)):
| 索引 | 格式 | 实现 |
|---|---|---|
| 1~6 | BMF_1/4/8/16/24/32BPP | 各自位深专用函数(DIB_32BPP_*等) |
| 0, 7~10 | 0 / BMF_4RLE / 8RLE / JPEG / PNG | 全部 Dummy 桩(返回 FALSE/空操作)——RLE 需先解压(《分析_28》),JPEG/PNG 由 DIB 引擎不支持直接绘制 |
2.2 dib.c vs dib_new.c
- dib.c(默认):
DIB_BitBlt/DIB_BitBltSrcCopy/DIB_ColorFill填入手写实现; - dib_new.c(USE_DIBLIB):这三项填NULL(0)——BitBlt 不再经函数表,而由 [bitblt_new.c](file:///d:/reactos/win32ss/gdi/eng/bitblt_new.c#L97-L142) 的
EngBitBlt直接构造BLTDATA调 DibLib 函数。
3. BLTINFO 与 DIB_DoRop([dib.h](file:///d:/reactos/win32ss/gdi/dib/dib.h#L20-L32) / [dib.c](file:///d:/reactos/win32ss/gdi/dib/dib.c#L91-L192))
3.1 BLTINFO — 位块传输上下文
typedefstruct_BLTINFO{SURFOBJ*DestSurface;SURFOBJ*SourceSurface;SURFOBJ*PatternSurface;// 图案画刷表面XLATEOBJ*XlateSourceToDest;// 源→目标颜色转换XLATEOBJ*XlatePatternToDest;RECTL DestRect;POINTL SourcePoint;BRUSHOBJ*Brush;POINTL BrushOrigin;ROP4 Rop4;}BLTINFO,*PBLTINFO;(diblib 版的等价物是BLTDATA,见第 6 节。)
3.2 DIB_DoRop — 通用 ROP 计算
ULONGDIB_DoRop(ULONG Rop,ULONG Dest,ULONG Source,ULONG Pattern){/* 16 个命名 ROP 走优化分支(SRCCOPY 直接返回 Source 等) */caseR3_OPINDEX_SRCCOPY:returnSource;caseR3_OPINDEX_SRCINVERT:returnDest^Source;.../* 其余任意 ROP:4 位并行布尔运算 */Rop|=(Rop<<24)|(Rop<<16)|(Rop<<8);// ROP3 扩展成 4 字节for(i=0;i<8;i++){/* 用 ExpandDest/Source/Pattern[16] 把 4 位值展开成 32 位掩码, 一次布尔运算同时算出 4 个像素位的 ROP 结果 */ResultNibble=Rop&ExpandDest[Dest&0xF]&ExpandSource[Source&0xF]&ExpandPattern[Pattern&0xF];...}}设计:16 个常用 ROP3 用位运算直达;任意 ROP用"4 位并行"技巧(每 4 位查一张 32 位展开表,一次 & 计算 4 位结果),兼顾速度与通用性。
4. 各位深实现模式(以 [dib32bpp.c](file:///d:/reactos/win32ss/gdi/dib/dib32bpp.c) 为例)
4.1 像素原语 — 直接内存寻址
DIB_32BPP_PutPixel(SurfObj,x,y,c)// pvScan0 + y*lDelta + x*4 → *(PDWORD) = cDIB_32BPP_GetPixel(SurfObj,x,y)// 同址读DIB_32BPP_VLine(...)// 沿 lDelta 步进整列写DIB_32BPP_HLine(...)// 整行连续写(i386 有汇编加速版)1bpp/4bpp 额外处理位打包:1bpp 用notmask[]/MASK1BPP(x)位掩码,4bpp 每字节两像素(高/低半字节)。
4.2 BitBltSrcCopy — 源位深分发
DIB_32BPP_BitBltSrcCopy内部按源表面位深(1/4/8/16/24/32bpp)switch 分发,逐行/逐像素读取源(经DIB_GetSource宏 +XLATEOBJ_iXlate转目标色)写入目标;同时处理:
- 负 lDelta(bottom-up 位图)与翻转(
bLeftToRight/bTopToBottom); - 源与目标同表面时的方向处理。
4.3 i386 汇编加速([i386/](file:///d:/reactos/win32ss/gdi/dib/i386))
| 汇编文件 | 加速点 |
|---|---|
dib32bpp_hline.s | 32bpp 水平线(SSE/字长优化整行填充) |
dib24bpp_hline.s | 24bpp 水平线 |
dib32bpp_colorfill.s | 32bpp 纯色填充 |
非 x86 平台用 C 版dib24bppc.c/dib32bppc.c替代。
5. 通用 XXBPP 函数(全位深共用)
| 函数 | 位置 | 说明 |
|---|---|---|
DIB_XXBPP_StretchBlt | [stretchblt.c](file:///d:/reactos/win32ss/gdi/dib/stretchblt.c) | 拉伸采样(放大/缩小),DibFunctionsForBitmapFormat[*].DIB_StretchBlt全部指向它 |
DIB_XXBPP_AlphaBlend | [alphablend.c](file:///d:/reactos/win32ss/gdi/dib/alphablend.c) | 通用 alpha 混合(AC_SRC_OVER),内部建 3 个 EXLATEOBJ 在 RGB 与源/目标间往返 |
DIB_XXBPP_FloodFillSolid | [floodfill.c](file:///d:/reactos/win32ss/gdi/dib/floodfill.c) | 洪水填充(FillRgn 边界填充算法) |
dib*gen.c | 构建期生成 | native-gendib工具(sdk/tools)按位深生成 8/16/32bpp 变体 |
6. DibLib — 新 DIB 库(USE_DIBLIB)
6.1 设计目标
消灭手写重复:BitBlt 有 6 个位深 × 源/目标组合 + 16 种 ROP,手写爆炸。DibLib 用宏模板(DibLib.h)按位深参数化,一次定义全组合。
6.2 像素宏族([DibLib.h](file:///d:/reactos/win32ss/gdi/diblib/DibLib.h#L43-L82))
#define_ReadPixel_1(pjSource,jShift)(((*(pjSource))>>(jShift))&1)#define_WritePixel_1(pjDest,jShift,ulColor)...#define_ReadPixel_4/8/16/24/32...// 每种位深的读/写/步进/右向左步进#define_NextPixel_32(ppj,pjShift)(void)(*(ppj)+=4)配合__DIB_FUNCTION_NAME_SRCDST(name, src_bpp, dst_bpp)宏自动生成Dib_XXX_S1_D32这类函数名——同一份模板代码实例化为 36 种源/目标位深组合。
6.3 BLTDATA 与函数表([DibLib_interface.h](file:///d:/reactos/win32ss/gdi/diblib/DibLib_interface.h))
typedefstruct{ULONG iFormat;PBYTE pvScan0;PBYTE pjBase;LONG lDelta;...BYTE jBpp;}SURFINFO;typedefstruct{SURFINFO siSrc/siDst/siPat/siMsk;ULONG ulWidth/ulHeight;...ROP4;PFN_DOROP apfnDoRop[2];}BLTDATA;externconstPFN_DIBFUNCTION gapfnDibFunction[];// 按 ROP3 索引的 256 项分发表externconstPFN_DIBFUNCTION gapfnMaskFunction[8];// 掩码组合表6.4 新 EngBitBlt([bitblt_new.c](file:///d:/reactos/win32ss/gdi/eng/bitblt_new.c#L97-L142))
EngBitBlt(USE_DIBLIB 版本) ├─ 填充 BLTDATA(rop4 → apfnDoRop[2] 取 gapfnRop 前后景函数;pxlo → pfnXlate) ├─ ROP4_USES_SOURCE/PATTERN/MASK 检查并锁定对应表面 ├─ CalculateCoordinates:按裁剪矩形计算源/图案/掩码起始像素地址(含 bottom-up/右到左修正) ├─ 裁剪三档:TRIVIAL 一次 / RECT 求交 / COMPLEX 枚举矩形(同表面选方向) └─ 每块:按 ROP+掩码查 gapfnDibFunction/gapfnMaskFunction → Dib_*_Sxx_Dyy 执行6.5 ROP 优化文件族
| 文件 | 内容 |
|---|---|
BitBlt_SRCCOPY.c等 15 个 | 每个常用 ROP3 一个优化实现(Dib_BitBlt_SRCCOPY_Sxx_Dyy),整行/整块快速路径 |
BitBlt_other.c | 通用 4 位并行 ROP 兜底(含纯色预转换) |
RopFunctions.c/h | gapfnRop[256](ROP3→函数指针)、Dib_DoRop等价物 |
MaskBlt.c+MaskCopy/MaskPaint/MaskPatBlt/... | 掩码参与的 8 种组合(gapfnMaskFunction[8]) |
7. 与《架构分析》标注对照
| 标注 | 核对 |
|---|---|
架构图第 72 行:gdi/dib/ + gdi/diblib/(软件渲染) | 准确。补充:dib/ 是手写各位深旧实现(DibFunctionsForBitmapFormat函数表);diblib/ 是宏模板生成的新实现(BLTDATA+gapfnDibFunction),由USE_DIBLIB条件编译切换 |
8. 源码索引
| 文件 | 关键内容 |
|---|---|
| [dib.h](file:///d:/reactos/win32ss/gdi/dib/dib.h) | DIB_FUNCTIONS 表、BLTINFO、ROP4 宏(ROP4_SRCCOPY 等)、DIB_GetSource 宏 |
| [dib.c](file:///d:/reactos/win32ss/gdi/dib/dib.c) | DibFunctionsForBitmapFormat 初始化、DIB_DoRop(Expand* 表 4 位并行)、Dummy_* 桩 |
| [dib_new.c](file:///d:/reactos/win32ss/gdi/dib/dib_new.c) | USE_DIBLIB 版函数表(BitBlt 项为 NULL) |
| [dib1bpp.c ~ dib32bpp.c](file:///d:/reactos/win32ss/gdi/dib/dib32bpp.c) | 各位深 PutPixel/GetPixel/H/VLine/BitBlt/BitBltSrcCopy |
| [stretchblt.c](file:///d:/reactos/win32ss/gdi/dib/stretchblt.c) / [alphablend.c](file:///d:/reactos/win32ss/gdi/dib/alphablend.c) / [floodfill.c](file:///d:/reactos/win32ss/gdi/dib/floodfill.c) | DIB_XXBPP_* 通用实现 |
| [i386/](file:///d:/reactos/win32ss/gdi/dib/i386) | 汇编加速(24/32bpp hline、32bpp colorfill) |
| [diblib/DibLib.h](file:///d:/reactos/win32ss/gdi/diblib/DibLib.h) | 像素宏族、函数名生成宏、BLTDATA 相关 |
| [diblib/DibLib_interface.h](file:///d:/reactos/win32ss/gdi/diblib/DibLib_interface.h) | SURFINFO/BLTDATA、gapfnDibFunction/gapfnMaskFunction |
| [diblib/BitBlt*.c](file:///d:/reactos/win32ss/gdi/diblib/BitBlt_SRCCOPY.c) / MaskBlt.c / RopFunctions.c | ROP 优化实现、掩码组合、ROP 函数表 |
| [bitblt_new.c](file:///d:/reactos/win32ss/gdi/eng/bitblt_new.c) | USE_DIBLIB 版 EngBitBlt(BLTDATA + CalculateCoordinates) |
关联模块:
- 引擎入口:《分析_4》3.1(EngBitBlt 双层)、《分析_17/26/27》(FillSolid/AlphaBlend/StretchBlt 的 DIB 调用)
- 颜色转换:
XLATEOBJ_iXlate(《分析_19》) - RLE 位图:需先经
DecompressBitmap(《分析_28》rlecomp.c)解压 - 表面来源:
EngCreateBitmap(surface.c,BMF_* 格式)
本文档基于 ReactOS 源代码
win32ss/gdi/dib/、gdi/diblib/及关联模块分析(2026 年 8 月)