三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

ReactOS 图形系统分析(29):DIB 引擎与 DIB 库 — gdi/dib/ + gdi/diblib

ReactOS 图形系统分析(29):DIB 引擎与 DIB 库 — gdi/dib/ + gdi/diblib

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~6BMF_1/4/8/16/24/32BPP各自位深专用函数(DIB_32BPP_*等)
0, 7~100 / 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.s32bpp 水平线(SSE/字长优化整行填充)
dib24bpp_hline.s24bpp 水平线
dib32bpp_colorfill.s32bpp 纯色填充

非 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/hgapfnRop[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.cROP 优化实现、掩码组合、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 月)

← 返回列表