Делаем краудсорсовый проект по Canvas - страница 18

 

К сожалению, сегодняшние попытки справится с проблемой задержки обновления картинки методом сохранения массива с "цифровой маской" не привели к успеху. Однако, и неудачей это назвать тоже нельзя. Просто не удалось сделать окончательный вывод о причине торможения и найти глобальное решение этой проблемы.

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

И так, - мои выводы:

1. Если сохранять изображения в массивах, - то массивов должно быть много. Причем, - неопределенно много...  То есть каждый ресурс требует своего массива постоянной памяти. В моей реализации интерфейса, количество канвасов (ресурсов, полотен) может быть в несколько раз больше чем количество окон.  Этого требует практика.

Поясню почему:

 В некоторых случаях этот подход значительно более удобен, чем рисование всех объектов окна на одном канвасе.  Например, - при прокрутке таблицы в элементе "поле обзора (VEIW BOX)", удобно поместить элементы таблицы на отдельный канвас внутри этого элемента и прокручивать этот канвас, как целый объект. Скорость прокрутки получается выше.  Значит, каждый такой элемент несет в себе отдельный канвас. Иначе, нужно переписывать все изображение окна сохраненное в памяти. Это одназначно будет дольше.

Тем более, совершенно неудобно, рисовать все окна на одном канвасе,  - как тогда их перемещать? Представим, что мы создали один "мега" канвас на всю площадь графика. Все наши окна будут рисоваться на нем. После рисования окон на канвасе, мы попытаемся их перемещать, но для этого придется переписывать всю картинку этого общего "мега" канваса. Картинка очень большая и количество переписываемых значений будет огромным. Даже если картинка сохранена, придется переписывать в памяти огромную площадь на каждом смещении курсора. Очевидно, что это неэффективно.

2. Думая о методе сохранения изображений и работы с ними, я вспомнил о функции "ResourceReadImage()". Эта функция считывает ресурс и помещает его цифровую маску в массив. Значит, - сохранять изображение не нужно, потому что оно уже сохранено на уровне терминала и его можно востребовать с помощью этой функции. Это значительно упрощает задачу. И так: можно затребовать изображение с помощью "ResourceReadImage()", получить его в массив и далее - менять значения массива, относящиеся к конкретному элементу, находящемуся "под событием" интерфейса. Этот подход выглядит более привлекательно, на мой взгляд. Однако, остается вопрос - сколько времени будет занимать заполнение массива изображением функцией "ResourceReadImage()"? Очевидно, это тоже зависит от площади канваса. Возможно, это вообще не будет визуально заметно, но в любом случае, загружать нужно только один раз пока курсор находится на площади конкретного канваса. При переходе на другой канвас, можно очистить массив и загрузить изображение другого канваса.

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

На сегодня пока все.
 

Реter Konow:

В моей реализации интерфейса, количество канвасов (ресурсов, полотен) может быть в несколько раз больше чем количество окон.  Этого требует практика.

этого требует ваша практика.

но как ваше же практика и показывает - такая реализация ущербна в плане скорости и удобства.

А как показывает практика, но уже моя, удобство работы достигается именно на одном канвасе и нет никаких препятствий при формировании основного канваса временно прорисовывать окно таблицы на свойм канвасе и потом делать BitBlt на основной.

Не знаю зачем вы планировали "массивов должно быть много. Причем, - неопределенно много... " - но сами же видите что это тупиковый путь.

 
o_O:

этого требует ваша практика.

но как ваше же практика и показывает - такая реализация ущербна в плане скорости и удобства.

А как показывает практика, но уже моя, удобство работы достигается именно на одном канвасе и нет никаких препятствий при формировании основного канваса временно прорисовывать окно таблицы на свойм канвасе и потом делать BitBlt на основной.

Не знаю зачем вы планировали "массивов должно быть много. Причем, - неопределенно много... " - но сами же видите что это тупиковый путь.

Возможно, Вы нашли лучшее решение. Я с удовольствием посмотрю на него. Если можете, выложите gif, где четко видна скорость реакции элементов на клик. Я после выложу свой gif. Вы увидите о чем я говорю, а я увижу о чем Вы говорите. 
 
Реter Konow:
Возможно, Вы нашли лучшее решение. Я с удовольствием посмотрю на него. Если можете, выложите gif, где четко видна скорость реакции элементов на клик. Я после выложу свой gif. Вы увидите о чем я говорю, а я увижу о чем Вы говорите. 

видео не записал, но скидываю пример. набросал по быстрому.

там 600 раскрывающихся списков.

поводите мышкой - при каждой событии и смене цвета происходит перерисовка общего CCanvas. получите ту самую интерактивность.

Итоговый размер можете видеть в свойствах битмапа - 1500х600 px (для сравнения с вашими 800 х 500 и 250 мс лагом). Что равно 900 000 точек, и перерисовываются все мгновенно.  Ни о каких секундах  речи быть не может.

Каждый список отрисовывается сначала у себя на своём канвасе в своём размере (чтоб не выйти за границы) и потом только плюхается на общий. То есть имеем 600 вызовов ResourceCreate на каждое событие от мышки.
Это значит, как видите по скорости реакции, что кадров достаточно и мультики показывать.

Разработчики MT дали удовлетворительный инструмент без тормозов (я про ResourceCreate битмапов)

Файлы:
Gtest.ex5  150 kb
 
o_O:

видео не записал, но скидываю пример. набросал по быстрому.

там 600 раскрывающихся списков.

поводите мышкой - при каждой событии и смене цвета происходит перерисовка общего CCanvas. получите ту самую интерактивность.

Итоговый размер можете видеть в свойствах битмапа - 1500х600 px (для сравнения с вашими 800 х 500 и 250 мс лагом). Что равно 900 000 точек, и перерисовываются все мгновенно.  Ни о каких секундах  речи быть не может.

Каждый список отрисовывается сначала у себя на своём канвасе в своём размере (чтоб не выйти за границы) и потом только плюхается на общий. То есть имеем 600 вызовов ResourceCreate на каждое событие от мышки.
Это значит, как видите по скорости реакции, что кадров достаточно и мультики показывать.

Разработчики MT дали удовлетворительный инструмент без тормозов (я про ResourceCreate битмапов)

Ну что ж, этого вполне достаточно для подтверждения Ваших слов... Однако, повторю свой вчерашний вопрос: изображение сохранено?

Я вчера говорил, - если хранить однажды созданное изображение, менять в нем только конкретную область, и сразу посылать в ResourceCreate(), то задержки не будет. Ваш метод работы с канвасом мне еще не знаком. Я еще не знаю как именно Вы добились этого результата.

У меня еще вопрос: пользуясь для создания вышеприведенного примера классом CCanvas, Вы можете описать принцип реализации этого решения?

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


P.S. Впрочем, секреты я люблю разгадывать сам...) Я все равно решу эту задачу.

 
Реter Konow:
пользуясь для создания вышеприведенного примера классом CCanvas, Вы можете описать принцип реализации этого решения?

принципе линейный -проходим по списку контролов и отрисовываем каждый в нужном месте на канвасе.
для рисования контролов используются только функции CCanvas. Ничего от себя не делал.

например те списки в свернутом виде рисуются в виде двух элементов - в данном примере кнопок (в других стилях по другому)
вызываются функции канваса
    FillRectangle // заполнить фон
    Rectangle // рамка вокруг
    FontSet // установить шрифт
    TextOut // вывести текст

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

нет. 

изображение сохранено?

да, в массиве который находится в CCanvas

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

не совсем так.

в моём примере перерисовывается весь массив. Массив очищается и заполняется всё полотно снова на каждой отрисовке. Затем вызывается ResourceCreate.

 
o_O:

в моём примере перерисовывается весь массив. Массив очищается и заполняется всё полотно снова на каждой отрисовке. Затем вызывается ResourceCreate.

Спасибо за развернутый ответ.

Странно, но у меня все тоже самое. Изображение всего окна полностью воссоздается на каждом событии интерфейса. Оно строится в локальном одномерном массиве, который после завершения этой процедуры отправляется в ResourceCreate.

Не понимаю, почему у меня тормозит... Завтра выложу gif где покажу зависимость между размером окна и скоростью реакции элементов.

Все это очень странно...

 
Реter Konow:

Спасибо за развернутый ответ.

Странно, но у меня все тоже самое. Изображение всего окна полностью воссоздается на каждом событии интерфейса. Оно строится в локальном одномерном массиве, который после завершения этой процедуры отправляется в ResourceCreate.

Не понимаю, почему у меня тормозит... Завтра выложу gif где покажу зависимость между размером окна и скоростью реакции элементов.

Все это очень странно...

Если не сложно, сделайте gif-анимацию с загрузкой CPU в диспетчере задач. Или проще выложить скомпилированный файл, как это сделал sergeev. Чтобы можно было самому протестировать у себя.
 
Anatoli Kazharski:
Если не сложно, сделайте gif-анимацию с загрузкой CPU в диспетчере задач. Или проще выложить скомпилированный файл, как это сделал sergeev. Чтобы можно было самому протестировать у себя.

Хорошо, сделаю видео с загрузкой CPU. Но насчет скомпилированного файла - пока не буду выкладывать.

Просто очень стыдно за баги...)))

Когда исправлю их - обещаю выложить.

 
Реter Konow:

Хорошо, сделаю видео с загрузкой CPU. Но насчет скомпилированного файла - пока не буду выкладывать.

Просто очень стыдно за баги...)))

Когда исправлю их - обещаю выложить.

Ок. Не спешите. )
Причина обращения: