diff options
author | Tor Lillqvist <tml@iki.fi> | 2013-03-30 01:39:22 +0200 |
---|---|---|
committer | Tor Lillqvist <tml@iki.fi> | 2013-03-30 08:41:33 +0200 |
commit | d08a58a6845a3423d7d2919e157d1b205d68db51 (patch) | |
tree | 2de6aaf29982ff471b32119c8378d4a17faef64d | |
parent | 62f6e67f6b0986208cf1030e265b51f1bf154bc7 (diff) |
Render the "headless" frames to the UI view in the LO thread
We used to render them in the app main (GUI) thread, which is
dangerous, accessing the headless frames in one thread while the LO
thread (where the "main" LibreOffice code is running) might be
updating and changing them.
This fixes some problems like that part of the document did not show
up. If I would test the app on a multi-core iPad, presumably I would
have seen even more problems.
But this also introduces new problems: Now the UI doesn't appear
incrementally (for instance, with an actually progressing progress bar
during the loading of the document) as it used to. Now it all appeads
all of a sudden, everything at once. Which would be fine if it
happened very quickly after starting the app, but it doesn't... on the
original iPad it takes half a minute.
Change-Id: I04068e0d884aa5cb86acefa76449aac4e081b193
-rw-r--r-- | vcl/inc/ios/iosinst.hxx | 19 | ||||
-rw-r--r-- | vcl/ios/iosinst.cxx | 78 |
2 files changed, 66 insertions, 31 deletions
diff --git a/vcl/inc/ios/iosinst.hxx b/vcl/inc/ios/iosinst.hxx index d5d6b8c378ba..654bd58d180f 100644 --- a/vcl/inc/ios/iosinst.hxx +++ b/vcl/inc/ios/iosinst.hxx @@ -20,6 +20,14 @@ #ifndef IOS_SALINST_H #define IOS_SALINST_H +#include <pthread.h> + +#include <premac.h> +#include <CoreGraphics/CoreGraphics.h> +#include <postmac.h> + +#include <tools/link.hxx> + #include "headless/svpinst.hxx" #include "headless/svpframe.hxx" @@ -37,12 +45,21 @@ public: SalFrame* CreateFrame( SalFrame* pParent, sal_uLong nStyle ); SalFrame* CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle ); - virtual bool AnyInput( sal_uInt16 nType ); + // virtual bool AnyInput( sal_uInt16 nType ); SalFrame *getFocusFrame() const; void damaged( IosSalFrame *frame, const basegfx::B2IBox& rDamageRect); + + typedef struct { + CGContextRef context; + CGRect rect; + } RenderWindowsArg; + DECL_LINK( RenderWindows, RenderWindowsArg* ); + + pthread_mutex_t m_aRenderMutex; + pthread_cond_t m_aRenderCond; }; #endif // IOS_SALINST_H diff --git a/vcl/ios/iosinst.cxx b/vcl/ios/iosinst.cxx index 97159180d11f..b2c151654f55 100644 --- a/vcl/ios/iosinst.cxx +++ b/vcl/ios/iosinst.cxx @@ -87,13 +87,19 @@ IosSalInstance *IosSalInstance::getInstance() IosSalInstance::IosSalInstance( SalYieldMutex *pMutex ) : SvpSalInstance( pMutex ) { - + pthread_cond_init( &m_aRenderCond, NULL ); + pthread_mutex_init( &m_aRenderMutex, NULL ); + pthread_mutex_lock( &m_aRenderMutex ); } IosSalInstance::~IosSalInstance() { + pthread_cond_destroy( &m_aRenderCond ); + pthread_mutex_destroy( &m_aRenderMutex ); } +#if 0 + bool IosSalInstance::AnyInput( sal_uInt16 nType ) { if( (nType & VCL_INPUT_TIMER) != 0 ) @@ -104,6 +110,8 @@ bool IosSalInstance::AnyInput( sal_uInt16 nType ) return SvpSalInstance::s_pDefaultInstance->PostedEventsInQueue(); } +#endif + class IosSalSystem : public SvpSalSystem { public: IosSalSystem() : SvpSalSystem() {} @@ -254,38 +262,48 @@ void lo_set_view_size(int width, int height) viewHeight = height; } -extern "C" -void lo_render_windows( CGContextRef context, CGRect rect ) +IMPL_LINK( IosSalInstance, RenderWindows, RenderWindowsArg*, arg ) { - if( IosSalInstance::getInstance() != NULL ) { - int i = 0; - std::list< SalFrame* >::const_iterator it; - for( it = IosSalInstance::getInstance()->getFrames().begin(); it != IosSalInstance::getInstance()->getFrames().end(); i++, it++ ) { - SvpSalFrame *pFrame = static_cast<SvpSalFrame *>(*it); - SalFrameGeometry aGeom = pFrame->GetGeometry(); - CGRect bbox = CGRectMake( aGeom.nX, aGeom.nY, aGeom.nWidth, aGeom.nHeight ); - if ( pFrame->IsVisible() && - CGRectIntersectsRect( rect, bbox ) ) { - - const basebmp::BitmapDeviceSharedPtr aDevice = pFrame->getDevice(); - CGDataProviderRef provider = - CGDataProviderCreateWithData( NULL, - aDevice->getBuffer().get(), - aDevice->getSize().getY() * aDevice->getScanlineStride(), - NULL ); - CGImage *image = - CGImageCreate( aDevice->getSize().getX(), aDevice->getSize().getY(), - 8, 32, aDevice->getScanlineStride(), - CGColorSpaceCreateDeviceRGB(), - kCGImageAlphaNoneSkipLast, - provider, - NULL, - false, - kCGRenderingIntentDefault ); - CGContextDrawImage( context, bbox, image ); - } + int i = 0; + std::list< SalFrame* >::const_iterator it; + for( it = getFrames().begin(); it != getFrames().end(); i++, it++ ) { + SvpSalFrame *pFrame = static_cast<SvpSalFrame *>(*it); + SalFrameGeometry aGeom = pFrame->GetGeometry(); + CGRect bbox = CGRectMake( aGeom.nX, aGeom.nY, aGeom.nWidth, aGeom.nHeight ); + if ( pFrame->IsVisible() && + CGRectIntersectsRect( arg->rect, bbox ) ) { + + const basebmp::BitmapDeviceSharedPtr aDevice = pFrame->getDevice(); + CGDataProviderRef provider = + CGDataProviderCreateWithData( NULL, + aDevice->getBuffer().get(), + aDevice->getSize().getY() * aDevice->getScanlineStride(), + NULL ); + CGImage *image = + CGImageCreate( aDevice->getSize().getX(), aDevice->getSize().getY(), + 8, 32, aDevice->getScanlineStride(), + CGColorSpaceCreateDeviceRGB(), + kCGImageAlphaNoneSkipLast, + provider, + NULL, + false, + kCGRenderingIntentDefault ); + CGContextDrawImage( arg->context, bbox, image ); } } + pthread_cond_signal( &m_aRenderCond ); + return 0; +} + +extern "C" +void lo_render_windows( CGContextRef context, CGRect rect ) +{ + IosSalInstance *pInstance = IosSalInstance::getInstance(); + if ( pInstance == NULL ) + return; + IosSalInstance::RenderWindowsArg arg = { context, rect }; + Application::PostUserEvent( LINK( pInstance, IosSalInstance, RenderWindows), &arg ); + pthread_cond_wait( &pInstance->m_aRenderCond, &pInstance->m_aRenderMutex ); } extern "C" |