ReactOS 图形系统分析(31):内核 GDI — ntgdi

ReactOS 图形系统分析(31):内核 GDI --- ntgdi/

1. 概述

ntgdi/win32ss/gdi/ntgdi/,53 个文件)是 内核态 GDI(Graphics Device Interface) ------win32k.sys 中直接承接用户态 gdi32.dll/win32u.dll 系统调用的层。它处于架构最核心的位置:

复制代码
用户态: gdi32.dll(GDI API 包装)→ win32u.dll(NtGdi* 系统调用)
    ↓
ntgdi/(内核 GDI ← 本分析对象)
    ├─ NtGdi* 系统调用入口(238 个,31 个文件)
    ├─ GDI 对象管理(句柄表/引用计数/属性池)
    ├─ DC 状态机(DC 结构/生命周期/属性/坐标变换)
    ├─ 裁剪合成(prgnVis/prgnRao/prgnAPI → XCLIPOBJ)
    └─ 绘制命令(位块/线/形/文本/路径/区域/调色板/打印/D3D/OpenGL)
    ↓
gdi/eng/(引擎:DDI 分发 + 软件渲染,见《分析_4~28》)
    ↓
gdi/dib/ + gdi/diblib/(像素实现,见《分析_29/30》)→ 显示驱动 → 帧缓冲

三大职责:

职责 说明
系统调用入口 全部 NtGdi*(238 个)在 ntgdi 实现:用户参数探测(ProbeForRead+SEH)、句柄校验、锁 DC,然后转内部 IntGdi*/Gre*
GDI 对象管理 句柄表(gpentHmgr)、引用计数(gpaulRefCount)、对象锁、属性池------DC/位图/画刷/画笔/字体/调色板/区域/路径的统一生命周期
绘制状态机 DC 结构(DC+DCLEVEL+DC_ATTR)、坐标变换(世界→页面→设备)、裁剪区域合成、ROP/混合模式------把"应用请求"翻译成"引擎可执行的表面操作"

与《分析_4》的关系: 《分析_4》的架构图把 win32k 分为 ntgdi/(内核 GDI:对象管理、DC、系统调用)------本分析正是该层的展开,且与已产出的分册互相对应(见第 9 节)。


2. 系统调用层 --- NtGdi* 入口

2.1 调用机制

复制代码
gdi32.dll: BitBlt(hdc,...) → NtGdiBitBlt(win32u 转发)
    ↓ win32k.spec / w32ksvc 表
ntgdi/bitblt.c: NtGdiBitBlt(锁 DC → 取表面 → 内部处理)
    ↓ IntEngBitBlt(eng,见《分析_4》3.1)

2.2 入口分布(238 个,按文件统计)

文件 NtGdi* 数 典型入口
d3dkmt.c(file:///d:/reactos/win32ss/gdi/ntgdi/d3dkmt.c) 55 NtGdiDdDDI*(D3DKMT 内核接口:Present/Lock/CreateDevice 等)
font.c(file:///d:/reactos/win32ss/gdi/ntgdi/font.c) 17 NtGdiCreateFontIndirect/NtGdiEnumFonts 等字体枚举/创建
coord.c(file:///d:/reactos/win32ss/gdi/ntgdi/coord.c) 16 NtGdiSetWorldTransform/NtGdiGetDeviceCaps
palette.c(file:///d:/reactos/win32ss/gdi/ntgdi/palette.c) 14 NtGdiCreatePalette/NtGdiRealizePalette
bitblt.c(file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c) 13 NtGdiBitBlt/NtGdiStretchBlt/NtGdiAlphaBlend/NtGdiFillRgn/NtGdiFrameRgn
path.c(file:///d:/reactos/win32ss/gdi/ntgdi/path.c) 13 NtGdiBeginPath/NtGdiEndPath/NtGdiStrokePath/NtGdiFillPath
region.c(file:///d:/reactos/win32ss/gdi/ntgdi/region.c) 12 NtGdiCreateRectRgn/NtGdiCombineRgn/NtGdiPtInRegion
dcobjs.c(file:///d:/reactos/win32ss/gdi/ntgdi/dcobjs.c) 9 NtGdiCreateDC/NtGdiDeleteDC/NtGdiSaveDC/NtGdiRestoreDC
text.c(file:///d:/reactos/win32ss/gdi/ntgdi/text.c) 8 NtGdiTextOut/NtGdiGetTextExtent/NtGdiGetTextMetrics
bitmaps.c(file:///d:/reactos/win32ss/gdi/ntgdi/bitmaps.c) 7 NtGdiCreateBitmap/NtGdiGetBitmapBits/NtGdiSetBitmapBits
brush.cpp(file:///d:/reactos/win32ss/gdi/ntgdi/brush.cpp) 7 NtGdiCreateSolidBrush/NtGdiCreatePatternBrush
fillshap.c(file:///d:/reactos/win32ss/gdi/ntgdi/fillshap.c) 6 NtGdiEllipse/NtGdiRoundRect/NtGdiGradientFill/NtGdiFloodFill
cliprgn.c(file:///d:/reactos/win32ss/gdi/ntgdi/cliprgn.c) 6 NtGdiSelectClipRgn/NtGdiGetClipRgn
icm.c(file:///d:/reactos/win32ss/gdi/ntgdi/icm.c) 6 NtGdiGetColorSpace/NtGdiCreateColorSpace
print.c(file:///d:/reactos/win32ss/gdi/ntgdi/print.c) 7 NtGdiResetDC/NtGdiStartDoc/NtGdiStartPage
其余(dcutil/dibobj/gdibatch/arc/dclife/line/pen/metafile/wingl/stockobj/init 等) ~30 NtGdiGetPixel/NtGdiCreateDIBitmap/NtGdiFlushUserBatch/NtGdiAngleArc/NtGdiCreatePen

通用入口模式 (以 NtGdiAlphaBlend(file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c#L13-L131) 为例):DC_LockDc 校验/锁定 → 源目标位图/表面定位 → IntEng* 调引擎 → DC_UnlockDc;用户结构一律 ProbeForRead + _SEH2_TRY 拷贝进内核。


3. GDI 对象管理(gdiobj.c(file:///d:/reactos/win32ss/gdi/ntgdi/gdiobj.c) + gdipool.c(file:///d:/reactos/win32ss/gdi/ntgdi/gdipool.c) + dibobj.c(file:///d:/reactos/win32ss/gdi/ntgdi/dibobj.c))

3.1 句柄表(会话空间共享)

复制代码
InitGdi(会话初始化)
    ├─ 句柄表节映射 → gpentHmgr(GDI_HANDLE_COUNT 项,会话共享)
    └─ 引用计数表 gpaulRefCount = EngAllocSectionMem(见《分析_23/21》)
  • 句柄 = 表索引;GDIOBJ_AllocObjWithHandle 分配、GDIOBJ_ReferenceObjectByHandle 取用(带类型校验 + 引用计数 gpaulRefCount[idx] 原子增减);
  • 句柄表映射到用户态(Peb->GdiSharedHandleTable),gdi32 可直接读写共享表优化句柄操作;
  • 每个对象带 BASEOBJECT 头(BaseFlags/hHmgr/pEntry)与类型派生的锁/释放回调(如 SURFACE_vCleanup)。

3.2 对象类型

对象 头文件 管理要点
DC dc.h DCLEVEL 层叠 + DC_ATTR 属性(见第 4 节)
位图 SURFACE eng/surface.h hDIBSection/hSecure/dwOffset(DIB Section,见《分析_21/23》)
画刷 BRUSH brush.h 逻辑画刷 + 引擎 EBRUSHOBJ 实现(engbrush.c)
画笔 PEN pen.h 逻辑笔 + 宽笔判定(line.c)
字体 LFONT/TEXTOBJ text.h 字体句柄 + FreeType 实现(freetype.c)
调色板 PALETTE palette.h PAL_* 标志(见《分析_19》)
区域 REGION region.h 区域数据(RDH/矩形缓冲)
路径 PATH path.h pPoints/pFlags + EXTPATHDATA 双表示(见《分析_18》)

3.3 属性池(gdipool.c)

c 复制代码
ppiCurrent->pPoolDcAttr     = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
ppiCurrent->pPoolBrushAttr  = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
ppiCurrent->pPoolRgnAttr    = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG');

按进程 的固定大小属性对象池(DC 属性/画刷属性/区域属性),避免频繁 EngAllocMem 小对象开销------进程创建时建(init.c GdiProcessCreate),销毁时回收(GdiPoolDestroy)。

3.4 系统对象(stockobj.c)

CreateStockObjects(系统字体/空画笔/黑白画笔等 21 个库存 GDI 对象)+ CreateSysColorObjects(系统颜色画刷)------由 IntGetSysColorBrush 等按索引取用。


4. DC 管理(dcobjs.c(file:///d:/reactos/win32ss/gdi/ntgdi/dcobjs.c) / dclife.c(file:///d:/reactos/win32ss/gdi/ntgdi/dclife.c) / dcstate.c(file:///d:/reactos/win32ss/gdi/ntgdi/dcstate.c) / dcattr.c(file:///d:/reactos/win32ss/gdi/ntgdi/dcattr.c) / dcutil.c(file:///d:/reactos/win32ss/gdi/ntgdi/dcutil.c))

4.1 DC 结构(dc.h(file:///d:/reactos/win32ss/gdi/ntgdi/dc.h))

c 复制代码
typedef struct _DCLEVEL          // 每层保存状态(SaveDC/RestoreDC 压栈)
{
    HPALETTE hpal; PPALETTE ppal; PBRUSH pbrFill; PBRUSH pbrLine;
    LFONT *plfnt; HGDIOBJ hPath; FLONG flPath;
    PREGION prgnClip; COLORADJUSTMENT ca;
    MATRIX mxWorldToDevice; MATRIX mxDeviceToWorld;   // 变换矩阵
    ...
} DCLEVEL;

typedef enum { DCTYPE_DIRECT, DCTYPE_MEMORY, DCTYPE_INFO } DCTYPE;

typedef struct _DC {              // 完整 DC
    BASEOBJECT BaseObject;
    DCTYPE dctype;  FLONG fs;     // DC_DISPLAY/DC_DIRECT 等标志
    PDCLEVEL dclevel;             // 层叠栈(当前层 + 历史层)
    PDC_ATTR pdcattr;             // 属性(前景/背景色、ROP2、映射模式...)
    SURFACE *pSurface;  PSURFACE psurf;
    XCLIPOBJ co;                  // 内嵌裁剪对象
    PPDEVOBJ ppdev;               // 物理设备(屏幕)
    ...
} DC, *PDC;
  • DCLEVEL 层叠SaveDC 压栈 / RestoreDC 弹栈,实现 DC 状态保存(含变换/字体/裁剪/画刷);
  • DC_ATTR :常规属性(crBackgroundClr/crForegroundClr/jROP2/jBkMode/iGraphicsMode/ptlCurrent 等,见《分析_17》的 MIX 构造);
  • DCTYPE:DIRECT(设备/屏幕)、MEMORY(内存 DC,选位图)、INFO(信息 DC,只查能力不绘制)。

4.2 生命周期与关键操作

文件 内容
dcobjs.c NtGdiCreateDC/NtGdiDeleteDC/NtGdiSaveDC/NtGdiRestoreDCDC_LockDc 句柄校验
dclife.c NtGdiOpenDCW(打开设备)、NtGdiCreateCompatibleDCNtGdiDeleteObjectAppIntGdiFillRgn 前的裁剪合成 + MouseSafety(见《分析_24》)
dcstate.c DC 状态字段更新/脏标记(DC_vUpdateFillBrush 等)
dcattr.c DC_ATTR 初始化/复制(GdiPool 分配)
dcutil.c IntGdiSetPixel/IntGdiGetPixelEXLATEOBJ 转色,见《分析_19》)、IntLPtoDP 等工具

5. 坐标变换与映射模式(coord.c(file:///d:/reactos/win32ss/gdi/ntgdi/coord.c) + xformobj.c(file:///d:/reactos/win32ss/gdi/ntgdi/xformobj.c) + coord.h(file:///d:/reactos/win32ss/gdi/ntgdi/coord.h))

复制代码
世界坐标 →(SetWorldTransform) → 页面坐标 →(映射模式 MM_*) → 设备坐标 →(设备原点) → 屏幕
MATRIX mxWorldToDevice / mxDeviceToWorld(FLOATOBJ,见《分析_22》)
  • 变换矩阵xformobj.cFLOATOBJ_XFORM(eM11...eDy)实现 SetWorldTransform/CombineTransform/ModifyWorldTransformcoord.hIntLPtoDP 做点乘;
  • 映射模式coord.c 处理 MM_TEXT/MM_ISOTROPIC/MM_ANISOTROPIC/MM_HIMETRIC 等,用 EngMulDiv 换算 WindowExt/ViewportExt(见《分析_22》);
  • DC 原点ptlDCOrig 偏移在绘制前并入(见《分析_17》IntGdiFillRgn 的 REGION_bOffsetRgn)。

6. 裁剪区域合成(cliprgn.c(file:///d:/reactos/win32ss/gdi/ntgdi/cliprgn.c) + dclife.c)

复制代码
prgnVis(可见区域) ∩ prgnRao(窗口重定向/系统区) = 有效裁剪
    + prgnAPI(SelectClipRgn 的 API 裁剪)
    ↓ IntEngInitClipObj + IntEngUpdateClipRegion(dclife.c)
XCLIPOBJ(→ 引擎裁剪枚举,见《分析_4》2.2/3.2)

NtGdiSelectClipRgn 设置 API 裁剪;绘制前 IntGdiFillRgn/IntEngBitBlt 等把三层区域求交合成为 XCLIPOBJ 传给引擎(配合《分析_24》的 MouseSafety 隐藏光标)。


7. 绘制命令子系统

子系统 文件 典型功能 引擎对接
位图对象 bitmaps.c(file:///d:/reactos/win32ss/gdi/ntgdi/bitmaps.c) / dibobj.c(file:///d:/reactos/win32ss/gdi/ntgdi/dibobj.c) CreateBitmap/CreateDIBSection/Get·SetBitmapBits、DIB 位图 EngCreateBitmap(《分析_21》)、DecompressBitmap(《分析_28》)
位块传输 bitblt.c(file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c) BitBlt/StretchBlt/TransparentBlt/AlphaBlend/FillRgn/PaintRgn/FrameRgn IntEng*(《分析_4/26/27》)
线条 line.c(file:///d:/reactos/win32ss/gdi/ntgdi/line.c) LineTo/Polyline/宽笔判定 IntEngLineTo(《分析_5》)
弧/贝塞尔 arc.c(file:///d:/reactos/win32ss/gdi/ntgdi/arc.c) / bezier.c(file:///d:/reactos/win32ss/gdi/ntgdi/bezier.c) Arc/Ellipse/Pie/AngleArc、贝塞尔转折线 GDI_Bezier → 路径/折线
形状填充 fillshap.c(file:///d:/reactos/win32ss/gdi/ntgdi/fillshap.c) / polyfill.c(file:///d:/reactos/win32ss/gdi/ntgdi/polyfill.c) 椭圆/圆角矩形/GradientFill/FloodFill、多边形 IntEngGradientFill(《分析_26》)/IntEngFillPolygon
文本 text.c(file:///d:/reactos/win32ss/gdi/ntgdi/text.c) / freetype.c(file:///d:/reactos/win32ss/gdi/ntgdi/freetype.c) / font.c(file:///d:/reactos/win32ss/gdi/ntgdi/font.c) TextOut/度量、字形渲染(FreeType→MaskBlt)、字体枚举/资源 IntExtTextOutW(《分析_16》)
路径 path.c(file:///d:/reactos/win32ss/gdi/ntgdi/path.c) BeginPath/EndPath/StrokePath/FillPath/WidenPath PATH_*(《分析_18》)
区域/矩形 region.c(file:///d:/reactos/win32ss/gdi/ntgdi/region.c) / rect.c(file:///d:/reactos/win32ss/gdi/ntgdi/rect.c) 区域布尔运算/命中测试 IntGdiCombineRgn
画笔/画刷 pen.c(file:///d:/reactos/win32ss/gdi/ntgdi/pen.c) / brush.cpp(file:///d:/reactos/win32ss/gdi/ntgdi/brush.cpp) 逻辑笔/画刷创建 EBRUSHOBJ_vInit(engbrush.c)
调色板/色彩 palette.c(file:///d:/reactos/win32ss/gdi/ntgdi/palette.c) / icm.c(file:///d:/reactos/win32ss/gdi/ntgdi/icm.c) 调色板实现/ICM 色彩空间 EXLATEOBJ(《分析_19》)
打印 print.c(file:///d:/reactos/win32ss/gdi/ntgdi/print.c) StartDoc/StartPage/ResetDC/假脱机 引擎打印桩(《分析_28》)
元文件 metafile.c(file:///d:/reactos/win32ss/gdi/ntgdi/metafile.c) PlayMetaFile 记录回放 转普通 GDI 调用
OpenGL wingl.c(file:///d:/reactos/win32ss/gdi/ntgdi/wingl.c) SetPixelFormat/SwapBuffers/DescribePixelFormat 与 D3D/驱动对接
DirectX 内核 d3dkmt.c(file:///d:/reactos/win32ss/gdi/ntgdi/d3dkmt.c) 55 个 NtGdiDdDDI*(D3DKMT) dxgkrnl/dxg
批处理 gdibatch.c(file:///d:/reactos/win32ss/gdi/ntgdi/gdibatch.c) 用户态 GDI 批处理刷出(NtGdiFlushUserBatch) ---
调试 gdidbg.c(file:///d:/reactos/win32ss/gdi/ntgdi/gdidbg.c) / gdikdbgext.c 引擎级 DPRINT/内核调试扩展 ---

8. 初始化与生命周期(init.c(file:///d:/reactos/win32ss/gdi/ntgdi/init.c))

函数 时机 内容
GdiProcessCreate 每进程创建 映射句柄表到 PEB、建 DC/画刷/区域属性池、初始化私有字体链表
GdiProcessDestroy 每进程销毁 清理私有字体、回收 GDI 对象与属性池
InitializeGreCSRSS 会话启动(CSRSS 初始化) DxStartupDxgkInt(Dxgkrnl 接口)、DxDdStartupDxGraphics(DirectX 显示驱动)、InitFontSupport(FreeType)
NtGdiInit 每进程 简单成功返回(真正的进程初始化在 GdiProcessCreate)

9. 与《架构分析》及各分册的关系

架构图条目 对应分册
ntgdi(对象管理/DC/系统调用) 本分析(31)
ntgdi 的线条 《分析_5》(line.c/IntGdiLineTo)
ntgdi 文本 《分析_16》(freetype.c/IntExtTextOutW)
ntgdi 渐变/区域填充 《分析_17/26》(IntGdiFillRgn/EngGradientFill)
ntgdi 路径 《分析_18》(PATH_*/path.c)
ntgdi 调色板/颜色 《分析_19》(EXLATEOBJ/palette.c)
ntgdi 设备注册 《分析_4》3.4(device.c→eng)
引擎 eng/ 《分析_4~28》(eng/ 全模块表)
DIB 软件渲染 《分析_29/30》(gdi/dib + diblib)
显示驱动 《分析_3》(framebuf/vga)、《分析_25》(pandisp)

10. 源码索引

文件 关键内容
intgdi.h(file:///d:/reactos/win32ss/gdi/ntgdi/intgdi.h) 内部 API 声明、WIN32_ROP4_TO_ENG_ROP4/FIXUP_ROP2 宏
init.c(file:///d:/reactos/win32ss/gdi/ntgdi/init.c) GdiProcessCreate/Destroy、InitializeGreCSRSS
dc.h(file:///d:/reactos/win32ss/gdi/ntgdi/dc.h) DC/DCLEVEL/DC_ATTR/DCTYPE 结构
gdiobj.c(file:///d:/reactos/win32ss/gdi/ntgdi/gdiobj.c) / gdiobj.h 句柄表、引用计数、GDIOBJ_* 对象管理
gdipool.c(file:///d:/reactos/win32ss/gdi/ntgdi/gdipool.c) DC/画刷/区域属性池
dcobjs.c(file:///d:/reactos/win32ss/gdi/ntgdi/dcobjs.c) / dclife.c / dcstate.c / dcattr.c / dcutil.c DC 生命周期/裁剪合成/状态/工具
coord.c(file:///d:/reactos/win32ss/gdi/ntgdi/coord.c) / coord.h / xformobj.c(file:///d:/reactos/win32ss/gdi/ntgdi/xformobj.c) 映射模式/世界变换
cliprgn.c(file:///d:/reactos/win32ss/gdi/ntgdi/cliprgn.c) API 裁剪
绘制子系统 bitblt.c/line.c/arc.c/bezier.c/fillshap.c/polyfill.c/text.c/freetype.c/font.c/path.c/region.c/rect.c/pen.c/brush.cpp/palette.c/icm.c/print.c/metafile.c/wingl.c/d3dkmt.c/gdibatch.c(详见第 7 节表)

关联模块:

  • 下层:gdi/eng(《分析_4~28》)、gdi/dib + diblib(《分析_29/30》)
  • 用户态:gdi32.dll / win32u.dll(NtGdi* 转发)
  • 同模块:ntuser(窗口/消息,与 DC 的 prgnVis 联动)、reactx(d3dkmt 的 D3D 对接)

本文档基于 ReactOS 源代码 win32ss/gdi/ntgdi/ 总览分析(2026 年 8 月)

相关推荐
caimouse1 小时前
ReactOS 图形系统分析(33):字体子系统 — font.c
c语言·开发语言·reactos
桦说编程17 小时前
盘点并发集合里那些容易误判的行为
java·后端·性能优化
RoboWizard20 小时前
金士顿Canvas系列存储卡有什么特别的技术优势?
人工智能·性能优化
k4m7v2pz1 天前
Rust 程序在 ReactOS 上“加载即崩“:从崩溃地址 0x6107104d 到 CRT 依赖的深度排查
rust·交叉编译·逆向工程·reactos·pe格式·windows兼容
k4m7v2pz1 天前
在Arch Linux笔记本上搭建ReactOS 0.4.15虚拟机:从Mac远程开发调试Windows XP风格应用的完整指南
qemu·虚拟机·kvm·交叉编译·mingw-w64·reactos
爱喝水的鱼丶1 天前
SAP-ABAP:BAPI 基础认知:SAP 标准业务对象接口的核心逻辑与调用入门
信息可视化·性能优化·sap·abap·bapi·开发交流·交流学习
AI服务老曹3 天前
边云协同视频分析性能优化指南:多站点部署下的资源瓶颈突破与调优实战
性能优化·音视频
A_cainiao_A3 天前
【ggml系列】【第五篇】ggml_compute_forward_mul_mat 矩阵乘法算子源码与性能优化深度解析
线性代数·性能优化·矩阵
ai产品老杨3 天前
边云协同视频分析性能优化指南:多站点部署下的参数配置与排查清单(边缘推理+云端管理)
性能优化·音视频