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 ...
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
)?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 ...
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
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
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