add some NEON 32bpp blitters
[sdl_omap.git] / src / video / symbian / EKA2 / dsa_new.cpp
1 #include "dsa.h"
2 #include "sdlepocapi.h"
3 #include <cdsb.h>
4
5
6 LOCAL_C TInt BytesPerPixel(TDisplayMode aMode)
7         {
8         return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; 
9         }
10
11
12 NONSHARABLE_CLASS(TDsa)
13         {
14         public:
15                 inline TDsa(const CDsa& aDsa);
16                 inline TBool IsFlip() const;
17                 inline TBool IsTurn() const;
18                 inline const TSize& SwSize() const;
19                 inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const;
20         private:
21                 const CDsa& iDsa;
22         };
23
24
25 inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa)
26         {       
27         }
28
29 inline TBool TDsa::IsTurn() const
30         {
31         return iDsa.iStateFlags & CDsa::EOrientation90;
32         }
33         
34 inline TBool TDsa::IsFlip() const
35         {
36         return iDsa.iStateFlags & CDsa::EOrientation180;
37         }       
38         
39 inline const TSize& TDsa::SwSize() const
40         {
41         return iDsa.SwSize();
42         }
43                 
44 inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const
45         {
46         iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight);
47         }
48         
49 template<class T, class S>      
50 void ClipCopy(const TDsa& iDsa, TUint8* aTarget,
51                                         const TUint8* aSource,
52                                         const TRect& aUpdateRect,
53                                         const TRect& aSourceRect)
54         {
55         const S* source = reinterpret_cast<const S*>(aSource);
56         const TInt lineWidth = aSourceRect.Width();
57         
58         source += (aUpdateRect.iTl.iY * lineWidth); 
59         const TInt sourceStartOffset = aUpdateRect.iTl.iX;
60         source += sourceStartOffset;
61         
62         T* targetPtr = reinterpret_cast<T*>(aTarget);
63         
64         const TInt scanLineWidth = iDsa.SwSize().iWidth;
65         
66         targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth; 
67         const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX);
68         
69         targetPtr += targetStartOffset;
70         
71         
72         const TInt height = aUpdateRect.Height(); 
73                 
74         const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth;
75         const TInt copyLen = aUpdateRect.Width();
76         
77         
78         if(iDsa.IsFlip())
79                 {
80                 
81                 targetPtr += scanLineWidth *  (height - 1);
82         
83                 for(TInt i = 0; i < height; i++) //source is always smaller
84                         {
85                         iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
86                         source += lineMove;
87                         targetPtr -= scanLineWidth;
88                         }
89                 }
90         else
91                 {
92                 
93                 
94                 for(TInt i = 0; i < height; i++) //source is always smaller
95                         {
96                         iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
97                         source += lineMove;
98                         targetPtr += scanLineWidth; // >> 2;
99                         }
100                 }
101
102         }
103         
104
105   
106 NONSHARABLE_CLASS(CDsaA) : public CDsa
107         {
108         public:
109                 CDsaA(RWsSession& aSession);
110         private:
111                 ~CDsaA();
112                 TUint8* LockSurface();
113                 void UnlockHWSurfaceRequestComplete();
114                 void UnlockHwSurface();
115                 void CreateSurfaceL();
116                 void Wipe(TInt aLength);
117                 void Free();
118                 void Update(CFbsBitmap& aBmp);
119                 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
120                 TInt ExternalUpdate();
121         //      void ExternalUpdate();
122         protected:
123                 CFbsBitmap* iBmp;
124                 CFbsBitmap* iCopyBmp;
125         };
126         
127         
128 CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession)
129         {
130         }
131         
132         
133 void CDsaA::Free()
134         {
135         delete iBmp;
136         iBmp = NULL;
137         }
138
139 CDsaA::~CDsaA()
140         {
141         __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
142         delete iCopyBmp;
143         }
144         
145 TUint8* CDsaA::LockSurface()
146         {
147         iBmp->LockHeap();
148         return reinterpret_cast<TUint8*>(iBmp->DataAddress());
149         }
150
151 void CDsaA::UnlockHWSurfaceRequestComplete()
152         {
153         PANIC(KErrNotSupported);
154         }
155
156 void CDsaA::UnlockHwSurface()
157         {
158         iBmp->UnlockHeap();
159         SetUpdating(EFalse);
160         Update(*iBmp);
161         }
162         
163 void CDsaA::Update(CFbsBitmap& aBmp)
164         {
165         if(!Blitter(aBmp))
166                 {
167                 if(SwSize() == HwRect().Size())
168                         Dsa().Gc()->BitBlt(HwRect().iTl, &aBmp);
169                 else
170                         Dsa().Gc()->DrawBitmap(HwRect(), &aBmp);
171                 }
172         DrawOverlays();
173         Dsa().ScreenDevice()->Update(); 
174         }
175 void CDsaA::CreateSurfaceL()
176         {
177         delete iBmp;
178         iBmp = NULL;
179         iBmp  = new (ELeave) CFbsBitmap();
180         User::LeaveIfError(iBmp->Create(SwSize(), DisplayMode()));
181         }
182
183 void CDsaA::Wipe(TInt aLength) //dont call in drawing
184         {
185         iBmp->LockHeap();
186         Mem::FillZ(iBmp->DataAddress(), aLength);
187         iBmp->UnlockHeap();
188         }
189         
190
191                 
192 TInt CDsaA::ExternalUpdate()
193         {
194         if(iCopyBmp->Handle() == 0)
195                 {
196                 const TInt err = iCopyBmp->Duplicate(iBmp->Handle());
197                 if(err != KErrNone)
198                         return err;
199                 }
200         Update(*iCopyBmp);
201         return KErrNone;
202         }
203         
204 void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)              
205         {
206         iCopyBmp = new (ELeave) CFbsBitmap();
207         CDsa::ConstructL(aWindow, aDevice);
208         }
209         
210         
211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
212
213 NONSHARABLE_CLASS(MDsbObs)
214         {
215         public:
216                 virtual void SurfaceReady() = 0;
217                 virtual CDirectScreenBitmap& Dsb() = 0;
218         };
219         
220 NONSHARABLE_CLASS(CDsbSurface) : public CActive
221         {
222         public:
223                 CDsbSurface(MDsbObs& aDsb);
224                 TUint8* Address();
225                 void Complete();
226                 ~CDsbSurface();
227         private:
228                 void RunL();
229                 void DoCancel();
230         private:
231                 MDsbObs& iDsb; 
232                 TUint8* iAddress;
233         };      
234
235 CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb)
236         {
237         CActiveScheduler::Add(this);
238         }
239
240 CDsbSurface::~CDsbSurface()
241         {
242         Cancel();
243         }
244         
245 void CDsbSurface::Complete()
246         {
247         if(iAddress != NULL && !IsActive())
248                 {
249                 iAddress = NULL;
250                 SetActive();
251                 iDsb.Dsb().EndUpdate(iStatus);
252                 }
253         }
254         
255 TUint8* CDsbSurface::Address()
256         {
257         if(iAddress == NULL && !IsActive())
258                 {
259                 TAcceleratedBitmapInfo info;
260                 if(KErrNone == iDsb.Dsb().BeginUpdate(info))
261                         iAddress = info.iAddress;
262                 }
263         return iAddress;
264         }
265         
266 void CDsbSurface::RunL()
267         {
268         iDsb.SurfaceReady();
269         }
270
271 void CDsbSurface::DoCancel()
272         {
273         //empty
274         }
275                 
276 NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs
277         {
278         public:
279                 CDsaB(RWsSession& aSession, TInt aFlags);
280         private:
281                 ~CDsaB();
282                 TUint8* LockSurface();
283                 void UnlockHWSurfaceRequestComplete();
284                 void UnlockHwSurface();
285                 void CreateSurfaceL();
286                 void Wipe(TInt aLength);
287                 void RecreateL();
288                 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
289                 CDirectScreenBitmap& Dsb();
290                 void SurfaceReady();
291                 TInt ExternalUpdate();
292         private:
293                 CDsbSurface* iSurface1;
294                 CDsbSurface* iSurface2;
295                 CDirectScreenBitmap* iDsb;
296                 TInt iType;
297         };
298
299 CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsa(aSession), iType(aFlags)
300         {
301         }
302
303
304         
305 void CDsaB::UnlockHWSurfaceRequestComplete()
306         {
307         iSurface1->Complete();
308         if(iSurface2 != NULL)
309                 iSurface2->Complete();
310         }       
311
312 void CDsaB::CreateSurfaceL()
313         {
314         __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported));
315         }
316         
317 void CDsaB::Wipe(TInt aLength) //dont call in drawing
318         {
319         TUint8* addr = LockSurface();
320         if(addr != NULL) 
321                 {
322                 Mem::FillZ(addr, aLength);
323                 UnlockHwSurface();
324                 }
325         }
326         
327
328 void CDsaB::UnlockHwSurface()
329         {
330         EpocSdlEnv::Request(CDsa::ERequestUpdate);
331         }
332         
333 TUint8* CDsaB::LockSurface()
334         {
335         TUint8* addr =  iSurface1->Address();
336         if(addr == NULL && iSurface2 != NULL)
337                 addr =  iSurface2->Address();
338         SetUpdating(addr == NULL);
339         return addr;
340         }
341         
342 void CDsaB::SurfaceReady()      
343         {
344         SetUpdating(EFalse);
345         }
346
347 CDirectScreenBitmap& CDsaB::Dsb()
348         {
349         return *iDsb;
350         }
351         
352 void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
353         {
354         if(iDsb == NULL)
355                 iDsb = CDirectScreenBitmap::NewL();     
356         CDsa::ConstructL(aWindow, aDevice);
357         if(iSurface1 == NULL)   
358                 iSurface1 = new (ELeave) CDsbSurface(*this);
359         if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer)
360                 iSurface2 = new (ELeave) CDsbSurface(*this);
361         }
362         
363 CDsaB::~CDsaB()
364         {
365         delete iSurface1;
366         delete iSurface2;
367         delete iDsb;
368         }       
369
370 void CDsaB::RecreateL()
371         {
372     iDsb->Close();
373     iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType));
374         }
375         
376 TInt CDsaB::ExternalUpdate()
377         {
378         if(LockSurface())
379                 {
380                 UnlockHWSurfaceRequestComplete();
381                 return KErrNone;
382                 }
383         return KErrNotReady;
384         }
385                 
386
387 /////////////////////////////////////////////////////////////////////////////////////////////////////   
388
389
390 CDsa* CDsa::CreateL(RWsSession& aSession)
391         {
392         if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB))
393                 {
394                 TInt flags = CDirectScreenBitmap::ENone;
395                 if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer))
396                         flags |= CDirectScreenBitmap::EDoubleBuffer;
397                 if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate))
398                         flags |= CDirectScreenBitmap::EIncrementalUpdate;
399                 return new (ELeave) CDsaB(aSession, flags);
400                 }
401     else
402         return new (ELeave) CDsaA(aSession);
403         }   
404         
405         
406 void CDsa::RecreateL()
407         {
408         }
409
410 void CDsa::Free()
411         {
412         }
413         
414 TSize CDsa::WindowSize() const
415         {
416         TSize size = iSwSize;
417         if(iStateFlags & EOrientation90)
418                 {
419                 const TInt tmp = size.iWidth;
420                 size.iWidth = size.iHeight;
421                 size.iHeight = tmp;
422                 }
423         return size;
424         }
425         
426 void CDsa::SetSuspend()
427         {
428         iStateFlags |= ESdlThreadSuspend;
429         }
430
431 void CDsa::ReleaseStop()
432         {
433         iStateFlags &= ~ESdlThreadExplicitStop;
434         }
435
436
437 TBool CDsa::Stopped() const
438         {
439         return (iStateFlags & ESdlThreadExplicitStop);
440         }
441
442 void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation)
443         {
444         TInt flags = 0;
445         switch(aOrientation)
446                 {
447                 case CSDL::EOrientation90:
448                         flags = EOrientation90;
449                         break;
450                 case CSDL::EOrientation180:
451                         flags = EOrientation180;
452                         break;
453                 case CSDL::EOrientation270:
454                         flags = EOrientation90 | EOrientation180;
455                         break;
456                 case CSDL::EOrientation0:
457                         flags = 0;
458                         break;
459                 }
460         if(flags != (iStateFlags & EOrientationFlags))
461                 {
462                 iStateFlags |= EOrientationChanged;
463                 iNewFlags = flags; //cannot be set during drawing...
464                 }
465         }
466
467 CDsa::~CDsa()
468     {
469     if(iDsa != NULL)
470         {
471         iDsa->Cancel();
472         }
473     iOverlays.Close();
474     delete iDsa;
475     User::Free(iLut256);
476     }
477          
478 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
479     {
480     if(iDsa != NULL)
481         {
482         iDsa->Cancel();
483         delete iDsa;
484         iDsa = NULL;
485         }
486         
487     iDsa = CDirectScreenAccess::NewL(
488                                 iSession,
489                                         aDevice,
490                                         aWindow,
491                                         *this);                         
492
493         if(iLut256 == NULL)
494                 iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32));
495         iTargetMode = aWindow.DisplayMode();
496         iTargetBpp = BytesPerPixel(DisplayMode());
497         iScreenRect = TRect(aWindow.Position(), aWindow.Size());
498         SetTargetRect();
499     RestartL();
500     }
501     
502 void CDsa::DrawOverlays()
503         {
504         const TInt last = iOverlays.Count() - 1;
505         for(TInt i = last; i >= 0 ; i--)
506                 iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize());
507         }
508
509 TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
510         {
511         TInt i;
512         for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++)
513                 {}
514         const TOverlay overlay = {&aOverlay, aPriority};
515         return iOverlays.Insert(overlay, i);
516         }
517         
518 TInt CDsa::RemoveOverlay(MOverlay& aOverlay)
519         {
520         for(TInt i = 0; i < iOverlays.Count(); i++)
521                 {
522                 if(iOverlays[i].iOverlay == &aOverlay)
523                         {
524                         iOverlays.Remove(i);
525                         return KErrNone;
526                         }
527                 }
528         return KErrNotFound;
529         }
530
531 void CDsa::LockPalette(TBool aLock)
532         {
533         if(aLock)
534                 iStateFlags |= EPaletteLocked;
535         else
536                 iStateFlags &= ~EPaletteLocked;
537         }
538 TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette)
539         {
540         if(iLut256 == NULL)
541                 return KErrNotFound;
542         const TInt count = aCount - aFirst;
543         if(count > 256)
544                 return KErrArgument;
545         if(iStateFlags & EPaletteLocked)
546                 return KErrNone;
547         for(TInt i = aFirst; i < count; i++) //not so busy here:-)
548                 {
549                 iLut256[i] = aPalette[i];
550                 }
551         return KErrNone;
552         }
553         
554         
555
556 void CDsa::RestartL()
557     {
558     //const TBool active = iDsa->IsActive();
559     
560     //if(!active)
561     
562     iDsa->StartL();     
563     
564     const RRegion* r = iDsa->DrawingRegion();
565     const TRect rect = r->BoundingRect();
566     iDsa->Gc()->SetClippingRegion(r);   
567    
568     if(rect != iScreenRect)
569         {
570     //  iDsa->Cancel();
571         return ;        
572                 }
573                 
574      
575         
576     //iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip
577         //targetrect shall no change
578         SetTargetRect();
579         RecreateL();
580
581     iStateFlags |= ERunning;
582     
583     ReleaseStop();
584     if(iStateFlags & ESdlThreadSuspend)
585         {
586         EpocSdlEnv::Resume();
587         iStateFlags &= ~ ESdlThreadSuspend;
588         }       
589     EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);      
590     }
591     
592 CDsa::CDsa(RWsSession& aSession) : 
593         iSession(aSession),
594         iStateFlags(0)
595         {
596 //      CActiveScheduler::Add(this);
597         iCFTable[0] = CopyMem;
598         iCFTable[1] = CopyMemFlipReversed;
599         iCFTable[2] = CopyMemReversed;
600         iCFTable[3] = CopyMemFlip;      
601         
602         iCFTable[4] = Copy256;
603         iCFTable[5] = Copy256FlipReversed;
604         iCFTable[6] = Copy256Reversed;
605         iCFTable[7] = Copy256Flip;      
606         
607         
608         iCFTable[8] = CopySlow;
609         iCFTable[9] = CopySlowFlipReversed;
610         iCFTable[10] = CopySlowReversed;
611         iCFTable[11] = CopySlowFlip;    
612         }
613         
614 RWsSession& CDsa::Session()
615         {
616         return iSession;
617         }
618
619 TInt CDsa::RedrawRequest()
620         {
621         if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning)))
622                 {
623                 return ExternalUpdate();
624                 }
625         return KErrNotReady;
626         }
627
628 TUint8* CDsa::LockHwSurface()
629         {
630         if((iStateFlags & EUpdating) == 0) //else frame is skipped
631                 {
632                 return LockSurface();
633                 }
634         return NULL; 
635         }
636
637 /*      
638 void CDsa::RunL()
639         {
640         iStateFlags &= ~EUpdating;
641         }
642                 
643         
644 void CDsa::DoCancel()
645         {
646         iStateFlags &= ~EUpdating;
647         //nothing can do, just wait?
648         }
649 */      
650
651         
652 TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode)
653         {
654         if(aHwSurface && aMode != DisplayMode())
655                 return KErrArgument;
656         
657         iSourceMode = aMode;
658         
659         iSourceBpp = BytesPerPixel(aMode);
660         
661         const TSize size = WindowSize();
662         if(aSize.iWidth > size.iWidth)
663                 return KErrTooBig;
664         if(aSize.iHeight > size.iHeight)
665                 return KErrTooBig;
666         
667         TRAPD(err, CreateSurfaceL());
668         if(err != KErrNone)
669                 return err;
670
671         SetCopyFunction();
672         
673         return KErrNone;
674         }
675         
676
677 void CDsa::CreateZoomerL(const TSize& aSize)
678         {
679         iSwSize = aSize;
680         iStateFlags |= EResizeRequest;
681         CreateSurfaceL();
682         SetTargetRect();
683         }
684         
685
686 /*
687 void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode)
688         {
689         CFbsBitmap* s = new CFbsBitmap();
690         s->Create(aSz, aMode);
691         s->LockHeap();
692         TUint32* addr = s->DataAddress();
693         Mem::Copy(addr, aData, aLength);
694         s->UnlockHeap();
695         s->Save(aName);
696         s->Reset();
697         delete s;
698         }
699         
700 void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz)
701         {
702         CFbsBitmap* s = new CFbsBitmap();
703         s->Create(aSz, EColor64K);
704         TBitmapUtil bmp(s);
705         bmp.Begin(TPoint(0, 0));
706         for(TInt j = 0; j < aSz.iHeight; j++)
707                 {
708                 bmp.SetPos(TPoint(0, j));
709                 for(TInt i = 0; i < aSz.iWidth; i++)
710                         {
711                         bmp.SetPixel(*aData);
712                         aData++;
713                         bmp.IncXPos();
714                         }
715                 }
716         bmp.End();
717         s->Save(aName);
718         s->Reset();
719         delete s;
720         }       
721         
722 TBuf<16> FooName(TInt aFoo)
723         {
724         TBuf<16> b;
725         b.Format(_L("C:\\pic%d.mbm"), aFoo);
726         return b;
727         }
728         
729 void ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos)
730         {
731         const TInt iSourceBpp = 1;
732         const TInt iTargetBpp = 4;
733         const TInt iScanLineWidth = 800; 
734         
735         TUint8* target = aTarget;
736         const TUint8* source = aSource;
737         const TInt lineWidth = aRect.Width();
738         source += iSourceBpp * (aRect.iTl.iY * lineWidth); 
739         const TInt sourceStartOffset = iSourceBpp *  aRect.iTl.iX;
740         source += sourceStartOffset;
741         target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth); 
742         const TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX);
743         target += targetStartOffset;
744         TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
745         const TInt targetWidth = iScanLineWidth >> 2;
746         const TInt height = aRect.Height(); 
747         }       
748 */
749 /*
750 void CDsa::ClipCopy(TUint8* aTarget,
751                                         const TUint8* aSource,
752                                         const TRect& aUpdateRect,
753                                         const TRect& aSourceRect) const
754         {
755         //TUint8* target = aTarget;
756         const TUint32* source = (const TUint32*) aSource;
757         const TInt lineWidth = aSourceRect.Width();
758         
759         source +=  (aUpdateRect.iTl.iY * lineWidth); 
760         const TInt sourceStartOffset =   aUpdateRect.iTl.iX;
761         source += sourceStartOffset;
762         
763         TUint32* targetPtr = reinterpret_cast<TUint32*>(aTarget);
764         
765         targetPtr +=  (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * SwSize().iWidth; 
766         const TInt targetStartOffset =  (aUpdateRect.iTl.iX + aSourceRect.iTl.iX);
767         
768         targetPtr += targetStartOffset;
769         
770 //      TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
771         
772         const TInt targetWidth32 = SwSize().iWidth;
773         
774         const TInt height = aUpdateRect.Height(); 
775                 
776         const TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
777         const TInt copyLen = aUpdateRect.Width();
778         
779         
780         if(iStateFlags & EOrientation180)
781                 {
782                 
783                 targetPtr += targetWidth32 *  (height - 1);
784         
785                 for(TInt i = 0; i < height; i++) //source is always smaller
786                         {
787                         iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height);
788                         source += lineMove;
789                         targetPtr -= targetWidth32;
790                         }
791                 }
792         else
793                 {
794                 
795                 
796                 for(TInt i = 0; i < height; i++) //source is always smaller
797                         {
798                         iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height);
799                         source += lineMove;
800                         targetPtr += targetWidth32; // >> 2;
801                         }
802                 }
803
804         }
805         
806 */
807
808 void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos) const
809         {
810         TUint8* target = aTarget;
811         const TUint8* source = aSource;
812         const TInt lineWidth = aRect.Width();
813         source += iSourceBpp * (aRect.iTl.iY * lineWidth); 
814         TInt sourceStartOffset = iSourceBpp *  aRect.iTl.iX;
815         source += sourceStartOffset;
816         target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth); 
817         TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX);
818         target += targetStartOffset;
819         TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
820         const TInt targetWidth = iScanLineWidth >> 2;
821         const TInt height = aRect.Height(); 
822         
823         TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
824         
825         if(iStateFlags & EOrientation180)
826                 {
827                 
828                 targetPtr += targetWidth *  (height - 1);
829         
830                 for(TInt i = 0; i < height; i++) //source is always smaller
831                         {
832                         iCopyFunction(*this, targetPtr, source, lineWidth, height);
833                         source += lineMove;
834                         targetPtr -= targetWidth;
835                         }
836                 }
837         else
838                 {
839                 
840                 
841                 for(TInt i = 0; i < height; i++) //source is always smaller
842                         {
843                         iCopyFunction(*this, targetPtr, source, lineWidth, height);
844                         source += lineMove;
845                         targetPtr += targetWidth;
846                         }
847                 }
848
849         }
850         
851                 
852         
853         /*
854 void CDsa::ClipCopy(TUint8* aTarget,
855                                         const TUint8* aSource,
856                                         const TRect& aUpdateRect,
857                                         const TRect& aSourceRect) const
858                 {
859                 const TDsa dsa(*this);
860                 switch(iSourceBpp)
861                         {
862                         case 1:
863                                 ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
864                                 break;
865                         case 2:
866                                 ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
867                                 break;
868                         case 4:
869                                 ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
870                                 break;
871                         }
872                 }       
873
874
875 */
876
877
878
879 void CDsa::Wipe() //dont call in drawing
880         {
881         if(IsDsaAvailable())
882                 Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight);
883         }
884         
885 void CDsa::SetCopyFunction()
886         {
887         //calculate offset to correct function in iCFTable according to given parameters
888         TInt function = 0;
889         const TInt KCopyFunctions = 4;
890         const TInt KOffsetToNative = 0;
891         const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions;
892         const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
893         const TInt KOffsetTo90Functions = 1;
894         const TInt KOffsetTo180Functions = 2;
895         
896         if(iSourceMode == DisplayMode())
897                 function = KOffsetToNative;             //0
898         else if(iSourceMode == EColor256)
899                 function = KOffsetTo256;                        //4
900         else
901                 function = KOffsetToOtherModes;         //8
902         
903         if(iStateFlags & EOrientation90)
904                 function += KOffsetTo90Functions;       // + 1
905         if(iStateFlags & EOrientation180)
906                 function += KOffsetTo180Functions;      //+ 2
907         
908         iCopyFunction = iCFTable[function];
909         
910         Wipe();
911         }
912         
913 inline void Rotate(TRect& aRect)
914         {
915         const TInt dx = aRect.iBr.iX - aRect.iTl.iX;
916         const TInt dy = aRect.iBr.iY - aRect.iTl.iY;
917
918         aRect.iBr.iX = aRect.iTl.iX + dy;
919         aRect.iBr.iY = aRect.iTl.iY + dx;
920         
921         const TInt tmp = aRect.iTl.iX;
922         aRect.iTl.iX = aRect.iTl.iY;
923         aRect.iTl.iY = tmp;
924         }
925         
926 /*      
927 int bar = 0;
928 */      
929 /*
930 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
931         {
932
933         if(iStateFlags & EOrientationChanged)
934                 {
935                 iStateFlags &= ~EOrientationFlags;
936                 iStateFlags |= iNewFlags;
937                 SetCopyFunction();
938                 iStateFlags &= ~EOrientationChanged;
939             EpocSdlEnv::WaitDeviceChange();
940             return EFalse; //skip this frame as data is may be changed
941                 }
942
943         if(iTargetAddr == NULL)
944                 {
945                 iTargetAddr = LockHwSurface();
946                 }
947                 
948         TUint8* target = iTargetAddr;
949         if(target == NULL)
950                 return EFalse;
951         
952         
953         TRect targetRect = TRect(TPoint(0, 0), SwSize());
954         
955         TRect sourceRect = aRect;
956         TRect updateRect = aUpdateRect;
957         
958 //      TPoint move(0, 0);
959         
960         
961         if(iStateFlags & EOrientation90)
962                 {
963                 Rotate(sourceRect);
964                 Rotate(updateRect);
965                 }
966                 
967         if(iSourceMode != DisplayMode() ||  targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
968                 {
969                 sourceRect.Intersection(targetRect); //so source always smaller or equal than target
970                 //updateRect.Intersection(targetRect);
971                 ClipCopy(target, aBits, updateRect, sourceRect);
972                 }
973         else
974                 {
975                 const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
976                 Mem::Copy(target, aBits, byteCount);
977                 }
978
979         return ETrue;
980         }
981         */
982         
983 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
984         {
985
986         if(iStateFlags & EOrientationChanged)
987                 {
988                 iStateFlags &= ~EOrientationFlags;
989                 iStateFlags |= iNewFlags;
990                 SetCopyFunction();
991                 iStateFlags &= ~EOrientationChanged;
992             EpocSdlEnv::WaitDeviceChange();
993             return EFalse; //skip this frame as data is may be changed
994                 }
995
996         if(iTargetAddr == NULL)
997                 {
998                 iTargetAddr = LockHwSurface();
999                 }
1000         TUint8* target = iTargetAddr;
1001         if(target == NULL)
1002                 return EFalse;
1003         
1004         
1005         TRect targetRect = Rect();
1006         TRect sourceRect = aRect;
1007         TRect updateRect = aUpdateRect;
1008         
1009         if(iStateFlags & EOrientation90)
1010                 {
1011                 Rotate(sourceRect);
1012                 Rotate(updateRect);
1013                 }
1014                 
1015         if(iSourceMode != DisplayMode() ||  targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
1016                 {
1017                 sourceRect.Intersection(targetRect); //so source always smaller or equal than target
1018                 updateRect.Intersection(targetRect);
1019                 ClipCopy(target, aBits, updateRect, sourceRect.iTl);
1020                 }
1021         else
1022                 {
1023                 const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
1024                 Mem::Copy(target, aBits, byteCount);
1025                 }
1026
1027         return ETrue;
1028         }       
1029 void CDsa::UpdateSwSurface()
1030         {
1031         iTargetAddr = NULL;
1032         UnlockHwSurface();      //could be faster if does not use AO, but only check status before redraw, then no context switch needed
1033         }
1034         
1035
1036 void CDsa::Resume()     
1037         {
1038         if(Stopped())
1039                 Restart(RDirectScreenAccess::ETerminateRegion);
1040         }
1041         
1042 void CDsa::DoStop()
1043         {
1044         if(IsDsaAvailable())
1045                 iStateFlags |= ESdlThreadExplicitStop;
1046         Stop();
1047         }
1048         
1049 void CDsa::Stop()
1050         {
1051         iStateFlags &= ~ERunning;
1052 //      Cancel(); //can be called only from main!
1053         iDsa->Cancel();
1054         }
1055         
1056 void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
1057         {
1058 //      iStateFlags |= EChangeNotify;
1059         Stop();
1060         }
1061         
1062 void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason)
1063         {
1064         if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart
1065                 {                                                                                               
1066                 TRAPD(err, RestartL());
1067                 PANIC_IF_ERROR(err);
1068                 }
1069         }
1070         
1071 void CDsa::SetBlitter(MBlitter* aBlitter)
1072         {
1073         iBlitter = aBlitter;
1074         }
1075         
1076         
1077 TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const      
1078         {
1079         TPoint pos = aPoint - iScreenRect.iTl;
1080         const TSize asz = iScreenRect.Size();
1081         if(iStateFlags & EOrientation180)
1082                 {
1083                 pos.iX = asz.iWidth - pos.iX;
1084                 pos.iY = asz.iHeight - pos.iY;  
1085                 }       
1086         if(iStateFlags & EOrientation90)
1087                 {
1088                 pos.iX = aPoint.iY;
1089                 pos.iY = aPoint.iX;     
1090                 }
1091         pos.iX <<= 16;
1092         pos.iY <<= 16;
1093         pos.iX /= asz.iWidth; 
1094         pos.iY /= asz.iHeight;
1095         pos.iX *= iSwSize.iWidth;
1096         pos.iY *= iSwSize.iHeight;
1097         pos.iX >>= 16;
1098         pos.iY >>= 16;
1099         return pos;     
1100         }
1101         
1102 void CDsa::SetTargetRect()
1103         {
1104         iTargetRect = iScreenRect;
1105         if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio))
1106                 {
1107                 const TSize asz = iScreenRect.Size();
1108                 const TSize sz = iSwSize;
1109                 
1110                 TRect rect;
1111                 
1112                 const TInt dh = (sz.iHeight << 16) / sz.iWidth;
1113
1114                 if((asz.iWidth * dh ) >> 16 <= asz.iHeight)
1115                         {
1116                         rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16));
1117                         }
1118                 else
1119                         {
1120                         const TInt dw = (sz.iWidth << 16) / sz.iHeight;
1121                 rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight));
1122                         }
1123                 rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1);  
1124                 
1125                 iTargetRect = rect;
1126                 iTargetRect.Move(iScreenRect.iTl);
1127
1128                 } 
1129         if(!(iStateFlags & EResizeRequest))
1130                 iSwSize = iScreenRect.Size();
1131 //      iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth;
1132         }
1133                 
1134 /*)
1135 TBool CDsa::ChangeTrigger()
1136         {
1137         const TBool change = iStateFlags & EChangeNotify;
1138         iStateFlags &= ~EChangeNotify;
1139         return change;
1140         }
1141 */      
1142 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1143
1144 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1145         {
1146         TUint32* target = aTarget;
1147         const TUint32* endt = target + aBytes; 
1148         const TUint8* source = aSource;
1149         while(target < endt)
1150                 {
1151                 *target++ = aDsa.iLut256[*source++]; 
1152                 }
1153         }
1154         
1155 void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1156         {
1157         const TUint32* target = aTarget;
1158         TUint32* endt = aTarget + aBytes; 
1159         const TUint8* source = aSource;
1160         while(target < endt)
1161                 {
1162                 *(--endt) = aDsa.iLut256[*source++]; 
1163                 }
1164         }       
1165         
1166 void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1167         {
1168         TUint32* target = aTarget;
1169         const TUint32* endt = target + aBytes; 
1170         const TUint8* column = aSource;
1171
1172         while(target < endt)
1173                 {
1174                 *target++ = aDsa.iLut256[*column];
1175                 column += aLineLen;
1176                 }
1177         }
1178         
1179 void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1180         {
1181         const TUint32* target = aTarget;
1182         TUint32* endt = aTarget + aBytes; 
1183         const TUint8* column = aSource;
1184
1185         while(target < endt)
1186                 {
1187                 *(--endt) = aDsa.iLut256[*column];
1188                 column += aLineLen;
1189                 }
1190         }               
1191
1192 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1193         {
1194         const TUint32* src = reinterpret_cast<const TUint32*>(aSource);
1195         Mem::Copy(aTarget, src, aBytes << 2);
1196         }
1197         
1198 void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1199         {
1200         TUint32* target = aTarget;
1201         const TUint32* endt = target + aBytes; 
1202         const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
1203
1204         while(target < endt)
1205                 {
1206                 *target++ = *column;
1207                 column += aLineLen;
1208                 }
1209         }
1210         
1211 void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1212         {
1213         const TUint32* target = aTarget;
1214         TUint32* endt = aTarget + aBytes; 
1215         const TUint32* source = reinterpret_cast<const TUint32*>(aSource);
1216         while(target < endt)
1217                 {
1218                 *(--endt) = *source++; 
1219                 }
1220         }       
1221         
1222         
1223 void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1224         {
1225         const TUint32* target = aTarget;
1226         TUint32* endt = aTarget + aBytes; 
1227         const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
1228
1229         while(target < endt)
1230                 {
1231                 *(--endt) = *column;
1232                 column += aLineLen;
1233                 }
1234         }
1235                         
1236 /*
1237
1238 LOCAL_C TRgb rgb16MA(TInt aValue)
1239         {
1240         return TRgb::Color16MA(aValue);
1241         }
1242 */      
1243 NONSHARABLE_CLASS(MRgbCopy)
1244         {
1245         public:
1246         virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0;
1247         virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0;
1248         };
1249         
1250 template <class T>
1251 NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
1252         {
1253         public:
1254         TRgbCopy(TDisplayMode aMode);
1255         void* operator new(TUint aBytes, TAny* aMem);
1256         void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed);
1257         void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed);
1258         static TUint32 Gray256(const TUint8& aPixel);
1259         static TUint32 Color256(const TUint8& aPixel);
1260         static TUint32 Color4K(const TUint16& aPixel);
1261         static TUint32 Color64K(const TUint16& aPixel);
1262         static TUint32 Color16M(const TUint32& aPixel);
1263         static TUint32 Color16MU(const TUint32& aPixel);
1264         static TUint32 Color16MA(const TUint32& aPixel);
1265         private:
1266                 typedef TUint32 (*TRgbFunc) (const T& aValue);
1267                 TRgbFunc iFunc;
1268         };
1269                 
1270                 
1271 template <class T>              
1272 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
1273         {
1274         return aMem;
1275         }
1276                 
1277 template <class T>
1278 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
1279         {
1280         switch(aMode)
1281                 {
1282                 case EGray256 : iFunc = (TRgbFunc) Gray256; break;
1283                 case EColor256 : iFunc =  (TRgbFunc) Color256; break;
1284                 case EColor4K : iFunc =  (TRgbFunc) Color4K; break;
1285                 case EColor64K : iFunc =  (TRgbFunc) Color64K; break;
1286                 case EColor16M : iFunc =  (TRgbFunc) Color16M; break;
1287                 case EColor16MU : iFunc =  (TRgbFunc) Color16MU; break;
1288                 case EColor16MA : iFunc =  (TRgbFunc) Color16MA; break;
1289                 default:
1290                         PANIC(KErrNotSupported);
1291                 }
1292         }
1293         
1294 template <class T>
1295 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed)
1296         {
1297         const T* source = reinterpret_cast<const T*>(aSource);
1298         TUint32* target = aTarget;
1299         TUint32* endt = target + aBytes;
1300         
1301         if(aReversed)
1302                 {
1303                 while(target < endt)
1304                         {
1305                         const T value = *source++;
1306                         *(--endt) = iFunc(value);//iFunc(value).Value();
1307                         }
1308                 }
1309         else
1310                 {
1311                 while(target < endt)
1312                         {
1313                         const T value = *source++;
1314                         *target++ = iFunc(value);//iFunc(value).Value();
1315                         }
1316                 }
1317         }
1318         
1319 template <class T>
1320 void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed)
1321         {
1322         const T* column = reinterpret_cast<const T*>(aSource);
1323         TUint32* target = aTarget;
1324         TUint32* endt = target + aBytes;
1325         
1326         if(aReversed)
1327                 {
1328                 while(target < endt)
1329                         {
1330                         *(--endt) = iFunc(*column);
1331                         column += aLineLen;
1332                         }
1333                 }
1334         else
1335                 {
1336                 while(target < endt)
1337                         {
1338                         *target++ = iFunc(*column);
1339                         column += aLineLen;
1340                         }
1341                 }
1342         }       
1343                 
1344 template <class T> TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
1345         {
1346         const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
1347         return px;
1348         }
1349         
1350 template <class T> TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
1351         {
1352         return TRgb::Color256(aPixel).Value();
1353         }
1354         
1355 template <class T> TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
1356         {
1357         TUint32 col = (aPixel & 0xF00) << 12;
1358         col |= (aPixel & 0xF00) << 8; 
1359         
1360         col |= (aPixel & 0x0F0) << 8;
1361         col |= (aPixel & 0x0F0);
1362         
1363         col |= (aPixel & 0x00F) << 4;
1364         col |= (aPixel & 0x00F);
1365         
1366         return col;
1367         }
1368         
1369 template <class T> TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
1370         {
1371         TUint32 col = (aPixel & 0xF800)<< 8;
1372         col |= (aPixel & 0xE000) << 3; 
1373         
1374         col |= (aPixel & 0x07E0) << 5;
1375         col |= (aPixel & 0xC0) >> 1;
1376         
1377         col |= (aPixel & 0x07E0) << 3;
1378         col |= (aPixel & 0x1C) >> 2;
1379         
1380         return col;
1381         }
1382         
1383 template <class T> TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
1384         {
1385         return TRgb::Color16M(aPixel).Value();
1386         }
1387         
1388 template <class T> TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
1389         {
1390         return TRgb::Color16MU(aPixel).Value();
1391         }
1392         
1393 template <class T> TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
1394         {
1395         return TRgb::Color16MA(aPixel).Value();
1396         }
1397
1398 typedef TUint64 TStackMem;
1399
1400 LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
1401         {
1402         if(aMode == EColor256 || aMode == EGray256)
1403                 {
1404                 return new (mem) TRgbCopy<TUint8>(aMode);
1405                 }
1406         if(aMode == EColor4K || aMode == EColor64K)
1407                 {
1408                 return new (mem) TRgbCopy<TUint16>(aMode);
1409                 }
1410         if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
1411                 {
1412                 return new (mem) TRgbCopy<TUint32>(aMode);
1413                 }
1414         PANIC(KErrNotSupported);
1415         return NULL;
1416         }
1417         
1418
1419 void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1420         {
1421         TStackMem mem = 0;
1422         GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue);   
1423         }
1424         
1425 void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1426         {
1427         TStackMem mem = 0;
1428         GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse);
1429         }
1430         
1431 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1432         {
1433         TStackMem mem = 0;
1434         GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);        
1435         }       
1436
1437 void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1438         {
1439         TStackMem mem = 0;
1440         GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); 
1441         }       
1442
1443 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////7