Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Hordi от Декабрь 25, 2008, 16:06



Название: Segfault при отрисовке QImage в потоке...
Отправлено: Hordi от Декабрь 25, 2008, 16:06
Столкнулся с неприятной вещью... Создаю в потоке QImage и когда на нем рисую текст через drawText - 1 к 10 программа падает... Замена отрисовки текста на drawImage такого эффекта не дает, к аналогичной проблеме приводит вызов из потока функций из QFontMetrics... Я уже весь свой код 10 раз пересмотрел и начал сомневаться, что проблема у меня...

Код вроде этого:

Код:

void threadFunc()
{
    QImage img(100,100,..._RGB16);
   
    QPainter pnt(&img);
    pnt.drawText(QPoint(...),"xxx");
}



Название: Re: Sigfoult при отрисовке QImage в потоке...
Отправлено: pastor от Декабрь 25, 2008, 16:13
Поидее все должно быть ОК. А какая версия Qt?


Название: Re: Sigfoult при отрисовке QImage в потоке...
Отправлено: Hordi от Декабрь 25, 2008, 16:51
4.4.3


Название: Re: Sigfoult при отрисовке QImage в потоке...
Отправлено: BRE от Декабрь 25, 2008, 17:42
Проверил у себя. Qt-4.4.3.
Программа не падает, но перестает отрисовываться GUI и Х в консоль сыпет:
Цитировать
X Error: RenderBadGlyphSet (invalid GlyphSet parameter) 167
  Extension:    149 (RENDER)
  Minor opcode: 25 (RenderCompositeGlyphs32)
  Resource id:  0x0
Если с текстом не работать, то все Ок.
Похоже на баг Qt.  ???


Название: Re: Sigfoult при отрисовке QImage в потоке...
Отправлено: BRE от Декабрь 25, 2008, 17:56
Вот тестовый проект.
Попробуйте у себя.


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: BRE от Декабрь 25, 2008, 18:27
Если в контексте нити создать QFont-объект и установить его в качестве текущего в QPainter, то вроде заработало.
Код
C++ (Qt)
void DrawThread::run()
{
QImage img( 300, 300, QImage::Format_RGB16 );
 
QFont font( "Arial", 12 );
 
QPainter p( &img );
p.setFont( font );
p.drawText( QPoint( 10, 10 ), "Test text" );
p.drawLine( QPoint( 20, 20 ), QPoint( 280, 280 ) );
}
 


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: pastor от Декабрь 25, 2008, 18:37
Воспроизвел краш и в линуксе и в винде. Предложеный BRE вариант работает нормально.

Qt 4.4.3, Windows XP, openSuse 11


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: BRE от Декабрь 25, 2008, 18:42
Ну все таки это костыль, IMHO.


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: ритт от Декабрь 25, 2008, 18:44
да, похоже на баг Qt.
необходимо отрапортовать Троллям...только у них сейчас каникулы до января...


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: pastor от Декабрь 25, 2008, 18:45
Ну все таки это костыль, IMHO.


+1

Нужно писать баг репорт


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: ритт от Декабрь 25, 2008, 18:47
Ну все таки это костыль, IMHO.

но это правильный костыль :)
только я вот не помню для какой версии была заявлена поддержка рисования в негуёвом (о как) потоке...ткните в доки кто-нибудь? у меня полнотекстовый поиск по ассистанту (люцена) почему-то не фунциклирует


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: BRE от Декабрь 25, 2008, 18:52
Раздел Paint System, там
Цитировать
Image
The QImage class provides a hardware-independent image representation which is designed and optimized for I/O, and for direct pixel access and manipulation. QImage supports several image formats including monochrome, 8-bit, 32-bit and alpha-blended images.
One advantage of using QImage as a paint device is that it is possible to guarantee the pixel exactness of any drawing operation in a platform-independent way. Another benefit is that the painting can be performed in another thread than the current GUI thread.


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: Hordi от Декабрь 25, 2008, 19:41
Вобщем повторяется если одновременно че-нить рисовать на widgete и в потоке че-нить делать... В аттаче похожий проектик, только я не QImage рисую, а просто из потока вызываю QFontMetrics.height()... Падает уверенно.

Я ща запулю Троллтечу письмо - все-таки коммерческая поддержка должна работать...


Название: Re: Sigfault при отрисовке QImage в потоке...
Отправлено: BRE от Декабрь 25, 2008, 20:04
Вобщем повторяется если одновременно че-нить рисовать на widgete и в потоке че-нить делать... В аттаче похожий проектик, только я не QImage рисую, а просто из потока вызываю QFontMetrics.height()... Падает уверенно.

Я ща запулю Троллтечу письмо - все-таки коммерческая поддержка должна работать...
У меня не падает, в консоль ничего не выдает.  ???
Что бросилось в глаза, у тебя _fm создается в контексте GUI, а height() ты дергаешь уже из контекста нити.


Название: Re: Segfault при отрисовке QImage в потоке...
Отправлено: Hordi от Декабрь 26, 2008, 11:58
Цитировать
У меня не падает, в консоль ничего не выдает. 
Что бросилось в глаза, у тебя _fm создается в контексте GUI, а height() ты дергаешь уже из контекста нити.
Да, но ведь в доке написано, что все функции QFontMetrics reentrant! Я пробовал из потока обращаться к QApplication::font() - также падает. Обойти конечно можно, хотя бы способом, указанным выше (QFont в потоке), но QFontMetrics содержит массу кода по поддержке многопоточности - он переинициализироваться должен если его вызывают не из потока создания, поэтому пусть костыли делают в Троллтече... Ну или умное объяснение такого поведения хотя бы наваяют :)


Название: Re: Segfault при отрисовке QImage в потоке...
Отправлено: Hordi от Декабрь 26, 2008, 12:03
Хотя конечно reentrant не означает потокобезопасность...


Название: Re: Segfault при отрисовке QImage в потоке...
Отправлено: hordi1 от Декабрь 30, 2008, 10:44
Отправил проблему в суппорт. Ответы коммерческой поддержки меня обрадовали:)
Ответ номер раз:

Painting from outside the GUI thread onto a QWidget or QPixmap is not supported.  You will need to emit a signal from the thread and have the GUI thread do the painting for you.  You can find more information about this here:

http://doc.trolltech.com/4.4/threads.html#painting-in-threads


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

Systems without FontConfig cannot render text outside the GUI thread even if it is onto a QImage.  Font metrics fall into this category.
You can test if font rendering can be used outside the GUI thread with the QFontDatabase::supportsThreadedFontRendering API.

I did take a look at the example.  I appreciate you writing a simple example that allows us to pinpoint the problem rather quickly.


На это письмо опять было отвечено, что FontConfig умеет место быть и QFontDatabase::supportsThreadedFontRendering возвращает TRUE. Ждем третьего ответа... :)


Название: Re: Segfault при отрисовке QImage в потоке...
Отправлено: Admin от Декабрь 30, 2008, 11:38
поддержка напоминает Яндекс
там есть такой чувак Платон

пишешь:
Че с моим
так на 1 сообщение пишет - типа посмотрим
и так по циклу

то есть что бы обратить на себя внимание нужно 3-4 письма. Это типа барьер, если ты не отстал - то достоин внимания не студента, а дорогого девелопера.


Название: Re: Segfault при отрисовке QImage в потоке...
Отправлено: Dendy от Декабрь 31, 2008, 19:30
Хотя конечно reentrant не означает потокобезопасность...

Термины reentrant и threadsafe не для классов, а для методов классов и отдельных функций. Часть методов могут быть threadsafe, часть - reentrant. Если все методы threadsafe - класс для удобства называет threadsafe тоже.

Вы всё верно сказали в предыдущем посте. QFontInfo, QFont и QFontMetrics используют атомарные операции для конструкторов и операций присвоения, другими словами они потокобезопастны при использовании локальных копий.

Пишу сейчас проект, который рисует текст с фоне в картинку - несколько раз вывалился с таким же сегфолтом. Как всегда грешил на свои кривые руки и искал ошибку по своему коду. После того как посмотрел исходники QFont понял что подобной ошибки - неправильного использования семейства QFont* - в клиентском коде не может быть в принципе. Значит проблема в самой Qt. Баг-репорт отправить не успел, надеюсь Тролли среагируют на ваше письмо и добавят в багзиллу. Если нет - пишите сюда, будем долбить их вместе.


Название: Re: Segfault при отрисовке QImage в потоке...
Отправлено: hordi1 от Январь 05, 2009, 11:40
Троллтечи согласились с ошибкой, кстати зарепорчена была ранее - проблема именно в фонто-зафисимых классах. Пофиксено будет в 4.4.4.

http://trolltech.com/developer/task-tracker/index_html?id=217988&method=entry