GUI на GDI+ - высокая нагрузка на CPU
От: AlexBP  
Дата: 25.09.14 14:13
Оценка:
Здравствуйте.
Делаю простое GUI на GDI+. Создал окно WC_STATIC с стилем WS_POPUP | SS_NOTIFY и в нем отрисовываю пару кнопок на GDI+
В сообщении WM_MOUSEMOVE просчитываю над какой кнопкой находится мышь, меняю картинку, если мышка над кнопкой и перерисовываю окно.
Если начать быстро двигать мышкой по кнопкам, при перерисовке окна загрузка CPU подымается до 20%. Хотелось бы оптимизировать этот показатель. Может кто ни будь подскажет секреты при создании окон для использования одного лишь GDI+ без других контролов, Или может по другому сообщения обрабатывать от этого окно... Не нашел как их либо вразумительных ответов в инете по этому вопросу.
Re: GUI на GDI+ - высокая нагрузка на CPU
От: Serpuh фотомер.рф
Дата: 25.09.14 17:00
Оценка:
А как кнопки ищешь? GraphicsPath.IsOutlineVisible? Сейчас посмотрел, тоже при быстром движении мыши до 20-30% проц занимается, но у меня просто поиск отрисованных графических объектов. Видать такая особенность GDI+.
Re[2]: GUI на GDI+ - высокая нагрузка на CPU
От: AlexBP  
Дата: 25.09.14 17:30
Оценка:
Здравствуйте, Serpuh, Вы писали:

S>А как кнопки ищешь? GraphicsPath.IsOutlineVisible? Сейчас посмотрел, тоже при быстром движении мыши до 20-30% проц занимается, но у меня просто поиск отрисованных графических объектов. Видать такая особенность GDI+.


А меня свой класс виджета. У виджета задан прямоугольник. И просто перебираю все виджеты над которым мышь, если найден, останавливаю цикл поиска.
Но это я уже протестировал. Оставлял поиск, но убирал перерисовку — нагрузка 0-1%. Возвращаю перерисовку — опять при движении мышки 17-20%.
Re[3]: GUI на GDI+ - высокая нагрузка на CPU
От: Serpuh фотомер.рф
Дата: 25.09.14 17:46
Оценка: -1
Здравствуйте, AlexBP, Вы писали:
ABP>Но это я уже протестировал. Оставлял поиск, но убирал перерисовку — нагрузка 0-1%. Возвращаю перерисовку — опять при движении мышки 17-20%.
Перерисовка всегда была дорогая в GDI+. Так что это нормально. Просто интересно, а почему тебя заботит такой локальный момент с загрузкой процессора?
Re[4]: GUI на GDI+ - высокая нагрузка на CPU
От: AlexBP  
Дата: 25.09.14 18:17
Оценка:
S>Перерисовка всегда была дорогая в GDI+. Так что это нормально. Просто интересно, а почему тебя заботит такой локальный момент с загрузкой процессора?

Думал может где то что то упустил.
Похожие приложения не так грузят CPU. Возможно они не на GDI+ сделаны.
Отредактировано 25.09.2014 18:19 AlexBP . Предыдущая версия .
Re[5]: GUI на GDI+ - высокая нагрузка на CPU
От: AlexBP  
Дата: 26.09.14 12:31
Оценка:
Посмотрел некоторые программы с нестандартным GUI и лаунчеры для игр. Максимум они грузят на 2-3%
А какая тогда альтернатива может быть для разработки графического GUI? Direct2D не подойдет, так как хотелось бы поддержку XP.
А вот интересно что Qt использует? Тоже GDI+?
Re: GUI на GDI+ - высокая нагрузка на CPU
От: rean  
Дата: 26.09.14 16:31
Оценка: 1 (1)
deleted
Отредактировано 22.04.2019 10:36 deleted2 . Предыдущая версия .
Re[2]: GUI на GDI+ - высокая нагрузка на CPU
От: AlexBP  
Дата: 26.09.14 21:51
Оценка:
Здравствуйте, rean, Вы писали:

ABP>>В сообщении WM_MOUSEMOVE просчитываю над какой кнопкой находится мышь, меняю картинку, если мышка над кнопкой и перерисовываю окно.


R>Видимо какой-то баг в обработке сообщений.


R>1. Очень похоже, что вы перерисовываете кнопку на каждый пиксел перемещения мышки. Таким образом, проход мышки под кнопкой будет сопряжен постоянной перерисовкой, пока мышка в движении.


Перерисовываю только тогда когда изменяется состояние кнопки.

R>2. Не понятно, для чего перерисовывать всё окно. В Win32 есть механизм отсечения, да и просто можно же определить, что именно стоит перерисовать, не затрагивая остальное.


Перерисовываю не все окно, а регион виджета.

С помощью программы Dependency Walker заметил, что Qt использует Windows GDI (gdi32.dll), а не GDI+. Значит GDI быстрее чем GDI+, или все же дело в обработке сообщений от окна
Re[6]: GUI на GDI+ - высокая нагрузка на CPU
От: Andrew S Россия http://alchemy-lab.com
Дата: 26.09.14 22:31
Оценка:
ABP>Посмотрел некоторые программы с нестандартным GUI и лаунчеры для игр. Максимум они грузят на 2-3%
ABP>А какая тогда альтернатива может быть для разработки графического GUI? Direct2D не подойдет, так как хотелось бы поддержку XP.

WTL, возможно, в некоторых случаях HTMLayout.

ABP>А вот интересно что Qt использует? Тоже GDI+?


Совет. Если хотите нормальный быстрый UI на win/C++, забудьте про GDI+, это АД. А также желательно забыть про QT и WPF/xaml. Написать контрол с нормальным биндингом на WTL не сильно сложнее, чем на любом из вышеперечисленных фреймворков, а по пользовательскому восприятию это обычно в разы лучше за счет использования стандартных контролов системы, где сценарии использования (поведение контрола, хоткеи и прочее) проработаны на порядок детальнее, чем в любом другом варианте.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: GUI на GDI+ - высокая нагрузка на CPU
От: rean  
Дата: 26.09.14 23:01
Оценка:
deleted
Отредактировано 22.04.2019 10:36 deleted2 . Предыдущая версия .
Re[7]: GUI на GDI+ - высокая нагрузка на CPU
От: AlexBP  
Дата: 26.09.14 23:19
Оценка:
AS>Совет. Если хотите нормальный быстрый UI на win/C++, забудьте про GDI+, это АД. А также желательно забыть про QT и WPF/xaml. Написать контрол с нормальным биндингом на WTL не сильно сложнее, чем на любом из вышеперечисленных фреймворков, а по пользовательскому восприятию это обычно в разы лучше за счет использования стандартных контролов системы, где сценарии использования (поведение контрола, хоткеи и прочее) проработаны на порядок детальнее, чем в любом другом варианте.

WTL использует обычные контролы виндовс. У нас в GUI контролы не используются. Из WinAPI только создание окна и инъекция в GUI событий мышки. GUI имеет несколько платформ отрисовки — DirectX, OpenGL... Теперь хотим его прикрутить к GDI+. Вот я и пытаюсь понять — при перерисовке проблема в GDI+ или в обработке сообщений от окна.
Re[4]: GUI на GDI+ - высокая нагрузка на CPU
От: AlexBP  
Дата: 26.09.14 23:25
Оценка:
Здравствуйте, rean, Вы писали:

ABP>>С помощью программы Dependency Walker заметил, что Qt использует Windows GDI (gdi32.dll), а не GDI+. Значит GDI быстрее чем GDI+, или все же дело в обработке сообщений от окна


R>Сейчас все, что можно, внутри винды использует видеокарту, даже GDI. Потери времени могут быть только на обвязку и инициализации. А их можно и там и там вынести за код отрисовки. Сейчас лучше всего рисовать через Direct2D. Vista+. Если же нужно очень качественно рисовать наклонные линии, рекомендую Antigrain.


R>Что именно у вас не так, не понятно. Попробуйте логгировать отрисовку и потом найти узкие места с помощью Performance Counters. Весь возможный код инициализации, включая загрузку картинок и шрифтов, выносите за пределы кода отрисовок. Если все-равно все кажется неоптимальным, можно кешировать целые куски изображения и быстро кидать их по BitBlt.


R>PS. У меня на достаточно древнем ноутбуке Все окно Firefox при изменении размера окна и полной перерисовки жрет меньше одного ядра (30% CPU). Так что ищите у себя баг или неоптимальное использование ресурсов. Не должно быть так.


Инициализация в отрисовке ) нет конечно.
Про Direct2D уже сказал выше. Для GUI уже подключена платформа DirectX — 9 версия работает и в XP.
Кешировать нет смысла, когда перерисовывается только необходимый регион.
Re[4]: GUI на GDI+ - высокая нагрузка на CPU
От: k0st1x Марс  
Дата: 29.09.14 06:08
Оценка:
Здравствуйте, rean, Вы писали:

R>Сейчас все, что можно, внутри винды использует видеокарту, даже GDI.


откуда такая информация?
на сколько я знаю, gdi/gdi+ используют CPU
и только direct2d/direct3d используют GPU.
Re[5]: GUI на GDI+ - высокая нагрузка на CPU
От: rean  
Дата: 29.09.14 20:15
Оценка:
deleted
Отредактировано 22.04.2019 10:35 deleted2 . Предыдущая версия .
Re: GUI на GDI+ - высокая нагрузка на CPU
От: CEMb  
Дата: 30.09.14 03:38
Оценка:
Здравствуйте, AlexBP, Вы писали:

ABP>Делаю простое GUI на GDI+. Создал окно WC_STATIC с стилем WS_POPUP | SS_NOTIFY и в нем отрисовываю пару кнопок на GDI+

А почему статик, а не нормальный диалог?
ABP>Если начать быстро двигать мышкой по кнопкам, при перерисовке окна загрузка CPU подымается до 20%. Хотелось бы оптимизировать этот показатель. Может кто ни будь подскажет секреты при создании окон для использования одного лишь GDI+ без других контролов, Или может по другому сообщения обрабатывать от этого окно... Не нашел как их либо вразумительных ответов в инете по этому вопросу.
А что там делается такого через GDI+, что нельзя сделать через GDI?

У меня в подписи как раз есть примерчик с нестандартными кнопками, используется GDI, причём состояние(перерисовка) кнопки меняется постоянно по таймеру, ничего не тормозит.
Общий принцип такой:
1. снимаем с контекста байтовый массив, через GetDIBits
2. делаем обработку над массивом. Это обычная память, всё работает быстро.
3. заливаем SetDIBitsToDevice.
Т.о. с самой видеопамятью работают только две простые функции.
Re[6]: GUI на GDI+ - высокая нагрузка на CPU
От: k0st1x Марс  
Дата: 30.09.14 06:20
Оценка:
Здравствуйте, rean, Вы писали:

R>>>Сейчас все, что можно, внутри винды использует видеокарту, даже GDI.

K>>откуда такая информация?

R>http://msdn.microsoft.com/en-us/library/windows/desktop/ff729480%28v=vs.85%29.aspx


спасибо за ссылку,
действительно, начиная с Win7 GDI работает через HW.
Re: GUI на GDI+ - высокая нагрузка на CPU
От: saf_e  
Дата: 30.09.14 08:17
Оценка:
Здравствуйте, AlexBP, Вы писали:

ABP>Здравствуйте.

ABP>Делаю простое GUI на GDI+. Создал окно WC_STATIC с стилем WS_POPUP | SS_NOTIFY и в нем отрисовываю пару кнопок на GDI+
ABP>В сообщении WM_MOUSEMOVE просчитываю над какой кнопкой находится мышь, меняю картинку, если мышка над кнопкой и перерисовываю окно.
ABP>Если начать быстро двигать мышкой по кнопкам, при перерисовке окна загрузка CPU подымается до 20%. Хотелось бы оптимизировать этот показатель. Может кто ни будь подскажет секреты при создании окон для использования одного лишь GDI+ без других контролов, Или может по другому сообщения обрабатывать от этого окно... Не нашел как их либо вразумительных ответов в инете по этому вопросу.

На текущем проекте куча ЮИ (самописного, постепенно уходим в сторону стнадартных контролов) на GDI+. Никаких сверхъестественных тормозов.

1. Если еще не пробовали в релизе, проверте, часто дебаг тормозит в самых неожиданных местах.
2. Если и там тормоза, проследите за сообщениями перерисовки (WM_PAINT, WM_ERASEBACKGROUND) если приходят когда не должны (т.е. стейт не меняется) -- ищите косяк.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.