LINUX.ORG.RU

Qt и видеопамять

 


1

2

Привет, лор, есть вопрос знатокам qt. Когда я создаю и рисую QLabel, выделяется сколько-то видеопамяти. Вопрос: освобождается ли эта память, когда я вызываю QLabel::hide()?

Я хотел проверить создать кучу лейбелов, hide() их, и при во время всего этого наблюдать за vram'ом. Но vram у меня от интела и мониторить его не получается.

Deleted

Когда я создаю и рисую QLabel, выделяется сколько-то видеопамяти.

Qt-приложение, по умолчанию работающее через иксы, не использует GPU (аппаратно-ускоренную отрисовку) и вот этот твой QLabel не является привычной текстурой, которая хранится в видеопамяти. Наверное корнями QLabel, как и любой другой Qt-виджет, уходит внутрь xcb/xlib/иксов, где и будет являтся каким-то там отрендеренным битмапом. Что-то я сильно сомневаюсь, что этот битмап хранится в VRAM, а не тупо в RAM. Но я могу ошибаться, тут люди знающие архитектуру иксов нужны.

P.S. Qt по hide() не удаляет виджет, а лишь скрывает его с формы, все данные и отрендеренный битмап где-то там должны сохраняться. Даже если бы Qt использовал аппаратное ускорение и QLabel был текстурой, то сам понимаешь, что удалять/создавать каждый раз текстуру по вызову show()/hide() – довольно накладно. Так что ничего там удаляться не должно.

EXL ★★★★★ ()
Последнее исправление: EXL (всего исправлений: 2)
Ответ на: комментарий от EXL

Qt-приложение, по умолчанию работающее через иксы, не использует GPU (аппаратно-ускоренную отрисовку)

Чё ты несёшь?

anonymous ()
Ответ на: комментарий от EXL

понял. а страдает ли производительность, если спрятать очень много лейбелов? не в смысле памяти. наверняка там есть лист активных и лист спрятанных виджетов и последние нигде не обрабатываются никак и их методы не вызываются где-нибудь глубоко в qt. это так? с другой стороны, что-то я не нашел способа пройтись по только видимым виджетам layout'a, кроме как через цикл до layout.count() и проверкой флага isHidden() на каждом элементе.

Deleted ()
Ответ на: комментарий от Deleted

Т.к. Qt использует двойную буферизацию, будет дополнительное расходование памяти на каждый QLabel.

Вопрос: просядет ли производительность от лишних QLabel?
Ответ: просядет.

Вопрос: заметит ли это пользователь?
Ответ: зависит от того, на сколько просядет производительность.

Вопрос: так на сколько просядет конкретно?
Ответ: зависит от количества QLabel'ов и еще от кучи специфичных для приложения параметров.

Вопрос: можно ли так делать?
Ответ: Кто же вам запретит? Но лучше так не делать.

trex6 ★★★★★ ()
Ответ на: комментарий от Deleted

а страдает ли производительность, если спрятать очень много лейбелов?

Страдать производительность будет на старте приложения, если очень много QLabel’ов начнут создаваться и складываться в кучу. По процу и по памяти. Чем больше виджетов будет конструироваться при запуске приложения, тем дольше оно будет запускаться.

Ещё, насколько я помню, при дёргании show() и hide() пересчитываются размеры как самих виджетов, так и формы.

последние нигде не обрабатываются никак и их методы не вызываются где-нибудь глубоко в qt. это так?

Не совсем так, вам никто не запрещает установить, например, другой текст в QLabel, пока он скрыт и отобразить его в нужное время.

с другой стороны, что-то я не нашел способа пройтись по только видимым виджетам layout’a, кроме как через цикл до layout.count() и проверкой флага isHidden() на каждом элементе.

Можете рассказать о своей задаче чуть больше? Если вы создаёте очень много элементов для отображения, то наверное вам лучше использовать встроенный в Qt фреймворк Graphics View Framework или же The State Machine Framework.

с другой стороны, что-то я не нашел способа пройтись по только видимым виджетам layout’a, кроме как через цикл до layout.count() и проверкой флага isHidden() на каждом элементе.

Вы можете объединить эти QLabel’ы в группы, можете попробовать использовать QStackedWidget. Можете подписать каждый такой QLabel на сигнал, который их скрывает или показывает и т. д. Всё зависит от вашей задачи.

EXL ★★★★★ ()
Ответ на: комментарий от Deleted

я не нашел способа пройтись

Складывай виджеты в два вектора: invisibleWidgets и visibleWidgets. Отнаследовавший (например от лабеля), переопредели show и hide методы, которые, до вызова метода родителя сделают нужные манипуляции с собой — удалят из одного и добавят в другой вектор. Так, чтобы получить список только видимых, достаточно будет обратиться к visibleWidgets.

Вот пишу я это всё и кажется, что ты какой-то синтетический тупняк хочешь.

deep-purple ★★★★★ ()
Ответ на: комментарий от deep-purple

Я точно не знаю, но Qt 4.x отказывалось стартовать без OpenGL >= 2.0, так что очень странно что оно не использует ускорение, но при этом требует OpenGL.

Deleted ()
Ответ на: комментарий от Deleted

Потому, что в виджетах есть КуГлВиджет. И не важно, используешь ты его или нет, но он там есть и требует свою зависимость.

deep-purple ★★★★★ ()

А ты ещё и на стековерфло с этим вопросом насрал...

deep-purple ★★★★★ ()
Ответ на: комментарий от deep-purple

А ты ещё и на стековерфло с этим вопросом насрал...

у тебя на аватарке фигурка, на задней части ее случаем не огромный нос висит? и что не так с вопросом?

Складывай виджеты в два вектора: invisibleWidgets и visibleWidgets.

ок, понял

Вот пишу я это всё и кажется, что ты какой-то синтетический тупняк хочешь.

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

Deleted ()
Ответ на: комментарий от EXL

Можете рассказать о своей задаче чуть больше? Если вы создаёте очень много элементов для отображения, то наверное вам лучше использовать встроенный в Qt фреймворк Graphics View Framework или же The State Machine Framework.

По сути хочу написать виджет для отображения логов со своими свистелками. Есть строки полей, эти строки выводятся один за другим, обычное дело. полей в разных строках может быть по-разному (и выравнивать их под соседние строки не всегда нужно). Но некоторые строки нужно группировать, скажем по какому-то полю, типа индекса или времени. Или если попадается слишком длинная строка лога и нужно всю инфу поместить в экран без перемотки. Соответственно, эти группы строк должны выглядить монолитно, а не просто как две строки, идущие подряд и с одинаковым фоном.

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

все это дело нужно будет уметь сортировать, фильтровать и.т.п.

Graphics и SMF насколько я понимаю для этой задачи слишком обширны.

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

Еще подсказали QTreeView, щас буду смотреть что оно умеет.

Deleted ()
Ответ на: комментарий от Deleted

так что очень странно что оно не использует ускорение, но при этом требует OpenGL.

Это нормальная практика в Qt. Вот и модуль QtGui в Qt 5 в 99.9% случаев не использует ускорение, но зависит от OpenGL.

Я точно не знаю, но Qt 4.x отказывалось стартовать без OpenGL >= 2.0

В Qt 4 была возможность задать QT_GRAPHICSSYSTEM=opengl ./app, из Qt 5 эта возможность выпилена. Сегодняшняя ситуация: QtWidgets не используют аппаратное ускорение, если это не задано явно через QT_QPA_PLATFORM=eglfs ./app, например.

EXL ★★★★★ ()

Неизвестно. Чтобы знать — пишут на vulkan.

anonymous ()
Ответ на: комментарий от Deleted

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

Так может лучше и взять QTableView тогда и не городить странные вещи?

EXL ★★★★★ ()
Ответ на: комментарий от EXL

а с QTableView есть возможность создать такую таблицу, что бы в разных строках было разное кол-во полей и что бы ширину каждой ячейки можно было настраивать?

Deleted ()
Ответ на: комментарий от EXL

Ячейки можно объединять. Их ширину тоже можно настраивать.

да, и правда можно. но ширину настроить у меня получилось только целой колонки, а не отдельной ячейки.

Deleted ()
Ответ на: комментарий от deep-purple

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

с другой стороны, можно сделать QListView, в каждой ячейке которого будет еще QVBoxWidget, в каждом из которых будет QHBoxWidget. И все это сделать как-то через делегаты, а не виджеты. Такое можно провернуть?

Deleted ()

Я хотел проверить создать кучу лейбелов, hide() их, и при во время всего этого наблюдать за vram'ом. Но vram у меня от интела и мониторить его не получается.

Запусти intel-gpu-overlay, от рута. В оверлее будет указано, сколько памяти используется. Утилита обычно находится в пакете с названием intel-gpu-tools.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

overlay нету, но есть intel_gpu_abrt, intel_gpu_frequency, intel_gpu_time, intel_gpu_top. В intel_gpu_top есть показатель render space 0/131072, но видимо это не то. У меня встроенная GMA видюха какой-то модели если что.

Deleted ()
Ответ на: комментарий от Deleted

QListView

Нет. Он слишком заточен под другое.

Короче, если так, то я бы сделал:

QScrollArea (область просмотра) -> QVBoxLayout -> Qwidget (элемент списка) -> QHBoxLayout -> QLabel (ячейка, которую можно растянуть/съёжить вне зависимости от появившихся выше).

deep-purple ★★★★★ ()
Ответ на: комментарий от Deleted

Возможно, ты пытаешься запустить intel_gpu_overlay, а программа называется intel-gpu-overlay. Вот так наименования из общего ряда выбивается.

Но по сути тебе не нужна именно эта программа. Достаточно в /sys/kernel/debug/dri/0/i915_gem_objects поглядеть. Там есть вся нужная информация. Если у тебя в /sys/kernel/debug пусто, смонтируй туда debugfs.

i-rinat ★★★★★ ()

Когда я создаю и рисую QLabel, выделяется сколько-то видеопамяти.

Видеопамять выделяется только для нативных виджетов: 1) окон вернего уровня; 2) устаревший QGLWidget (QOpenGLWidget уже не создает нативное окно); 3) виджетов, у которых вызывался метод winId. Все остальное расходует только оперативку и отрисовывается в буферы родительского окна

annulen ★★★★★ ()
Ответ на: комментарий от i-rinat

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

Deleted ()
Ответ на: комментарий от Deleted

При такой постановке задачи не стоит использовать виджеты для отдельных строк. Лично я бы сделал кастомную вьюху на базе QAbstractItemView. Сортировка и фильтрация делается в модели

annulen ★★★★★ ()
Ответ на: комментарий от annulen

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

Deleted ()
Ответ на: комментарий от Deleted

Если строк на экране видно мало, а работать должно на современном компе, то такой вариант вполне может прокатить. Главное понимать, что это дичь, а не нормальное решение :)

annulen ★★★★★ ()
Ответ на: комментарий от annulen

да не совсем дичь, лишнее время то только уходит на саму инициализацию лейбелов и виджетов, разве нет? я думаю самому рисовать не может быть намного быстрее.

Deleted ()
Ответ на: комментарий от Deleted

1. Такие вещи без model-view делать криво

2. Время уходит на лейаут этих виджетов, а еще они едят оперативы больше, чем надо

annulen ★★★★★ ()
Ответ на: комментарий от annulen

без model-view делать криво

Я понимаю о чём ты, но ты бы примером показал. Как представлю что ради нескольких ячеек в ряду нужно заводить ДВЕ модели (вторая для фильтрации) с этими вот «index.row()» и прочими сигналами о добавлении/удалении элементов — мне аж плохо становится. А так же, не забудь про кастомизацию внешнего вида вьюАйтема.

deep-purple ★★★★★ ()
Ответ на: комментарий от deep-purple

А так же, не забудь про кастомизацию внешнего вида вьюАйтема.

Не сложнее чем кастомизировать внешний вид кучи виджетов

annulen ★★★★★ ()
Ответ на: комментарий от annulen

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

deep-purple ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.