Home | History | Annotate | Download | only in EKA2
      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 	}