ReactOS 图形系统分析(4):GDI 引擎 (eng)

ReactOS 图形系统分析(4):GDI 引擎 (eng)

1. 概述

GDI 引擎(Graphics Device Interface Engine) 位于 win32ss/gdi/eng/,是 ReactOS 图形子系统(win32k.sys)的核心渲染引擎 。它实现了 Windows GDI 的 DDI(Device Driver Interface) 层,向上服务内核 GDI(ntgdi/)的绘图请求,向下调度显示驱动的硬件加速回调,并为无硬件加速的情况提供完整的软件渲染回退。

复制代码
┌─────────────────────────────────────────────┐
│ ntgdi/ (内核 GDI:对象管理、DC、系统调用)    │
├─────────────────────────────────────────────┤
│ gdi/eng/ (GDI 引擎 ← 本分析对象)            │
│  - 表面管理 / 裁剪 / 位块传输 / 画刷         │
│  - 设备对象 (PDEV/LDEV/MDEV) 管理            │
│  - DDI 分发:调用驱动 or 软件渲染             │
├──────────────┬──────────────┬───────────────┤
│ gdi/dib/     │ 显示驱动 DDI  │ 字体驱动       │
│ (软件渲染)   │ framebuf/vga │ bmfd/ftfd      │
└──────────────┴──────────────┴───────────────┘

1.1 模块文件构成

文件 功能
surface.c(file:///d:/reactos/win32ss/gdi/eng/surface.c) / surface.h(file:///d:/reactos/win32ss/gdi/eng/surface.h) 表面管理:EngCreateSurface/EngModifySurface/EngLockSurface
bitblt.c(file:///d:/reactos/win32ss/gdi/eng/bitblt.c) 位块传输核心:EngBitBlt、IntEngBitBlt、MaskBlt
clip.c(file:///d:/reactos/win32ss/gdi/eng/clip.c) 裁剪:EngCreateClip、CLIPOBJ 枚举
pdevobj.c(file:///d:/reactos/win32ss/gdi/eng/pdevobj.c) / pdevobj.h(file:///d:/reactos/win32ss/gdi/eng/pdevobj.h) 物理设备对象管理
ldevobj.c(file:///d:/reactos/win32ss/gdi/eng/ldevobj.c) / ldevobj.h(file:///d:/reactos/win32ss/gdi/eng/ldevobj.h) 逻辑设备对象管理(驱动加载)
mdevobj.c(file:///d:/reactos/win32ss/gdi/eng/mdevobj.c) / mdevobj.h(file:///d:/reactos/win32ss/gdi/eng/mdevobj.h) 映射设备对象(多显示器)
device.c(file:///d:/reactos/win32ss/gdi/eng/device.c) 图形设备注册表、EngpRegisterGraphicsDevice
driverobj.c(file:///d:/reactos/win32ss/gdi/eng/driverobj.c) / driverobj.h(file:///d:/reactos/win32ss/gdi/eng/driverobj.h) 驱动对象管理
engbrush.c(file:///d:/reactos/win32ss/gdi/eng/engbrush.c) 画刷对象:BRUSHOBJ 管理
engwindow.c(file:///d:/reactos/win32ss/gdi/eng/engwindow.c) 窗口对象(EWNDOBJ)管理
lineto.c(file:///d:/reactos/win32ss/gdi/eng/lineto.c) 线条绘制(IntEngLineTo)
string.c(file:///d:/reactos/win32ss/gdi/eng/string.c) 字符串绘制(IntEngTextOut 相关)
paint.c(file:///d:/reactos/win32ss/gdi/eng/paint.c) 区域填充
pathobj.c(file:///d:/reactos/win32ss/gdi/eng/pathobj.c) 路径对象
xlateobj.c(file:///d:/reactos/win32ss/gdi/eng/xlateobj.c) / xlateobj.h(file:///d:/reactos/win32ss/gdi/eng/xlateobj.h) 颜色转换对象
semaphor.c(file:///d:/reactos/win32ss/gdi/eng/semaphor.c) 信号量:EngAcquireSemaphore
mapping.c(file:///d:/reactos/win32ss/gdi/eng/mapping.c) / mapping.h(file:///d:/reactos/win32ss/gdi/eng/mapping.h) 坐标映射
math.c(file:///d:/reactos/win32ss/gdi/eng/math.c) / float.c(file:///d:/reactos/win32ss/gdi/eng/float.c) 数学/浮点运算
mem.c(file:///d:/reactos/win32ss/gdi/eng/mem.c) 引擎内存分配
mouse.c(file:///d:/reactos/win32ss/gdi/eng/mouse.c) / mouse.h(file:///d:/reactos/win32ss/gdi/eng/mouse.h) 指针(光标)管理
multidisp.c(file:///d:/reactos/win32ss/gdi/eng/multidisp.c) / pandisp.c(file:///d:/reactos/win32ss/gdi/eng/pandisp.c) 多显示器/平移显示
engmisc.c(file:///d:/reactos/win32ss/gdi/eng/engmisc.c) 杂项
alphablend.c(file:///d:/reactos/win32ss/gdi/eng/alphablend.c) Alpha 混合
gradient.c(file:///d:/reactos/win32ss/gdi/eng/gradient.c) 渐变填充
stretchblt.c(file:///d:/reactos/win32ss/gdi/eng/stretchblt.c) / transblt.c(file:///d:/reactos/win32ss/gdi/eng/transblt.c) 拉伸/透明传输
rlecomp.c(file:///d:/reactos/win32ss/gdi/eng/rlecomp.c) RLE 压缩
sort.c(file:///d:/reactos/win32ss/gdi/eng/sort.c) 排序工具
engevent.c(file:///d:/reactos/win32ss/gdi/eng/engevent.c) / engevent.h(file:///d:/reactos/win32ss/gdi/eng/engevent.h) 事件对象
stubs.c(file:///d:/reactos/win32ss/gdi/eng/stubs.c) / umpdstubs.c(file:///d:/reactos/win32ss/gdi/eng/umpdstubs.c) 桩函数
eng.h(file:///d:/reactos/win32ss/gdi/eng/eng.h) 引擎内部 API 声明
inteng.h(file:///d:/reactos/win32ss/gdi/eng/inteng.h) IntEng* 内部接口
engobjects.h(file:///d:/reactos/win32ss/gdi/eng/engobjects.h) 内部对象(XCLIPOBJ/EWNDOBJ)

2. 核心数据结构

2.1 SURFACE --- 引擎表面(surface.h(file:///d:/reactos/win32ss/gdi/eng/surface.h))

引擎管理的所有可绘制表面(屏幕、位图、DIB section)统一用 SURFACE 表示,其公开部分是 DDI 层使用的 SURFOBJ

c 复制代码
typedef struct _SURFACE
{
    BASEOBJECT  BaseObject;    // GDI 对象头(句柄/锁/标志)
    SURFOBJ     SurfObj;       // 公开的 SURFOBJ(DDI 层使用)
    FLONG       flags;         // 表面标志(HOOK_* 位、类型位)
    struct _PALETTE  * const ppal;   // 关联调色板
    struct _EWNDOBJ  *pWinObj;       // 窗口对象(窗口表面)
    union {
        HANDLE  hSecureUMPD;   // UMPD 表面
        HANDLE  hMirrorParent; // 镜像表面
        HANDLE  hDDSurface;    // DirectDraw 表面
    };
    SIZEL       sizlDim;       // 位图尺寸
    HDC         hdc;           // 关联 DC
    ULONG       cRef;          // 引用计数
    HPALETTE    hpalHint;
    HANDLE      hDIBSection;   // DIB Section
    HANDLE      hSecure;
    DWORD       dwOffset;
    DWORD       biClrImportant;
    ULONG       biCompression;
} SURFACE, *PSURFACE;

SURFOBJ(DDI 公开部分)字段:

字段 含义
sizlBitmap 表面尺寸(宽×高)
pvBits / pvScan0 像素数据地址(帧缓冲或系统内存)
lDelta 行距(每行字节数)
iBitmapFormat 位图格式(BMF_1BPP ~ BMF_32BPP)
iType 类型(STYPE_BITMAP / STYPE_DEVICE)
hpal 调色板句柄
dhpdev / hdev 关联设备

表面标志位(_SURFACEFLAGS)关键项:

复制代码
HOOK_BITBLT        // 目标表面挂钩了驱动 DrvBitBlt
HOOK_STRETCHBLT    // 挂钩了 DrvStretchBlt
HOOK_TEXTOUT       // 挂钩了 DrvTextOut
HOOK_LINETO        // 挂钩了 DrvLineTo
...
UMDP_SURFACE       // 用户模式驱动的表面
MIRROR_SURFACE     // 镜像表面
DIRECTDRAW_SURFACE // DirectDraw 表面
PDEV_SURFACE       // 设备表面(屏幕)
API_BITMAP         // 应用创建的位图
DDB_SURFACE        // 设备相关位图

2.2 XCLIPOBJ / CLIPOBJ --- 扩展裁剪对象(engobjects.h(file:///d:/reactos/win32ss/gdi/eng/engobjects.h))

CLIPOBJ 是 DDI 层公开的裁剪对象;引擎内部使用扩展的 XCLIPOBJ(= CLIPOBJ + RWNDOBJ + 私有字段):

c 复制代码
typedef struct _XCLIPOBJ
{
  CLIPOBJ;              // 公开部分:rclBounds, iDComplexity, iMode 等
  RWNDOBJ;              // 窗口对象:pvConsumer, rclClient, psoOwner
  struct _REGION *pClipRgn;   // 裁剪区域(Rao 区域或 Vis 区域)
  RECTL   rclClipRgn;        // 裁剪矩形
  RECTL*  Rects;             // 枚举用矩形缓冲区
  DWORD   cScan;             // 扫描段数
  ULONG   EnumPos;           // 枚举位置
  ULONG   iDirection;        // 枚举方向(CD_ANY/CD_LEFTDOWN 等)
  ULONG   iType;             // 裁剪类型
  LONG    lUpDown;           // 从上到下标记
  BOOL    bAll;              // 是否全矩形
  DWORD   RectCount;
  PVOID   pDDA;
} XCLIPOBJ, *PXCLIPOBJ;

裁剪复杂度(iDComplexity,决定渲染策略):

  • DC_TRIVIAL --- 无裁剪(全矩形),直接绘制
  • DC_RECT --- 单一矩形裁剪
  • DC_COMPLEX --- 复杂区域,需要矩形枚举逐块绘制

EngCreateClip 分配 {XCLIPOBJ co; REGION ro;} 组合结构,pco->co.pClipRgn = &pco->ro

窗口表面扩展: EWNDOBJ(= XCLIPOBJ + HWND + ChangeProc + PixelFormat)用于窗口表面,使显示驱动能跟踪窗口变化。

2.3 设备对象体系

引擎用四层对象管理显示设备(详见 ReactOS图形系统架构分析.md 第 3.3 节):

复制代码
LDEVOBJ (逻辑设备:驱动加载 + DDI 函数表)
   ↓ 引用
PDEVOBJ (物理设备:DrvEnablePDEV 初始化硬件)
   ↓ 拥有
SURFACE (显示表面:DrvEnableSurface 创建)
   ↓ 聚合
MDEVOBJ (映射设备:管理多个 PDEV,多显示器)

PDEVOBJ 关键字段: ppdevNext(链表)、cPdevRefs(引用计数)、hsemDevLock(设备锁)、ahsurf[HS_DDI_MAX](引擎表面句柄数组)、flFlags(PDEV_DISPLAY/PDEV_PRINTER 等)。

LDEVOBJ 核心:

c 复制代码
typedef struct _LDEVOBJ
{
    LIST_ENTRY leLink;
    SYSTEM_GDI_DRIVER_INFORMATION *pGdiDriverInfo;
    LDEVTYPE ldevtype;         // LDEV_DEVICE_DISPLAY / PRINTER / META / MIRROR / FONT
    ULONG cRefs;
    ULONG ulDriverVersion;
    union {
        PVOID apfn[INDEX_LAST];        // DDI 函数指针数组
        DRIVER_FUNCTIONS pfn;          // 具名 DDI 函数表
    };
} LDEVOBJ, *PLDEVOBJ;

LDEV 的 DDI 函数表包含显示驱动可实现的全部回调(INDEX_DrvEnablePDEV ~ INDEX_DrvTextOut 等),引擎通过 GDIDEVFUNCS(surf) 宏从表面取得设备函数表。


3. 核心功能模块

3.1 位块传输 --- EngBitBlt / IntEngBitBlt(bitblt.c(file:///d:/reactos/win32ss/gdi/eng/bitblt.c))

BitBlt 是引擎最核心的操作。存在双层实现

第一层:IntEngBitBlt(设备挂钩决策)

#mermaid-svg-Q3fMdO3m3gmmJMBF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Q3fMdO3m3gmmJMBF .error-icon{fill:#552222;}#mermaid-svg-Q3fMdO3m3gmmJMBF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Q3fMdO3m3gmmJMBF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .marker.cross{stroke:#333333;}#mermaid-svg-Q3fMdO3m3gmmJMBF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Q3fMdO3m3gmmJMBF p{margin:0;}#mermaid-svg-Q3fMdO3m3gmmJMBF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .cluster-label text{fill:#333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .cluster-label span{color:#333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .cluster-label span p{background-color:transparent;}#mermaid-svg-Q3fMdO3m3gmmJMBF .label text,#mermaid-svg-Q3fMdO3m3gmmJMBF span{fill:#333;color:#333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .node rect,#mermaid-svg-Q3fMdO3m3gmmJMBF .node circle,#mermaid-svg-Q3fMdO3m3gmmJMBF .node ellipse,#mermaid-svg-Q3fMdO3m3gmmJMBF .node polygon,#mermaid-svg-Q3fMdO3m3gmmJMBF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Q3fMdO3m3gmmJMBF .rough-node .label text,#mermaid-svg-Q3fMdO3m3gmmJMBF .node .label text,#mermaid-svg-Q3fMdO3m3gmmJMBF .image-shape .label,#mermaid-svg-Q3fMdO3m3gmmJMBF .icon-shape .label{text-anchor:middle;}#mermaid-svg-Q3fMdO3m3gmmJMBF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Q3fMdO3m3gmmJMBF .rough-node .label,#mermaid-svg-Q3fMdO3m3gmmJMBF .node .label,#mermaid-svg-Q3fMdO3m3gmmJMBF .image-shape .label,#mermaid-svg-Q3fMdO3m3gmmJMBF .icon-shape .label{text-align:center;}#mermaid-svg-Q3fMdO3m3gmmJMBF .node.clickable{cursor:pointer;}#mermaid-svg-Q3fMdO3m3gmmJMBF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .arrowheadPath{fill:#333333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Q3fMdO3m3gmmJMBF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q3fMdO3m3gmmJMBF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Q3fMdO3m3gmmJMBF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q3fMdO3m3gmmJMBF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Q3fMdO3m3gmmJMBF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Q3fMdO3m3gmmJMBF .cluster text{fill:#333;}#mermaid-svg-Q3fMdO3m3gmmJMBF .cluster span{color:#333;}#mermaid-svg-Q3fMdO3m3gmmJMBF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Q3fMdO3m3gmmJMBF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Q3fMdO3m3gmmJMBF rect.text{fill:none;stroke-width:0;}#mermaid-svg-Q3fMdO3m3gmmJMBF .icon-shape,#mermaid-svg-Q3fMdO3m3gmmJMBF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q3fMdO3m3gmmJMBF .icon-shape p,#mermaid-svg-Q3fMdO3m3gmmJMBF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Q3fMdO3m3gmmJMBF .icon-shape .label rect,#mermaid-svg-Q3fMdO3m3gmmJMBF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q3fMdO3m3gmmJMBF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Q3fMdO3m3gmmJMBF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Q3fMdO3m3gmmJMBF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是







IntEngBitBlt

(内部入口,被 ntgdi 调用)
裁剪目标矩形

到目标表面尺寸
与 pco->rclBounds 求交
pco 是 DC_RECT?
pco = NULL (简化)
保留 pco
ROP 使用源?
计算源矩形并裁剪

到源表面尺寸

修正目标矩形
psoSrc = NULL
目标表面

HOOK_BITBLT?
pfnBitBlt = GDIDEVFUNCS(目标).BitBlt

(调用显示驱动 DrvBitBlt)
源表面

HOOK_BITBLT?
pfnBitBlt = GDIDEVFUNCS(源).BitBlt
pfnBitBlt = EngBitBlt

(引擎软件实现)
按翻转修正矩形

(左→右/上→下)
调用 pfnBitBlt 执行

关键代码:

c 复制代码
/* 决定调用哪个 BitBlt 实现 */
if (psurfTrg->flags & HOOK_BITBLT)
{
    pfnBitBlt = GDIDEVFUNCS(psoTrg).BitBlt;   // 目标表面挂钩了驱动 → 调驱动
}
else if (psoSrc && psurfSrc->flags & HOOK_BITBLT)
{
    pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt;   // 源表面挂钩了驱动 → 调驱动
}
else
{
    pfnBitBlt = EngBitBlt;                     // 否则软件渲染
}
第二层:EngBitBlt(软件渲染,含裁剪分析)

#mermaid-svg-qT0R2VvxduZNRxSt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qT0R2VvxduZNRxSt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qT0R2VvxduZNRxSt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qT0R2VvxduZNRxSt .error-icon{fill:#552222;}#mermaid-svg-qT0R2VvxduZNRxSt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qT0R2VvxduZNRxSt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qT0R2VvxduZNRxSt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qT0R2VvxduZNRxSt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qT0R2VvxduZNRxSt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qT0R2VvxduZNRxSt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qT0R2VvxduZNRxSt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qT0R2VvxduZNRxSt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qT0R2VvxduZNRxSt .marker.cross{stroke:#333333;}#mermaid-svg-qT0R2VvxduZNRxSt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qT0R2VvxduZNRxSt p{margin:0;}#mermaid-svg-qT0R2VvxduZNRxSt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qT0R2VvxduZNRxSt .cluster-label text{fill:#333;}#mermaid-svg-qT0R2VvxduZNRxSt .cluster-label span{color:#333;}#mermaid-svg-qT0R2VvxduZNRxSt .cluster-label span p{background-color:transparent;}#mermaid-svg-qT0R2VvxduZNRxSt .label text,#mermaid-svg-qT0R2VvxduZNRxSt span{fill:#333;color:#333;}#mermaid-svg-qT0R2VvxduZNRxSt .node rect,#mermaid-svg-qT0R2VvxduZNRxSt .node circle,#mermaid-svg-qT0R2VvxduZNRxSt .node ellipse,#mermaid-svg-qT0R2VvxduZNRxSt .node polygon,#mermaid-svg-qT0R2VvxduZNRxSt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qT0R2VvxduZNRxSt .rough-node .label text,#mermaid-svg-qT0R2VvxduZNRxSt .node .label text,#mermaid-svg-qT0R2VvxduZNRxSt .image-shape .label,#mermaid-svg-qT0R2VvxduZNRxSt .icon-shape .label{text-anchor:middle;}#mermaid-svg-qT0R2VvxduZNRxSt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qT0R2VvxduZNRxSt .rough-node .label,#mermaid-svg-qT0R2VvxduZNRxSt .node .label,#mermaid-svg-qT0R2VvxduZNRxSt .image-shape .label,#mermaid-svg-qT0R2VvxduZNRxSt .icon-shape .label{text-align:center;}#mermaid-svg-qT0R2VvxduZNRxSt .node.clickable{cursor:pointer;}#mermaid-svg-qT0R2VvxduZNRxSt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qT0R2VvxduZNRxSt .arrowheadPath{fill:#333333;}#mermaid-svg-qT0R2VvxduZNRxSt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qT0R2VvxduZNRxSt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qT0R2VvxduZNRxSt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qT0R2VvxduZNRxSt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qT0R2VvxduZNRxSt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qT0R2VvxduZNRxSt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qT0R2VvxduZNRxSt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qT0R2VvxduZNRxSt .cluster text{fill:#333;}#mermaid-svg-qT0R2VvxduZNRxSt .cluster span{color:#333;}#mermaid-svg-qT0R2VvxduZNRxSt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qT0R2VvxduZNRxSt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qT0R2VvxduZNRxSt rect.text{fill:none;stroke-width:0;}#mermaid-svg-qT0R2VvxduZNRxSt .icon-shape,#mermaid-svg-qT0R2VvxduZNRxSt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qT0R2VvxduZNRxSt .icon-shape p,#mermaid-svg-qT0R2VvxduZNRxSt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qT0R2VvxduZNRxSt .icon-shape .label rect,#mermaid-svg-qT0R2VvxduZNRxSt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qT0R2VvxduZNRxSt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qT0R2VvxduZNRxSt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qT0R2VvxduZNRxSt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是



DC_TRIVIAL
DC_RECT
DC_COMPLEX
EngBitBlt

(软件实现)
分析 ROP4 使用情况

UsesSource/UsesMask

翻转方向 bLeftToRight/bTopToBottom
ROP4 == NOOP?
直接返回 (空操作)
规范化目标矩形

RECTL_vMakeWellOrdered
使用源?
源点/源矩形裁剪

防越界
无源
与裁剪边界求交

限制在 pco->rclBounds
裁剪类型?
恢复翻转方向

直接调用 BltRectFunc 一次
与裁剪矩形求交

调用一次 BltRectFunc
确定绘制方向

CLIPOBJ_cEnumStart 初始化枚举

CLIPOBJ_bEnum 循环枚举矩形

逐矩形求交并调用 BltRectFunc
返回结果

BltRectFunc 选择(引擎内部分发到 DIB 引擎):

c 复制代码
if (UsesMask)
{
    BltRectFunc = BltMask;              // 带掩码传输
}
else if ((rop4 & 0xFF) == R3_OPINDEX_PATCOPY && 纯色画刷)
{
    BltRectFunc = BltPatCopy;           // 纯色填充(DIB_ColorFill)
}
else
{
    BltRectFunc = CallDibBitBlt;        // 通用 → DIB 函数表
}

CallDibBitBlt 构造 BLTINFO 并调用 DibFunctionsForBitmapFormat[格式].DIB_BitBlt(SRCCOPY 走 DIB_BitBltSrcCopy 快路径),最终由 DIB 引擎完成像素级操作(见《ReactOS图形系统架构分析.md》第 6 章)。

ROP4 宏(inteng.h(file:///d:/reactos/win32ss/gdi/eng/inteng.h)):

c 复制代码
#define ROP4_USES_DEST(Rop4)    ((((Rop4) & 0xAAAA) >> 1) != ((Rop4) & 0x5555))
#define ROP4_USES_SOURCE(Rop4)  ((((Rop4) & 0xCCCC) >> 2) != ((Rop4) & 0x3333))
#define ROP4_USES_PATTERN(Rop4) ((((Rop4) & 0xF0F0) >> 4) != ((Rop4) & 0x0F0F))
#define ROP4_USES_MASK(Rop4)    ((((Rop4) & 0xFF00) >> 8) != ((Rop4) & 0x00ff))

ROP4 高字节为背景 ROP、低字节为前景 ROP;引擎据此判断操作依赖哪些输入(源/图案/掩码),决定是否剪裁对应表面。

3.2 裁剪管理 --- clip.c

c 复制代码
HCLIP APIENTRY EngCreateClip(VOID)   // 创建 XCLIPOBJ + REGION 组合对象
CLIPOBJ_cEnumStart(pco, ..., CT_RECTANGLES, Direction, 0)  // 初始化矩形枚举
CLIPOBJ_bEnum(pco, sizeof(RECT_ENUM), (PVOID)&RectEnum)    // 枚举下一批矩形(最多 32 个)

裁剪区域枚举把复杂区域拆成矩形列表,RECT_ENUM 单次最多返回 ENUM_RECT_LIMIT(32) 个矩形,CLIPOBJ_bEnum 返回 TRUE 表示还有更多。

3.3 表面管理 --- surface.c

函数 功能
EngCreateSurface 创建引擎表面(分配 SURFACE)
EngCreateDeviceSurface 为设备创建表面(显示驱动用)
EngModifySurface 修改表面(重新指定像素/格式)
EngLockSurface / EngUnlockSurface 锁定/解锁表面(返回 SURFOBJ)
EngDeleteSurface 删除表面
EngAssociateSurface 将表面关联到设备(framebuf 用它绑定屏幕表面)
EngCopyBits 表面间位复制
EngGetCurrentCodePage 代码页查询

3.4 设备对象管理

PDEVOBJ(pdevobj.c(file:///d:/reactos/win32ss/gdi/eng/pdevobj.c))核心函数:

函数 功能
PDEVOBJ_AllocPDEV 分配 PDEV
PDEVOBJ_vDeletePDEV 删除 PDEV
PDEVOBJ_bEnablePDEV 调用 DrvEnablePDEV 启用设备
PDEVOBJ_vCompletePDEV 完成设备初始化
PDEVOBJ_bEnableDirectDraw 启用 DirectDraw
PDEVOBJ_bDynamicModeChange 动态模式切换
PDEVOBJ_bSwitchMode 切换显示模式
PDEVOBJ_lChangeDisplaySettings 修改显示设置(ChangeDisplaySettings 内核实现)
PDEVOBJ_vRefreshModeList 刷新模式列表

LDEVOBJ(ldevobj.c(file:///d:/reactos/win32ss/gdi/eng/ldevobj.c))核心函数:

函数 功能
LDEVOBJ_pLoadDriver 加载指定名称的显示驱动
LDEVOBJ_pLoadInternal 加载内部驱动(DIB 引擎等)
LDEVOBJ_bBuildDevmodeList 构建 DEVMODE 列表
LDEVOBJ_bProbeAndCaptureDevmode 选择最佳 DEVMODE

设备注册(device.c(file:///d:/reactos/win32ss/gdi/eng/device.c)):

c 复制代码
PGRAPHICS_DEVICE EngpRegisterGraphicsDevice(
    PUNICODE_STRING pusDeviceName,     // 设备名
    PUNICODE_STRING pusDisplayDrivers, // InstalledDisplayDrivers(多驱动)
    PUNICODE_STRING pusDescription)    // 设备描述

维护全局图形设备链表(gpGraphicsDeviceFirst/Last):

  • gpPrimaryGraphicsDevice --- 主显示设备
  • gpVgaGraphicsDevice --- VGA 兼容设备(win32k 查找时优先)
  • 每个设备带 hLdev(逻辑设备)、cPdev

3.5 引擎信号量 --- semaphor.c

c 复制代码
EngAcquireSemaphore(hsem)          // 排他获取
EngAcquireSemaphoreShared(hsem)    // 共享获取(读锁)
EngReleaseSemaphore(hsem)          // 释放
EngDeleteSemaphore(hsem)           // 删除
EngCreateSemaphore()               // 创建

引擎用信号量保护设备列表、表面引用计数等全局状态。

3.6 画刷对象 --- engbrush.c

EBRUSHOBJ(引擎画刷对象)封装画刷,核心操作:

  • BRUSHOBJ_psoPattern --- 获取图案表面(图案画刷)
  • BRUSHOBJ_pvGetRbrush --- 获取驱动画刷
  • 纯色画刷用 iSolidColor(0xFFFFFFFF 表示非纯色,需图案)
  • 虚线/几何画刷的构建

引擎在 BitBlt 中使用画刷判断:pbo->iSolidColor == 0xFFFFFFFF 时从 BRUSHOBJ_psoPattern 获取图案表面作为 PatternSurface 传给 DIB 引擎。

3.7 其他核心功能

模块 函数 功能
lineto.c IntEngLineTo 直线绘制(Bresenham 或驱动 DrvLineTo)
string.c IntEngTextOut 文本输出
paint.c IntEngFillPath 路径填充
alphablend.c EngAlphaBlend Alpha 混合
gradient.c EngGradientFill 渐变填充
stretchblt.c EngStretchBlt 拉伸位块传输
transblt.c EngTransparentBlt 透明位块传输
xlateobj.c EngCreateXlate 颜色转换对象
mouse.c 指针管理 光标表面管理
engwindow.c EWNDOBJ 窗口对象跟踪
engevent.c EngCreateEvent 事件对象
mem.c EngAllocMem 引擎内存分配
float.c/math.c FLOATOBJ 浮点坐标计算

4. 渲染管线(引擎视角)

#mermaid-svg-VAscw6FVoZsg9nxg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VAscw6FVoZsg9nxg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VAscw6FVoZsg9nxg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VAscw6FVoZsg9nxg .error-icon{fill:#552222;}#mermaid-svg-VAscw6FVoZsg9nxg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VAscw6FVoZsg9nxg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VAscw6FVoZsg9nxg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VAscw6FVoZsg9nxg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VAscw6FVoZsg9nxg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VAscw6FVoZsg9nxg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VAscw6FVoZsg9nxg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VAscw6FVoZsg9nxg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VAscw6FVoZsg9nxg .marker.cross{stroke:#333333;}#mermaid-svg-VAscw6FVoZsg9nxg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VAscw6FVoZsg9nxg p{margin:0;}#mermaid-svg-VAscw6FVoZsg9nxg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VAscw6FVoZsg9nxg .cluster-label text{fill:#333;}#mermaid-svg-VAscw6FVoZsg9nxg .cluster-label span{color:#333;}#mermaid-svg-VAscw6FVoZsg9nxg .cluster-label span p{background-color:transparent;}#mermaid-svg-VAscw6FVoZsg9nxg .label text,#mermaid-svg-VAscw6FVoZsg9nxg span{fill:#333;color:#333;}#mermaid-svg-VAscw6FVoZsg9nxg .node rect,#mermaid-svg-VAscw6FVoZsg9nxg .node circle,#mermaid-svg-VAscw6FVoZsg9nxg .node ellipse,#mermaid-svg-VAscw6FVoZsg9nxg .node polygon,#mermaid-svg-VAscw6FVoZsg9nxg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VAscw6FVoZsg9nxg .rough-node .label text,#mermaid-svg-VAscw6FVoZsg9nxg .node .label text,#mermaid-svg-VAscw6FVoZsg9nxg .image-shape .label,#mermaid-svg-VAscw6FVoZsg9nxg .icon-shape .label{text-anchor:middle;}#mermaid-svg-VAscw6FVoZsg9nxg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VAscw6FVoZsg9nxg .rough-node .label,#mermaid-svg-VAscw6FVoZsg9nxg .node .label,#mermaid-svg-VAscw6FVoZsg9nxg .image-shape .label,#mermaid-svg-VAscw6FVoZsg9nxg .icon-shape .label{text-align:center;}#mermaid-svg-VAscw6FVoZsg9nxg .node.clickable{cursor:pointer;}#mermaid-svg-VAscw6FVoZsg9nxg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VAscw6FVoZsg9nxg .arrowheadPath{fill:#333333;}#mermaid-svg-VAscw6FVoZsg9nxg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VAscw6FVoZsg9nxg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VAscw6FVoZsg9nxg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VAscw6FVoZsg9nxg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VAscw6FVoZsg9nxg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VAscw6FVoZsg9nxg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VAscw6FVoZsg9nxg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VAscw6FVoZsg9nxg .cluster text{fill:#333;}#mermaid-svg-VAscw6FVoZsg9nxg .cluster span{color:#333;}#mermaid-svg-VAscw6FVoZsg9nxg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VAscw6FVoZsg9nxg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VAscw6FVoZsg9nxg rect.text{fill:none;stroke-width:0;}#mermaid-svg-VAscw6FVoZsg9nxg .icon-shape,#mermaid-svg-VAscw6FVoZsg9nxg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VAscw6FVoZsg9nxg .icon-shape p,#mermaid-svg-VAscw6FVoZsg9nxg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VAscw6FVoZsg9nxg .icon-shape .label rect,#mermaid-svg-VAscw6FVoZsg9nxg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VAscw6FVoZsg9nxg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VAscw6FVoZsg9nxg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VAscw6FVoZsg9nxg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 显示驱动/硬件
gdi/dib/ (软件渲染)
gdi/eng/ (引擎)
ntgdi/ (内核 GDI)


NtGdiBitBlt / NtGdiTextOut / NtGdiLineTo
DC 处理:裁剪区域合成

prgnVis/prgnRao/prgnAPI
XCLIPOBJ 构造

EngCreateClip + 区域求交
IntEngBitBlt / IntEngLineTo / IntEngTextOut
目标表面挂钩了驱动?

(HOOK_* 标志)
调用 DDI:DrvBitBlt/DrvLineTo/DrvTextOut

(硬件加速)
EngBitBlt 软件路径

裁剪分析 (TRIVIAL/RECT/COMPLEX)
DIB 函数表分发

DibFunctionsForBitmapFormat
DIB_32BPP_BitBlt / PutPixel 等

按位深实现
framebuf.dll 等

(DrvBitBlt 回调)
帧缓冲/显存

渲染决策核心: 引擎通过表面的 HOOK_* 标志判断驱动是否实现了某 DDI。例如目标表面(屏幕)如果被 framebuf 挂钩了 HOOK_BITBLT,则调用 GDIDEVFUNCS(psoTrg).BitBlt;但 framebuf 不实现 DrvBitBlt(见《ReactOS 图形系统分析_3.md》),因此实际仍回退到 EngBitBlt 软件渲染。


5. 与显示驱动的 DDI 交互

5.1 DDI 函数索引

引擎通过 INDEX_* 常量索引驱动的 DDI 函数表(GDIDEVFUNCS 宏从表面取 hdevLDEVOBJ → 函数表):

c 复制代码
#define GDIDEVFUNCS(pso) \
    (LDEVOBJ_pLDevObjForSurface(pso)->pfn)

常用索引:INDEX_DrvEnablePDEVINDEX_DrvEnableSurfaceINDEX_DrvBitBltINDEX_DrvTextOutINDEX_DrvLineToINDEX_DrvStretchBltINDEX_DrvSetPaletteINDEX_DrvGetModes 等(共 INDEX_LAST 个)。

5.2 钩子标志与 DDI 调度

HOOK_* 标志 对应 DDI 引擎回退实现
HOOK_BITBLT DrvBitBlt EngBitBlt → DIB_BitBlt
HOOK_STRETCHBLT DrvStretchBlt EngStretchBlt
HOOK_TEXTOUT DrvTextOut IntEngTextOut
HOOK_LINETO DrvLineTo IntEngLineTo
HOOK_FILLPATH DrvFillPath EngFillPath
HOOK_STROKEPATH DrvStrokePath EngStrokePath

回退原则: 驱动未挂钩的操作一律由引擎软件实现兜底------这是显示驱动可以"极简"(如 framebuf 只实现 12 个 DDI)的根本原因。


6. 构建配置

cmake 复制代码
# win32ss/CMakeLists.txt 中 win32k.sys 的 eng/ 部分
gdi/eng/bitblt.c
gdi/eng/bitblt_new.c     # 新版(USE_DIBLIB 时)
gdi/eng/clip.c
gdi/eng/device.c
gdi/eng/driverobj.c
gdi/eng/engbrush.c
gdi/eng/engevent.c
gdi/eng/engmisc.c
gdi/eng/engwindow.c
gdi/eng/error.c
gdi/eng/float.c
gdi/eng/gradient.c
gdi/eng/ldevobj.c
gdi/eng/lineto.c
gdi/eng/mapping.c
gdi/eng/math.c
gdi/eng/mdevobj.c
gdi/eng/mem.c
gdi/eng/mouse.c
gdi/eng/multidisp.c
gdi/eng/paint.c
gdi/eng/pandisp.c
gdi/eng/pathobj.c
gdi/eng/pdevobj.c
gdi/eng/perfcnt.c
gdi/eng/rlecomp.c
gdi/eng/semaphor.c
gdi/eng/sort.c
gdi/eng/stretchblt.c
gdi/eng/string.c
gdi/eng/surface.c
gdi/eng/transblt.c
gdi/eng/xlateobj.c
gdi/eng/stubs.c
gdi/eng/umpdstubs.c
gdi/eng/copybits.c
gdi/eng/alphablend.c

引擎代码全部编译进 win32k.sys(与 ntgdi、ntuser、dib 同一模块),非独立 DLL。


7. 设计特点总结

  1. 单一内核模块:引擎、内核 GDI、DIB 渲染全部编译进 win32k.sys,无跨模块边界开销。
  2. HOOK 标志驱动的 DDI 调度 :通过表面 HOOK_* 标志判断是否调用驱动实现,未挂钩一律软件回退------这是显示驱动极简化(framebuf 仅 12 个 DDI)的架构基础。
  3. 双层 BitBltIntEngBitBlt(设备决策+剪裁)→ EngBitBlt(软件路径+裁剪枚举)→ DIB_*(像素实现),层次清晰。
  4. 裁剪复杂度分级:DC_TRIVIAL/DC_RECT/DC_COMPLEX 三种复杂度对应"直接画/单次求交/矩形枚举"三种策略,兼顾简单与复杂场景性能。
  5. ROP4 输入分析:通过 ROP4 位运算判断操作依赖源/图案/掩码,提前剪裁或跳过不需要的表面。
  6. 四层设备对象:LDEV(驱动)→ PDEV(物理设备)→ SURFACE(表面)→ MDEV(多显示器),职责分离。
  7. 面向 DDI 的公开结构:SURFOBJ/CLIPOBJ/BRUSHOBJ/XLATEOBJ 等对象以 DDI 约定形式暴露,保证第三方显示驱动二进制兼容。

8. 源码索引

文件 关键内容
eng.h(file:///d:/reactos/win32ss/gdi/eng/eng.h) 引擎内部 API 声明、MIX_TO_ROP4
inteng.h(file:///d:/reactos/win32ss/gdi/eng/inteng.h) IntEng* 接口、ROP4 宏、SPAN 结构
engobjects.h(file:///d:/reactos/win32ss/gdi/eng/engobjects.h) XCLIPOBJ、EWNDOBJ、RWNDOBJ
surface.h(file:///d:/reactos/win32ss/gdi/eng/surface.h) / surface.c SURFACE 结构、表面管理
bitblt.c(file:///d:/reactos/win32ss/gdi/eng/bitblt.c) EngBitBlt、IntEngBitBlt、BltMask、CallDibBitBlt
clip.c(file:///d:/reactos/win32ss/gdi/eng/clip.c) EngCreateClip、CLIPOBJ_bEnum
pdevobj.h(file:///d:/reactos/win32ss/gdi/eng/pdevobj.h) / pdevobj.c PDEVOBJ、模式切换
ldevobj.h(file:///d:/reactos/win32ss/gdi/eng/ldevobj.h) / ldevobj.c LDEVOBJ、驱动加载
mdevobj.h(file:///d:/reactos/win32ss/gdi/eng/mdevobj.h) / mdevobj.c MDEVOBJ 多显示器
device.c(file:///d:/reactos/win32ss/gdi/eng/device.c) GRAPHICS_DEVICE、EngpRegisterGraphicsDevice
engbrush.c(file:///d:/reactos/win32ss/gdi/eng/engbrush.c) EBRUSHOBJ、BRUSHOBJ_psoPattern
lineto.c(file:///d:/reactos/win32ss/gdi/eng/lineto.c) IntEngLineTo
string.c(file:///d:/reactos/win32ss/gdi/eng/string.c) 文本输出
xlateobj.h(file:///d:/reactos/win32ss/gdi/eng/xlateobj.h) / xlateobj.c XLATEOBJ 颜色转换
semaphor.c(file:///d:/reactos/win32ss/gdi/eng/semaphor.c) 引擎信号量

关联模块:

  • 上层调用者:ntgdi/(file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c)(内核 GDI 系统调用层)
  • 软件渲染后端:gdi/dib/(file:///d:/reactos/win32ss/gdi/dib/dib.c) 与 gdi/diblib/(file:///d:/reactos/win32ss/gdi/diblib/DibLib.c)(DIB 函数表)
  • 消费引擎服务的显示驱动:displays/framebuf/(file:///d:/reactos/win32ss/drivers/displays/framebuf/enable.c)(EngCreateBitmap 等)
  • 设备注册来源:ntuser/display.c(file:///d:/reactos/win32ss/user/ntuser/display.c)(EngpRegisterGraphicsDevice)

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

相关推荐
caimouse3 小时前
ReactOS 图形系统分析(11):映射设备对象 — MDEVOBJ(多显示器)
系统架构·计算机外设
国科安芯21 小时前
详解ADC 规则组外部触发:CH2、CH3 与 TRGO2
运维·网络·单片机·嵌入式硬件·mcu·系统架构
Dr.kangder1 天前
嵌入式面试总结(十)——流水线
单片机·嵌入式硬件·面试·职场和发展·系统架构·嵌入式
ZJU_统一阿萨姆1 天前
【推理优化】推理的本质:prefill 与 decode 两阶段
语言模型·系统架构
郑州光合科技余经理1 天前
餐饮预定系统架构拆解:订单链路、权限组织与私有化源码交付
java·开发语言·前端·数据库·人工智能·系统架构·php
youngerwang2 天前
【软件系统架构师案例分析每日深耕 Day 13】多质量属性权衡:电商大促架构设计
系统架构·案例分析·电商大促·多质量属性
火云牌神2 天前
前后端分离:约束 AI 分工,避免接口耦合与职责错乱
人工智能·系统架构·ai编程·前后端分离·vibecoding
简单同学2 天前
深入 NVIDIA GPU:CSDN 专栏发布索引
系统架构·gpu
youngerwang2 天前
【软件系统架构案例分析每日深耕 Day 17】CBAM成本效益分析:微服务改造决策
微服务·系统架构·cbam·案例每日深耕·微服务改造