PDD_SURFCB_LOCK回调函数 (ddrawint.h)
DdLock 回调函数锁定图面内存的指定区域,并提供指向与图面关联的内存块的有效指针。
语法
PDD_SURFCB_LOCK PddSurfcbLock;
DWORD PddSurfcbLock(
PDD_LOCKDATA unnamedParam1
)
{...}
参数
unnamedParam1
指向包含执行锁定所需的信息的 DD_LOCKDATA 结构。
返回值
DdLock 返回以下回调代码之一:
注解
DdLock 应将 lpLock 中DD_LOCKDATA结构的 ddRVal 成员设置为DDERR_WASSTILLDRAWING,并在 blit 或 flip 正在进行时返回DDHAL_DRIVER_HANDLED。
除非 DD_LOCKDATA 的 dwFlags 成员另有指定,否则驱动程序可以返回指向 DD_LOCKDATA 的 lpSurfData 成员中图面顶部的内存指针。 如果驱动程序需要计算其自己的图面地址,则可以依赖于在 DD_LOCKDATA 的 fpProcess 成员中传递的指针作为指向其 DirectDraw 可访问帧缓冲区的用户模式映射的每进程指针。
锁不提供对请求的内存块的独占访问;也就是说,多个线程可以同时锁定同一个图面。 应用程序负责同步对要获取其指针的内存块的访问。
在基于 NT 的操作系统上运行的驱动程序不应从其 DdLock 函数返回指向系统内存的指针,除非该驱动程序的 DdCreateSurface 函数以前使用 PLEASE_ALLOC_USERMEM 标志分配了此类内存。 如果未使用PLEASE_ALLOC_USERMEM,则每当应用程序尝试访问此类内存时,都可能会收到错误。 有关详细信息 ,请参阅 NT 内核实现DDLOCK_NOSYSLOCK 。
可以使用禁用的 PDEV 调用 DdLock。 通过调用显示驱动程序的 DrvAssertMode 函数禁用或启用 PDEV。 有关详细信息 ,请参阅管理 PDEV 。
NT 内核DDLOCK_NOSYSLOCK的实现
应用程序可以使用 DirectDraw 和 Direct3D 的应用程序编程接口 (API) 来获取视频内存资源上的长时间锁定。 此类锁称为“NOSYSLOCK”锁。 这些锁的运行方式不同于以下段落中所述的典型视频内存锁。DirectDraw 运行时使用 DD_LOCKDATA 的 dwFlags 成员中指定的DDLOCK_NOSYSLOCK标志调用驱动程序的 DdLock 函数后,运行时将检查指向驱动程序返回的图面内容的指针。 运行时不会将驱动程序返回的指针直接传递给应用程序,而是创建视频内存的第二个用户模式映射, (本地和非本地) ,并计算该映射中的等效虚拟地址。 此虚拟地址称为指向内存锁的别名指针。 运行时将此别名锁定指针传递给应用程序。 应用程序使用此别名锁定指针直接读取和写入视频内存。 应用程序和驱动程序都不知道它使用不同的锁定内存指针。
稍后,在模式切换时,DirectDraw 运行时会记录任何未完成的别名锁定指针。 运行时会重新映射视频内存的用户模式映射,并允许模式切换继续,而不是像典型的视频内存锁那样等待别名锁指针完成。 运行时将用户模式映射重新映射到单个虚拟页面;应用程序继续读取和写入该虚拟页面,否则不知道任何更改。 然后,运行时必须通过调用驱动程序的 DdUnlock 函数来清理别名锁指针。 运行时可以清理别名锁指针,因为应用程序不再写入视频内存。 由于此清理发生在模式切换时,因此序列中的下一步是丢失图面,这意味着销毁驱动程序的每个图面对象。 换句话说,运行时为所有图面(包括应用程序继续视为锁定的表面)调用驱动程序的 DdDestroySurface 函数。 事实上,应用程序继续读取和写入系统内存的虚拟页。
仅当 DdLock 返回的内存指针是视频内存的某种映射时,此过程才有效。 此视频内存映射可以是由 DirectDraw 内核模式运行时执行的非本地视频内存的用户模式映射,也可以是驱动程序的 DdMapMemory 函数提供的映射。 如果内存指针不能归因于其中一个映射,则运行时不会重新映射锁。 模式切换将继续,这意味着通过分别调用驱动程序的 DdUnlock 和 DdDestroySurface 函数来解锁和销毁驱动程序的 Surface 对象。 然后,驱动程序通常会释放驱动程序在锁定时分配的任何系统内存。 由于应用程序仍在写入此内存,因此会发生访问冲突。
因此,驱动程序不应尝试从其 DdLock 函数返回系统内存指针,除非该驱动程序的 DdCreateSurface 函数以前使用 PLEASE_ALLOC_USERMEM 标志分配了此类内存。 DirectDraw 运行时拥有以这种方式分配的内存,并且可以延迟释放此内存,直到应用程序解锁内存。 因此,驱动程序的 DdLock 函数可以返回以这种方式分配的内存的指针,而不会有应用程序崩溃的风险。
要求
要求 | 值 |
---|---|
目标平台 | 桌面 |
标头 | ddrawint.h (包括 Winddi.h) |