2 #include "sdlepocapi.h"
6 LOCAL_C
int BytesPerPixel(TDisplayMode aMode
)
8 return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode
) - 1) >> 3) + 1;
12 NONSHARABLE_CLASS(CBitmapSurface
) : public T
15 CBitmapSurface(RWsSession
& aSession
);
18 void ConstructL(RWindow
& aWindow
, CWsScreenDevice
& aDevice
);
20 TUint8
* LockSurface();
21 void UnlockHwSurface();
22 void CreateSurfaceL();
24 void Update(CFbsBitmap
& aBmp
);
29 void CBitmapSurface
<T
>::ConstructL(RWindow
& aWindow
, CWsScreenDevice
& aDevice
)
31 T::ConstructL(aWindow
, aDevice
);
35 CBitmapSurface
<T
>::CBitmapSurface(RWsSession
& aSession
) : T(aSession
)
40 void CBitmapSurface
<T
>::Free()
48 CBitmapSurface
<T
>::~CBitmapSurface()
50 __ASSERT_DEBUG(iBmp
== NULL
, PANIC(KErrNotReady
));
54 TUint8
* CBitmapSurface
<T
>::LockSurface()
57 return reinterpret_cast<TUint8
*>(iBmp
->DataAddress());
61 void CBitmapSurface
<T
>::UnlockHwSurface()
64 T::SetUpdating(EFalse
);
69 void CBitmapSurface
<T
>::Update(CFbsBitmap
& aBmp
)
76 void CBitmapSurface
<T
>::CreateSurfaceL()
79 iBmp
= new (ELeave
) CFbsBitmap();
80 User::LeaveIfError(iBmp
->Create(T::SwSize(), T::DisplayMode()));
81 T::CreateSurfaceL(*iBmp
);
84 //////////////////////////////////////////////////////////////////////
86 NONSHARABLE_CLASS(CDsaGles
) : public CDsa
89 CDsaGles(RWsSession
& aSession
) : CDsa(aSession
) {}
92 TUint8
* LockSurface() { return NULL
; }
93 void UnlockHwSurface() {}
95 void CreateSurfaceL() {}
98 //////////////////////////////////////////////////////////////////////
100 NONSHARABLE_CLASS(CDsaBase
) : public CDsa
, public MDirectScreenAccess
103 CDsaBase(RWsSession
& aSession
) : CDsa(aSession
) { m_updateWholeScreen
= false; }
105 void ConstructL(RWindow
& aWindow
, CWsScreenDevice
& aDevice
);
108 void CompleteUpdate();
109 void DoBlt(CFbsBitmap
& aBmp
);
110 void CreateSurfaceL(CFbsBitmap
& aBmp
) {};
112 CDirectScreenAccess
* iDsa
;
115 void AbortNow(RDirectScreenAccess::TTerminationReasons aReason
);
116 void Restart(RDirectScreenAccess::TTerminationReasons aReason
);
120 void CDsaBase::ConstructL(RWindow
& aWindow
, CWsScreenDevice
& aDevice
)
122 CDsa::ConstructL(aWindow
, aDevice
);
130 iDsa
= CDirectScreenAccess::NewL(Session(), aDevice
, aWindow
, *this);
134 void CDsaBase::Resume()
137 Restart(RDirectScreenAccess::ETerminateRegion
);
140 void CDsaBase::CompleteUpdate()
142 iDsa
->ScreenDevice()->Update();
145 void CDsaBase::DoBlt(CFbsBitmap
& aBmp
)
147 if(SwSize() == HwRect().Size())
148 iDsa
->Gc()->BitBlt(HwRect().iTl
, &aBmp
);
150 iDsa
->Gc()->DrawBitmap(HwRect(), &aBmp
);
153 CDsaBase::~CDsaBase()
162 void CDsaBase::RestartL()
165 iDsa
->Gc()->SetClippingRegion(iDsa
->DrawingRegion());
172 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons
/*aReason*/)
177 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons
/*aReason*/)
179 TRAPD(err
, RestartL());
180 if(err
== KLeaveExit
)
190 void CDsaBase::Stop()
196 ///////////////////////////////////////////////////////////////////////
198 NONSHARABLE_CLASS(TDsa
)
201 inline TDsa(const CDsa
& aDsa
) : iDsa(aDsa
) {}
202 inline const TSize
& SwSize() const { return iDsa
.SwSize(); }
203 inline void Copy(TUint32
* aTarget
, const TUint8
* aSrc
, int aBytes
, int aHeight
) const;
208 inline void TDsa::Copy(TUint32
* aTarget
, const TUint8
* aSrc
, int aBytes
, int aHeight
) const
210 iDsa
.iCopyFunction(iDsa
, aTarget
, aSrc
, aBytes
, aHeight
);
213 template<class T
, class S
>
214 void ClipCopy(const TDsa
& iDsa
, TUint8
* aTarget
,
215 const TUint8
* aSource
,
216 const TRect
& aUpdateRect
,
217 const TRect
& aSourceRect
)
219 const S
* source
= reinterpret_cast<const S
*>(aSource
);
220 const int lineWidth
= aSourceRect
.Width();
222 source
+= (aUpdateRect
.iTl
.iY
* lineWidth
);
223 const int sourceStartOffset
= aUpdateRect
.iTl
.iX
;
224 source
+= sourceStartOffset
;
226 T
* targetPtr
= reinterpret_cast<T
*>(aTarget
);
228 const int scanLineWidth
= iDsa
.SwSize().iWidth
;
230 targetPtr
+= (aSourceRect
.iTl
.iY
+ aUpdateRect
.iTl
.iY
) * scanLineWidth
;
231 const int targetStartOffset
= (aUpdateRect
.iTl
.iX
+ aSourceRect
.iTl
.iX
);
233 targetPtr
+= targetStartOffset
;
236 const int height
= aUpdateRect
.Height();
238 const int lineMove
= lineWidth
;
239 const int copyLen
= aUpdateRect
.Width();
242 for(int i
= 0; i
< height
; i
++) //source is always smaller
244 iDsa
.Copy(reinterpret_cast<TUint32
*>(targetPtr
), reinterpret_cast<const TUint8
*>(source
), copyLen
, height
);
246 targetPtr
+= scanLineWidth
; // >> 2;
250 /////////////////////////////////////////////////////////////////////////////////////////////////////
252 CDsa
* CDsa::CreateL(RWsSession
& aSession
)
254 return new (ELeave
) CBitmapSurface
<CDsaBase
>(aSession
);
261 TSize
CDsa::WindowSize() const
266 void CDsa::SetSuspend()
268 iStateFlags
|= ESdlThreadSuspend
;
272 void CDsa::SetUpdating(TBool aUpdate
)
275 iStateFlags
|= EUpdating
;
277 iStateFlags
&= ~EUpdating
;
280 TBool
CDsa::Stopped() const
282 return (iStateFlags
& ESdlThreadExplicitStop
);
290 void CDsa::ConstructL(RWindow
& aWindow
, CWsScreenDevice
& /*aDevice*/)
293 iLut256
= new TUint32
[256];
294 iTargetMode
= aWindow
.DisplayMode();
295 iTargetBpp
= BytesPerPixel(DisplayMode());
296 iScreenRect
= TRect(aWindow
.Position(), aWindow
.Size());
301 void CDsa::DoBlt(CFbsBitmap
& /*aBmp*/)
305 void CDsa::LockPalette(TBool aLock
)
308 iStateFlags
|= EPaletteLocked
;
310 iStateFlags
&= ~EPaletteLocked
;
313 int CDsa::SetPalette(int aFirst
, int aCount
, TUint32
* aPalette
)
317 if(iStateFlags
& EPaletteLocked
)
319 for(int i
= aFirst
; i
< aFirst
+ aCount
; i
++)
321 iLut256
[i
] = aPalette
[i
];
326 CDsa::CDsa(RWsSession
& aSession
) :
331 iCFTable
[0] = CopyMem
;
332 iCFTable
[1] = Copy256
;
333 iCFTable
[2] = CopySlow
;
336 RWsSession
& CDsa::Session()
341 TUint8
* CDsa::LockHwSurface()
343 if((iStateFlags
& EUpdating
) == 0) //else frame is skipped
345 return LockSurface();
350 int CDsa::AllocSurface(const TSize
& aSize
, TDisplayMode aMode
)
354 iSourceBpp
= BytesPerPixel(aMode
);
356 const TSize size
= WindowSize();
357 if(aSize
.iWidth
> size
.iWidth
)
359 if(aSize
.iHeight
> size
.iHeight
)
362 TRAPD(err
, CreateSurfaceL());
371 void CDsa::ClipCopy(TUint8
* aTarget
,
372 const TUint8
* aSource
,
373 const TRect
& aUpdateRect
,
374 const TRect
& aSourceRect
) const
376 const TDsa
dsa(*this);
380 ::ClipCopy
<TUint32
, TUint8
>(dsa
, aTarget
, aSource
, aUpdateRect
, aSourceRect
);
383 ::ClipCopy
<TUint32
, TUint16
>(dsa
, aTarget
, aSource
, aUpdateRect
, aSourceRect
);
386 ::ClipCopy
<TUint32
, TUint32
>(dsa
, aTarget
, aSource
, aUpdateRect
, aSourceRect
);
391 void CDsa::SetCopyFunction()
393 //calculate offset to correct function in iCFTable according to given parameters
395 const int KCopyFunctions
= 1;
396 const int KOffsetToNative
= 0;
397 const int KOffsetTo256
= KOffsetToNative
+ KCopyFunctions
;
398 const int KOffsetToOtherModes
= KOffsetTo256
+ KCopyFunctions
;
400 if(iSourceMode
== DisplayMode())
401 function
= KOffsetToNative
;
402 else if(iSourceMode
== EColor256
)
403 function
= KOffsetTo256
;
405 function
= KOffsetToOtherModes
;
407 iCopyFunction
= iCFTable
[function
];
410 inline void Rotate(TRect
& aRect
)
412 const int dx
= aRect
.iBr
.iX
- aRect
.iTl
.iX
;
413 const int dy
= aRect
.iBr
.iY
- aRect
.iTl
.iY
;
415 aRect
.iBr
.iX
= aRect
.iTl
.iX
+ dy
;
416 aRect
.iBr
.iY
= aRect
.iTl
.iY
+ dx
;
418 const int tmp
= aRect
.iTl
.iX
;
419 aRect
.iTl
.iX
= aRect
.iTl
.iY
;
423 TBool
CDsa::AddUpdateRect(const TUint8
* aBits
, const TRect
& aUpdateRect
, const TRect
& aRect
)
425 if(iTargetAddr
== NULL
)
427 iTargetAddr
= LockHwSurface();
430 TUint8
* target
= iTargetAddr
;
435 TRect targetRect
= TRect(TPoint(0, 0), SwSize());
437 TRect sourceRect
= aRect
;
438 TRect updateRect
= aUpdateRect
;
440 if(iSourceMode
!= DisplayMode() || targetRect
!= sourceRect
|| targetRect
!= updateRect
)
442 sourceRect
.Intersection(targetRect
); //so source always smaller or equal than target
443 ClipCopy(target
, aBits
, updateRect
, sourceRect
);
447 const int byteCount
= aRect
.Width() * aRect
.Height() * iSourceBpp
; //this could be stored
448 Mem::Copy(target
, aBits
, byteCount
);
454 void CDsa::UpdateSwSurface()
457 UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
463 iStateFlags
|= ESdlThreadExplicitStop
;
469 iStateFlags
&= ~ERunning
;
474 iStateFlags
|= ERunning
;
476 iStateFlags
&= ~ESdlThreadExplicitStop
;
478 if(iStateFlags
& ESdlThreadSuspend
)
480 EpocSdlEnv::Resume();
481 iStateFlags
&= ~ ESdlThreadSuspend
;
483 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved
);
486 void CDsa::SetTargetRect()
488 iTargetRect
= iScreenRect
;
489 iSwSize
= iScreenRect
.Size();
492 RWindow
* CDsa::Window()
497 CDsa
* CDsa::CreateGlesDsaL()
499 CDsa
* dsa
= new (ELeave
) CDsaGles(Session());
500 CWsScreenDevice
* dummy
= NULL
;
501 dsa
->ConstructL(*Window(), *dummy
);
507 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
509 void CDsa::Copy256(const CDsa
& aDsa
, TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, int)
511 TUint32
* target
= aTarget
;
512 const TUint32
* endt
= target
+ aBytes
;
513 const TUint8
* source
= aSource
;
516 *target
++ = aDsa
.iLut256
[*source
++];
520 void CDsa::CopyMem(const CDsa
& /*aDsa*/, TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, int)
522 const TUint32
* src
= reinterpret_cast<const TUint32
*>(aSource
);
523 Mem::Copy(aTarget
, src
, aBytes
<< 2);
526 NONSHARABLE_CLASS(MRgbCopy
)
529 virtual void Copy(TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, TBool aReversed
) = 0;
530 virtual void FlipCopy(TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, int aLineLen
, TBool aReversed
) = 0;
534 NONSHARABLE_CLASS(TRgbCopy
) : public MRgbCopy
537 TRgbCopy(TDisplayMode aMode
);
538 void* operator new(TUint aBytes
, TAny
* aMem
);
539 void Copy(TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, TBool aReversed
);
540 void FlipCopy(TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, int aLineLen
, TBool aReversed
);
541 static TUint32
Gray256(const TUint8
& aPixel
);
542 static TUint32
Color256(const TUint8
& aPixel
);
543 static TUint32
Color4K(const TUint16
& aPixel
);
544 static TUint32
Color64K(const TUint16
& aPixel
);
545 static TUint32
Color16M(const TUint32
& aPixel
);
546 static TUint32
Color16MU(const TUint32
& aPixel
);
547 static TUint32
Color16MA(const TUint32
& aPixel
);
549 typedef TUint32 (*TRgbFunc
) (const T
& aValue
);
554 void* TRgbCopy
<T
>::operator new(TUint
/*aBytes*/, TAny
* aMem
)
560 TRgbCopy
<T
>::TRgbCopy(TDisplayMode aMode
)
564 case EGray256
: iFunc
= (TRgbFunc
) Gray256
; break;
565 case EColor256
: iFunc
= (TRgbFunc
) Color256
; break;
566 case EColor4K
: iFunc
= (TRgbFunc
) Color4K
; break;
567 case EColor64K
: iFunc
= (TRgbFunc
) Color64K
; break;
568 case EColor16M
: iFunc
= (TRgbFunc
) Color16M
; break;
569 case EColor16MU
: iFunc
= (TRgbFunc
) Color16MU
; break;
570 case EColor16MA
: iFunc
= (TRgbFunc
) Color16MA
; break;
572 PANIC(KErrNotSupported
);
577 void TRgbCopy
<T
>::Copy(TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, TBool aReversed
)
579 const T
* source
= reinterpret_cast<const T
*>(aSource
);
580 TUint32
* target
= aTarget
;
581 TUint32
* endt
= target
+ aBytes
;
587 const T value
= *source
++;
588 *(--endt
) = iFunc(value
);
595 const T value
= *source
++;
596 *target
++ = iFunc(value
);
602 void TRgbCopy
<T
>::FlipCopy(TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, int aLineLen
, TBool aReversed
)
604 const T
* column
= reinterpret_cast<const T
*>(aSource
);
605 TUint32
* target
= aTarget
;
606 TUint32
* endt
= target
+ aBytes
;
612 *(--endt
) = iFunc(*column
);
620 *target
++ = iFunc(*column
);
627 TUint32 TRgbCopy
<T
>::Gray256(const TUint8
& aPixel
)
629 const TUint32 px
= aPixel
<< 16 | aPixel
<< 8 | aPixel
;
634 TUint32 TRgbCopy
<T
>::Color256(const TUint8
& aPixel
)
636 return TRgb::Color256(aPixel
).Value();
640 TUint32 TRgbCopy
<T
>::Color4K(const TUint16
& aPixel
)
642 TUint32 col
= (aPixel
& 0xF00) << 12;
643 col
|= (aPixel
& 0xF00) << 8;
645 col
|= (aPixel
& 0x0F0) << 8;
646 col
|= (aPixel
& 0x0F0);
648 col
|= (aPixel
& 0x00F) << 4;
649 col
|= (aPixel
& 0x00F);
655 TUint32 TRgbCopy
<T
>::Color64K(const TUint16
& aPixel
)
657 TUint32 col
= (aPixel
& 0xF800)<< 8;
658 col
|= (aPixel
& 0xE000) << 3;
660 col
|= (aPixel
& 0x07E0) << 5;
661 col
|= (aPixel
& 0xC0) >> 1;
663 col
|= (aPixel
& 0x07E0) << 3;
664 col
|= (aPixel
& 0x1C) >> 2;
670 TUint32 TRgbCopy
<T
>::Color16M(const TUint32
& aPixel
)
672 return TRgb::Color16M(aPixel
).Value();
676 TUint32 TRgbCopy
<T
>::Color16MU(const TUint32
& aPixel
)
678 return TRgb::Color16MU(aPixel
).Value();
682 TUint32 TRgbCopy
<T
>::Color16MA(const TUint32
& aPixel
)
684 return TRgb::Color16MA(aPixel
).Value();
687 typedef TUint64 TStackMem
;
689 LOCAL_C MRgbCopy
* GetCopy(TAny
* mem
, TDisplayMode aMode
)
691 if(aMode
== EColor256
|| aMode
== EGray256
)
693 return new (mem
) TRgbCopy
<TUint8
>(aMode
);
695 if(aMode
== EColor4K
|| aMode
== EColor64K
)
697 return new (mem
) TRgbCopy
<TUint16
>(aMode
);
699 if(aMode
== EColor16M
|| aMode
== EColor16MU
|| aMode
== EColor16MA
)
701 return new (mem
) TRgbCopy
<TUint32
>(aMode
);
703 PANIC(KErrNotSupported
);
707 void CDsa::CopySlow(const CDsa
& aDsa
, TUint32
* aTarget
, const TUint8
* aSource
, int aBytes
, int)
710 GetCopy(&mem
, aDsa
.iSourceMode
)->Copy(aTarget
, aSource
, aBytes
, EFalse
);