webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp
changeset 10 a359256acfc6
parent 0 dd21522fd290
child 15 60c5402cb945
equal deleted inserted replaced
5:10e98eab6f85 10:a359256acfc6
    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};
    43 class CSynDecoder : public CActive
    44 class CSynDecoder : public CActive
    44     {
    45     {
    45     public:  // Constructors and destructor
    46     public:  // Constructors and destructor
    46         static CSynDecoder* NewL();
    47         static CSynDecoder* NewL();
    47         virtual ~CSynDecoder();
    48         virtual ~CSynDecoder();
    48 
    49 
    49     public:
    50     public:
    50         TInt Open(BmElem* aElem);
    51         void Open(const TDesC8& aData, TRequestStatus *status);
       
    52         void Lock() { iDecoderLock.Wait(); }
       
    53         void Release() { iDecoderLock.Signal(); }
    51 
    54 
    52     private: // From base class CActive
    55     private: // From base class CActive
    53         void DoCancel();
    56         void DoCancel();
    54         void RunL();
    57         void RunL();
    55         TInt RunError( TInt aError );
    58         TInt RunError( TInt aError );
    56         void SignalParent( TInt aError );
    59         void SignalParent( TInt aError );
       
    60         void StartDecodeL();        
       
    61         void SetIdle();
    57         
    62         
    58     private: // Private constructors
    63     private: // Private constructors
    59         CSynDecoder();
    64         CSynDecoder();
    60         void ConstructL() {}
    65         void ConstructL();
    61 
    66 
    62     private: // Data
    67     private: // Data
    63         BmElem* iElem; // not owned
    68         BmElem iElem;
    64         CImageDecoder* iDecoder; // owned
    69         CImageDecoder* iDecoder;
    65         CMaskedBitmap* iBitmap; // owned
    70         CMaskedBitmap* iBitmap;
       
    71         RFastLock iDecoderLock;
       
    72         DecoderState iDecodeState;
       
    73         RThread syncThread;
       
    74 
       
    75 friend class CSynDecodeThread;        
    66     };
    76     };
    67 
    77 
    68 // FORWARD DECLARATIONS
    78 // FORWARD DECLARATIONS
       
    79 CSynDecoder *CSynDecodeThread::iSyncDecoder = NULL;
    69 
    80 
    70 // ============================= LOCAL FUNCTIONS ===============================
    81 // ============================= LOCAL FUNCTIONS ===============================
    71 
    82 
    72 // ============================ MEMBER FUNCTIONS ===============================
    83 // ============================ MEMBER FUNCTIONS ===============================
    73 // -----------------------------------------------------------------------------
    84 // -----------------------------------------------------------------------------
    77 // -----------------------------------------------------------------------------
    88 // -----------------------------------------------------------------------------
    78 CSynDecoder::CSynDecoder() : CActive(CActive::EPriorityHigh)
    89 CSynDecoder::CSynDecoder() : CActive(CActive::EPriorityHigh)
    79     {
    90     {
    80     CActiveScheduler::Add( this );
    91     CActiveScheduler::Add( this );
    81     }
    92     }
       
    93 
       
    94 void CSynDecoder::ConstructL()
       
    95 {
       
    96     User::LeaveIfError(iDecoderLock.CreateLocal());
       
    97     SetIdle();
       
    98 }
    82 
    99 
    83 CSynDecoder* CSynDecoder::NewL()
   100 CSynDecoder* CSynDecoder::NewL()
    84     {
   101     {
    85     CSynDecoder* self = new (ELeave) CSynDecoder();
   102     CSynDecoder* self = new (ELeave) CSynDecoder();
    86     CleanupStack::PushL( self );
   103     CleanupStack::PushL( self );
    92 CSynDecoder::~CSynDecoder()
   109 CSynDecoder::~CSynDecoder()
    93     {
   110     {
    94     Cancel();
   111     Cancel();
    95     delete iDecoder;
   112     delete iDecoder;
    96     delete iBitmap;
   113     delete iBitmap;
    97     }
   114     iDecoderLock.Close();
    98 
   115     }
    99 // -----------------------------------------------------------------------------
   116 
   100 // OpenL
   117 // -----------------------------------------------------------------------------
   101 // -----------------------------------------------------------------------------
   118 // Decode - Decode request submitted from client thread
   102 TInt CSynDecoder::Open(BmElem* aElem)
   119 // -----------------------------------------------------------------------------
   103 {
   120 void CSynDecoder::Open(const TDesC8& aData, TRequestStatus *status)
   104     iElem = aElem;
   121 {
   105     // reset decoder
   122     iElem.iRequestStatus = status;
   106     TRAPD( err, 
   123     iElem.iData.Set(aData); 
   107         iDecoder = CImageDecoder::DataNewL(CEikonEnv::Static()->FsSession(), iElem->iData);
   124     iElem.iParentThreadId = RThread().Id();
   108         iBitmap = CMaskedBitmap::NewL();
   125     iElem.iBitmapHandle = 0;
   109         );
   126     iElem.iMaskHandle = 0;    
   110     if( err != KErrNone )
   127     iDecodeState = ENewDecodeRequest;
   111         return err;
   128 }
   112 
   129 
       
   130 void CSynDecoder::SetIdle()
       
   131 {
       
   132     iDecodeState = EDecoderIdle;
       
   133     if(!IsActive()) {
       
   134         iStatus = KRequestPending;
       
   135         SetActive();
       
   136     }
       
   137 }
       
   138 
       
   139 void CSynDecoder::StartDecodeL()
       
   140 {
       
   141     if(iDecoder) {
       
   142         delete iDecoder;
       
   143         iDecoder = NULL;
       
   144     }
       
   145     if(iBitmap) {
       
   146         delete iBitmap;
       
   147         iBitmap = NULL;
       
   148     }
       
   149     
       
   150     iDecoder = CImageDecoder::DataNewL(CEikonEnv::Static()->FsSession(), iElem.iData);
       
   151     iBitmap = CMaskedBitmap::NewL();
       
   152     
   113     TFrameInfo frameInfo = iDecoder->FrameInfo( 0 );
   153     TFrameInfo frameInfo = iDecoder->FrameInfo( 0 );
   114 
   154     TInt err = KErrNone;
   115     if( frameInfo.iFlags & TFrameInfo::ETransparencyPossible ) {
   155     if( frameInfo.iFlags & TFrameInfo::ETransparencyPossible ) {
   116         TDisplayMode maskmode = (frameInfo.iFlags & TFrameInfo::EAlphaChannel) ? EGray256 : EGray2;
   156         TDisplayMode maskmode = (frameInfo.iFlags & TFrameInfo::EAlphaChannel) ? EGray256 : EGray2;
   117 
       
   118         err = iBitmap->Create( frameInfo.iOverallSizeInPixels, EColor64K, maskmode );
   157         err = iBitmap->Create( frameInfo.iOverallSizeInPixels, EColor64K, maskmode );
   119     }
   158     }
   120     else
   159     else
   121         err = iBitmap->Create( frameInfo.iOverallSizeInPixels, EColor64K );
   160         err = iBitmap->Create( frameInfo.iOverallSizeInPixels, EColor64K );
   122     //
   161     User::LeaveIfError(err);
   123     if( err != KErrNone )
   162     
   124         return err;
   163     // start decoding
   125    // start decoding
       
   126     CFbsBitmap& dstBitmap = iBitmap->BitmapModifyable();
   164     CFbsBitmap& dstBitmap = iBitmap->BitmapModifyable();
   127     CFbsBitmap& dstMask = iBitmap->MaskModifyable();
   165     CFbsBitmap& dstMask = iBitmap->MaskModifyable();    
   128 
       
   129     if( ( frameInfo.iFlags & TFrameInfo::ETransparencyPossible ) && dstMask.Handle() )
   166     if( ( frameInfo.iFlags & TFrameInfo::ETransparencyPossible ) && dstMask.Handle() )
   130         iDecoder->Convert( &iStatus, dstBitmap, dstMask, 0 );
   167         iDecoder->Convert( &iStatus, dstBitmap, dstMask, 0 );
   131     else {
   168     else {
   132         dstMask.Reset();
   169         dstMask.Reset();
   133         iDecoder->Convert( &iStatus, dstBitmap, 0 );
   170         iDecoder->Convert( &iStatus, dstBitmap, 0 );
   134     }
   171     }
       
   172     
       
   173     iDecodeState = EDecodeInProgress;
   135     SetActive();
   174     SetActive();
   136     return KErrNone;
       
   137 }
   175 }
   138 
   176 
   139 // -----------------------------------------------------------------------------
   177 // -----------------------------------------------------------------------------
   140 // CSynDecoder::DoCancel
   178 // CSynDecoder::DoCancel
   141 // -----------------------------------------------------------------------------
   179 // -----------------------------------------------------------------------------
   142 void CSynDecoder::DoCancel()
   180 void CSynDecoder::DoCancel()
   143 {
   181 {
   144     iDecoder->Cancel();
   182     iDecoder->Cancel();
   145     SignalParent( KErrCancel );
   183     SignalParent( KErrCancel );
       
   184     SetIdle();
   146 }
   185 }
   147 
   186 
   148 // -----------------------------------------------------------------------------
   187 // -----------------------------------------------------------------------------
   149 // CSynDecoder::RunL
   188 // CSynDecoder::RunL
   150 // -----------------------------------------------------------------------------
   189 // -----------------------------------------------------------------------------
   151 void CSynDecoder::RunL()
   190 void CSynDecoder::RunL()
   152 {
   191 {    
   153     SignalParent( iStatus.Int() );
   192     switch(iDecodeState)
   154 
   193     {
   155     if( iStatus.Int() == KErrNone ) {
   194     case ENewDecodeRequest:
   156         iElem->iBitmapHandle = iBitmap->Bitmap().Handle();
   195         StartDecodeL(); // start async decode
   157         iElem->iMaskHandle = iBitmap->Mask().Handle();
   196         break;
   158 
   197     case EDecodeInProgress:
   159         RThread self;
   198         if( iStatus.Int() == KErrNone ) {
   160         self.Suspend(); 
   199             iElem.iBitmapHandle = iBitmap->Bitmap().Handle();
   161         self.Close();
   200             iElem.iMaskHandle = iBitmap->Mask().Handle();        
   162         // destroy
   201         }
   163         CActiveScheduler::Stop();
   202         
   164     }
   203         SignalParent(iStatus.Int());
       
   204         SetIdle();
       
   205         break;
       
   206     default:
       
   207         SetIdle();
       
   208     }        
   165 }
   209 }
   166 
   210 
   167 // -----------------------------------------------------------------------------
   211 // -----------------------------------------------------------------------------
   168 // CSynDecoder::RunError
   212 // CSynDecoder::RunError
   169 // -----------------------------------------------------------------------------
   213 // -----------------------------------------------------------------------------
   170 TInt CSynDecoder::RunError(TInt aError)
   214 TInt CSynDecoder::RunError(TInt aError)
   171 {
   215 {
   172     SignalParent( aError );
   216     SignalParent(aError);
       
   217     SetIdle();
   173     return KErrNone;
   218     return KErrNone;
   174 }
   219 }
   175 
   220 
   176 // -----------------------------------------------------------------------------
   221 // -----------------------------------------------------------------------------
   177 // CSynDecoder::RunError
   222 // CSynDecoder::RunError
   178 // -----------------------------------------------------------------------------
   223 // -----------------------------------------------------------------------------
   179 void CSynDecoder::SignalParent(TInt aError)
   224 void CSynDecoder::SignalParent(TInt aError)
   180 {
   225 {
   181     RThread parent;
   226     RThread parent;
   182     parent.Open(iElem->iParentThreadId);
   227     parent.Open(iElem.iParentThreadId);
   183     parent.RequestComplete(iElem->iRequestStatus, aError );
   228     parent.RequestComplete(iElem.iRequestStatus, aError );
   184     parent.Close();            
   229     parent.Close();
   185 
   230 }
   186     if (aError != KErrNone)
   231 
   187         CActiveScheduler::Stop();
       
   188 }
       
   189 
   232 
   190 CSynDecodeThread* CSynDecodeThread::NewL()
   233 CSynDecodeThread* CSynDecodeThread::NewL()
   191 {
   234 {
   192     CSynDecodeThread* self = new (ELeave) CSynDecodeThread();
   235     CSynDecodeThread* self = new (ELeave) CSynDecodeThread();
   193     CleanupStack::PushL(self);
   236     CleanupStack::PushL(self);
   199 CSynDecodeThread::CSynDecodeThread()
   242 CSynDecodeThread::CSynDecodeThread()
   200 {
   243 {
   201 }
   244 }
   202 
   245 
   203 CSynDecodeThread::~CSynDecodeThread()
   246 CSynDecodeThread::~CSynDecodeThread()
   204 {   	
   247 {
   205 	if(iUp) {
   248     CActiveScheduler::Stop(); 
   206 		iDecoderThread.Resume();
   249 	iDecoderThread.Close();
   207 		iDecoderThread.Kill(KErrNone);  
   250 }
   208 		iDecoderThread.Close();  
       
   209 	}
       
   210 	delete iElem;
       
   211 }
       
   212 
       
   213 
   251 
   214 void CSynDecodeThread::ConstructL()
   252 void CSynDecodeThread::ConstructL()
   215 {
   253 {   
   216 }
   254     _LIT(KThreadName, "ImgDecoder");
   217 
   255     User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, KMinHeapSize, KMaxHeapSize, NULL));
   218 TInt CSynDecodeThread::Decode(const TDesC8& aData, TRequestStatus* aRequestStatus)
   256     iDecoderThread.SetPriority(EPriorityMore);
   219 {
   257     TRequestStatus status = KRequestPending;
   220 	iElem = new (ELeave) BmElem;
   258     iDecoderThread.Rendezvous(status);
   221 	iElem->iData.Set( aData );
   259     iDecoderThread.Resume();
   222 	iElem->iParentThreadId = RThread().Id();
   260     User::WaitForRequest(status);
   223 	iElem->iRequestStatus = aRequestStatus;
   261     User::LeaveIfError(status.Int());
   224 
   262 }
   225     TBuf<20> randName;
   263 
   226 	TTime t;
   264 
   227 	t.HomeTime();
   265 TInt CSynDecodeThread::Decode(const TDesC8& aData)
   228 	randName.Num( I64INT(t.Int64()) );
   266 {
   229     
   267     iSyncDecoder->Lock();
   230 	TInt err = iDecoderThread.Create(randName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, KMinHeapSize, KMaxHeapSize, iElem);
   268     
   231     if (err==KErrNone) {
   269     //notify decoder thread about new request
   232 		iUp = ETrue;
   270     TRequestStatus status = KRequestPending;
   233         iDecoderThread.SetPriority(EPriorityMore);
   271     iSyncDecoder->Open(aData, &status);
   234         *aRequestStatus = KRequestPending;
   272     TRequestStatus *ps = &(iSyncDecoder->iStatus);
   235         iDecoderThread.Resume(); 
   273     iDecoderThread.RequestComplete(ps, KErrNone);
   236     }
   274 
   237     return err;
   275     //wait for decode complete
       
   276     User::WaitForRequest(status);    
       
   277     
       
   278     iSyncDecoder->Release();
       
   279     return status.Int();    
   238 }
   280 }
   239 
   281 
   240 void CSynDecodeThread::Handle(TInt& aBitmapHandle, TInt& aMaskHandle)
   282 void CSynDecodeThread::Handle(TInt& aBitmapHandle, TInt& aMaskHandle)
   241 {
   283 {
   242     aBitmapHandle = iElem->iBitmapHandle;
   284     aBitmapHandle = iSyncDecoder->iElem.iBitmapHandle;
   243     aMaskHandle = iElem->iMaskHandle;    
   285     aMaskHandle = iSyncDecoder->iElem.iMaskHandle;    
   244 }
   286 }
   245 
   287 
   246 TInt CSynDecodeThread::ScaleInThread(TAny *aPtr)
   288 TInt CSynDecodeThread::ScaleInThread(TAny *aPtr)
   247 {
   289 {
   248     CTrapCleanup* cleanup = CTrapCleanup::New();
   290     CTrapCleanup* cleanup = CTrapCleanup::New();
   249     CActiveScheduler* as = new CActiveScheduler;
   291     CActiveScheduler* as = new CActiveScheduler;
   250     CActiveScheduler::Install(as);  
   292     CActiveScheduler::Install(as);  
   251 
       
   252     CSynDecoder* decoder = NULL;         
       
   253 
       
   254     RFbsSession fbs;
   293     RFbsSession fbs;
   255     fbs.Connect();
   294     fbs.Connect();
   256 
   295 
   257     BmElem* elem = (BmElem*)aPtr;
   296     // start event loop
   258     TRAPD(err, decoder = CSynDecoder::NewL());
   297     TRAPD(err, iSyncDecoder = CSynDecoder::NewL());
   259 
   298     if (err == KErrNone) {
   260     if (err == KErrNone && (err = decoder->Open(elem))== KErrNone )
   299         // wait for decode request from client threads
   261         CActiveScheduler::Start();              
   300         RThread().Rendezvous(KErrNone);
   262     else {    
   301         CActiveScheduler::Start();
   263         RThread parent;
   302     }
   264         parent.Open(elem->iParentThreadId);
   303     else {
   265         parent.RequestComplete(elem->iRequestStatus, err);
   304         RThread().Rendezvous(err);
   266         parent.Close();            
   305     }
   267     }
   306     
   268 
   307     // thread shutdown 
   269     delete as;
   308     delete as;
   270     delete decoder; 
   309     delete iSyncDecoder; 
   271     delete cleanup; 
   310     delete cleanup; 
   272     fbs.Disconnect();       
   311     fbs.Disconnect();       
   273     return err;
   312     return err;
   274 }
   313 }