из того, что я прочитал здесь , кажется, что большинство функций Windows GDI ускорены. Так, например, при вызове BitBlt
или AlphaBlend
используется аппаратное ускорение, если оно доступно. Также упоминается, что содержимое окна хранится только в видеопамяти. Теперь все это хорошо и верно для оконного DC , но как я могу использовать DC DC , который находится в памяти видеокарты? И как только мы научимся получать прямой доступ к пикселям, я думаю, это потребует 1. временного копирования данных в системную память 2. изменения данных пикселей 3. копирования обратно в видеопамять.
Я пробовал два подхода, оба выделяют системную память, как я вижу в диспетчере задач ...
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 );
, а затем вызовите для получения битов
GetBitmapBits (...)
согласно различным комментариям это действительно должно создать совместимое растровое изображение в видеопамяти, но почему я все еще вижу увеличение системной памяти (даже когда я не вызываю 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; // сверху вниз
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);
в этом случае мы получаем указатель на биты немедленно ( m_pBits
), поэтому очевидно, что они находятся в системной памяти ...
Или это копия, которая хранится в системной памяти для обоих методов? Но если я изменю биты в системной памяти, вызов BitBlt
все равно должен будет снова проверить / скопировать из системной памяти ... не очень оптимизированный ИМХО.
РЕДАКТИРОВАТЬ: Я также пробовал создавать контроллеры домена памяти с помощью BeginBufferedPaint
и GetBufferedPaintBits
. Он также выделяет системную память, поэтому в этом отношении я полагаю, что это просто оболочка для вышеуказанных методов, но кэширует DC, поэтому следующий вызов не обязательно должен воссоздавать DC памяти. См. Статью Раймонда Чена .
РЕДАКТИРОВАТЬ №2: Я предполагаю, что на самом деле вопрос: Правильно ли я делаю создание DC памяти в методе 1 или 2, чтобы получить аппаратное ускорение операций GDI? Мне все кажется быстрым, и оба метода обеспечивают такую же скорость, так что нет возможности проверить это ...