Share via


função de retorno de chamada PDD_SURFCB_LOCK (ddrawint.h)

A função de retorno de chamada DdLock bloqueia uma área especificada da memória da superfície e fornece um ponteiro válido para um bloco de memória associado a uma superfície.

Sintaxe

PDD_SURFCB_LOCK PddSurfcbLock;

DWORD PddSurfcbLock(
  PDD_LOCKDATA unnamedParam1
)
{...}

Parâmetros

unnamedParam1

Aponta para uma estrutura DD_LOCKDATA que contém as informações necessárias para executar o bloqueio.

Retornar valor

O DdLock retorna um dos seguintes códigos de retorno de chamada:

Comentários

O DdLock deve definir o membro ddRVal da estrutura DD_LOCKDATA em lpLock para DDERR_WASSTILLDRAWING e retornar DDHAL_DRIVER_HANDLED se um blit ou flip estiver em andamento.

A menos que seja especificado de outra forma pelo membro dwFlags do DD_LOCKDATA, o driver pode retornar um ponteiro de memória para a parte superior da superfície no membro lpSurfData do DD_LOCKDATA. Se o driver precisar calcular seu próprio endereço para a superfície, ele poderá contar com o ponteiro passado no membro fpProcess de DD_LOCKDATA como sendo um ponteiro por processo para o mapeamento do modo de usuário do buffer de quadros acessível pelo DirectDraw.

Um bloqueio não fornece acesso exclusivo ao bloco de memória solicitado; ou seja, vários threads podem bloquear a mesma superfície ao mesmo tempo. É responsabilidade do aplicativo sincronizar o acesso ao bloco de memória cujo ponteiro está sendo obtido.

Um driver em execução em um sistema operacional baseado em NT não deve retornar um ponteiro para a memória do sistema de sua função DdLock , a menos que a função DdCreateSurface do driver tenha alocado anteriormente essa memória com o sinalizador PLEASE_ALLOC_USERMEM. Se PLEASE_ALLOC_USERMEM não tiver sido usado, os aplicativos poderão receber erros sempre que tentassem acessar essa memória. Consulte Implementação de DDLOCK_NOSYSLOCK do Kernel NT para obter mais informações.

O DdLock pode ser chamado com um PDEV desabilitado. Um PDEV está desabilitado ou habilitado chamando a função DrvAssertMode do driver de exibição. Consulte Gerenciando PDEVs para obter mais informações.

Implementação de DDLOCK_NOSYSLOCK do kernel NT

Os aplicativos podem usar as APIs (interfaces de programação de aplicativo) do DirectDraw e do Direct3D para obter bloqueios de longa duração em recursos de memória de vídeo. Esses bloqueios são chamados de bloqueios "NOSYSLOCK". Esses bloqueios operam de forma diferente dos bloqueios típicos de memória de vídeo, conforme descrito nos parágrafos a seguir.

Depois que o runtime do DirectDraw chama a função DdLock de um driver com o sinalizador DDLOCK_NOSYSLOCK especificado no membro dwFlags do DD_LOCKDATA, o runtime examina o ponteiro para o conteúdo da superfície retornado pelo driver. Em vez de passar o ponteiro retornado pelo driver diretamente para um aplicativo, o runtime cria um segundo mapeamento de memória de vídeo no modo de usuário (local e não local) e calcula o endereço virtual equivalente dentro desse mapeamento. Esse endereço virtual é conhecido como o ponteiro de alias para o bloqueio de memória. O runtime passa esse ponteiro alias-lock para o aplicativo. O aplicativo usa esse ponteiro alias-lock para ler e gravar diretamente na memória de vídeo. Nem o aplicativo nem o driver estão cientes de que ele usa um ponteiro de memória bloqueada diferente.

Posteriormente, em tempo de alternância de modo, o runtime do DirectDraw observa todos os ponteiros pendentes de alias-lock. Em vez de aguardar a conclusão dos ponteiros de alias-lock, como faria para um bloqueio típico de memória de vídeo, o runtime remapea o mapeamento do modo de usuário da memória de vídeo e permite que a opção de modo continue. O runtime remapea os mapeamentos do modo de usuário para uma única página fictícia; o aplicativo continua a ler e gravar nessa página fictícia, caso contrário, sem saber de nenhuma alteração. Em seguida, o runtime deve limpo ponteiros de alias-lock chamando a função DdUnlock do driver. O runtime pode limpo ponteiros de alias-lock porque o aplicativo não está mais gravando na memória de vídeo. Como essa limpo ocorre no tempo de alternância de modo, a próxima etapa na sequência é perder superfícies, o que significa destruir os objetos por superfície do driver. Em outras palavras, o runtime chama a função DdDestroySurface do driver para todas as superfícies, incluindo superfícies que o aplicativo continua a considerar como bloqueadas. Na verdade, o aplicativo continua a ler e gravar em uma página fictícia de memória do sistema.

Todo esse processo só funcionará se o ponteiro de memória retornado pelo DdLock for um mapeamento de memória de vídeo. Esse mapeamento de memória de vídeo pode ser o mapeamento do modo de usuário da memória de vídeo não local executada pelo runtime do modo kernel do DirectDraw ou o mapeamento fornecido pela função DdMapMemory do driver. Se o ponteiro de memória não puder ser atribuído a um desses mapeamentos, o runtime não remapeará o bloqueio. A opção de modo continua, o que significa que o objeto surface do driver é desbloqueado e destruído por meio de chamadas para as funções DdUnlock e DdDestroySurface do driver, respectivamente. Em seguida, o driver normalmente libera qualquer memória do sistema alocada pelo driver em tempo de bloqueio. Como o aplicativo ainda está gravando nessa memória, ocorre uma violação de acesso.

Consequentemente, um driver não deve tentar retornar ponteiros de memória do sistema de sua função DdLock , a menos que a função DdCreateSurface do driver tenha alocado anteriormente essa memória com o sinalizador PLEASE_ALLOC_USERMEM. O runtime do DirectDraw possui memória alocada dessa maneira e pode adiar a liberação dessa memória até que o aplicativo desbloqueie a memória. Portanto, a função DdLock do driver pode retornar ponteiros para a memória alocada dessa maneira sem correr o risco de falhar o aplicativo.

Requisitos

Requisito Valor
Plataforma de Destino Área de Trabalho
Cabeçalho ddrawint.h (inclua Winddi.h)

Confira também

DD_LOCKDATA

DdMapMemory

DdUnlock