Что это? *
Что это? *

Несмотря на рекомендации мейнтейнеров, этот модуль каждый раз возвращается в Qt Essentials Modules.

Некоторые требовали закопать и не откапывать, чтобы в мире было меньше страданий.

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

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

Речь пойдет про Qt Multimedia.

Qt Multimedia

Дополнительно к плееру QMediaPlayer и проигрыванию аудио QSoundEffect, киллер фичей модуля является доступ к камере QCamera.

И главная идея всего этого в том, чтобы имея одинаковый API оно работало на всех доступных платформах. К тому же, это есть главная философия всего Qt — доступно, удобно, быстро и кросс-платформенно.

Осторожно, спойлер

это не всегда получалось

Если вы столкнулись с проблемой в Qt Multimedia, то скорее всего это будет либо шоустопером, либо потребует немалых усилий, чтобы разобраться. Не каждому хочется становиться экспертом в GStreamer или, не дай бог, в DirectShow.

А все из-за чрезмерной и бессмысленной сложности в реализации, ну и чуточку потому что Qt Multimedia - это надстройка, API для платформозависимого кода, который базируется на медиа фреймворках: GStreamer, DirectShow, AVFoundation, PulseAudio, WindowsAudio и т. д.

Плагины

Все начиналось с гениальной идеи времен когда Qt был под Nokia и мультимедия была потенциальной и востребованной задачей. У каждого была нокия, и можно было и музыку проигрывать, а вдруг и видео, и может даже с камеры стрим сделать? Кто ж знал...

Поэтому можно представить такой диалог:

- Давайте напишем и релизним абстрактные интерфейсы и позволим сторонним разработчикам реализовывать их под нужные им платформы...

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

Осторожно, спойлер

не дописали.

И никого не смутило, что громадное количество функционала либо не реализована вообще, либо работает не так, как ожидается.

А что делать, если нижележащий медиа фреймворк не поддерживает требуемый функционал и не собирается от слова совсем, например, проигрывание в обратную сторону или получения время начала и конца видео фрейма?

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

В основе лежит QMediaServiceProviderPlugin, который возвращает QMediaService, который возвращает QMediaControl.

Каждая фича задумывалась, как реализация QMediaControl, абстрактного интерфейса. Нужно лишь было запросить реализацию у сервиса, например:

service->requestControl(QMediaPlayerControl_iid) , ничего не напоминает?

Если же такой реализации интерфейса нет, то и фича не реализована, все просто.

По сути, доступ к какому-то функционалу предоставляли реализации абстрактных интерфейсов QMediaControl, таких как QMediaPlayerControl или QCameraControl. Можно было работать напрямую с ними и радоваться (нет).

Надо больше API

Но решили придумать еще один слой, чтобы работать с этими интерфейсами. Например, QMediaPlayer требует реализации QMediaPlayerControl, а QCamera - реализацию QCameraControl. ИлиQVideoProbe — потенциально очень восстребованный API, но не везде реализован и еще почему оно такое все сложное? А QSoundEffect — это вообще другая история, со своими костылями. И так далее.

А как вам идея, придумать API чтобы проигрывать плейлист - QMediaPlaylistControl? Как много сторонних пользователей реализовали этот интерфейс?

Но разработчики пошли дальше и внедрили публичный API слоем выше, который тоже требовал реализации под платформу, но этому не суждено было сбыться: например, поддержка перечислений, таких как QAudio::Role или QMediaPlayer::Flag.

Поэтому каждый раз, когда вам надо некий функционал, вам давалась возможность проверить есть ли он в наличии:

QMediaPlayer::availability, QMediaPlayer::hasSupport, QMediaObject::isMetaDataAvailable, QCamera::isCaptureModeSupported, QCameraExposure::isFlashModeSupported, QCamera::supportedLocks и т.д.

Понятное дело, что пользователи в основном проходили мимо подобных танцполов и старались использовать только то, что реализовано. Но как проверить что именно доступно на требуемой платформе?

Бекенды

Так появился список фич под платформу: https://wiki.qt.io/Qt_5.13_Multimedia_Backends

Представляю как пользователь хочет просто эффективно зарендерить стрим с камеры, открывает эту страницу и убеждается, что рендеринг в окно реализован только в GStreamer и то, только для виджетов... (Как много таких, кто так делал?) А потом обнаруживает, что на некоторых платформах fps иногда проседает с 22 до 10. Но почему об этом не написно? Как это пофиксить? А что такое рендеринг в окно? Хотя оно как-то работает, и на этом спасибо.

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

И да, вы скорее всего неправильно понимаете что такое Qt Multimedia и что такое Qt вообще.

Это вам не конструктор

Вы — разработчик и хотите инструмент, легко подключаемый/отключаемый, который решит ваши задачи наиболее эффективным способом, даст достаточно полный контроль над происходящим и у вас есть выбор, что можно использовать, и что проигнорировать. А сам инструмент - впереди планеты по передовым технологиям, выжимает из железа максимум, борется за каждый такт процессора, покрывает самые экзотические потребности, и на него можно положиться.

Как вы уже поняли, это не про Qt. Хотя пока неочевидно почему.

И да, Qt пытается выжать максимум из алгоритмов на котором он основан, заявляется, что производительность должна упираться в железо, а не в софт.

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

Например, QString не должен и не планировался быть эффективнее и лучше, чем std::string. QList не должен заменить std::vector и вообще, использовать Qt контейнеры без QObject и QCoreApplication бессмысленно.

Qt - это решение обычных задач обычным способом без особых требований. Он по определению уступает нативным, платформозависимым решениям.

А Qt Multimedia не является и не должен быть мультимедия фреймворком, это всего лишь небольшая часть большой среды разработки. Это монолит, с плотной связностью и кучей зависимостей внутри модуля и с другими частями системы. Например, рендеринг видео до недавнего времени был сильно инкапсулирован. Считалось, что рендеринг — это детали реализации, и не стоит пользователей посвещать в это: посмотритеQMediaPlayer::setVideoOutput или попробуйте понять как ускорить рендеринг используя OpenGL.

Qt Multimedia - не для вас

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

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

Если вам потребуется что-то более специфическое, то Qt Multimedia - не для вас.

Поэтому самое главное договориться где будет начинаться что-то специфическое, а где все еще мейнстрим.

И это всегда решалось тем, что если что-то не работает, то we don't give a shit мы посмотрим насколько тяжело это починить.

Осторожно, спойлер

скорее всего тяжело

gst-pipeline:

Так как в основном мейнтейнеры работали на линуксе, то именно под линукс больше всего допиленного до ума кода, к тому же GStreamer со своими пайплайнами сильно воодушевлял.

Наверное, наиболее востребованной фичей была возможность создавать произвольные пайплайны (custom pipelines). Так как это специфика GStreamer, то создавать отдельный публичный, а, значит, неумираемый API, не было никакой возможности.

Многие годы в коридорах летала идея оставить только один бекенд GStreamer, некоторые робкие попытки даже были сделаны. Так как удалять систему плагинов было нельзя, то попытались дать пользователям возможность выбирать какой бекенд надо подгружать, и собирать/деплоить сразу несколько. Так в винде появилось аж три бекенда: DirectShow, WMF и GStreamer.

Так же придумали передавать пайплайны в плеер через урл с кастомной схемой:

player->setMedia(QUrl("gst-pipeline: videotestsrc ! qtvideosink");

Используя qtvideosink элемент в пайплайне можно было рендерить буфера в QML или QWidget.

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

Если вам захотелось использовать нестандартный пайплайн, то Qt Multimedia вам не подходит.

Это все еще детали реализации

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

Первым делом было понятно, что любой бекенд будет возвращать видео буфера — придумали QVideoFrame.

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

На свет появился QVideoRendererControl, который принимает в себя еще одно произведение искусства - QAbstractVideoSurface.

Абстрактный QAbstractVideoSurface требуется реализовать, чтобы принимать туда видео фреймы.

Далее подсмотрев, что можно передавать хендлер окна в бекенд, то можно добиться copy-free рендеринга. Придумали QVideoWindowControl и QVideoWidgetControl. ПотомQVideoWidgetControl оказался мало востребован, плохо реализуем, и вообще дублировал функционал.

Хотя все это публичный API, это все еще детали реализации.

Бунтарство

Но важное для рендеринга открытие, хоть через плечо, но смогли придумать — QAbstractVideoSurface.QVideoRendererControl удалось реализовать под все платформы.

Даже много лет назад для QML VideoOutput кто-то добавил скрытую возможность рисовать произвольные видео фреймы, без медиа плеера. Чем не попытка расколоть монолит? Чистейшее бунтарство...

class Source : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QAbstractVideoSurface *videoSurface READ videoSurface WRITE setVideoSurface)
public:
    QAbstractVideoSurface* videoSurface() const { return m_surface; }
    void setVideoSurface(QAbstractVideoSurface *surface)
    {
        m_surface = surface;
    }

    QAbstractVideoSurface *m_surface = nullptr;
};

Source src;
auto vo = rootObject->findChild<QDeclarativeVideoOutput *>("videoOutput");
vo->setSource(&src);
src.m_surface->present(videoFrame);

А знаете как рисовать прямо в QVideoWidget?

class VideoRenderer : public QVideoRendererControl
{
public:
    QAbstractVideoSurface *surface() const override
    {
        return m_surface;
    }

    void setSurface(QAbstractVideoSurface *surface) override
    {
        m_surface = surface;
    }

    QAbstractVideoSurface *m_surface = nullptr;
};

class MediaService : public QMediaService
{
public:
    MediaService(VideoRenderer *vr, QObject* parent = nullptr)
        : QMediaService(parent)
        , m_renderer(vr)
    {
    }

    QMediaControl* requestControl(const char *name) override
    {
        if (qstrcmp(name, QVideoRendererControl_iid) == 0)
            return m_renderer;

        return nullptr;
    }

    void releaseControl(QMediaControl *) override
    {
    }

    VideoRenderer *m_renderer = nullptr;
};

class MediaObject : public QMediaObject
{
public:
    MediaObject(VideoRenderer *vr, QObject* parent = nullptr)
        : QMediaObject(parent, new MediaService(vr, parent))
    {
    }
};

class VideoWidget : public QVideoWidget
{
public:
    // Moved to public
    bool setMediaObject(QMediaObject *object) override
    {
        return QVideoWidget::setMediaObject(object);
    }
};

VideoRenderer vr;

VideoWidget w;
w.show();

MediaObject mo(&vr);
w.setMediaObject(&mo);
vr.m_surface->present(videoFrame);

И потом пришло время дать доступ к внутренним реализациям QAbstractVideoSurface: так появились QVideoWidget::videoSurface, QGraphicsVideoItem::videoSurface и QDeclarativeVideoOutput::videoSurface

Это воспринималось довольно скептически. Считалось, что есть более эффективные способы рисования фреймов, чем QVideoWidget или QML VideoOutput.

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

Все должно работать из коробки

Как результат, эту концепцию перенесли даже в Qt Multimedia 6, переименовав QAbstractVideoSurface в QVideoSink, что дает возможность использовать рендеры из Qt Multimedia, а не копировать/реализовывать их самим.

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

Хотя надо просто знать тонкости настройки, тогда не больно (нет).

P.S. * Заглавная картинка - это пример с QRadioDataControl, и вряд ли найдется тот, кто когда-либо это использовал.

Если вы еще тут и, вдруг, интересен свободный и кроссплатформенный плеер на основе FFmpeg?

Комментарии (28)


  1. redneko
    26.12.2021 21:41

    Если вы еще тут, и вдруг интересен свободный и кроссплатформенный плеер на основе FFmpeg?

    Интересен. Пытался в своё время заставить ffplay выдувать через Decklink в SDI, но две вещи остановили:

    1. Нарастающий рассинхрон звука и видео при малейших ошибках в MPEG2TS или отсутствии потока по входу на некоторое время

    2. Долгое время ожидания первого кадра, порядка 6-7 секунд. От настроек кодека не зависит. Cinegy, Aja Bridge Live, да даже Dune укладываются в секунду-полторы.


    1. valbok Автор
      27.12.2021 13:55

      если ffplay не умеет, то плееры, на основе ffmpeg, тоже не сумеют. Эх, точно также и с gst. Сначало надо проверять через gst-launch...


      1. redneko
        27.12.2021 14:08

        FFmpeg (равно как и ffplay) умеют нативно работать с картами от Blackmagic, используя их API. Но вот эти два момента перечеркннули всю затею плейаута. Кодер на базе этой связки работает нормально, даже телетекст захватывает на ура из SDI (как в sd, так и VANC для HD)


  1. Paulus
    27.12.2021 02:20
    +2

    По опыту QtVLC часто неплохая альтернатива без всех этих хлопот.


    1. valbok Автор
      27.12.2021 13:53

      Вцелом, если просто проигрывать видео, то и QtMultimedia нормально, особенно если это линукс. К тому же QtVLC сильно старый, наверное ему тяжело в QML...


  1. Deranged
    27.12.2021 12:39
    +2

    Никогда не забуду, как я неделю искал причину "зависания" UI в QtQuick приложении. Как оказалось, из-за вызова g_source_remove (отключает обработку системных message в главном message loop) вместо g_source_destroy из ~QGstreamerBusHelperPrivate, по тому, что я имел глупость использовать QAudioDecoder в фоновом потоке (API-то вроде как синхронное, хотя из доков сложно понять). А QAudioDecoder пришлось использовать для самодельного вывода звука через QAudioOutput, по тому, что циклический вывод коротких звуков через QMediaPlayer вызывал серьезные утечки памяти с gstreamer бекендом.

    Это был второй по веселости баг, после 2х недель отладки другого трудноуловимого "повисания" приложения. Как выяснилось, из-за несовместимых форматов поверхностей и OpenGL'контекста. Ну правильно, проверять код возврата glMakeCurrent - это не по нашему. Не вышло - ну и хрен с ним. Сам же программист дурак, да? Не нашел в справке по QQuickWindow описание метода setDefaultAlphaBuffer? На! RTFM!

    Оххх, а сколько было веселья с переключением в полноэкранный режим. Особо умные разработчики решили, что это хорошая идея автоматом врубать "истинный" полноэкранный режим OpenGL когда геометрия клиентской части окна совпадает с геометрией экрана. Такие мелочи как контекстные меню и подсказки (которых из коробки не было и пришлось сделать самому), т.е. всплывающие окна поверх полноэкрана - разрабов не озаботили. А выглядит оно так себе. Поэтому сейчас используется элегантное решение с выезжанием окна на 1 пиксель за границы экрана, что бы случайно не включился полноэкранный режим. Такой borderless full screen по Qt-шному.

    Но это под Win. А под X11 у нас ведь xinerama, и если надо на несколько мониторов - это уже через XSendEvent с _NET_WM_FULLSCREEN_MONITORS. Ой, но ведь оно не всеми оконными менеджерами поддерживается, так что еще надо смотреть на XDG_CURRENT_DESKTOP. Даа, кроссплатформа что надо.

    Ох, а как земечательно сделан "многопоточный рендеринг" (QSG_RENDER_LOOP=threaded). Который на самом деле просто тормозит GUI поток и ждет пока там отрисует фоновый. Что по факту просто медленнее чем нарисовать кадр синхронно из GUI потока... Ух, а если еще в приложении несколько окон...

    А производительность рендеринга на больших scenegraph? Хочешь 100500 QQuickItem с автоматической обрезкой геометрии? Неее, это тебе надо QGraphicsScene. Там тебе и BSP-дерево, и растровое кеширование, и шрифты без глюков на масштабе, отличном от 1:1 (ох уж этот distance field). Но вот проблемка - оно же для QPainter... Ну ничего есть же QSGSimpleTextureNode, дальше пользователи платформы как-нить сообразят.

    А глюк c разваливающимся деревом...

    В общем, если бы у меня были злейшие враги, я бы от души пожелал им стать первоклассными разработчиками кроссплатформенных Desktop приложений на C++/Qt.


    1. valbok Автор
      27.12.2021 12:56

      А QAudioDecoder пришлось использовать для самодельного вывода звука через QAudioOutput, по тому, что циклический вывод коротких звуков через QMediaPlayer вызывал серьезные утечки памяти с gstreamer бекендом.

      Ну, скорее всего QAudioDecoder никогда и не работал, если учесть, что только wmf и gst реализовали это. И сам файл был закодированный, и нужно было его проиграть? QMediaPlayer правильный выбор тут, а утечки, это наверное было очень давно.


    1. valbok Автор
      27.12.2021 13:04

      (API-то вроде как синхронное, хотя из доков сложно понять)

      Что-то мне подсказывает, что это не совсем так. И не следует рассчитывать, что API в других потоках будут работать. Лучше создавать и использовать их на главном, но через сигналы.


      1. Deranged
        27.12.2021 13:20

        Грузить UI поток перекачкой семпл-буферов не хотелось. Сигналы - лишние события и задержки. UI высоконагруженный, не хотелось, что бы воспроизведение аудио заикалось до окончания декодирования. Оно работает нормально, только нельзя уничтожать QAudioDecoder. Утечки QMediaPlayer - в 5.9 оно точно есть, а дальше не знаю. Это, конечно, относительно давно, только вот обновить версию QT для большого приложения занятие не из простых. Нужно выделять время на обкатку новых багов.


        1. valbok Автор
          27.12.2021 14:04

          Оно работает нормально, только нельзя уничтожать QAudioDecoder.

          О, это называется повезло. Но этот класс мертворожденный и никогда не использовался по-серьезному, он то реализован только в gst и wmf...И его благополучно удалось похоронить и не откапывать. Надеюсь не воскреснет.

          Уточнение про

          (API-то вроде как синхронное, хотя из доков сложно понять)

          Там внутри может быть куча тредов и так, и да, такого рода АПИ как QAudioOutput, можно и нужно юзать на соседних потоках, чтобы птенциально не было прерываний. Но вот ожидать повышение производительности в таких классах как QMediaPlayer, то наверное не стоит.


    1. valbok Автор
      27.12.2021 13:08

      Не нашел в справке по QQuickWindow описание метода setDefaultAlphaBuffer? 

      Зависания были в том, что не рендерилось вообще, типа завис UI, или рендерилось черным? И useAlpha помогло? Там было много блендинга?


      1. Deranged
        27.12.2021 13:16
        +1

        Переставало рендерится после показа модального диалога, для которого у окна была включена прозрачность. А у основного окна не была. Оставался последний нарисованный кадр в окне, который стирался белым при утаскивании окна за границу экрана. При этом внятно юзеры сформулировать причину "зависания" не смогли. Типа что-то сделали и оно перестало обновлять окно. При этом всплывало только на Linux. Виндузовый opengl32.dll такое прощает.


    1. valbok Автор
      27.12.2021 13:15

      Поэтому сейчас используется элегантное решение с выезжанием окна на 1 пиксель за границы экрана, что бы случайно не включился полноэкранный режим. Такой borderless full screen по Qt-шному.

      А есть доки на эту тему?

       т.е. всплывающие окна поверх полноэкрана - разрабов не озаботили. А выглядит оно так себе

      Такой костыль нужен был из-за этой проблемы? Это какая платформа? Может там требовали оверлей окна, другие фреймбаферы?

      А, это винда...


      1. Deranged
        27.12.2021 13:42
        +1

        Есть QWindow::showFullScreen и он врубает настоящий полноэкранный режим. И он так же врубается автоматом, если у окна отключить рамку и задать геометрию под экран. В этом режиме попытки показать поверх полноэкранного приложения другие окна выглядят так себе. Все мерцает, появляется/пропадает. В общем такое. Попробуйте запустить старую полноэкранную игру, а потом поверх неё вытащить другое окно. Поэтому сейчас в моде borderless full screen (просто top level окно с геометрией на весь экран).


    1. valbok Автор
      27.12.2021 13:22

      если надо на несколько мониторов - это уже через XSendEvent с _NET_WM_FULLSCREEN_MONITORS. Ой, но ведь оно не всеми оконными менеджерами поддерживается, так что еще надо смотреть на XDG_CURRENT_DESKTOP

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


    1. valbok Автор
      27.12.2021 13:33

      SG_RENDER_LOOP=threaded). Который на самом деле просто тормозит GUI поток и ждет пока там отрисует фоновый. Что по факту просто медленнее чем нарисовать кадр синхронно из GUI потока.

      Интересно,

      This offers significant performance improvements, but imposes certain restrictions on where and when interaction with the scene graph can happen.

      2. The render thread prepares to draw a new frame and initiates a block on the GUI thread.

      4. GUI thread is blocked.


      1. Deranged
        27.12.2021 13:47

        По факту оно предлагает существенное падение производительности :) Очень специфическое у кого-то в QT представление о параллелелизме. Выполняем поток, планируем вызов функции в другом потоке, а потом ждем в 1м пока второй поток не выполнит функцию. Это медленнее хотя бы за счет необходимости переключения контекста потока и синхронизации туда-сюда-обратно. Я бы еще понял, если бы scene graph рендерился параллельно в несколько потоков, или если бы GUI поток продолжал бы выполнение в процессе отрисовки, т.е. следующий кадр готовился бы, пока рисуется текущий. Но по факту ничего такого нет, это просто пыль в глаза. Типа вот, смотрите - у нас многопоточность!


        1. valbok Автор
          27.12.2021 15:14

          Кажется, там все сложнее. И да, насколько помню, когда-то лимит был 30 фпс, потом 60, и уже надеюсь такой хардлимит убрали.
          И разные платформы реагируют по-разному, обычно гуи и мейн тред совпадает, но бывает и нет. Но думаю есть идея, что блокировать мейн тред, когда гуи рисуется - это дизайн, и могут сказать, что не стоит расчитывать на ускорение рисования, переводя сам рендеринг в отдельный поток.


          1. Deranged
            27.12.2021 21:58

            Я тоже думал что - ну не может же быть, нафига так делать, в чем вообще смысл. Но по факту я видел в отладчике именно это. Когда я понял что именно происходит, я был, так сказать, удивлен. У меня есть теория, что таким образом сделана изоляция состояния OpenGL, там она thread local. Не могли видимо, найти какой-нибудь глюк, состояние-то между вызовами отрисовки сохраняется. И таким вот образом запатчили - просто выкинули draw call'ы в фоновый поток. Но работает оно синхронно. Никакого профита по производительности такой подход дать в принципе не может.


            1. valbok Автор
              27.12.2021 23:10

              Думаю тут стоит подчеркнуть,

              я видел в отладчике именно это.

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

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

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


    1. valbok Автор
      27.12.2021 13:42

      Хочешь 100500 QQuickItem с автоматической обрезкой геометрии?

      Это как?

       Неее, это тебе надо QGraphicsScene. Там тебе и BSP-дерево, и растровое кеширование, и шрифты без глюков на масштабе, отличном от 1:1 (ох уж этот distance field).

      Это про то, что если много айтемов, то виджетам таке проще хендлить?

      Ну ничего есть же QSGSimpleTextureNode

      Всмысле, надо самому писать?


      1. Deranged
        27.12.2021 13:56
        +1

        Ну, какую-нибудь диаграммку, например, нарисовать. Из блоков и связей. Например, из 100к блоков 100к связей. И блоки какие-нибудь не простые, а с текстом, заголовками, входами/выходами. Если перевести в полигоны - для OpenGL это семечки. Современные 3D модельки содержат на порядки больше геометрии. Но вот если это описывать через QQuickItem'ы.... Так что тут или glBegin и вперед низкоуровневые draw call'ы, или чего-нибудь другое. Смешно, что QGraphicsScene, будучи полностью software rendered, такое вывозит без труда. Но его напрямую вывести в QtQuick нельзя. Нужен вьюпорт (прямоугольник, ездящий по диаграмме - какую часть рисовать). А Flickable подсунуть Image - не выйдет. Растеризовать-то надо только часть. В общем, есть сложности стыковки.


        1. valbok Автор
          27.12.2021 15:28

           Так что тут или glBegin и вперед низкоуровневые draw call'ы, или чего-нибудь другое.

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

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


    1. valbok Автор
      27.12.2021 13:43

      А глюк c разваливающимся деревом...

      При рендеринге? Каким деревом?


      1. Deranged
        27.12.2021 13:57
        +1

        TreeView в QtQuickControls 1.0 - такое себе.


    1. valbok Автор
      27.12.2021 13:46

      В общем, если бы у меня были злейшие враги, я бы от души пожелал им стать первоклассными разработчиками кроссплатформенных Desktop приложений на C++/Qt.

      Ну, первоклассные....они даже не обидятся.


    1. IGR2014
      27.12.2021 20:07
      +1

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

      Это вроде прикол самого OpenGL. У меня в pet-проекте и без Qt то-же самое происходит


      1. Deranged
        27.12.2021 21:53

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