• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "dsa.h"
2 #include "sdlepocapi.h"
3 #include <cdsb.h>
4 
BytesPerPixel(TDisplayMode aMode)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 	}