diff options
author | Tor Lillqvist <tml@iki.fi> | 2013-03-31 20:39:01 +0300 |
---|---|---|
committer | Tor Lillqvist <tml@iki.fi> | 2013-03-31 21:55:10 +0300 |
commit | 41a70cc2d32dde3e2c76a6f1d4f3dd1b32bb1c02 (patch) | |
tree | 4dc2a1023e0f33a1fb9a288a91cf3245425e0e25 /vcl/ios/iosinst.cxx | |
parent | 14d909632e208fa1b3a27212633cf3607ccf1136 (diff) |
Try redrawing in multiple phases to avoid blocking the UI thread too long
When initially calling lo_render_windows() from a redrawRect(), just
post the user event asking for a redraw of the (headless) windows, and
return without actually drawing anything to the context.
Then when the RenderWindows() callback for that user event eventually
gets called (which during startup and/or loading of a document might
be several seconds later, as there is lots of other activity going on
also as "user events"), ask the UI thread for a fresh redraw, and wait
for lo_render_windows() in that phase to signal the actual redraw of
the "headless" windows into the context.
Unfortunately this doesn't work well enough. It is not a good idea to
not draw anything in response to a drawRect() it seems. The affected
rectangle gets initialised to black. So there is now irritating
flashing. One sees an almost ready document (and the UI elements which
still are there), but then it goes away for some time before finally
re-appearding. Quite silly. So I will revert this, and I am committing
it just to keep the code for reference in git.
Change-Id: I9ee490345f093d80113c36f9e3268cab5a810dd0
Diffstat (limited to 'vcl/ios/iosinst.cxx')
-rw-r--r-- | vcl/ios/iosinst.cxx | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/vcl/ios/iosinst.cxx b/vcl/ios/iosinst.cxx index 4767c46e3e12..444d1acea47c 100644 --- a/vcl/ios/iosinst.cxx +++ b/vcl/ios/iosinst.cxx @@ -107,6 +107,8 @@ IosSalInstance::IosSalInstance( SalYieldMutex *pMutex ) rc = pthread_mutex_init( &m_aRenderMutex, NULL ); SAL_WARN_IF( rc != 0, "vcl.ios", "pthread_mutex_init failed: " << strerror( rc ) ); #endif + + m_aRenderWindowsState.state = IDLE; } IosSalInstance::~IosSalInstance() @@ -279,7 +281,7 @@ void lo_set_view_size(int width, int height) viewHeight = height; } -IMPL_LINK( IosSalInstance, RenderWindows, RenderWindowsArg*, arg ) +IMPL_LINK_NOARG( IosSalInstance, RenderWindows ) { int rc; @@ -290,6 +292,19 @@ IMPL_LINK( IosSalInstance, RenderWindows, RenderWindowsArg*, arg ) NSLog(@"RenderWindows: mutex locked"); + m_aRenderWindowsState.state = WAITING; + + /* We need to poke the UI thread to do drawRect() which calls + * lo_render_windows() which signals the condition so we can + * continue. + */ + lo_damaged( m_aRenderWindowsState.rect ); + + while (m_aRenderWindowsState.state != GOAHEAD) { + rc = pthread_cond_wait( &m_aRenderCond, &m_aRenderMutex ); + SAL_WARN_IF( rc != 0, "vcl.ios", "pthread_cond_wait failed: " << strerror( rc ) ); + } + NSDate *a = [NSDate date]; for( std::list< SalFrame* >::const_iterator it = getFrames().begin(); @@ -299,7 +314,7 @@ IMPL_LINK( IosSalInstance, RenderWindows, RenderWindowsArg*, arg ) SalFrameGeometry aGeom = pFrame->GetGeometry(); CGRect bbox = CGRectMake( aGeom.nX, aGeom.nY, aGeom.nWidth, aGeom.nHeight ); if ( pFrame->IsVisible() && - CGRectIntersectsRect( arg->rect, bbox ) ) { + CGRectIntersectsRect( m_aRenderWindowsState.rect, bbox ) ) { const basebmp::BitmapDeviceSharedPtr aDevice = pFrame->getDevice(); CGDataProviderRef provider = @@ -316,11 +331,11 @@ IMPL_LINK( IosSalInstance, RenderWindows, RenderWindowsArg*, arg ) NULL, false, kCGRenderingIntentDefault ); - CGContextDrawImage( arg->context, bbox, image ); + CGContextDrawImage( m_aRenderWindowsState.context, bbox, image ); } } - arg->done = true; + m_aRenderWindowsState.state = IDLE; rc = pthread_cond_signal( &m_aRenderCond ); SAL_WARN_IF( rc != 0, "vcl.ios", "pthread_cond_signal failed:" << strerror( rc ) ); @@ -354,16 +369,25 @@ void lo_render_windows( CGContextRef context, CGRect rect ) NSLog(@"lo_render_windows: mutex locked"); - IosSalInstance::RenderWindowsArg arg = { false, context, rect }; - Application::PostUserEvent( LINK( pInstance, IosSalInstance, RenderWindows), &arg ); - - while (!arg.done) { - rc = pthread_cond_wait( &pInstance->m_aRenderCond, &pInstance->m_aRenderMutex ); - SAL_WARN_IF( rc != 0, "vcl.ios", "pthread_cond_wait failed: " << strerror( rc ) ); + if (pInstance->m_aRenderWindowsState.state == IosSalInstance::IDLE) { + pInstance->m_aRenderWindowsState.state = IosSalInstance::PENDING; + pInstance->m_aRenderWindowsState.context = context; + pInstance->m_aRenderWindowsState.rect = rect; + Application::PostUserEvent( LINK( pInstance, IosSalInstance, RenderWindows ) ); + } else { + pInstance->m_aRenderWindowsState.context = context; + pInstance->m_aRenderWindowsState.rect = CGRectUnion( pInstance->m_aRenderWindowsState.rect, rect ); + if (pInstance->m_aRenderWindowsState.state == IosSalInstance::WAITING) { + pInstance->m_aRenderWindowsState.state = IosSalInstance::GOAHEAD; + pthread_cond_signal( &pInstance->m_aRenderCond ); + while (pInstance->m_aRenderWindowsState.state != IosSalInstance::IDLE) { + rc = pthread_cond_wait( &pInstance->m_aRenderCond, &pInstance->m_aRenderMutex ); + SAL_WARN_IF( rc != 0, "vcl.ios", "pthread_cond_wait failed: " << strerror( rc ) ); + } + } } - NSLog(@"lo_render_windows: mutex unlocked"); - + NSLog(@"lo_render_windows: unlocking mutex"); rc = pthread_mutex_unlock( &pInstance->m_aRenderMutex ); SAL_WARN_IF( rc != 0, "vcl.ios", "pthread_mutex_unlock failed: " << strerror( rc ) ); |