При рисовании в окне предыдущее содержимое обычно отбрасывается? и как лучше их сохранить?
Я пытаюсь ускорить рендеринг (как по задержке, так и по пропускной способности) в редакторе векторных изображений Inkscape, чтобы он был более удобным для художника.
Я пытаюсь решить, следует ли рисовать непосредственно в окне или рисовать на промежуточной внеэкранной поверхности, а затем скопировать ее в окно.
Если весь холст нужно каждый раз перерисовывать, то рисование непосредственно в окне будет быстрее за счет сохранения пропускной способности памяти. Но, к сожалению, Inkscape не выполняет рендеринг с помощью графического процессора, поэтому он не может перерисовать все окно, только те прямоугольники, которые были признаны недействительными.
Допустим, у меня есть 2 прямоугольника, которые нужно перерисовать.
Первый способ - получить подповерхность для каждого прямоугольника, используя gdk_window_begin_draw_frame(rect), нарисовать и отправить его на экран. Но недостатком является то, что вы не можете нарисовать 2 параллельно, потому что GTK позволяет блокировать только 1 прямоугольник за раз.
Второй метод, о котором я подумал, - попросить оконную систему (GTK) ограничить рамку из двух прямоугольников. Затем нарисуйте 2 параллельно и отправьте результаты на экран. Но здесь проблема в том, что GTK не сохраняет старое содержимое окна - оно очищает всю область обновления, создавая пустые области в промежутке между двумя прямоугольниками.
Таким образом, чтобы 2-й метод работал, я мог бы либо попросить GUI toolkit сохранить содержимое окна, либо выполнить рендеринг в промежуточный буфер, который сохраняет все окно. Но это потребует дополнительного копирования. Я хочу знать, принято ли отбрасывать предыдущее содержимое при рисовании? Я знаю, что отбрасывание имеет преимущество в производительности, заключающееся в том, что нет необходимости ждать завершения предыдущего рендеринга и не нужно считывать данные из памяти GPU в память CPU. Этот совет дан для glGapBuffer() OpenGL и LockRect() поверхностей DirectX. Но у glMapBuffer() есть возможность вернуть старое содержимое. Так должна ли у GTK такая опция? Или это слишком много, чтобы спросить?
Кажется, многие проблемы, с которыми я сталкиваюсь, являются искусственными из-за ограничений инструментария GUI. Например, если инструментарий GUI позволяет обновлять несколько регионов параллельно, то первый метод будет работать и будет проще. OpenGL позволяет вам делать это с помощью glMapBufferRange().
Я хотел бы получить хорошее решение для GTK, но в то же время я хотел бы знать, если бы у вас был очень прямой доступ к оборудованию GPU, как бы вы реализовали частичный чертеж, который я описал наиболее эффективно?