summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <laszlo.nemeth@collabora.com>2015-11-27 21:59:30 +0100
committerAndras Timar <andras.timar@collabora.com>2015-12-01 12:53:28 +0000
commit945da612c70cc67c3b182c3f2ecdfd4333c8f456 (patch)
treed0c32bc97a2c7202ba166d96fd792955fda7d090
parent224ceff5f2c64ff47f4e687ac674d0a320bb9872 (diff)
tdf#95614 fix freezing with linked graphic
When an unloaded linked picture comes into the visible view (including repainting a page), SwNoTextFrm::PaintPicture() starts a thread to load it in the background using the TriggerAsyncRetrieveInputStream() method of the graphic node. To avoid to start a second thread on the same graphic node, TriggerAsyncRetrieveInputStream() checks mpThreadConsumer, the graphic node member variable for the possible thread object. The problem is that when the thread finished and SwGrfNode::UpdateLinkWithInputStream() reset mpThreadConsumer, the graphic object of the graphic node is still in unloaded state (its type is GRAPHIC_DEFAULT or GRAPHIC_NONE instead of GRAPHIC_BITMAP or GRAPHIC_GDIMETAFILE) for a while, because its modification is solved asynchronously after several SvFileObject::GetData() calls. In the intermediate state of the graphic object, with the high priority repaints of the new scheduler, PaintPicture() could start new thread to load the image again. Using the new member variable SwGrfNode::mbUpdateLinkInProgress, this patch will prevent the graphic node to start newer thread unnecessarily. Change-Id: I9433f0fa4613294103a00a3955fc2f35d8863b59 Reviewed-on: https://gerrit.libreoffice.org/19974 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r--sw/inc/ndgrf.hxx3
-rw-r--r--sw/source/core/doc/notxtfrm.cxx15
-rw-r--r--sw/source/core/graphic/ndgrf.cxx7
3 files changed, 18 insertions, 7 deletions
diff --git a/sw/inc/ndgrf.hxx b/sw/inc/ndgrf.hxx
index 668c5f5ecc61..e7b22617c292 100644
--- a/sw/inc/ndgrf.hxx
+++ b/sw/inc/ndgrf.hxx
@@ -51,6 +51,7 @@ class SW_DLLPUBLIC SwGrfNode: public SwNoTextNode
boost::shared_ptr< SwAsyncRetrieveInputStreamThreadConsumer > mpThreadConsumer;
bool mbLinkedInputStreamReady;
+ bool mbUpdateLinkInProgress;
com::sun::star::uno::Reference<com::sun::star::io::XInputStream> mxInputStream;
bool mbIsStreamReadOnly;
@@ -198,6 +199,8 @@ public:
boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > GetThreadConsumer() { return mpThreadConsumer;}
bool IsLinkedInputStreamReady() const { return mbLinkedInputStreamReady;}
+ bool IsUpdateLinkInProgress() const { return mbUpdateLinkInProgress;}
+ void SetUpdateLinkInProgress(bool b) { mbUpdateLinkInProgress = b; }
void TriggerAsyncRetrieveInputStream();
void ApplyInputStream(
com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xInputStream,
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 02a815b02304..d943e6dffeca 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -897,10 +897,11 @@ void SwNoTextFrm::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfArea
{
Size aTmpSz;
::sfx2::SvLinkSource* pGrfObj = pGrfNd->GetLink()->GetObj();
- if( !pGrfObj ||
- !pGrfObj->IsDataComplete() ||
- !(aTmpSz = pGrfNd->GetTwipSize()).Width() ||
- !aTmpSz.Height() || !pGrfNd->GetAutoFormatLvl() )
+ if ( ( !pGrfObj ||
+ !pGrfObj->IsDataComplete() ||
+ !(aTmpSz = pGrfNd->GetTwipSize()).Width() ||
+ !aTmpSz.Height() || !pGrfNd->GetAutoFormatLvl() ) &&
+ !pGrfNd->IsUpdateLinkInProgress() )
{
pGrfNd->TriggerAsyncRetrieveInputStream(); // #i73788#
}
@@ -909,9 +910,13 @@ void SwNoTextFrm::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfArea
GetRealURL( *pGrfNd, aText );
::lcl_PaintReplacement( aAlignedGrfArea, aText, *pShell, this, false );
bContinue = false;
+ } else if ( rGrfObj.GetType() != GRAPHIC_DEFAULT &&
+ rGrfObj.GetType() != GRAPHIC_NONE &&
+ pGrfNd->IsUpdateLinkInProgress() )
+ {
+ pGrfNd->SetUpdateLinkInProgress( false );
}
}
-
if( bContinue )
{
if( rGrfObj.GetGraphic().IsSupportedGraphic())
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
index 5c2867e5a6a2..dbbe3793d31d 100644
--- a/sw/source/core/graphic/ndgrf.cxx
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -71,6 +71,7 @@ SwGrfNode::SwGrfNode(
mpReplacementGraphic(0),
// #i73788#
mbLinkedInputStreamReady( false ),
+ mbUpdateLinkInProgress( false ),
mbIsStreamReadOnly( false )
{
maGrfObj.SetSwapStreamHdl( LINK(this, SwGrfNode, SwapGraphic) );
@@ -89,6 +90,7 @@ SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
mpReplacementGraphic(0),
// #i73788#
mbLinkedInputStreamReady( false ),
+ mbUpdateLinkInProgress( false ),
mbIsStreamReadOnly( false )
{
maGrfObj.SetSwapStreamHdl( LINK(this, SwGrfNode, SwapGraphic) );
@@ -112,6 +114,7 @@ SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
mpReplacementGraphic(0),
// #i73788#
mbLinkedInputStreamReady( false ),
+ mbUpdateLinkInProgress( false ),
mbIsStreamReadOnly( false )
{
maGrfObj.SetSwapStreamHdl( LINK(this, SwGrfNode, SwapGraphic) );
@@ -521,7 +524,6 @@ bool SwGrfNode::SwapIn( bool bWaitForData )
bool bRet = false;
bInSwapIn = true;
SwBaseLink* pLink = static_cast<SwBaseLink*>((::sfx2::SvBaseLink*) refLink);
-
if( pLink )
{
if( GRAPHIC_NONE == maGrfObj.GetType() ||
@@ -1089,7 +1091,6 @@ void SwGrfNode::TriggerAsyncRetrieveInputStream()
OSL_FAIL( "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
return;
}
-
if ( mpThreadConsumer.get() == 0 )
{
mpThreadConsumer.reset( new SwAsyncRetrieveInputStreamThreadConsumer( *this ) );
@@ -1104,6 +1105,7 @@ void SwGrfNode::TriggerAsyncRetrieveInputStream()
}
mpThreadConsumer->CreateThread( sGrfNm, sReferer );
}
+
}
@@ -1137,6 +1139,7 @@ void SwGrfNode::UpdateLinkWithInputStream()
// #i88291#
mxInputStream.clear();
GetLink()->clearStreamToLoadFrom();
+ mbUpdateLinkInProgress = true;
mbLinkedInputStreamReady = false;
mpThreadConsumer.reset();
}