Конференция "Игры" » Самый быстрый вывод растра. [Delphi, Windows]
 
  • IPranker © (07.02.11 22:28) [0]
    Всем привет. :)

    Имеется указатель на пиксель-данные рисунка. (DIB-Секция)
    Созданный через CreateDIBSection.
    Рисую через SetDIBitsToDevice или через BitBlt. (Разницы никакой)
    Слышал, что DIB выводиться достаточно медленно в отличии от DDB. Но доступ к пикселям DIB'а быстрее чем у DDB. Вот такая интересность.

    Вопрос: Как МАКСИМАЛЬНО увеличить скорость блиттинга?
    Есть странная идея: перед выводом переводить DIB в DDB, а потом обратно. Будет ли выигрыш в скорости?

    P.S. Хвалённая своё молниеносной скоростью функция SetDIBitsToDevice работает почему-то не быстрее BitBlt.
    Как так?

    Всем спасибо.
  • Студент (08.02.11 19:47) [1]
    Вы не сможете выводить битмап в оперативке на экран быстрее чем это позволяет графическая оболочка ОС... Максимальная скорость вывода возможна только через OGL/DX - так как там текстуры все уже в видеопамяти...

    И все тормоза вовсе не в выводе на экран, а в построении кадра... Покажите мне чтоб BitBlt хоть где-то хоть каплю тормозил... =\\


    > перед выводом переводить DIB в DDB, а потом обратно.


    Только зазря время тратить...


    > Но доступ к пикселям DIB'а быстрее чем у DDB


    ам... Вообще-то не так... У DDB нет доступа к пикселям... Всё только через Api...


    > Хвалённая своё молниеносной скоростью функция SetDIBitsToDevice


    Кто вам такое сказал?
  • Sapersky (08.02.11 20:46) [2]
    Ну собственно да, основной тормоз - копирование из системной памяти в видео, и вообще любое копирование между разными типами памяти (видео->системная ещё медленнее).
    Относительно DDB - по всей видимости они располагаются в видеопамяти, отсюда все достоинства и недостатки. Достоинства, впрочем, сомнительные - с ними практически ничего нельзя сделать (никаких спецэффектов, в отличие от DX/OGL), можно только быстро вывести на экран.
    Так что для софтверного рендера используйте DIB, причём рекомендую 32-битный вместо 24-битного, на некоторых картах быстрее, на других без разницы. 8-битный буфер тоже выводится довольно быстро - за счёт малого объёма данных, видимо.
    Разница в скорости функций (BitBlt vs SetDIBitsToDevice) или её отсутствие, вероятно, зависит от конкретной карты и драйвера.
  • IPranker © (08.02.11 21:53) [3]
    >>> ам... Вообще-то не так... У DDB нет доступа к пикселям... Всё только через Api...
    В TBitmap сделали доступ и к DDB, а так да нету.

    >>> Кто вам такое сказал?
    Где-то слышал.

    >>> Так что для софтверного рендера используйте DIB, причём рекомендую 32-битный
    Да, так и делаю.

    Потом ещё пару вопросов задам... :)
  • Студент (09.02.11 00:11) [4]

    > причём рекомендую 32-битный вместо 24-битного


    Ну... Я бы сказал что это зависит от целей, масштабов (размеров) и способов оптимизации... %)
    А что означает "на некоторых картах", оно ж всё равно в оперативке вроде?


    > В TBitmap сделали доступ и к DDB, а так да нету.


    Вы пробовали? Я пробовал (на Д7SP2)... Картинка вообще никак не изменяется пока не перевести обратно в DIB (соответствующим методом [или как там его] класса)...
    Я вообще склоняюсь к работе непосредственно с HBITMAP, без всяких надстроек (тем более классовых)...

    м... Или что вы имели ввиду под "доступ"?
  • IPranker © (09.02.11 14:25) [5]

    > Студент   (09.02.11 00:11) [4]


    > Я вообще склоняюсь к работе непосредственно с HBITMAP, без
    > всяких надстроек (тем более классовых)...


    Сейчас работаю с HBITMAP, но к примеру, для различных манипуляций проще воспользоваться обёрткой TBitmap. Чем писать тоже самое на голом WinAPI.


    Var
      Bmp: TBitmap;
      DIB: HBITMAP;
    begin
      Bmp.Handle:= DIB;
      Bmp.HandleType:= bmDDB;
    end;



     
    >>> м... Или что вы имели ввиду под "доступ"?
    См. пример Bitmap Speed.
    http://delphikingdom.ru/asp/viewitem.asp?catalogid=169#10

    Действительно, разницы в скорости блиттинга между DIB и DDB почти никакой.
    А вот на другом, более мощном компе, DIB проигрывал ровно в 10 раз.
  • IPranker © (09.02.11 14:34) [6]
    Почитал комменты к статье и выяснилось, что всё же при так сказать, хороших условиях DDB выводится в 10-15 раз быстрее. Есть над чем задуматься.
  • Sapersky (09.02.11 20:42) [7]
    А что означает "на некоторых картах", оно ж всё равно в оперативке вроде?

    Я имею в виду скорость BitBlt буфера на экран. На экране обычно 32 бита, и при использовании 24-битного буфера драйверу нужно конвертировать 24->32. У некоторых вендоров эта конверсия получается "прозрачно", у других добавляет тормозов (ATI). Хотя может они уже исправились, самые последние карты не тестировал.

    Я вообще склоняюсь к работе непосредственно с HBITMAP, без всяких надстроек (тем более классовых)...

    Есть такая библиотечка FastLib, там очень простая и "лёгкая" надстройка (только DIB):
    http://sapersky.narod.ru/files/FastLIBv389i.rar
    По достоинствам я уже отписывался:
    http://pda.delphimaster.net/?id=1186325580&n=9&from=99

    Почитал комменты к статье и выяснилось, что всё же при так сказать, хороших условиях DDB выводится в 10-15 раз быстрее. Есть над чем задуматься.

    Так ничего кроме выводиться он не умеет.
    Задумываться следует разве что о переходе на "честную" аппаратную графику - DX/OGL. Или вот у MS есть новомодный API специально для аппаратно-ускоренного 2D - Direct2D. По сути, обычная надстройка для 2D-через-3D вроде PowerDraw/Asphyre, но (вероятно) более функциональная и качественная.
  • CrytoGen (09.02.11 21:46) [8]
    Если бы в ней ещё была вертикальная синхронизация... А так приходиться использовать текстуры в Direct3D :)
  • Студент (10.02.11 15:55) [9]
    По вашей ссылке я не увидел конкретных применений, только общую информацию (хотя довольно интересную)... Пример BitmapSpeed по моему изначально неправильный... Он не так меряет и вообще не то...
    Он что меряет - вывод или рисование? И рисование происходит не прямым доступом к пикселям а через ещё одну обёртку - TCanvas, то есть как бы на том же api... Да и со случайными числами так нехорошо делать, чистота эксперимента нарушается...
    И там делается через TBitmap, а оно вообще очень глючное... Один метод ScanLine там совершенно через одно место сделан... По моим сведениям любая другая обёртка на порядок лучше (сам не проверял, я вручную на указателях всё делаю)...

    Нужна какая-то конкретная задача, а не так... И ещё раз повторю - главное скорость создания нового кадра, а не вывод на экран...


    > Я имею в виду скорость BitBlt буфера на экран. На экране обычно 32 бита, ...


    Хм... О таком не задумывался... Надо проверить... Только у меня 24 у экрана...


    > при использовании 24-битного буфера драйверу нужно конвертировать
    > 24->32. У некоторых вендоров эта конверсия получается "прозрачно",
    >  у других добавляет тормозов (ATI).


    ам... А это разве не dwm делает ещё до отправления на монитор? о__о

    А у вас нет случайно результатов тестов сравнения FastLib/ExGraphics/TDIB/кто_то_там_ещё ?


    > Или вот у MS есть новомодный API специально для аппаратно-
    > ускоренного 2D - Direct2D.


    Новомодный?? Да оно кажись старше меня... %)


    > А вот на другом, более мощном компе, DIB проигрывал ровно
    > в 10 раз.


    Ну если уж и проводить подобное сравнение, то нужно делать по правилам - пишем сюда исходный код программы-теста, советуемся со всеми "а всё ли так, а не забыли ли чего", и каждый из заинтересовавшихся присутствующих  компилирует у себя тест и отписывается здесь же о результатах теста (какое железо - какие цифры)... :)
  • IPranker © (10.02.11 16:33) [10]

    > Студент   (10.02.11 15:55) [9]


    > Пример BitmapSpeed по моему изначально неправильный... Он
    > не так меряет и вообще не то...


    Конкретней?


    > Он что меряет - вывод или рисование? И рисование происходит
    > не прямым доступом к пикселям а через ещё одну обёртку -
    >  TCanvas, то есть как бы на том же api...


    Ты пример то аще смотрел? Измеряет блиттинг, доступ к пикселям и рисование через GDI.

    > Да и со случайными
    > числами так нехорошо делать, чистота эксперимента нарушается.

    См. комменты примера, работа со псевдослучайными числами там одинакова.

    > И там делается через TBitmap, а оно вообще очень глючное.
    > .. Один метод ScanLine там совершенно через одно место сделан.
    > .. По моим сведениям любая другая обёртка на порядок лучше
    > (сам не проверял, я вручную на указателях всё делаю)...

    Чем он глючный? O_o

    > Новомодный?? Да оно кажись старше меня... %)

    КакбЭ только начиная с Висты появился.


    > Ну если уж и проводить подобное сравнение, то нужно делать
    > по правилам - пишем сюда исходный код программы-теста, советуемся
    > со всеми "а всё ли так, а не забыли ли чего", и каждый из
    > заинтересовавшихся присутствующих  компилирует у себя тест
    > и отписывается здесь же о результатах теста (какое железо
    > - какие цифры)... :)


    Вообще-то я про Bitmap Speed говорил. ;)
  • Студент (10.02.11 16:57) [11]
    Я вижу в каментах строку "Время измеряется с помощью функции GetTickCount", тогда как в самом коде этой функции вообще не вызывается...

    Ещё строка "за счёт визуального контроля хорошо видно, что вывод DDB-изображения выполняется существенно быстрее, чем DIB" - это каким же макаром скорость может быть видной глазу (особенно при частоте выше 25 кадров в секунду)?

    Доступ к пикселям там вообще не меряется... (Я уж не говорю про то что у DDB его нет в принципе)

    А рисование через GDI - позапрошлый век... Как минимум GDI+ и то если только под винду писать...
  • IPranker © (10.02.11 19:17) [12]

    > Студент   (10.02.11 16:57) [11]


    > Я вижу в каментах строку "Время измеряется с помощью функции
    > GetTickCount", тогда как в самом коде этой функции вообще
    > не вызывается...
    >


    Да ёмаё, сложно качнуть исходник и взглянуть?
    Время измеряется через точный QPC.


    >
    > Ещё строка "за счёт визуального контроля хорошо видно, что
    > вывод DDB-изображения выполняется существенно быстрее, чем
    > DIB" - это каким же макаром скорость может быть видной глазу
    > (особенно при частоте выше 25 кадров в секунду)?


    Ну дык если DDB в 10 раз быстрее выводиться.
    Плюс цикл на несколько тысяч иттераций.
    То результат виден не вооружённым глазом.


    > Доступ к пикселям там вообще не меряется... (Я уж не говорю
    > про то что у DDB его нет в принципе)
    >


    ScanLine жЕ!


    > А рисование через GDI - позапрошлый век... Как минимум GDI+
    > и то если только под винду писать...


    O_o
  • Студент (10.02.11 19:32) [13]

    > Да ёмаё, сложно качнуть исходник и взглянуть?
    > Время измеряется через точный QPC.


    Я про это и говорю... Используется QueryPerformanceCounter, а в каментах говорят GetTickCount (я тот исходник и цитировал)... Каменты словно от другой версии программы...


    > То результат виден не вооружённым глазом.


    Человеческий глаз не способен различать мелькание если выводится более 25 кадров в секунду (из курса биологии)...


    > ScanLine жЕ!


    Это не доступ к пикселям, это метод класса TBitmap (считающий смещение указателя), который как я уже говорил сделан через одно место...
  • IPranker © (10.02.11 20:01) [14]

    > Студент   (10.02.11 19:32) [13]


    > Я про это и говорю... Используется QueryPerformanceCounter,
    >  а в каментах говорят GetTickCount (я тот исходник и цитировал).
    > .. Каменты словно от другой версии программы...
    >


    Автор статьи по началу так измерял, но погрешность большая.
    Правильнее использовать QPC.


    > Человеческий глаз не способен различать мелькание если выводится
    > более 25 кадров в секунду (из курса биологии)...


    Дык написано же:

    >Плюс цикл на несколько тысяч иттераций.    
    >То результат виден не вооружённым глазом.



    > Это не доступ к пикселям, это метод класса TBitmap (считающий
    > смещение указателя),


    А доступ к чему? ;D

    > который как я уже говорил сделан через одно место...

    ScanLine cделан чуток не оптимизированно, да какая разница?
    Ведь условия измерения одни и те же. Разница результатов всегда будет одинакова.
  • Sapersky (10.02.11 22:36) [15]
    Если бы в ней ещё была вертикальная синхронизация... А так приходиться использовать текстуры в Direct3D :)

    Ну VSync на практике не всегда нужен... но странно, что такую банальную вещь не сделали, что им стоило...

    Хм... О таком не задумывался... Надо проверить... Только у меня 24 у экрана...

    Так я и пишу "обычно 32". Но 24 всё-таки большая редкость по нынешним временам.

    А это разве не dwm делает ещё до отправления на монитор? о__о

    Вообще да, Висту/7 я как-то позабыл... (тестировал на 98-XP). Но думаю что там примерно то же самое, формат одинаковый - меньше потенциальных проблем.

    А у вас нет случайно результатов тестов сравнения FastLib/ExGraphics/TDIB/кто_то_там_ещё ?

    Сравнения конкретно чего? Скорости всяких спецэффектов?
    По скорости самой быстрой должна быть SpriteUtils2. Но там исходники страшненькие, почти чистый asm, и заточено оно строго под KOL - на мой вкус, неудобно.
    FastLib, ИМХО, разумный компромисс в этом смысле. Хотя тоже страшненькая, особенно с т.з. блюстителей принципов ООП.
    Graphics32 по многим параметрам лучше - стилистически "чисто" написана, есть документация, есть визуальные компоненты, проект развивается и т.д. По скорости - сравнивал только поворот картинки - чуть медленнее Фастлиба, но большинству такая разница пофиг, прочие достоинства компенсируют (впрочем, сам я G32 использовал очень мало - не исключаю, что там свои задвиги по аналогии с "нет VSync").
    TDIB не тестировал, но "на глаз", судя по исходникам - не особо быстрый.
  • CrytoGen (10.02.11 22:42) [16]
    У меня задача специфическая. Посмотрел MSDN, похоже синхронизация всё же есть. Но нормальных заголовков для Delphi 7 пока не обнаружил, да и Direct3D больше простора даёт.
  • JRTeston (10.02.11 23:02) [17]
    Студент   [13]
    ...
    > Человеческий глаз не способен различать мелькание если выводится
    > более 25 кадров в секунду (из курса биологии)...

    Это ты выдумываешь, нет такого в курсе биологии (или можешь страницу и учебник назавать?).
    Восприятие частоты в огромной степени зависит от типа и инерциальности источника. Мерцание обычной ЭЛТ трубки я (и еще куча народа) видит при 60Гц (а некоторые и при 70). Так что про 25 кадров как абсолютное значение - сказки.
  • IPranker © (10.02.11 23:19) [18]

    > CrytoGen   (10.02.11 22:42) [16]


    > Посмотрел MSDN, похоже синхронизация всё же есть.


    Можно поподробнее?


    > Студент   (10.02.11 15:55) [9]

    >А у вас нет случайно результатов тестов сравнения FastLib/ExGraphics
    >/TDIB/кто_то_там_ещё ?

    http://www.delphimaster.ru/articles/dib/index.html
  • Студент (10.02.11 23:35) [19]
    Возможно прозвучит грубовато, но на заборе тоже написано... Не надо слепо верить всему что кто-то где-то написал...
    Ставлю хоть сто, хоть несколько тысяч - на глаз вообще никакой разницы... Сами-то смотрели?
    Кстати а на ноуте прога вообще зависает вместе с виндой наглухо...


    > А доступ к чему? ;D


    Ни к чему... Просто берёт переменную, делает несколько сложений, умножений, преобразований типов, вызовов подфункций... Пустая трата времени (ничего не делающая)... И считается каждый раз заново... К тому же вызывается как функция - ещё больше тормозов получаются...
    А битмап как был так и остался... Ничего не изменилось, ничего не нарисовалось - что считается-то? Ничего ж и не делалось!


    > Разница результатов всегда будет одинакова.


    С чего вы взяли? У меня в этом BitmapSpeed всегда разная... И это я ещё на старом компе не смотрел...

    А вы попробуйте что-нибудь нарисовать на dib вручную - и вот тогда будет что мерить... "gdi VS руки"...
    Дам подсказку: если последние - прямые, то ими почти завсегда быстрее будет... Если DDB и выводится там иногда слегка быстрее, то в сумме с прорисовкой оно просто отдыхает...
 
Конференция "Игры" » Самый быстрый вывод растра. [Delphi, Windows]
Есть новые Нет новых   [134427   +38][b:0][p:0.001]