Discussion:
Threaded font work
Gerald Brandt
2014-02-13 04:16:24 UTC
Permalink
Hi,

I have an app that potentially does a lot of font stuff every key press. Basically all it does is GetTextExtent in order to perform word wrapping.

At times, the app can take multiple seconds to do its work. I decided to move my font measurement into a thread to help free up the main GUI.

Knowing some stuff wouldn't work in a thread, I created wxCommandEvents to pass some work back to the main process. In the event loop, I do this:

void cEditorCtrl::OnLayoutSetBaseFont(wxCommandEvent &event)
{
UNUSED_ARGUMENT(event) ;

cEditorRender *render = mLayouts[mUseLayout] ;

wxFont font = render->GetBaseFont() ; // get the base font of the editor
if(mWordWrap == true)
{
font.Scale(render->mFontScale) ;
}
mLayoutDC.SelectObject(mLayoutBitmap) ;
mLayoutDC.SetFont(font) ;

}

to set a base font for the DC. mLayoutBitmap and mLayoutDC are created in the class.

I get a gtk error on the SetFont... occasionally. I'm guaranteed a crash if I hold down a key, calling this event handler for every keystroke. The error is:

(WordTsar:12826): Gtk-CRITICAL **: IA__gtk_text_attributes_ref: assertion 'values != NULL' failed

(WordTsar:12826): Gtk-CRITICAL **: IA__gtk_text_attributes_ref: assertion 'values != NULL' failed
WordTsar: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.

Any idea why this happens?

Gerald

ps: I moved the SelectObject into the class Init, and got a different error, usually at the same rate as mentioned above:

*** Error in `./WordTsar': double free or corruption (fasttop): 0x00007fd78c008ed0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x80996)[0x7fd7a0bd8996]
/usr/lib/x86_64-linux-gnu/libpango-1.0.so.0(pango_font_description_free+0x2e)[0x7fd7a272bc4e]
./WordTsar[0x6040a3]
./WordTsar[0x445864]
./WordTsar[0x45b5db]
./WordTsar[0x4ab79e]
./WordTsar[0x4aa8e7]
./WordTsar[0x4aa561]
./WordTsar[0x4aa428]
./WordTsar[0x4aa22f]
./WordTsar[0x7842e9]
./WordTsar[0x784c40]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x7f6e)[0x7fd7a0f27f6e]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fd7a0c529cd]
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Gerald Brandt
2014-02-13 04:47:27 UTC
Permalink
Seems I may have answered my own question. I added code to set a flag when the event was completed doing its work, and my thread waits until the flag is set before it continues. The problem is either gone, or MUCH harder to hit.

Gerald
Post by Gerald Brandt
Hi,
I have an app that potentially does a lot of font stuff every key press. Basically all it does is GetTextExtent in order to perform word wrapping.
At times, the app can take multiple seconds to do its work. I decided to move my font measurement into a thread to help free up the main GUI.
void cEditorCtrl::OnLayoutSetBaseFont(wxCommandEvent &event)
{
UNUSED_ARGUMENT(event) ;
cEditorRender *render = mLayouts[mUseLayout] ;
wxFont font = render->GetBaseFont() ; // get the base font of the editor
if(mWordWrap == true)
{
font.Scale(render->mFontScale) ;
}
mLayoutDC.SelectObject(mLayoutBitmap) ;
mLayoutDC.SetFont(font) ;
}
to set a base font for the DC. mLayoutBitmap and mLayoutDC are created in the class.
(WordTsar:12826): Gtk-CRITICAL **: IA__gtk_text_attributes_ref: assertion 'values != NULL' failed
(WordTsar:12826): Gtk-CRITICAL **: IA__gtk_text_attributes_ref: assertion 'values != NULL' failed
WordTsar: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.
Any idea why this happens?
Gerald
*** Error in `./WordTsar': double free or corruption (fasttop): 0x00007fd78c008ed0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x80996)[0x7fd7a0bd8996]
/usr/lib/x86_64-linux-gnu/libpango-1.0.so.0(pango_font_description_free+0x2e)[0x7fd7a272bc4e]
./WordTsar[0x6040a3]
./WordTsar[0x445864]
./WordTsar[0x45b5db]
./WordTsar[0x4ab79e]
./WordTsar[0x4aa8e7]
./WordTsar[0x4aa561]
./WordTsar[0x4aa428]
./WordTsar[0x4aa22f]
./WordTsar[0x7842e9]
./WordTsar[0x784c40]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x7f6e)[0x7fd7a0f27f6e]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fd7a0c529cd]
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
or visit http://groups.google.com/group/wx-users
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Vadim Zeitlin
2014-02-13 21:55:02 UTC
Permalink
On Wed, 12 Feb 2014 22:16:24 -0600 Gerald Brandt wrote:

GB> I have an app that potentially does a lot of font stuff every key
GB> press. Basically all it does is GetTextExtent in order to perform word
GB> wrapping.

Perhaps you'll find GetPartialTextExtents() useful. It's vastly more
efficient than calling GetTextExtent() multiple times.

GB> At times, the app can take multiple seconds to do its work. I decided
GB> to move my font measurement into a thread to help free up the main GUI.

This isn't really going to work, fonts are GUI objects and can only be
used safely from the main thread.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Gerald Brandt
2014-02-13 22:29:10 UTC
Permalink
Post by Vadim Zeitlin
GB> I have an app that potentially does a lot of font stuff every key
GB> press. Basically all it does is GetTextExtent in order to perform word
GB> wrapping.
Perhaps you'll find GetPartialTextExtents() useful. It's vastly more
efficient than calling GetTextExtent() multiple times.
If I recall, GetPartialTextExtents works great, but with some fonts under Linux (Ubuntu) is may return less widths than actual characters in the string. Something combines letters into ligatures (e.g.: ij into a single character), so if I have the string "this ij a test", instead of 14 widths, I get 13 widths, and no indicator of which characters it combined.
Post by Vadim Zeitlin
GB> At times, the app can take multiple seconds to do its work. I decided
GB> to move my font measurement into a thread to help free up the main GUI.
This isn't really going to work, fonts are GUI objects and can only be
used safely from the main thread.
Yeah, figured that out. I created events to get the main thread to do the work. The GUI is still more responsive this way, but I take a speed hit.
Post by Vadim Zeitlin
Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Loading...