add some NEON 32bpp blitters
[sdl_omap.git] / src / video / symbian / EKA2 / dsa_old.cpp
1 #include "dsa.h"
2 #include "sdlepocapi.h"
3 #include <cdsb.h>
4
5 LOCAL_C TInt BytesPerPixel(TDisplayMode aMode)
6         {
7         return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; 
8         }
9
10
11 ////////////////////////////////////////////////////////////////////////////////////////////////
12   
13 NONSHARABLE_CLASS(CDsaA) : public CDsa
14         {
15         public:
16                 CDsaA(RWsSession& aSession);
17         private:
18                 ~CDsaA();
19                 TUint8* LockSurface();
20                 void UnlockHWSurfaceRequestComplete();
21                 void UnlockHwSurface();
22                 void CreateSurfaceL();
23                 void Wipe(TInt aLength);
24                 void RecreateL();
25                 void Free();
26                 TInt ExternalUpdate() {return 0;}
27         private:
28                 CFbsBitmap* iBmp;       
29         };
30         
31         
32 CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession)
33         {
34         }
35         
36 void CDsaA::Free()
37         {
38         delete iBmp;
39         iBmp = NULL;
40         }
41
42 CDsaA::~CDsaA()
43         {
44         __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
45         }
46         
47 TUint8* CDsaA::LockSurface()
48         {
49         iBmp->LockHeap();
50         return reinterpret_cast<TUint8*>(iBmp->DataAddress());
51         }
52
53 void CDsaA::UnlockHWSurfaceRequestComplete()
54         {
55         PANIC(KErrNotSupported);
56         }
57
58 void CDsaA::UnlockHwSurface()
59         {
60         iBmp->UnlockHeap();
61         SetUpdating(EFalse);
62         Dsa().Gc()->BitBlt(HwRect().iTl, iBmp);
63         Dsa().ScreenDevice()->Update();
64         }
65
66 void CDsaA::CreateSurfaceL()
67         {
68         delete iBmp;
69         iBmp = NULL;
70         iBmp  = new (ELeave) CFbsBitmap();
71         User::LeaveIfError(iBmp->Create(HwRect().Size(), DisplayMode()));
72         }
73
74 void CDsaA::Wipe(TInt aLength) //dont call in drawing
75         {
76         iBmp->LockHeap();
77         Mem::FillZ(iBmp->DataAddress(), aLength);
78         iBmp->UnlockHeap();
79         }
80         
81 void CDsaA::RecreateL()
82         {
83         }
84
85 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86
87 NONSHARABLE_CLASS(MDsbObs)
88         {
89         public:
90                 virtual void SurfaceReady() = 0;
91                 virtual CDirectScreenBitmap& Dsb() = 0;
92         };
93         
94 NONSHARABLE_CLASS(CDsbSurface) : public CActive
95         {
96         public:
97                 CDsbSurface(MDsbObs& aDsb);
98                 TUint8* Address();
99                 void Complete();
100                 ~CDsbSurface();
101         private:
102                 void RunL();
103                 void DoCancel();
104         private:
105                 MDsbObs& iDsb; 
106                 TUint8* iAddress;
107         };      
108
109 CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb)
110         {
111         CActiveScheduler::Add(this);
112         }
113
114 CDsbSurface::~CDsbSurface()
115         {
116         Cancel();
117         }
118         
119 void CDsbSurface::Complete()
120         {
121         if(iAddress != NULL && !IsActive())
122                 {
123                 iAddress = NULL;
124                 SetActive();
125                 iDsb.Dsb().EndUpdate(iStatus);
126                 }
127         }
128         
129 TUint8* CDsbSurface::Address()
130         {
131         if(iAddress == NULL && !IsActive())
132                 {
133                 TAcceleratedBitmapInfo info;
134                 if(KErrNone == iDsb.Dsb().BeginUpdate(info))
135                         iAddress = info.iAddress;
136                 }
137         return iAddress;
138         }
139         
140 void CDsbSurface::RunL()
141         {
142         iDsb.SurfaceReady();
143         }
144
145 void CDsbSurface::DoCancel()
146         {
147         //empty
148         }
149                 
150 NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs
151         {
152         public:
153                 CDsaB(RWsSession& aSession);
154         private:
155                 ~CDsaB();
156                 TUint8* LockSurface();
157                 void UnlockHWSurfaceRequestComplete();
158                 void UnlockHwSurface();
159                 void CreateSurfaceL();
160                 void Wipe(TInt aLength);
161                 void RecreateL();
162                 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
163                 void Free();
164                 CDirectScreenBitmap& Dsb();
165                 void SurfaceReady();
166                 TInt ExternalUpdate() {return 0;}
167         private:
168                 CDsbSurface* iSurface1;
169                 CDsbSurface* iSurface2;
170                 CDirectScreenBitmap* iDsb;
171         };
172
173 CDsaB::CDsaB(RWsSession& aSession) : CDsa(aSession)
174         {
175         }
176
177 void CDsaB::Free()
178         {
179         }
180         
181 void CDsaB::UnlockHWSurfaceRequestComplete()
182         {
183         iSurface1->Complete();
184         iSurface2->Complete();
185         }       
186
187 void CDsaB::CreateSurfaceL()
188         {
189         }
190         
191 void CDsaB::Wipe(TInt aLength) //dont call in drawing
192         {
193         TUint8* addr = LockSurface();
194         if(addr != NULL) 
195                 {
196                 Mem::FillZ(addr, aLength);
197                 UnlockHwSurface();
198                 }
199         }
200
201 void CDsaB::UnlockHwSurface()
202         {
203         EpocSdlEnv::Request(CDsa::ERequestUpdate);
204         }
205         
206 TUint8* CDsaB::LockSurface()
207         {
208         TUint8* addr =  iSurface1->Address();
209         if(addr == NULL)
210                 addr =  iSurface2->Address();
211         SetUpdating(addr == NULL);
212         return addr;
213         }
214         
215 void CDsaB::SurfaceReady()      
216         {
217         SetUpdating(EFalse);
218         }
219
220 CDirectScreenBitmap& CDsaB::Dsb()
221         {
222         return *iDsb;
223         }
224         
225 void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
226         {
227         if(iDsb == NULL)
228                 iDsb = CDirectScreenBitmap::NewL();     
229         CDsa::ConstructL(aWindow, aDevice);
230         iSurface1 = new (ELeave) CDsbSurface(*this);
231         iSurface2 = new (ELeave) CDsbSurface(*this);
232         }
233         
234 CDsaB::~CDsaB()
235         {
236         delete iSurface1;
237         delete iSurface2;
238         delete iDsb;
239         }       
240
241 void CDsaB::RecreateL()
242         {
243     iDsb->Close();
244     iDsb->Create(HwRect(), CDirectScreenBitmap::EDoubleBuffer);
245         }
246
247 /////////////////////////////////////////////////////////////////////////////////////////////////////   
248
249
250 TSize CDsa::WindowSize() const
251         {
252         TSize size = HwRect().Size();
253         if(iStateFlags & EOrientation90)
254                 {
255                 const TInt tmp = size.iWidth;
256                 size.iWidth = size.iHeight;
257                 size.iHeight = tmp;
258                 }
259         return size;
260         }
261         
262 void CDsa::SetSuspend()
263         {
264         iStateFlags |= ESdlThreadSuspend;
265         }
266
267 void CDsa::ReleaseStop()
268         {
269         iStateFlags &= ~ESdlThreadExplicitStop;
270         }
271
272
273 TBool CDsa::Stopped() const
274         {
275         return (iStateFlags & ESdlThreadExplicitStop);
276         }
277
278 void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation)
279         {
280         TInt flags = 0;
281         switch(aOrientation)
282                 {
283                 case CSDL::EOrientation90:
284                         flags = EOrientation90;
285                         break;
286                 case CSDL::EOrientation180:
287                         flags = EOrientation180;
288                         break;
289                 case CSDL::EOrientation270:
290                         flags = EOrientation90 | EOrientation180;
291                         break;
292                 case CSDL::EOrientation0:
293                         flags = 0;
294                         break;
295                 }
296         if(flags != (iStateFlags & EOrientationFlags))
297                 {
298                 iStateFlags |= EOrientationChanged;
299                 iNewFlags = flags; //cannot be set during drawing...
300                 }
301         }
302
303 CDsa::~CDsa()
304     {
305     if(iDsa != NULL)
306         {
307         iDsa->Cancel();
308         }
309     delete iDsa;
310     User::Free(iLut256);
311     }
312          
313 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
314     {
315     if(iDsa != NULL)
316         {
317         iDsa->Cancel();
318         delete iDsa;
319         iDsa = NULL;
320         }
321         
322         
323     iDsa = CDirectScreenAccess::NewL(
324                                 iSession,
325                                         aDevice,
326                                         aWindow,
327                                         *this);                         
328
329         if(iLut256 == NULL)
330                 iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32));
331         iTargetMode = aWindow.DisplayMode();
332         iTargetBpp = BytesPerPixel(DisplayMode());
333         iTargetRect = TRect(aWindow.Position(), aWindow.Size());
334     RestartL();
335     }
336
337 void CDsa::LockPalette(TBool aLock)
338         {
339         if(aLock)
340                 iStateFlags |= EPaletteLocked;
341         else
342                 iStateFlags &= ~EPaletteLocked;
343         }
344 TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette)
345         {
346         if(iLut256 == NULL)
347                 return KErrNotFound;
348         const TInt count = aCount - aFirst;
349         if(count > 256)
350                 return KErrArgument;
351         if(iStateFlags & EPaletteLocked)
352                 return KErrNone;
353         for(TInt i = aFirst; i < count; i++) //not so busy here:-)
354                 {
355                 iLut256[i] = aPalette[i];
356                 }
357         return KErrNone;
358         }
359         
360         
361
362         
363 void CDsa::RestartL()
364     {
365     //const TBool active = iDsa->IsActive();
366     
367     //if(!active)
368     iDsa->StartL();
369     
370     RRegion* r = iDsa->DrawingRegion();
371     iDsa->Gc()->SetClippingRegion(r);
372     TRect rect = r->BoundingRect();
373    
374     if(rect.IsEmpty())
375         {
376         return;
377         }
378         
379     iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip
380         
381         RecreateL();
382
383     iStateFlags |= ERunning;
384 //    iScanLineWidth = iTargetBpp * HwRect().Width();
385     ReleaseStop();
386     if(iStateFlags & ESdlThreadSuspend)
387         {
388         EpocSdlEnv::Resume();
389         iStateFlags &= ~ ESdlThreadSuspend;
390         }
391     }
392     
393 CDsa::CDsa(RWsSession& aSession) : 
394         iSession(aSession),
395         iStateFlags(0)
396         {
397 //      CActiveScheduler::Add(this);
398         iCFTable[0] = CopyMem;
399         iCFTable[1] = CopyMemFlipReversed;
400         iCFTable[2] = CopyMemReversed;
401         iCFTable[3] = CopyMemFlip;      
402         
403         iCFTable[4] = Copy256;
404         iCFTable[5] = Copy256FlipReversed;
405         iCFTable[6] = Copy256Reversed;
406         iCFTable[7] = Copy256Flip;      
407         
408         
409         iCFTable[8] = CopySlow;
410         iCFTable[9] = CopySlowFlipReversed;
411         iCFTable[10] = CopySlowReversed;
412         iCFTable[11] = CopySlowFlip;    
413         }
414         
415 RWsSession& CDsa::Session()
416         {
417         return iSession;
418         }
419
420
421
422 TUint8* CDsa::LockHwSurface()
423         {
424         if((iStateFlags & EUpdating) == 0) //else frame is skipped
425                 {
426                 return LockSurface();
427                 }
428         return NULL; 
429         }
430
431 /*      
432 void CDsa::RunL()
433         {
434         iStateFlags &= ~EUpdating;
435         }
436                 
437         
438 void CDsa::DoCancel()
439         {
440         iStateFlags &= ~EUpdating;
441         //nothing can do, just wait?
442         }
443 */      
444         
445 TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode)
446         {
447         if(aHwSurface && aMode != DisplayMode())
448                 return KErrArgument;
449         
450         iSourceMode = aMode;
451         
452         iSourceBpp = BytesPerPixel(aMode);
453         
454         const TSize size = WindowSize();
455         if(aSize.iWidth > size.iWidth)
456                 return KErrTooBig;
457         if(aSize.iHeight > size.iHeight)
458                 return KErrTooBig;
459         
460         TRAPD(err, CreateSurfaceL());
461         if(err != KErrNone)
462                 return err;
463
464
465         SetCopyFunction();
466         
467         EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);
468         
469         return KErrNone;
470         }
471         
472
473 /*
474 void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode)
475         {
476         CFbsBitmap* s = new CFbsBitmap();
477         s->Create(aSz, aMode);
478         s->LockHeap();
479         TUint32* addr = s->DataAddress();
480         Mem::Copy(addr, aData, aLength);
481         s->UnlockHeap();
482         s->Save(aName);
483         s->Reset();
484         delete s;
485         }
486         
487 void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz)
488         {
489         CFbsBitmap* s = new CFbsBitmap();
490         s->Create(aSz, EColor64K);
491         TBitmapUtil bmp(s);
492         bmp.Begin(TPoint(0, 0));
493         for(TInt j = 0; j < aSz.iHeight; j++)
494                 {
495                 bmp.SetPos(TPoint(0, j));
496                 for(TInt i = 0; i < aSz.iWidth; i++)
497                         {
498                         bmp.SetPixel(*aData);
499                         aData++;
500                         bmp.IncXPos();
501                         }
502                 }
503         bmp.End();
504         s->Save(aName);
505         s->Reset();
506         delete s;
507         }       
508         
509 TBuf<16> FooName(TInt aFoo)
510         {
511         TBuf<16> b;
512         b.Format(_L("C:\\pic%d.mbm"), aFoo);
513         return b;
514         }
515 */
516 void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TRect& aTargetPos) const
517         {
518         TUint8* target = aTarget;
519         const TUint8* source = aSource;
520         const TInt lineWidth = aRect.Width();
521         source += iSourceBpp * (aRect.iTl.iY * lineWidth); 
522         TInt sourceStartOffset = iSourceBpp *  aRect.iTl.iX;
523         source += sourceStartOffset;
524         target += iTargetBpp * ((aTargetPos.iTl.iY + aRect.iTl.iY ) * lineWidth); 
525         TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iTl.iX);
526         target += targetStartOffset;
527         TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
528         const TInt targetWidth = HwRect().Size().iWidth;
529         const TInt height = aRect.Height(); 
530         
531         TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
532         
533         if(iStateFlags & EOrientation180)
534                 {
535                 
536                 targetPtr += targetWidth *  (height - 1);
537         
538                 for(TInt i = 0; i < height; i++) //source is always smaller
539                         {
540                         iCopyFunction(*this, targetPtr, source, lineWidth, height);
541                         source += lineMove;
542                         targetPtr -= targetWidth;
543                         }
544                 }
545         else
546                 {
547                 
548                 
549                 for(TInt i = 0; i < height; i++) //source is always smaller
550                         {
551                         iCopyFunction(*this, targetPtr, source, lineWidth, height);
552                         source += lineMove;
553                         targetPtr += targetWidth;
554                         }
555                 }
556
557         }
558         
559         
560
561
562 void CDsa::Wipe() //dont call in drawing
563         {
564         if(IsDsaAvailable())
565                 Wipe(iTargetBpp * iScreenRect.Width() * iScreenRect.Height());
566         }
567         
568 void CDsa::SetCopyFunction()
569         {
570         //calculate offset to correct function in iCFTable according to given parameters
571         TInt function = 0;
572         const TInt KCopyFunctions = 4;
573         const TInt KOffsetToNative = 0;
574         const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions;
575         const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
576         const TInt KOffsetTo90Functions = 1;
577         const TInt KOffsetTo180Functions = 2;
578         
579         if(iSourceMode == DisplayMode())
580                 function = KOffsetToNative;             //0
581         else if(iSourceMode == EColor256)
582                 function = KOffsetTo256;                        //4
583         else
584                 function = KOffsetToOtherModes;         //8
585         
586         if(iStateFlags & EOrientation90)
587                 function += KOffsetTo90Functions;       // + 1
588         if(iStateFlags & EOrientation180)
589                 function += KOffsetTo180Functions;      //+ 2
590         
591         iCopyFunction = iCFTable[function];
592         
593         Wipe();
594         }
595         
596 inline void Rotate(TRect& aRect)
597         {
598         const TInt dx = aRect.iBr.iX - aRect.iTl.iX;
599         const TInt dy = aRect.iBr.iY - aRect.iTl.iY;
600
601         aRect.iBr.iX = aRect.iTl.iX + dy;
602         aRect.iBr.iY = aRect.iTl.iY + dx;
603         
604         const TInt tmp = aRect.iTl.iX;
605         aRect.iTl.iX = aRect.iTl.iY;
606         aRect.iTl.iY = tmp;
607         }
608         
609 /*      
610 int bar = 0;
611 */      
612 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
613         {
614
615         if(iStateFlags & EOrientationChanged)
616                 {
617                 iStateFlags &= ~EOrientationFlags;
618                 iStateFlags |= iNewFlags;
619                 SetCopyFunction();
620                 iStateFlags &= ~EOrientationChanged;
621             EpocSdlEnv::WaitDeviceChange();
622             return EFalse; //skip this frame as data is may be changed
623                 }
624
625         if(iTargetAddr == NULL)
626                 {
627                 iTargetAddr = LockHwSurface();
628                 }
629         TUint8* target = iTargetAddr;
630         if(target == NULL)
631                 return EFalse;
632         
633         
634         TRect targetRect = HwRect();
635         TRect sourceRect = aRect;
636         TRect updateRect = aUpdateRect;
637         
638         if(iStateFlags & EOrientation90)
639                 {
640                 Rotate(sourceRect);
641                 Rotate(updateRect);
642                 }
643                 
644         if(iSourceMode != DisplayMode() ||  targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
645                 {
646                 sourceRect.Intersection(targetRect); //so source always smaller or equal than target
647                 updateRect.Intersection(targetRect);
648                 ClipCopy(target, aBits, updateRect, sourceRect);
649                 }
650         else
651                 {
652                 const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
653                 Mem::Copy(target, aBits, byteCount);
654                 }
655
656         return ETrue;
657         }
658         
659 CDsa* CDsa::CreateL(RWsSession& aSession)
660         {
661         if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB))
662                 {
663                 TInt flags = CDirectScreenBitmap::ENone;
664                 if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer))
665                         flags |= CDirectScreenBitmap::EDoubleBuffer;
666                 if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate))
667                         flags |= CDirectScreenBitmap::EIncrementalUpdate;
668                 return new (ELeave) CDsaB(aSession);
669                 }
670     else
671         return new (ELeave) CDsaA(aSession);
672         }       
673
674 void CDsa::CreateZoomerL(const TSize& aSize)
675         {
676         iSwSize = aSize;
677         iStateFlags |= EResizeRequest;
678         CreateSurfaceL();
679         SetTargetRect();
680         }
681         
682 TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const      
683         {
684         TPoint pos = aPoint - iScreenRect.iTl;
685         const TSize asz = iScreenRect.Size();
686         if(iStateFlags & EOrientation180)
687                 {
688                 pos.iX = asz.iWidth - pos.iX;
689                 pos.iY = asz.iHeight - pos.iY;  
690                 }       
691         if(iStateFlags & EOrientation90)
692                 {
693                 pos.iX = aPoint.iY;
694                 pos.iY = aPoint.iX;     
695                 }
696         pos.iX <<= 16;
697         pos.iY <<= 16;
698         pos.iX /= asz.iWidth; 
699         pos.iY /= asz.iHeight;
700         pos.iX *= iSwSize.iWidth;
701         pos.iY *= iSwSize.iHeight;
702         pos.iX >>= 16;
703         pos.iY >>= 16;
704         return pos;     
705         }
706         
707 void CDsa::SetTargetRect()
708         {
709         iTargetRect = iScreenRect;
710         if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio))
711                 {
712                 const TSize asz = iScreenRect.Size();
713                 const TSize sz = iSwSize;
714                 
715                 TRect rect;
716                 
717                 const TInt dh = (sz.iHeight << 16) / sz.iWidth;
718
719                 if((asz.iWidth * dh ) >> 16 <= asz.iHeight)
720                         {
721                         rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16));
722                         }
723                 else
724                         {
725                         const TInt dw = (sz.iWidth << 16) / sz.iHeight;
726                 rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight));
727                         }
728                 rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1);  
729                 
730                 iTargetRect = rect;
731                 iTargetRect.Move(iScreenRect.iTl);
732
733                 } 
734         if(!(iStateFlags & EResizeRequest))
735                 iSwSize = iScreenRect.Size();
736 //      iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth;
737         }
738                 
739 void CDsa::RecreateL()
740         {
741         }
742
743 void CDsa::Free()
744         {
745         }
746                 
747 void CDsa::UpdateSwSurface()
748         {
749         iTargetAddr = NULL;
750         UnlockHwSurface();      //could be faster if does not use AO, but only check status before redraw, then no context switch needed
751         }
752
753 void CDsa::SetBlitter(MBlitter* aBlitter)
754         {
755         iBlitter = aBlitter;
756         }
757         
758 void CDsa::DrawOverlays()
759         {
760         const TInt last = iOverlays.Count() - 1;
761         for(TInt i = last; i >= 0 ; i--)
762                 iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize());
763         }
764
765 TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
766         {
767         TInt i;
768         for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++)
769                 {}
770         const TOverlay overlay = {&aOverlay, aPriority};
771         return iOverlays.Insert(overlay, i);
772         }
773         
774 TInt CDsa::RemoveOverlay(MOverlay& aOverlay)
775         {
776         for(TInt i = 0; i < iOverlays.Count(); i++)
777                 {
778                 if(iOverlays[i].iOverlay == &aOverlay)
779                         {
780                         iOverlays.Remove(i);
781                         return KErrNone;
782                         }
783                 }
784         return KErrNotFound;
785         }
786                 
787 TInt CDsa::RedrawRequest()
788         {
789         if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning)))
790                 {
791                 return ExternalUpdate();
792                 }
793         return KErrNotReady;
794         }
795
796
797 void CDsa::Resume()     
798         {
799         if(Stopped())
800                 Restart(RDirectScreenAccess::ETerminateRegion);
801         }
802         
803 void CDsa::DoStop()
804         {
805         if(IsDsaAvailable())
806                 iStateFlags |= ESdlThreadExplicitStop;
807         Stop();
808         }
809         
810 void CDsa::Stop()
811         {
812         iStateFlags &= ~ERunning;
813 //      Cancel(); //can be called only from main!
814         iDsa->Cancel();
815         }
816         
817 void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
818         {
819 //      iStateFlags |= EChangeNotify;
820         Stop();
821         }
822         
823 void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason)
824         {
825         if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart
826                 {                                                                                               
827                 TRAPD(err, RestartL());
828                 PANIC_IF_ERROR(err);
829                 }
830         }
831 /*)
832 TBool CDsa::ChangeTrigger()
833         {
834         const TBool change = iStateFlags & EChangeNotify;
835         iStateFlags &= ~EChangeNotify;
836         return change;
837         }
838 */      
839 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
840
841 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
842         {
843         TUint32* target = aTarget;
844         const TUint32* endt = target + aBytes; 
845         const TUint8* source = aSource;
846         while(target < endt)
847                 {
848                 *target++ = aDsa.iLut256[*source++]; 
849                 }
850         }
851         
852 void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
853         {
854         const TUint32* target = aTarget;
855         TUint32* endt = aTarget + aBytes; 
856         const TUint8* source = aSource;
857         while(target < endt)
858                 {
859                 *(--endt) = aDsa.iLut256[*source++]; 
860                 }
861         }       
862         
863 void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
864         {
865         TUint32* target = aTarget;
866         const TUint32* endt = target + aBytes; 
867         const TUint8* column = aSource;
868
869         while(target < endt)
870                 {
871                 *target++ = aDsa.iLut256[*column];
872                 column += aLineLen;
873                 }
874         }
875         
876 void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
877         {
878         const TUint32* target = aTarget;
879         TUint32* endt = aTarget + aBytes; 
880         const TUint8* column = aSource;
881
882         while(target < endt)
883                 {
884                 *(--endt) = aDsa.iLut256[*column];
885                 column += aLineLen;
886                 }
887         }               
888
889 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
890         {
891         Mem::Copy(aTarget, aSource, aBytes);
892         }
893         
894 void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
895         {
896         TUint32* target = aTarget;
897         const TUint32* endt = target + aBytes; 
898         const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
899
900         while(target < endt)
901                 {
902                 *target++ = *column;
903                 column += aLineLen;
904                 }
905         }
906         
907 void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
908         {
909         const TUint32* target = aTarget;
910         TUint32* endt = aTarget + aBytes; 
911         const TUint32* source = reinterpret_cast<const TUint32*>(aSource);
912         while(target < endt)
913                 {
914                 *(--endt) = *source++; 
915                 }
916         }       
917         
918         
919 void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
920         {
921         const TUint32* target = aTarget;
922         TUint32* endt = aTarget + aBytes; 
923         const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
924
925         while(target < endt)
926                 {
927                 *(--endt) = *column;
928                 column += aLineLen;
929                 }
930         }
931                         
932
933 typedef TRgb (*TRgbFunc) (TInt aValue);
934
935 LOCAL_C TRgb rgb16MA(TInt aValue)
936         {
937         return TRgb::Color16MA(aValue);
938         }
939         
940 NONSHARABLE_CLASS(MRgbCopy)
941         {
942         public:
943         virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0;
944         virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0;
945         };
946 template <class T>
947 NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
948         {
949         public:
950         TRgbCopy(TDisplayMode aMode);
951         void* operator new(TUint aBytes, TAny* aMem);
952         void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed);
953         void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed);
954         private:
955                 TRgbFunc iFunc;
956         };
957                 
958 template <class T>              
959 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
960         {
961         return aMem;
962         }
963                 
964 template <class T>
965 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
966         {
967         switch(aMode)
968         {
969         case EGray256 : iFunc = TRgb::Gray256; break;
970         case EColor256 : iFunc = TRgb::Color256; break;
971         case EColor4K : iFunc = TRgb::Color4K; break;
972         case EColor64K : iFunc = TRgb::Color64K; break;
973         case EColor16M : iFunc = TRgb::Color16M; break;
974         case EColor16MU : iFunc = TRgb::Color16MU; break;
975         case EColor16MA : iFunc = rgb16MA; break;
976         default:
977                 PANIC(KErrNotSupported);
978         }
979         }
980         
981 template <class T>
982 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed)
983         {
984         const T* source = reinterpret_cast<const T*>(aSource);
985         TUint32* target = aTarget;
986         TUint32* endt = target + aBytes;
987         
988         if(aReversed)
989                 {
990                 while(target < endt)
991                         {
992                         TUint32 value = *source++;
993                         *(--endt) = iFunc(value).Value();
994                         }
995                 }
996         else
997                 {
998                 while(target < endt)
999                         {
1000                         TUint32 value = *source++;
1001                         *target++ = iFunc(value).Value();
1002                         }
1003                 }
1004         }
1005         
1006 template <class T>
1007 void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed)
1008         {
1009         const T* column = reinterpret_cast<const T*>(aSource);
1010         TUint32* target = aTarget;
1011         TUint32* endt = target + aBytes;
1012         
1013         if(aReversed)
1014                 {
1015                 while(target < endt)
1016                         {
1017                         *(--endt) = iFunc(*column).Value();
1018                         column += aLineLen;
1019                         }
1020                 }
1021         else
1022                 {
1023                 while(target < endt)
1024                         {
1025                         *target++ = iFunc(*column).Value();
1026                         column += aLineLen;
1027                         }
1028                 }
1029         }       
1030         
1031
1032 typedef TUint64 TStackMem;
1033
1034 LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
1035         {
1036         if(aMode == EColor256 || aMode == EGray256)
1037                 {
1038                 return new (mem) TRgbCopy<TUint8>(aMode);
1039                 }
1040         if(aMode == EColor4K || aMode == EColor64K)
1041                 {
1042                 return new (mem) TRgbCopy<TUint16>(aMode);
1043                 }
1044         if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
1045                 {
1046                 return new (mem) TRgbCopy<TUint32>(aMode);
1047                 }
1048         PANIC(KErrNotSupported);
1049         return NULL;
1050         }
1051         
1052
1053 void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1054         {
1055         TStackMem mem = 0;
1056         GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue);   
1057         }
1058         
1059 void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
1060         {
1061         TStackMem mem = 0;
1062         GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse);
1063         }
1064         
1065 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1066         {
1067         TStackMem mem = 0;
1068         GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);        
1069         }       
1070
1071 void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
1072         {
1073         TStackMem mem = 0;
1074         GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); 
1075         }