2011-09-21 7 views
8

según lo que he leído here Parece que la mayoría de las funciones de Windows GDI están aceleradas. Entonces, por ejemplo, una llamada a BitBlt o AlphaBlend usa la aceleración de hardware si está disponible. También menciona que los contenidos de una ventana se guardan solo en la memoria de video. Ahora todo esto es bueno y cierto para una ventana DC, pero ¿cómo puedo usar una memoria DC que reside en la memoria de la tarjeta de video? Y una vez que hayamos logrado eso, cómo obtener acceso directo a los píxeles, creo que implicaría 1. copia temporal de los datos a la memoria del sistema 2. modificar los datos de los píxeles 3. copiar de nuevo a la memoria de video.CreateCompatibleBitmap y CreateDIBSection (Memory DC's)

He intentado dos enfoques, tanto asignar memoria del sistema que he podido ver en el administrador de tareas ...

  1. CreateCompatibleBitmap

    HDC hDC = GetDC(NULL); 
    m_hDC = CreateCompatibleDC(hDC); 
    m_hBmp = CreateCompatibleBitmap(hDC, cx, cy); 
    ReleaseDC(NULL, hDC); 
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp); 
    

    y luego llamar para obtener los bits

    GetBitmapBits(...) 
    

    Según varios comentarios, esto debería crear el mapa de bits compatible en la memoria de video y, ¿por qué aún puedo ver un aumento en la memoria del sistema (incluso cuando no llamo al GetBitmapBits)?

  2. CreateDIBSection

    HDC hDC = GetDC(NULL); 
    m_hDC = CreateCompatibleDC(hDC); 
    
    BITMAPINFO bmi; 
    memset(&bmi, 0, sizeof(BITMAPINFO)); 
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    bmi.bmiHeader.biWidth = cx; 
    bmi.bmiHeader.biHeight = -cy; // top-down 
    bmi.bmiHeader.biPlanes = 1; 
    bmi.bmiHeader.biBitCount = 32; 
    bmi.bmiHeader.biCompression = BI_RGB; 
    m_hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, NULL); 
    
    ReleaseDC(NULL, hDC); 
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp); 
    

    en este caso, recibimos el puntero a los bits de inmediato (m_pBits) así que es obvio que éstas residen en la memoria del sistema ...

o es una copia que se guarda en la memoria del sistema para ambos métodos? Pero si cambio los bits en la memoria del sistema una llamada a BitBlt todavía tendría que verificar/copiar desde la memoria del sistema otra vez ... no muy optimizado en mi humilde opinión.

EDITAR: También he intentado crear DC de memoria utilizando BeginBufferedPaint y GetBufferedPaintBits. También asigna memoria del sistema, por lo que supongo que es solo una envoltura para los métodos anteriores, pero almacena en caché los DC, por lo que una próxima llamada no necesariamente tiene que volver a crear una memoria DC. Ver el article de Raymond Chen.

EDIT # 2: Supongo que la pregunta real es: ¿Estoy haciendo la creación de DC de memoria correcta en el método 1 o 2 para obtener operaciones aceleradas por hardware de GDI? Para mí todo parece rápido, y ambos métodos proporcionan la misma velocidad también, por lo que no hay realmente una manera de verificarlo ...

+0

Pensé que siempre reside en la memoria del sistema y solo se intercambia en la memoria de video cuando se procesa en la pantalla ... – AJG85

+0

Eso significa que no podemos crearlo en la memoria de video y las funciones GDI no aceleran el hardware cuando se trabaja una memoria DC? – demorge

+2

Las funciones de GDI para * operaciones de blitting solamente * son hardware acelerado en Windows 7 exclusivamente. GDI + sigue siendo software renderizado incluso en Windows 7 y aún es mucho más lento. Si está haciendo algo complejo que requiere rendimiento, la respuesta simple es no usar GDI. Use OpenGL o DirectX si desea acceso directo al hardware. GDI fue siempre será una abstracción. – AJG85

Respuesta

3

Los DC de memoria no se crean en un dispositivo. Están diseñados para poner salida GDI en la memoria.

De Memory Device Contexts en MSDN:

para habilitar aplicaciones para colocar la producción en la memoria en lugar de enviar a un dispositivo real, utilice un contexto de dispositivo especial para mapa de bits operaciones llama un contexto de dispositivo memoria. Una memoria DC permite que el sistema trate una parte de la memoria como un dispositivo virtual.

Si desea gráficos 2d acelerados por hardware, debe considerar usar Direct2D.

+0

Aah que aclara las cosas, y también dice: * Al mostrar un DIB o un DDB creado desde un DIB en un dispositivo de paleta, puede mejorar la velocidad a la que se dibuja la imagen organizando la paleta lógica para que coincida con diseño de la paleta del sistema. * Lo que deja en claro que 'CreateCompatibleBitmap' debería ser el método más rápido, pero como mi sistema se ejecuta en color de 32 bits,' CreateDIBSection' usando un diseño de 32 bits es igual de rápido (es el mismo formato de mapa de bits creado por ambas funciones). – demorge

+0

Según mi experiencia con Direct2D frente al rendimiento de GDI, no recomendaría el uso de Direct2D. Es lento, aproximadamente a la misma velocidad que GDI. – Trinidad