线性内存分配

每当可以更改音调以匹配表面宽度时,都会将显示内存视为 线性 ,同时考虑到对齐要求 (,如下图所示) 。 例如,如果分片只能达到 8 字节步幅,并且使用了 31 像素的子画面,则每条显示行都需要调整一条,以便将下一行对齐在 8 字节边界上。

根据对齐要求,将像素深度(以字节为单位)乘以图面宽度来确定间距。 如果显示器跨 640 8 位像素,则间距为 640。 如果像素为 16 位 (2 个字节) 并且有 640 X 480 屏幕,则间距为 1280 (640 * 2) 。 同样,640 宽、32 位 (4 字节) 像素屏幕的间距为 2560 (640 * 4) 线性显示内存。

下图演示了一个主要图面和一个暂存区域的线性内存堆分配。

显示具有一个主要表面和一个暂存区域的线性内存堆分配的示意图。

指向主图面开头的指针是 fpPrimary,它是 VIDEOMEMORYINFO 结构的成员。 将主图面和各种 Windows 缓存的大小添加到此中,以提供指向暂存区域开头的指针,由 VIDEOMEMORY 结构的 fpStart 成员指示。 由 VIDEOMEMORY 结构的 fpEnd 成员指示的终结点是通过添加剩余内存的大小减 1 来计算的。

VIDEOMEMORY 结构包含管理显示内存堆的信息。 此示例在 VIDEOMEMORY 结构数组中只有一个元素,因为只有一个堆。 VIDMEM_ISLINEAR,VIDEOMEMORY 结构的 dwFlags 成员中的标志,表示此为线性内存。

以下伪代码演示了如何为线性内存设置 VIDEOMEMORY 结构:

/*
 * video memory pool usage
 */
static VIDEOMEMORY vidMem [] = {
    { VIDMEM_ISLINEAR, 0x00000000, 0x00000000,
           { 0 }, { 0 } },
};/*

以下伪代码演示如何设置线性内存堆:

/*
 * video memory pool information
 */

/* Calculate the number of video memory heaps */
    ddHALInfo.vmiData.dwNumHeaps = sizeof ( vidMem ) / sizeof ( vidMem [ 0 ] );

/* set up the pointer to the first available video memory after the primary surface */
    ddHALInfo.vmiData.pvmList     = vidMem;

/*
 * remainder of screen memory
 */

    VideoHeapBase = ddHALInfo.vmiData.fpPrimary + dwPrimarySurfaceSize + dwCacheSize;
    VideoHeapEnd = VideoHeapBase + dwDDOffScreenSize - 1;

    vidMem[ 0 ].fpStart = VideoHeapBase;
    vidMem[ 0 ].fpEnd = VideoHeapEnd;

通过将 GDI 主图面的开头添加到主图面的大小以及 Windows 画笔、笔和 VDD 缓存的大小来计算第一个可用暂存区域的开头。 结果用于将 VIDEOMEMORY 结构的第一个元素中的起始点设置为暂存区域的开头。

通过将暂存区域的开头添加到暂存区域的大小,并减去一个以使其包含,来找到暂存区域的结束。 结果用于设置第一个 (的终点,在本例中,仅将 VIDEOMEMORY 结构的) 元素设置为暂存区域的末尾。 如果有多个堆,则终结点设置为此堆的末尾,下一个堆从此堆离开的位置开始。