Simplify CDsa::SetCopyFunction().
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blob7ab28c854408e37e64104e9bb7545bd40ec46b64
1 #include "dsa.h"
2 #include "sdlepocapi.h"
3 #include <cdsb.h>
4 #include <basched.h>
6 static int BytesPerPixel(TDisplayMode aMode)
8 return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1;
11 template<class T>
12 class CBitmapSurface : public T
14 public:
15 CBitmapSurface(RWsSession& aSession);
17 private:
18 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
19 ~CBitmapSurface();
20 TUint8* LockSurface();
21 void UnlockHwSurface();
22 void CreateSurfaceL(const TSize& aSize);
23 void Free();
24 void Update(CFbsBitmap& aBmp);
25 CFbsBitmap* iBmp;
28 template<class T>
29 void CBitmapSurface<T>::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
31 T::ConstructL(aWindow, aDevice);
34 template<class T>
35 CBitmapSurface<T>::CBitmapSurface(RWsSession& aSession) : T(aSession)
39 template<class T>
40 void CBitmapSurface<T>::Free()
42 delete iBmp;
43 iBmp = NULL;
44 T::Free();
47 template<class T>
48 CBitmapSurface<T>::~CBitmapSurface()
50 __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
53 template<class T>
54 TUint8* CBitmapSurface<T>::LockSurface()
56 iBmp->LockHeap();
57 return reinterpret_cast<TUint8*>(iBmp->DataAddress());
60 template<class T>
61 void CBitmapSurface<T>::UnlockHwSurface()
63 iBmp->UnlockHeap();
64 T::SetUpdating(EFalse);
65 Update(*iBmp);
68 template<class T>
69 void CBitmapSurface<T>::Update(CFbsBitmap& aBmp)
71 T::DoBlt(aBmp);
72 T::CompleteUpdate();
75 template<class T>
76 void CBitmapSurface<T>::CreateSurfaceL(const TSize& aSize)
78 Free();
79 iBmp = new CFbsBitmap();
80 User::LeaveIfError(iBmp->Create(aSize, T::DisplayMode()));
83 //////////////////////////////////////////////////////////////////////
85 class CDsaGles : public CDsa
87 public:
88 CDsaGles(RWsSession& aSession) : CDsa(aSession) {}
90 private:
91 TUint8* LockSurface() { return NULL; }
92 void UnlockHwSurface() {}
93 void Resume() {}
94 void CreateSurfaceL(const TSize& aSize) {}
97 //////////////////////////////////////////////////////////////////////
99 class CDsaBase : public CDsa, public MDirectScreenAccess
101 protected:
102 CDsaBase(RWsSession& aSession) : CDsa(aSession) { m_updateWholeScreen = false; }
103 ~CDsaBase();
104 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
105 void Stop();
106 void Resume();
107 void CompleteUpdate();
108 void DoBlt(CFbsBitmap& aBmp);
110 CDirectScreenAccess* iDsa;
112 private:
113 void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
114 void Restart(RDirectScreenAccess::TTerminationReasons aReason);
115 void RestartL();
118 void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
120 CDsa::ConstructL(aWindow, aDevice);
121 if(iDsa != NULL)
123 iDsa->Cancel();
124 delete iDsa;
125 iDsa = NULL;
128 iDsa = CDirectScreenAccess::NewL(Session(), aDevice, aWindow, *this);
129 RestartL();
132 void CDsaBase::Resume()
134 if(Stopped())
135 Restart(RDirectScreenAccess::ETerminateRegion);
138 void CDsaBase::CompleteUpdate()
140 iDsa->ScreenDevice()->Update();
143 void CDsaBase::DoBlt(CFbsBitmap& aBmp)
145 iDsa->Gc()->BitBlt(TPoint(0, 0), &aBmp);
148 CDsaBase::~CDsaBase()
150 if(iDsa != NULL)
152 iDsa->Cancel();
154 delete iDsa;
157 void CDsaBase::RestartL()
159 iDsa->StartL();
160 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
162 Start();
165 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
167 Stop();
170 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
172 TRAPD(err, RestartL());
173 if(err == KLeaveExit)
175 Stop();
177 else
179 PANIC_IF_ERROR(err);
183 void CDsaBase::Stop()
185 CDsa::Stop();
186 iDsa->Cancel();
189 ///////////////////////////////////////////////////////////////////////
191 class TDsa
193 public:
194 inline TDsa(const CDsa& aDsa) : iDsa(aDsa) {}
195 inline void Copy(TUint32* aTarget, const TUint8* aSrc, int aBytes) const;
196 private:
197 const CDsa& iDsa;
200 inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, int aBytes) const
202 iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes);
205 template<class T, class S>
206 void ClipCopy(const TDsa& iDsa, TUint8* aTarget,
207 const TUint8* aSource,
208 const TRect& aUpdateRect,
209 const TRect& aSourceRect)
211 const S* source = reinterpret_cast<const S*>(aSource);
212 const int lineWidth = aSourceRect.Width();
214 source += (aUpdateRect.iTl.iY * lineWidth);
215 const int sourceStartOffset = aUpdateRect.iTl.iX;
216 source += sourceStartOffset;
218 T* targetPtr = reinterpret_cast<T*>(aTarget);
220 const int scanLineWidth = aSourceRect.iBr.iX;
222 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
223 const int targetStartOffset = aUpdateRect.iTl.iX;
225 targetPtr += targetStartOffset;
227 const int height = aUpdateRect.Height();
229 const int lineMove = lineWidth;
230 const int copyLen = aUpdateRect.Width();
233 for(int i = 0; i < height; i++) //source is always smaller
235 iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen);
236 source += lineMove;
237 targetPtr += scanLineWidth;
241 /////////////////////////////////////////////////////////////////////////////////////////////////////
243 CDsa* CDsa::CreateL(RWsSession& aSession)
245 return new CBitmapSurface<CDsaBase>(aSession);
248 void CDsa::Free()
252 void CDsa::SetSuspend()
254 iStateFlags |= ESdlThreadSuspend;
258 void CDsa::SetUpdating(TBool aUpdate)
260 if(aUpdate)
261 iStateFlags |= EUpdating;
262 else
263 iStateFlags &= ~EUpdating;
266 TBool CDsa::Stopped() const
268 return (iStateFlags & ESdlThreadExplicitStop);
271 CDsa::~CDsa()
273 delete[] iLut256;
276 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
278 if(iLut256 == NULL)
279 iLut256 = new TUint32[256];
280 iTargetMode = aWindow.DisplayMode();
281 iTargetBpp = BytesPerPixel(DisplayMode());
282 iWindow = &aWindow;
285 void CDsa::DoBlt(CFbsBitmap& /*aBmp*/)
289 int CDsa::SetPalette(int aFirst, int aCount, TUint32* aPalette)
291 if(iLut256 == NULL)
292 return KErrNotFound;
293 for(int i = aFirst; i < aFirst + aCount; i++)
295 iLut256[i] = aPalette[i];
297 return KErrNone;
300 CDsa::CDsa(RWsSession& aSession) :
301 iStateFlags(0),
302 iSession(aSession)
305 iCFTable[0] = CopyMem;
306 iCFTable[1] = Copy256;
307 iCFTable[2] = CopySlow;
310 RWsSession& CDsa::Session()
312 return iSession;
315 TUint8* CDsa::LockHwSurface()
317 if((iStateFlags & EUpdating) == 0) //else frame is skipped
319 return LockSurface();
321 return NULL;
324 int CDsa::AllocSurface(const TSize& aSize, TDisplayMode aMode)
326 iSourceMode = aMode;
327 iSourceBpp = BytesPerPixel(aMode);
329 TRAPD(err, CreateSurfaceL(aSize));
330 if(err != KErrNone)
331 return err;
333 SetCopyFunction();
335 return KErrNone;
338 void CDsa::ClipCopy(TUint8* aTarget,
339 const TUint8* aSource,
340 const TRect& aUpdateRect,
341 const TRect& aSourceRect) const
343 const TDsa dsa(*this);
344 switch(iSourceBpp)
346 case 1:
347 ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
348 break;
349 case 2:
350 ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
351 break;
352 case 4:
353 ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
354 break;
358 void CDsa::SetCopyFunction()
360 if(iSourceMode == DisplayMode())
361 iCopyFunction = iCFTable[0];
362 else if(iSourceMode == EColor256)
363 iCopyFunction = iCFTable[1];
364 else
365 iCopyFunction = iCFTable[2];
368 inline void Rotate(TRect& aRect)
370 const int dx = aRect.iBr.iX - aRect.iTl.iX;
371 const int dy = aRect.iBr.iY - aRect.iTl.iY;
373 aRect.iBr.iX = aRect.iTl.iX + dy;
374 aRect.iBr.iY = aRect.iTl.iY + dx;
376 const int tmp = aRect.iTl.iX;
377 aRect.iTl.iX = aRect.iTl.iY;
378 aRect.iTl.iY = tmp;
381 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
383 if(iTargetAddr == NULL)
385 iTargetAddr = LockHwSurface();
388 TUint8* target = iTargetAddr;
389 if(target == NULL)
390 return EFalse;
392 TRect sourceRect = aRect;
393 TRect updateRect = aUpdateRect;
395 if(iSourceMode != DisplayMode() || aRect != aUpdateRect)
397 ClipCopy(target, aBits, aUpdateRect, aRect);
399 else
401 const int byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
402 memcpy(target, aBits, byteCount);
405 return ETrue;
408 void CDsa::UpdateSwSurface()
410 iTargetAddr = NULL;
411 UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
414 void CDsa::DoStop()
416 if(IsDsaAvailable())
417 iStateFlags |= ESdlThreadExplicitStop;
418 Stop();
421 void CDsa::Stop()
423 iStateFlags &= ~ERunning;
426 void CDsa::Start()
428 iStateFlags |= ERunning;
430 iStateFlags &= ~ESdlThreadExplicitStop;
432 if(iStateFlags & ESdlThreadSuspend)
434 EpocSdlEnv::Resume();
435 iStateFlags &= ~ ESdlThreadSuspend;
439 RWindow* CDsa::Window()
441 return iWindow;
444 CDsa* CDsa::CreateGlesDsaL()
446 CDsa* dsa = new CDsaGles(Session());
447 CWsScreenDevice* dummy = NULL;
448 dsa->ConstructL(*Window(), *dummy);
449 Free();
450 delete this;
451 return dsa;
454 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
456 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes)
458 TUint32* target = aTarget;
459 const TUint32* endt = target + aBytes;
460 const TUint8* source = aSource;
461 while(target < endt)
463 *target++ = aDsa.iLut256[*source++];
467 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, int aBytes)
469 memcpy(aTarget, aSource, aBytes << 2);
472 class MRgbCopy
474 public:
475 virtual void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes) = 0;
478 template <class T>
479 class TRgbCopy : public MRgbCopy
481 public:
482 TRgbCopy(TDisplayMode aMode);
483 void* operator new(TUint aBytes, void* aMem);
484 void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes);
485 static TUint32 Gray256(const TUint8& aPixel);
486 static TUint32 Color256(const TUint8& aPixel);
487 static TUint32 Color4K(const TUint16& aPixel);
488 static TUint32 Color64K(const TUint16& aPixel);
489 static TUint32 Color16M(const TUint32& aPixel);
490 static TUint32 Color16MU(const TUint32& aPixel);
491 static TUint32 Color16MA(const TUint32& aPixel);
492 private:
493 typedef TUint32 (*TRgbFunc) (const T& aValue);
494 TRgbFunc iFunc;
497 template <class T>
498 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, void* aMem)
500 return aMem;
503 template <class T>
504 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
506 switch(aMode)
508 case EGray256 : iFunc = (TRgbFunc) Gray256; break;
509 case EColor256 : iFunc = (TRgbFunc) Color256; break;
510 case EColor4K : iFunc = (TRgbFunc) Color4K; break;
511 case EColor64K : iFunc = (TRgbFunc) Color64K; break;
512 case EColor16M : iFunc = (TRgbFunc) Color16M; break;
513 case EColor16MU : iFunc = (TRgbFunc) Color16MU; break;
514 case EColor16MA : iFunc = (TRgbFunc) Color16MA; break;
515 default:
516 PANIC(KErrNotSupported);
520 template <class T>
521 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, int aBytes)
523 const T* source = reinterpret_cast<const T*>(aSource);
524 TUint32* target = aTarget;
525 TUint32* endt = target + aBytes;
527 while(target < endt)
529 const T value = *source++;
530 *target++ = iFunc(value);
534 template <class T>
535 TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
537 const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
538 return px;
541 template <class T>
542 TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
544 return TRgb::Color256(aPixel).Value();
547 template <class T>
548 TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
550 TUint32 col = (aPixel & 0xF00) << 12;
551 col |= (aPixel & 0xF00) << 8;
553 col |= (aPixel & 0x0F0) << 8;
554 col |= (aPixel & 0x0F0);
556 col |= (aPixel & 0x00F) << 4;
557 col |= (aPixel & 0x00F);
559 return col;
562 template <class T>
563 TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
565 TUint32 col = (aPixel & 0xF800)<< 8;
566 col |= (aPixel & 0xE000) << 3;
568 col |= (aPixel & 0x07E0) << 5;
569 col |= (aPixel & 0xC0) >> 1;
571 col |= (aPixel & 0x07E0) << 3;
572 col |= (aPixel & 0x1C) >> 2;
574 return col;
577 template <class T>
578 TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
580 return TRgb::Color16M(aPixel).Value();
583 template <class T>
584 TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
586 return TRgb::Color16MU(aPixel).Value();
589 template <class T>
590 TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
592 return TRgb::Color16MA(aPixel).Value();
595 typedef TUint64 TStackMem;
597 static MRgbCopy* GetCopy(void* mem, TDisplayMode aMode)
599 if(aMode == EColor256 || aMode == EGray256)
601 return new (mem) TRgbCopy<TUint8>(aMode);
603 if(aMode == EColor4K || aMode == EColor64K)
605 return new (mem) TRgbCopy<TUint16>(aMode);
607 if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
609 return new (mem) TRgbCopy<TUint32>(aMode);
611 PANIC(KErrNotSupported);
612 return NULL;
615 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes)
617 TStackMem mem = 0;
618 GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes);