add some NEON 32bpp blitters
[sdl_omap.git] / src / video / symbian / EKA2 / dsa_new.cpp
CommitLineData
e14743d1 1#include "dsa.h"
2#include "sdlepocapi.h"
3#include <cdsb.h>
4
5
6LOCAL_C TInt BytesPerPixel(TDisplayMode aMode)
7 {
8 return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1;
9 }
10
11
12NONSHARABLE_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
25inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa)
26 {
27 }
28
29inline TBool TDsa::IsTurn() const
30 {
31 return iDsa.iStateFlags & CDsa::EOrientation90;
32 }
33
34inline TBool TDsa::IsFlip() const
35 {
36 return iDsa.iStateFlags & CDsa::EOrientation180;
37 }
38
39inline const TSize& TDsa::SwSize() const
40 {
41 return iDsa.SwSize();
42 }
43
44inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const
45 {
46 iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight);
47 }
48
49template<class T, class S>
50void 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
106NONSHARABLE_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
128CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession)
129 {
130 }
131
132
133void CDsaA::Free()
134 {
135 delete iBmp;
136 iBmp = NULL;
137 }
138
139CDsaA::~CDsaA()
140 {
141 __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
142 delete iCopyBmp;
143 }
144
145TUint8* CDsaA::LockSurface()
146 {
147 iBmp->LockHeap();
148 return reinterpret_cast<TUint8*>(iBmp->DataAddress());
149 }
150
151void CDsaA::UnlockHWSurfaceRequestComplete()
152 {
153 PANIC(KErrNotSupported);
154 }
155
156void CDsaA::UnlockHwSurface()
157 {
158 iBmp->UnlockHeap();
159 SetUpdating(EFalse);
160 Update(*iBmp);
161 }
162
163void 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 }
175void CDsaA::CreateSurfaceL()
176 {
177 delete iBmp;
178 iBmp = NULL;
179 iBmp = new (ELeave) CFbsBitmap();
180 User::LeaveIfError(iBmp->Create(SwSize(), DisplayMode()));
181 }
182
183void 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
192TInt 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
204void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
205 {
206 iCopyBmp = new (ELeave) CFbsBitmap();
207 CDsa::ConstructL(aWindow, aDevice);
208 }
209
210
211//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
212
213NONSHARABLE_CLASS(MDsbObs)
214 {
215 public:
216 virtual void SurfaceReady() = 0;
217 virtual CDirectScreenBitmap& Dsb() = 0;
218 };
219
220NONSHARABLE_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
235CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb)
236 {
237 CActiveScheduler::Add(this);
238 }
239
240CDsbSurface::~CDsbSurface()
241 {
242 Cancel();
243 }
244
245void CDsbSurface::Complete()
246 {
247 if(iAddress != NULL && !IsActive())
248 {
249 iAddress = NULL;
250 SetActive();
251 iDsb.Dsb().EndUpdate(iStatus);
252 }
253 }
254
255TUint8* 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
266void CDsbSurface::RunL()
267 {
268 iDsb.SurfaceReady();
269 }
270
271void CDsbSurface::DoCancel()
272 {
273 //empty
274 }
275
276NONSHARABLE_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
299CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsa(aSession), iType(aFlags)
300 {
301 }
302
303
304
305void CDsaB::UnlockHWSurfaceRequestComplete()
306 {
307 iSurface1->Complete();
308 if(iSurface2 != NULL)
309 iSurface2->Complete();
310 }
311
312void CDsaB::CreateSurfaceL()
313 {
314 __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported));
315 }
316
317void 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
328void CDsaB::UnlockHwSurface()
329 {
330 EpocSdlEnv::Request(CDsa::ERequestUpdate);
331 }
332
333TUint8* 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
342void CDsaB::SurfaceReady()
343 {
344 SetUpdating(EFalse);
345 }
346
347CDirectScreenBitmap& CDsaB::Dsb()
348 {
349 return *iDsb;
350 }
351
352void 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
363CDsaB::~CDsaB()
364 {
365 delete iSurface1;
366 delete iSurface2;
367 delete iDsb;
368 }
369
370void CDsaB::RecreateL()
371 {
372 iDsb->Close();
373 iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType));
374 }
375
376TInt CDsaB::ExternalUpdate()
377 {
378 if(LockSurface())
379 {
380 UnlockHWSurfaceRequestComplete();
381 return KErrNone;
382 }
383 return KErrNotReady;
384 }
385
386
387/////////////////////////////////////////////////////////////////////////////////////////////////////
388
389
390CDsa* 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
406void CDsa::RecreateL()
407 {
408 }
409
410void CDsa::Free()
411 {
412 }
413
414TSize 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
426void CDsa::SetSuspend()
427 {
428 iStateFlags |= ESdlThreadSuspend;
429 }
430
431void CDsa::ReleaseStop()
432 {
433 iStateFlags &= ~ESdlThreadExplicitStop;
434 }
435
436
437TBool CDsa::Stopped() const
438 {
439 return (iStateFlags & ESdlThreadExplicitStop);
440 }
441
442void 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
467CDsa::~CDsa()
468 {
469 if(iDsa != NULL)
470 {
471 iDsa->Cancel();
472 }
473 iOverlays.Close();
474 delete iDsa;
475 User::Free(iLut256);
476 }
477
478void 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
502void 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
509TInt 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
518TInt 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
531void CDsa::LockPalette(TBool aLock)
532 {
533 if(aLock)
534 iStateFlags |= EPaletteLocked;
535 else
536 iStateFlags &= ~EPaletteLocked;
537 }
538TInt 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
556void 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
592CDsa::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
614RWsSession& CDsa::Session()
615 {
616 return iSession;
617 }
618
619TInt CDsa::RedrawRequest()
620 {
621 if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning)))
622 {
623 return ExternalUpdate();
624 }
625 return KErrNotReady;
626 }
627
628TUint8* CDsa::LockHwSurface()
629 {
630 if((iStateFlags & EUpdating) == 0) //else frame is skipped
631 {
632 return LockSurface();
633 }
634 return NULL;
635 }
636
637/*
638void CDsa::RunL()
639 {
640 iStateFlags &= ~EUpdating;
641 }
642
643
644void CDsa::DoCancel()
645 {
646 iStateFlags &= ~EUpdating;
647 //nothing can do, just wait?
648 }
649*/
650
651
652TInt 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
677void CDsa::CreateZoomerL(const TSize& aSize)
678 {
679 iSwSize = aSize;
680 iStateFlags |= EResizeRequest;
681 CreateSurfaceL();
682 SetTargetRect();
683 }
684
685
686/*
687void 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
700void 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
722TBuf<16> FooName(TInt aFoo)
723 {
724 TBuf<16> b;
725 b.Format(_L("C:\\pic%d.mbm"), aFoo);
726 return b;
727 }
728
729void 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/*
750void 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
808void 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 /*
854void 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
879void CDsa::Wipe() //dont call in drawing
880 {
881 if(IsDsaAvailable())
882 Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight);
883 }
884
885void 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
913inline 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/*
927int bar = 0;
928*/
929/*
930TBool 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
983TBool 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 }
1029void 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
1036void CDsa::Resume()
1037 {
1038 if(Stopped())
1039 Restart(RDirectScreenAccess::ETerminateRegion);
1040 }
1041
1042void CDsa::DoStop()
1043 {
1044 if(IsDsaAvailable())
1045 iStateFlags |= ESdlThreadExplicitStop;
1046 Stop();
1047 }
1048
1049void CDsa::Stop()
1050 {
1051 iStateFlags &= ~ERunning;
1052// Cancel(); //can be called only from main!
1053 iDsa->Cancel();
1054 }
1055
1056void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
1057 {
1058// iStateFlags |= EChangeNotify;
1059 Stop();
1060 }
1061
1062void 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
1071void CDsa::SetBlitter(MBlitter* aBlitter)
1072 {
1073 iBlitter = aBlitter;
1074 }
1075
1076
1077TPoint 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
1102void 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/*)
1135TBool CDsa::ChangeTrigger()
1136 {
1137 const TBool change = iStateFlags & EChangeNotify;
1138 iStateFlags &= ~EChangeNotify;
1139 return change;
1140 }
1141*/
1142/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1143
1144void 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
1155void 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
1166void 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
1179void 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
1192void 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
1198void 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
1211void 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
1223void 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
1238LOCAL_C TRgb rgb16MA(TInt aValue)
1239 {
1240 return TRgb::Color16MA(aValue);
1241 }
1242*/
1243NONSHARABLE_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
1250template <class T>
1251NONSHARABLE_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
1271template <class T>
1272void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
1273 {
1274 return aMem;
1275 }
1276
1277template <class T>
1278TRgbCopy<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
1294template <class T>
1295void 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
1319template <class T>
1320void 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
1344template <class T> TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
1345 {
1346 const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
1347 return px;
1348 }
1349
1350template <class T> TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
1351 {
1352 return TRgb::Color256(aPixel).Value();
1353 }
1354
1355template <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
1369template <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
1383template <class T> TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
1384 {
1385 return TRgb::Color16M(aPixel).Value();
1386 }
1387
1388template <class T> TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
1389 {
1390 return TRgb::Color16MU(aPixel).Value();
1391 }
1392
1393template <class T> TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
1394 {
1395 return TRgb::Color16MA(aPixel).Value();
1396 }
1397
1398typedef TUint64 TStackMem;
1399
1400LOCAL_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
1419void 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
1425void 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
1431void 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
1437void 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