Share via


PDD_SURFCB_LOCK función de devolución de llamada (ddrawint.h)

La función de devolución de llamada DdLock bloquea un área especificada de memoria expuesta y proporciona un puntero válido a un bloque de memoria asociado a una superficie.

Sintaxis

PDD_SURFCB_LOCK PddSurfcbLock;

DWORD PddSurfcbLock(
  PDD_LOCKDATA unnamedParam1
)
{...}

Parámetros

unnamedParam1

Apunta a una estructura DD_LOCKDATA que contiene la información necesaria para realizar el bloqueo.

Valor devuelto

DdLock devuelve uno de los siguientes códigos de devolución de llamada:

Comentarios

DdLock debe establecer el miembro ddRVal de la estructura de DD_LOCKDATA en lpLock en DDERR_WASSTILLDRAWING y devolver DDHAL_DRIVER_HANDLED si un blit o flip está en curso.

A menos que el miembro dwFlags de DD_LOCKDATA especifique lo contrario, el controlador puede devolver un puntero de memoria a la parte superior de la superficie en el miembro lpSurfData de DD_LOCKDATA. Si el controlador necesita calcular su propia dirección para la superficie, puede confiar en el puntero pasado en el miembro fpProcess de DD_LOCKDATA como puntero por proceso a la asignación en modo de usuario de su búfer de fotogramas accesibles para DirectDraw.

Un bloqueo no proporciona acceso exclusivo al bloque de memoria solicitado; es decir, varios subprocesos pueden bloquear la misma superficie al mismo tiempo. Es responsabilidad de la aplicación sincronizar el acceso al bloque de memoria cuyo puntero se obtiene.

Un controlador que se ejecuta en un sistema operativo basado en NT no debe devolver un puntero a la memoria del sistema desde su función DdLock a menos que la función DdCreateSurface del controlador haya asignado previamente dicha memoria con la marca PLEASE_ALLOC_USERMEM. Si no se usó PLEASE_ALLOC_USERMEM, las aplicaciones podrían recibir errores cada vez que intentaron acceder a dicha memoria. Para obtener más información, consulte Implementación del kernel de NT de DDLOCK_NOSYSLOCK .

Se puede llamar a DdLock con un PDEV deshabilitado. Un PDEV está deshabilitado o habilitado llamando a la función DrvAssertMode del controlador de pantalla. Consulte Administración de PDEV para obtener más información.

Implementación del kernel de NT de DDLOCK_NOSYSLOCK

Las aplicaciones pueden usar las interfaces de programación de aplicaciones (API) de DirectDraw y Direct3D para obtener bloqueos de larga duración en los recursos de memoria de vídeo. Estos bloqueos se denominan bloqueos "NOSYSLOCK". Estos bloqueos funcionan de forma diferente a los típicos bloqueos de memoria de vídeo, como se describe en los párrafos siguientes.

Después de que el tiempo de ejecución de DirectDraw llame a la función DdLock de un controlador con la marca DDLOCK_NOSYSLOCK especificada en el miembro dwFlags de DD_LOCKDATA, el tiempo de ejecución examina el puntero al contenido de la superficie devuelto por el controlador. En lugar de pasar el puntero devuelto por el controlador directamente a una aplicación, el tiempo de ejecución crea una segunda asignación en modo de usuario de memoria de vídeo (local y no local) y calcula la dirección virtual equivalente dentro de esa asignación. Esta dirección virtual se conoce como puntero de alias al bloqueo de memoria. El tiempo de ejecución pasa este puntero de bloqueo de alias a la aplicación. La aplicación usa este puntero de bloqueo de alias para leer y escribir directamente en la memoria de vídeo. Ni la aplicación ni el controlador son conscientes de que usa un puntero de memoria bloqueada diferente.

Más adelante, en tiempo de cambio de modo, el tiempo de ejecución de DirectDraw anota los punteros de bloqueo de alias pendientes. En lugar de esperar a que los punteros de bloqueo de alias se completen, como lo haría para un bloqueo típico de memoria de vídeo, el tiempo de ejecución reasigna la asignación en modo de usuario de la memoria de vídeo y permite que el cambio de modo continúe. El tiempo de ejecución reasigna las asignaciones en modo de usuario a una sola página ficticía; La aplicación continúa leyendo y escribiendo en esa página ficticía, de lo contrario, no es consciente de los cambios. A continuación, el tiempo de ejecución debe limpiar punteros de bloqueo de alias mediante una llamada a la función DdUnlock del controlador. El tiempo de ejecución puede limpiar punteros de bloqueo de alias porque la aplicación ya no está escribiendo en la memoria de vídeo. Dado que esta limpieza se produce en el tiempo de cambio de modo, el siguiente paso de la secuencia es perder superficies, lo que significa destruir los objetos por superficie del controlador. En otras palabras, el tiempo de ejecución llama a la función DdDestroySurface del controlador para todas las superficies, incluidas las superficies que la aplicación sigue considerando como bloqueadas. De hecho, la aplicación sigue leyendo y escribiendo en una página ficticía de memoria del sistema.

Este proceso completo solo funciona si el puntero de memoria devuelto por DdLock es una asignación de memoria de vídeo. Esta asignación de memoria de vídeo puede ser la asignación en modo de usuario de la memoria de vídeo no local realizada por el tiempo de ejecución del modo kernel de DirectDraw o la asignación proporcionada por la función DdMapMemory del controlador. Si el puntero de memoria no se puede atribuir a una de estas asignaciones, el tiempo de ejecución no reasigna el bloqueo. El modificador de modo continúa, lo que significa que el objeto de superficie del controlador se desbloquea y destruye mediante llamadas a las funciones DdUnlock y DdDestroySurface del controlador, respectivamente. A continuación, el controlador libera normalmente cualquier memoria del sistema que el controlador haya asignado en tiempo de bloqueo. Dado que la aplicación sigue escribiendo en esta memoria, se produce una infracción de acceso.

Por lo tanto, un controlador no debe intentar devolver punteros de memoria del sistema desde su función DdLock a menos que la función DdCreateSurface del controlador haya asignado previamente dicha memoria con la marca PLEASE_ALLOC_USERMEM. El tiempo de ejecución de DirectDraw posee la memoria asignada de esta manera y puede aplazar la liberación de esta memoria hasta que la aplicación desbloquea la memoria. Por lo tanto, la función DdLock del controlador puede devolver punteros a la memoria asignada de esta manera sin riesgo de bloquear la aplicación.

Requisitos

Requisito Value
Plataforma de destino Escritorio
Encabezado ddrawint.h (incluya Winddi.h)

Consulte también

DD_LOCKDATA

DdMapMemory

DdUnlock