Partager via


PDD_SURFCB_LOCK fonction de rappel (ddrawint.h)

La fonction de rappel DdLock verrouille une zone de mémoire de surface spécifiée et fournit un pointeur valide vers un bloc de mémoire associé à une surface.

Syntaxe

PDD_SURFCB_LOCK PddSurfcbLock;

DWORD PddSurfcbLock(
  PDD_LOCKDATA unnamedParam1
)
{...}

Paramètres

unnamedParam1

Pointe vers une structure de DD_LOCKDATA qui contient les informations requises pour effectuer le verrouillage.

Valeur retournée

DdLock retourne l’un des codes de rappel suivants :

Remarques

DdLock doit définir le membre ddRVal de la structure de DD_LOCKDATA sur lpLock sur DDERR_WASSTILLDRAWING et retourner DDHAL_DRIVER_HANDLED si une fente ou un retournement est en cours.

Sauf indication contraire par le membre dwFlags de DD_LOCKDATA, le pilote peut retourner un pointeur mémoire vers le haut de la surface dans le membre lpSurfData de DD_LOCKDATA. Si le pilote doit calculer sa propre adresse pour la surface, il peut s’appuyer sur le pointeur transmis dans le membre fpProcess de DD_LOCKDATA comme pointeur par processus vers le mappage en mode utilisateur de sa mémoire tampon de trame accessible à DirectDraw.

Un verrou ne fournit pas d’accès exclusif au bloc de mémoire demandé ; Autrement dit, plusieurs threads peuvent verrouiller la même surface en même temps. Il incombe à l’application de synchroniser l’accès au bloc de mémoire dont le pointeur est obtenu.

Un pilote s’exécutant sur un système d’exploitation NT ne doit pas renvoyer de pointeur vers la mémoire système à partir de sa fonction DdLock , sauf si la fonction DdCreateSurface de ce pilote a précédemment alloué cette mémoire avec l’indicateur PLEASE_ALLOC_USERMEM. Si PLEASE_ALLOC_USERMEM n’a pas été utilisé, les applications peuvent recevoir des erreurs chaque fois qu’elles tentent d’accéder à cette mémoire. Pour plus d’informations, consultez Implémentation du noyau NT de DDLOCK_NOSYSLOCK .

DdLock peut être appelé avec un PDEV désactivé. Un PDEV est désactivé ou activé en appelant la fonction DrvAssertMode du pilote d’affichage. Pour plus d’informations, consultez Gestion des PDEVs .

Implémentation du noyau NT de DDLOCK_NOSYSLOCK

Les applications peuvent utiliser les interfaces de programmation d’applications (API) de DirectDraw et de Direct3D pour obtenir des verrous de longue durée sur les ressources de mémoire vidéo. Ces verrous sont appelés verrous « NOSYSLOCK ». Ces verrous fonctionnent différemment des verrous de mémoire vidéo classiques, comme décrit dans les paragraphes suivants.

Une fois que le runtime DirectDraw appelle la fonction DdLock d’un pilote avec l’indicateur DDLOCK_NOSYSLOCK spécifié dans le membre dwFlags de DD_LOCKDATA, le runtime examine le pointeur vers le contenu de la surface retournée par le pilote. Au lieu de transmettre le pointeur retourné par le pilote directement à une application, le runtime crée un deuxième mappage en mode utilisateur de la mémoire vidéo (locale et non locale) et calcule l’adresse virtuelle équivalente dans ce mappage. Cette adresse virtuelle est appelée pointeur d’alias vers le verrou de mémoire. Le runtime transmet ce pointeur de verrouillage d’alias à l’application. L’application utilise ce pointeur de verrouillage d’alias pour lire et écrire directement dans la mémoire vidéo. Ni l’application ni le pilote ne savent qu’ils utilisent un autre pointeur de mémoire verrouillée.

Plus tard, au moment du changement de mode, le runtime DirectDraw note tous les pointeurs de verrouillage d’alias en suspens. Au lieu d’attendre que les pointeurs de verrouillage d’alias se terminent, comme c’est le cas pour un verrouillage de la mémoire vidéo classique, le runtime remapppe le mappage en mode utilisateur de la mémoire vidéo et permet au commutateur de mode de continuer. Le runtime remapppe les mappages en mode utilisateur sur une seule page factice ; l’application continue de lire et d’écrire dans cette page factice, sans connaître les modifications éventuelles. Le runtime doit ensuite propre les pointeurs de verrouillage d’alias en appelant la fonction DdUnlock du pilote. Le runtime peut propre des pointeurs de verrouillage d’alias, car l’application n’écrit plus dans la mémoire vidéo. Étant donné que cette propre se produit au moment du changement de mode, l’étape suivante de la séquence consiste à perdre des surfaces, ce qui signifie détruire les objets par surface du pilote. En d’autres termes, le runtime appelle la fonction DdDestroySurface du pilote pour toutes les surfaces, y compris les surfaces que l’application continue de considérer comme verrouillées. En fait, l’application continue de lire et d’écrire dans une page factice de mémoire système.

Tout ce processus fonctionne uniquement si le pointeur de mémoire retourné par DdLock est un mappage de la mémoire vidéo. Ce mappage vidéo-mémoire peut être le mappage en mode utilisateur de la mémoire vidéo non locale effectué par le runtime en mode noyau DirectDraw ou le mappage fourni par la fonction DdMapMemory du pilote. Si le pointeur mémoire ne peut pas être attribué à l’un de ces mappages, le runtime ne remappage pas le verrou. Le commutateur de mode continue, ce qui signifie que l’objet surface du pilote est déverrouillé et détruit via des appels aux fonctions DdUnlock et DdDestroySurface du pilote respectivement. Le pilote libère alors généralement toute la mémoire système allouée par le pilote au moment du verrouillage. Étant donné que l’application écrit toujours dans cette mémoire, une violation d’accès se produit.

Par conséquent, un pilote ne doit pas tenter de retourner des pointeurs de mémoire système à partir de sa fonction DdLock , sauf si la fonction DdCreateSurface de ce pilote a précédemment alloué cette mémoire avec l’indicateur PLEASE_ALLOC_USERMEM. Le runtime DirectDraw possède la mémoire allouée de cette manière et peut différer la libération de cette mémoire jusqu’à ce que l’application déverrouille la mémoire. Par conséquent, la fonction DdLock du pilote peut retourner des pointeurs vers la mémoire allouée de cette manière sans risque de blocage de l’application.

Configuration requise

Condition requise Valeur
Plateforme cible Desktop (Expérience utilisateur)
En-tête ddrawint.h (inclure Winddi.h)

Voir aussi

DD_LOCKDATA

DdMapMemory

DdUnlock