CreateCompatibleBitmap и CreateDIBSection (DC памяти)

из того, что я прочитал здесь , кажется, что большинство функций Windows GDI ускорены. Так, например, при вызове BitBlt или AlphaBlend используется аппаратное ускорение, если оно доступно. Также упоминается, что содержимое окна хранится только в видеопамяти. Теперь все это хорошо и верно для оконного DC , но как я могу использовать DC DC , который находится в памяти видеокарты? И как только мы научимся получать прямой доступ к пикселям, я думаю, это потребует 1. временного копирования данных в системную память 2. изменения данных пикселей 3. копирования обратно в видеопамять.

Я пробовал два подхода, оба выделяют системную память, как я вижу в диспетчере задач ...

  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 ); 
     

    , а затем вызовите для получения битов

     GetBitmapBits (...) 
     

    согласно различным комментариям это действительно должно создать совместимое растровое изображение в видеопамяти, но почему я все еще вижу увеличение системной памяти (даже когда я не вызываю 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; // сверху вниз 
    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? Мне все кажется быстрым, и оба метода обеспечивают такую ​​же скорость, так что нет возможности проверить это ...

8
задан demorge 21 September 2011 в 17:13
поделиться