PDD_SURFCB_LOCK funzione di callback (ddrawint.h)
La funzione callback DdLock blocca un'area specificata di memoria di superficie e fornisce un puntatore valido a un blocco di memoria associato a una superficie.
Sintassi
PDD_SURFCB_LOCK PddSurfcbLock;
DWORD PddSurfcbLock(
PDD_LOCKDATA unnamedParam1
)
{...}
Parametri
unnamedParam1
Punta a una struttura DD_LOCKDATA che contiene le informazioni necessarie per eseguire il blocco.
Valore restituito
DdLock restituisce uno dei codici di callback seguenti:
Commenti
DdLock deve impostare il membro ddRVal della struttura DD_LOCKDATA in lpLock su DDERR_WASSTILLDRAWING e restituire DDHAL_DRIVER_HANDLED se è in corso un blit o flip.
Se non diversamente specificato dal membro dwFlags di DD_LOCKDATA, il driver può restituire un puntatore alla parte superiore della superficie nel membro lpSurfData di DD_LOCKDATA. Se il driver deve calcolare il proprio indirizzo per la superficie, può basarsi sul puntatore passato nel membro fpProcess di DD_LOCKDATA come puntatore per processo al mapping in modalità utente del buffer frame accessibile da DirectDraw.
Un blocco non fornisce l'accesso esclusivo al blocco di memoria richiesto; ovvero, più thread possono bloccare la stessa superficie contemporaneamente. È responsabilità dell'applicazione sincronizzare l'accesso al blocco di memoria il cui puntatore viene ottenuto.
Un driver in esecuzione in un sistema operativo basato su NT non deve restituire un puntatore alla memoria di sistema dalla sua funzione DdLock a meno che la funzione DdCreateSurface del driver in precedenza allocata tale memoria con il flag di PLEASE_ALLOC_USERMEM. Se PLEASE_ALLOC_USERMEM non è stato usato, le applicazioni potrebbero ricevere errori ogni volta che hanno tentato di accedere a tale memoria. Per altre informazioni, vedere Implementazione del kernel NT di DDLOCK_NOSYSLOCK .
DdLock può essere chiamato con un PDEV disabilitato. Un PDEV è disabilitato o abilitato chiamando la funzione DrvAssertMode del driver visualizzato. Per altre informazioni, vedere Gestione di PDEV .
Implementazione del kernel NT di DDLOCK_NOSYSLOCK
Le applicazioni possono usare le interfacce di programmazione dell'applicazione Direct3D e Direct3D per ottenere blocchi di durata prolungata sulle risorse di memoria video. Tali blocchi sono denominati blocchi "NOSYSLOCK". Questi blocchi funzionano in modo diverso rispetto ai blocchi tipici della memoria video, come descritto nei paragrafi seguenti.Dopo che il runtime DirectDraw chiama la funzione DdLock di un driver con il flag DDLOCK_NOSYSLOCK specificato nel membro dwFlags di DD_LOCKDATA, il runtime esamina il puntatore al contenuto della superficie restituito dal driver. Anziché passare il puntatore restituito dal driver direttamente a un'applicazione, il runtime crea un secondo mapping in modalità utente della memoria video (sia locale che non locale) e calcola l'indirizzo virtuale equivalente all'interno di tale mapping. Questo indirizzo virtuale è noto come puntatore alias al blocco di memoria. Il runtime passa questo puntatore alias-lock all'applicazione. L'applicazione usa questo puntatore di blocco alias per leggere e scrivere direttamente nella memoria video. Né l'applicazione né il driver sono consapevoli che usa un puntatore a memoria bloccata diverso.
In seguito, all'ora del commutatore in modalità, il runtime DirectDraw annota eventuali puntatori di blocco alias in sospeso. Invece di attendere il completamento dei puntatori alias-lock, in quanto sarebbe per un tipico blocco in memoria video-il runtime esegue nuovamente il mapping in modalità utente della memoria video e consente al commutatore di modalità video di continuare. Il runtime esegue il mapping in modalità utente a una singola pagina fittizia; l'applicazione continua a leggere e scrivere in quella pagina fittizia, altrimenti inconsapevoli di eventuali modifiche. Il runtime deve quindi pulire i puntatori alias-lock chiamando la funzione DdUnlock del driver. Il runtime può pulire i puntatori alias-lock perché l'applicazione non scrive più in memoria video. Poiché questa pulizia si verifica all'ora del commutatore in modalità, il passaggio successivo della sequenza consiste nel perdere le superfici, che significa distruggere gli oggetti per superficie del driver. In altre parole, il runtime chiama la funzione DdDestroySurface del driver per tutte le superfici, incluse le superfici che l'applicazione continua a considerare bloccata. Infatti, l'applicazione continua a leggere e scrivere in una pagina fittizia della memoria di sistema.
Questo intero processo funziona solo se il puntatore alla memoria restituito da DdLock è un mapping della memoria video. Questo mapping di memoria video può essere il mapping in modalità utente della memoria video non locale eseguita dal runtime in modalità kernel DirectDraw o il mapping fornito dalla funzione DdMapMemory del driver. Se il puntatore alla memoria non può essere attribuito a uno di questi mapping, il runtime non esegue il mapping del blocco. L'opzione di modalità continua, il che significa che l'oggetto superficie del driver viene sbloccato e distrutto tramite chiamate alla funzione DdUnlock del driver e DdDestroySurface rispettivamente. Il driver rilascia in genere qualsiasi memoria di sistema allocata al momento del blocco. Poiché l'applicazione sta ancora scrivendo in questa memoria, si verifica una violazione di accesso.
Di conseguenza, un driver non deve tentare di restituire puntatori di memoria di sistema dalla funzione DdLock a meno che la funzione DdCreateSurface del driver in precedenza allocata tale memoria con il flag di PLEASE_ALLOC_USERMEM. Il runtime DirectDraw possiede la memoria allocata in questo modo e può rinviare la versione di questa memoria fino a quando l'applicazione sblocca la memoria. Pertanto, la funzione DdLock del driver può restituire puntatori alla memoria allocata in questo modo senza rischio di arresto anomalo dell'applicazione.
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Desktop |
Intestazione | ddrawint.h (include Winddi.h) |