First public contribution.
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "BackGroundCompression.h"
19 _LIT(KFbsBgCompThrdName, "FbsBgCompressThread");
20 const TInt KFbsBgCompThrdStackSize = 4096;
23 CFbsBackgroundCompressionQueueElement::CFbsBackgroundCompressionQueueElement(CBitmapObject* aSrcObj, TBitmapfileCompressionScheme aScheme):
24 iSourceObject(aSrcObj),
25 iCompressionScheme(aScheme)
27 __ASSERT_DEBUG(aSrcObj->iCompressionQueueElement == NULL, User::Invariant());
28 aSrcObj->iCompressionQueueElement = this;
31 CFbsBackgroundCompressionQueueElement::~CFbsBackgroundCompressionQueueElement()
34 iSourceObject->iCompressionQueueElement = NULL;
35 if (!iMessage.IsNull())
36 iMessage.Complete(KErrNone);
39 void CFbsBackgroundCompressionQueueElement::CompleteOutstandingRequestAndDestroy(TInt aReason)
41 if (!iMessage.IsNull())
42 iMessage.Complete(aReason);
46 void CFbsBackgroundCompressionQueueElement::CompleteOutstandingRequest(const CSession2* aSession)
48 if (!iMessage.IsNull() && iMessage.Session() == aSession)
49 iMessage.Complete(KErrDisconnected);
53 CFbsBackgroundCompression* CFbsBackgroundCompression::NewL(CFbTop& aFbTop)
55 CFbsBackgroundCompression* self = new(ELeave) CFbsBackgroundCompression(aFbTop);
56 CleanupStack::PushL(self);
58 CleanupStack::Pop(self);
62 CFbsBackgroundCompression::CFbsBackgroundCompression(CFbTop& aFbTop):
63 CActive(CActive::EPriorityIdle),
65 iCompressionQueue(_FOFF(CFbsBackgroundCompressionQueueElement, iLink))
67 CActiveScheduler::Add(this);
70 void CFbsBackgroundCompression::ConstructL()
72 TThreadCreateInfo threadCreateInfo(KFbsBgCompThrdName, (TThreadFunction)ThreadFunction, KFbsBgCompThrdStackSize, this);
73 threadCreateInfo.SetUseHeap(NULL);
74 threadCreateInfo.SetOwner(EOwnerProcess);
75 threadCreateInfo.SetPaging(TThreadCreateInfo::EUnspecified); //Use the creating process's paging attributes.
76 User::LeaveIfError(iThread.Create(threadCreateInfo));
77 iThreadCreated = ETrue;
78 iThread.SetPriority(EPriorityAbsoluteVeryLow);
79 User::LeaveIfError(iThreadGo.CreateLocal(0));
80 User::LeaveIfError(iThreadMutex.CreateLocal());
84 CFbsBackgroundCompression::~CFbsBackgroundCompression()
86 // destructor should be called only after all sessions with the server have been closed
87 // so there should not be any bitmap objects left
88 __ASSERT_DEBUG(iCompressionQueue.IsEmpty(), User::Invariant());
89 __ASSERT_DEBUG(iBitmapObject == NULL, User::Invariant());
92 iThread.Kill(KErrNone);
99 TInt CFbsBackgroundCompression::AddToCompressionQueue(CBitmapObject* aSrcObj, TBitmapfileCompressionScheme aScheme, const RMessage2* aMessage)
101 __ASSERT_DEBUG(aSrcObj != NULL, User::Invariant());
102 CFbsBackgroundCompressionQueueElement* element = new CFbsBackgroundCompressionQueueElement(aSrcObj, aScheme);
105 iCompressionQueue.AddLast(*element);
108 TInt ret = PrepareCompression();
115 iThread.Rendezvous(iStatus);
119 if (aMessage != NULL)
120 element->iMessage = *aMessage;
125 void CFbsBackgroundCompression::RemoveFromCompressionQueue(CBitmapObject* aSrcObj)
127 __ASSERT_DEBUG(aSrcObj != NULL, User::Invariant());
128 CFbsBackgroundCompressionQueueElement* element = aSrcObj->iCompressionQueueElement;
131 if (iBitmapObject != NULL && iCompressionQueue.IsFirst(element))
134 iBitmapObject->Close();
135 iBitmapObject = NULL;
136 iThreadMutex.Signal();
142 void CFbsBackgroundCompression::CompleteOutstandingRequests(const CSession2* aSession)
144 TDblQueIter<CFbsBackgroundCompressionQueueElement> iterator(iCompressionQueue);
145 CFbsBackgroundCompressionQueueElement* element;
146 while ((element = iterator++) != NULL)
147 element->CompleteOutstandingRequest(aSession);
150 void CFbsBackgroundCompression::CompressAll()
152 if (iBitmapObject != NULL) // check if a compression is in progress
154 User::WaitForRequest(iStatus);
155 FinalizeCompression(iStatus);
156 TRequestStatus* status = &iStatus;
157 User::RequestComplete(status, KErrCompletion);
159 while (!iCompressionQueue.IsEmpty())
161 TInt ret = PrepareCompression();
164 iCompressionQueue.First()->CompleteOutstandingRequestAndDestroy(ret);
167 TRequestStatus status;
168 iThread.Rendezvous(status);
170 User::WaitForRequest(status);
171 FinalizeCompression(status);
175 TInt CFbsBackgroundCompression::PrepareCompression()
177 __ASSERT_DEBUG(!iCompressionQueue.IsEmpty(), User::Invariant());
178 __ASSERT_DEBUG(iBitmapObject == NULL, User::Invariant());
179 CFbsBackgroundCompressionQueueElement* element = iCompressionQueue.First();
180 CBitwiseBitmap* srcBmp = element->iSourceObject->Address();
181 CBitmapObject* bmpObj = NULL;
182 TRAPD(ret, bmpObj = iFbTop.CreateBitmapL(srcBmp->SizeInPixels(), srcBmp->DisplayMode(), KUidCFbsBitmapCreation, ETrue));
185 ret = bmpObj->Address()->CopyData(*srcBmp);
192 iBitmapObject = bmpObj;
193 iCompressionScheme = element->iCompressionScheme;
194 iThreadMutex.Signal();
198 void CFbsBackgroundCompression::FinalizeCompression(const TRequestStatus& aStatus)
200 __ASSERT_DEBUG(!iCompressionQueue.IsEmpty(), User::Invariant());
201 __ASSERT_DEBUG(iBitmapObject != NULL, User::Invariant());
203 CFbsBackgroundCompressionQueueElement* element = iCompressionQueue.First();
204 if (aStatus == KErrNone)
206 element->iSourceObject->SetCleanBitmap(iBitmapObject);
207 iFbTop.NotifyDirtyBitmap(*element->iSourceObject, NULL);
211 iBitmapObject->Close();
213 iBitmapObject = NULL;
214 element->CompleteOutstandingRequestAndDestroy(aStatus.Int());
215 iThreadMutex.Signal();
218 void CFbsBackgroundCompression::RunL()
220 // check if CompressAll() or RemoveFromCompressionQueue() have been called before
221 if (iBitmapObject != NULL)
223 FinalizeCompression(iStatus);
225 while (!iCompressionQueue.IsEmpty())
227 TInt ret = PrepareCompression();
231 iThread.Rendezvous(iStatus);
235 iCompressionQueue.First()->CompleteOutstandingRequestAndDestroy(ret);
239 void CFbsBackgroundCompression::DoCancel()
241 iThread.RendezvousCancel(iStatus);
244 TInt CFbsBackgroundCompression::ThreadFunction(CFbsBackgroundCompression* aSelf)
246 TBool notDone = ETrue; // to suppress compiler warning
247 // coverity[dead_error_condition]
248 // coverity[loop_condition]
251 aSelf->iThreadGo.Wait();
252 aSelf->iThreadMutex.Wait();
253 if (aSelf->iBitmapObject != NULL)
255 TInt ret = aSelf->iBitmapObject->Address()->CompressData(aSelf->iCompressionScheme);
256 RThread::Rendezvous(ret);
260 // bitmap removed from queue before background thread had a chance to compress it
261 RThread::Rendezvous(KErrAbort);
263 aSelf->iThreadMutex.Signal();
265 // coverity[dead_error_line]