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