18 |
18 |
19 #include "config.h" |
19 #include "config.h" |
20 #include <e32std.h> |
20 #include <e32std.h> |
21 #include "SyncDecodeThread.h" |
21 #include "SyncDecodeThread.h" |
22 #include "MaskedBitmap.h" |
22 #include "MaskedBitmap.h" |
23 #include <ImageConversion.h> |
23 #include <imageconversion.h> |
24 |
24 |
25 namespace TBidirectionalState { |
25 namespace TBidirectionalState { |
26 class TRunInfo; |
26 class TRunInfo; |
27 }; |
27 }; |
28 |
28 |
29 #include <EIKENV.H> |
29 #include <eikenv.h> |
30 |
30 |
31 #define KMaxHeapSize 0x1000000 |
31 #define KMaxHeapSize 0x1000000 |
32 |
32 |
33 class BmElem |
33 class BmElem |
34 { |
34 { |
38 TRequestStatus* iRequestStatus; |
38 TRequestStatus* iRequestStatus; |
39 TInt iBitmapHandle; |
39 TInt iBitmapHandle; |
40 TInt iMaskHandle; |
40 TInt iMaskHandle; |
41 }; |
41 }; |
42 |
42 |
43 enum DecoderState {ENewDecodeRequest, EDecodeInProgress, EDecoderIdle, EDecoderTerminate}; |
43 enum DecoderState {ENewDecodeRequest, EDecodeInProgress, EDecoderIdle}; |
44 class CSynDecoder : public CActive |
44 class CSynDecoder : public CActive |
45 { |
45 { |
46 public: // Constructors and destructor |
46 public: // Constructors and destructor |
47 static CSynDecoder* NewL(); |
47 static CSynDecoder* NewL(); |
48 virtual ~CSynDecoder(); |
48 virtual ~CSynDecoder(); |
49 |
49 |
50 public: |
50 public: |
51 void Open(const TDesC8& aData, TRequestStatus *status); |
51 void Open(const TDesC8& aData, TRequestStatus *status); |
52 void Lock() { iDecoderLock.Wait(); } |
52 void Lock() { iDecoderLock.Wait(); } |
53 void Release() { iDecoderLock.Signal(); } |
53 void Release() { iDecoderLock.Signal(); } |
54 void Terminate() { iDecodeState = EDecoderTerminate; } |
|
55 |
54 |
56 private: // From base class CActive |
55 private: // From base class CActive |
57 void DoCancel(); |
56 void DoCancel(); |
58 void RunL(); |
57 void RunL(); |
59 TInt RunError( TInt aError ); |
58 TInt RunError( TInt aError ); |
69 BmElem iElem; |
68 BmElem iElem; |
70 CImageDecoder* iDecoder; |
69 CImageDecoder* iDecoder; |
71 CMaskedBitmap* iBitmap; |
70 CMaskedBitmap* iBitmap; |
72 RFastLock iDecoderLock; |
71 RFastLock iDecoderLock; |
73 DecoderState iDecodeState; |
72 DecoderState iDecodeState; |
|
73 RThread syncThread; |
74 |
74 |
75 friend class CSynDecodeThread; |
75 friend class CSynDecodeThread; |
76 }; |
76 }; |
77 |
77 |
78 // FORWARD DECLARATIONS |
78 // FORWARD DECLARATIONS |
117 // ----------------------------------------------------------------------------- |
117 // ----------------------------------------------------------------------------- |
118 // Decode - Decode request submitted from client thread |
118 // Decode - Decode request submitted from client thread |
119 // ----------------------------------------------------------------------------- |
119 // ----------------------------------------------------------------------------- |
120 void CSynDecoder::Open(const TDesC8& aData, TRequestStatus *status) |
120 void CSynDecoder::Open(const TDesC8& aData, TRequestStatus *status) |
121 { |
121 { |
122 // FbsSession is needed for parent thread if it doesn't have already |
|
123 if(!RFbsSession::GetSession()) |
|
124 RFbsSession::Connect(); |
|
125 |
|
126 iElem.iRequestStatus = status; |
122 iElem.iRequestStatus = status; |
127 iElem.iData.Set(aData); |
123 iElem.iData.Set(aData); |
128 iElem.iParentThreadId = RThread().Id(); |
124 iElem.iParentThreadId = RThread().Id(); |
129 iElem.iBitmapHandle = 0; |
125 iElem.iBitmapHandle = 0; |
130 iElem.iMaskHandle = 0; |
126 iElem.iMaskHandle = 0; |
254 { |
243 { |
255 } |
244 } |
256 |
245 |
257 CSynDecodeThread::~CSynDecodeThread() |
246 CSynDecodeThread::~CSynDecodeThread() |
258 { |
247 { |
259 // signal the thread to do cleanup and stop |
248 CActiveScheduler::Stop(); |
260 iSyncDecoder->Terminate(); |
249 iDecoderThread.Close(); |
261 TRequestStatus *ps = &(iSyncDecoder->iStatus); |
|
262 iDecoderThread.RequestComplete(ps, KErrNone); |
|
263 |
|
264 iDecoderThread.Close(); |
|
265 } |
250 } |
266 |
251 |
267 void CSynDecodeThread::ConstructL() |
252 void CSynDecodeThread::ConstructL() |
268 { |
253 { |
269 _LIT(KThreadName, "iconDecoder"); |
254 _LIT(KThreadName, "ImgDecoder"); |
270 RAllocator &allocator = User::Allocator(); |
255 RAllocator &allocator = User::Allocator(); |
271 TInt err = iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL); |
256 User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL)); |
272 if(err == KErrAlreadyExists) { |
|
273 // It may happen only in rare cases, if container browserengine..dll was unloaded and loaded again before |
|
274 // syncDecodeThread could close itself (scheduled). In that case, we kill that thread since we can't reuse that |
|
275 // and create a new one with same name. |
|
276 RThread th; |
|
277 th.Open(KThreadName); |
|
278 th.Kill(KErrNone); |
|
279 th.Close(); |
|
280 |
|
281 // Leave this time if problem still exists |
|
282 User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL)); |
|
283 } |
|
284 |
|
285 iDecoderThread.SetPriority(EPriorityMore); |
257 iDecoderThread.SetPriority(EPriorityMore); |
286 TRequestStatus status = KRequestPending; |
258 TRequestStatus status = KRequestPending; |
287 iDecoderThread.Rendezvous(status); |
259 iDecoderThread.Rendezvous(status); |
288 iDecoderThread.Resume(); |
260 iDecoderThread.Resume(); |
289 User::WaitForRequest(status); |
261 User::WaitForRequest(status); |