Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Гурман от Май 28, 2015, 00:47



Название: Странное падение при рендеринге SVG в QImage
Отправлено: Гурман от Май 28, 2015, 00:47
Внутри наследника QWidget в paintEvent() имею такой код (поискал в Инете - везде сделано аналогично):
Код:
    QImage image(size(), QImage::Format_RGB32);
    QPainter p( &image );
    svg->render( &p ); // svg - это QSvgRenderer, который точно содержит то, что нужно
на последней строке падает где-то глубоко внутри, в функции comp_func_SourceOver_sse2(...).

Почти идентичный код из svgview.cpp (пока руки не дошли проверить его работу), пример из самого Qt, также как и у меня выполняется в paintEvent() наследника QWidget:
Код:
buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
            QPainter p(&buffer);
            p.setViewport(0, 0, width(), height());
            p.eraseRect(0, 0, width(), height());
            doc->render(&p);
То есть, существенной разницы с моим вариантом не вижу. Пробовал и Format_ARGB32_Premultiplied, и вьюпорт задавать, и прямоугольник очищать - также падает.

При этом:
Код:
    QPainter p( this ); // рисуем на QWidget
    svg->render( &p );
работает, но мне нужно рисовать на QImage, а не QWidget.

Нашел похожую тему в Сети - при сборке minGW тоже падает в аналогичном месте. Пишут, что при сборке MSVS работает. Но мне надо обязательно GNU, мультиплатформенность...

Кто-нибудь ещё сталкивался? Обходы есть?


Название: Re: Странное падение при рендеринге SVG в QImage
Отправлено: gil9red от Май 28, 2015, 08:08
Код:
    QPainter p( this ); // рисуем на QWidget
    svg->render( &p );
работает, но мне нужно рисовать на QImage, а не QWidget.

Код
C++ (Qt)
QImage im;
...
QPainter p( &im );
svg->render( &p );
 


Название: Re: Странное падение при рендеринге SVG в QImage
Отправлено: Гурман от Май 28, 2015, 13:07
Спасибо, кэп, а посмотреть на первое моё сообщение, где тоже самое написано? Или якобы проблема в том, что QImage размер и тип заданы? Нифига. Проблема не в этом, даже не буду пробовать. Проблема в svg->render() внутри paintEvent(). Сделал рисование в отдельной функции, вызываемой только при изменении цвета или самого svg, ис п преобразованием в QPixmap, а в paintEvent() только drawPixmap(). Так ничего не валится, работает.

Странно, поскольку в примере из Qt рендеринг делается в paintEvent(), но проверять его работу некогда.


Название: Re: Странное падение при рендеринге SVG в QImage
Отправлено: Гурман от Сентябрь 15, 2015, 20:39
up

Снова влип в эту дырку. При рендеринге SVG, выполняемом в обработчике dropEvent(), глухо падает в глубине... Исследование показало, что в 4.7 (как минимум) есть баг при восстановлении стека, если рисование с SSE2 инструкциями было вызвано из отдельной нити. Так и есть - dropEvent() вызывается не в основной нити, и тогда падает. А при прямых вызовах в основной нити приложения всё отлично работает. Возможно, в 4.8 это было уже исправлено, поскольку все ссылки на дырку содержат версию 4.7. Но в ней можно сделать обход с помощью metaObject()->invokeMethod(...,Qt::QueuedConnection,...). В моём случае этот рендеринг выполняется очень редко, поэтому такой способ вызова меня вполне устраивает. Может кому-нибудь пригодится, если тоже лбом стукнется.

Хотелось, бы, чтобы кто-нибудь подтвердил, что в 4.8 и старше этого бага уже нет.


Название: Re: Странное падение при рендеринге SVG в QImage
Отправлено: GreatSnake от Сентябрь 16, 2015, 10:17
Так и есть - dropEvent() вызывается не в основной нити
Это как это ???


Название: Re: Странное падение при рендеринге SVG в QImage
Отправлено: Гурман от Сентябрь 16, 2015, 13:50
Так и есть - dropEvent() вызывается не в основной нити
Это как это ???

Глубоко не копал, но если в перегруженном методе QGraphicsScene::dropEvent( QGraphicsSceneDragDropEvent *event ) вызвать любую функцию GUI, то будет падение, как при вызове из параллельной нити. Достаточно там просто QMessageBox::warning() вызвать, и на нём рухнет. Может быть, это та же дырка версии 4.7, ковырять некогда.

Впрочем, сейчас проверил  вызовом  qDebug()<<QThread::currentThreadId(); - идентификатор нити один и тот же в её конструкторе и в обработчике dropEvent(). Но тем не менее, эффект имеет место.