Remove LOCAL_C abomination.
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blobd05fb81c8934e329a49d23676d87225ec3a9bf1e
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 (ELeave) 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, int aHeight) const;
196 private:
197 const CDsa& iDsa;
200 inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, int aBytes, int aHeight) const
202 iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight);
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, height);
236 source += lineMove;
237 targetPtr += scanLineWidth;
241 /////////////////////////////////////////////////////////////////////////////////////////////////////
243 CDsa* CDsa::CreateL(RWsSession& aSession)
245 return new (ELeave) 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 //calculate offset to correct function in iCFTable according to given parameters
361 int function = 0;
362 const int KCopyFunctions = 1;
363 const int KOffsetToNative = 0;
364 const int KOffsetTo256 = KOffsetToNative + KCopyFunctions;
365 const int KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
367 if(iSourceMode == DisplayMode())
368 function = KOffsetToNative;
369 else if(iSourceMode == EColor256)
370 function = KOffsetTo256;
371 else
372 function = KOffsetToOtherModes;
374 iCopyFunction = iCFTable[function];
377 inline void Rotate(TRect& aRect)
379 const int dx = aRect.iBr.iX - aRect.iTl.iX;
380 const int dy = aRect.iBr.iY - aRect.iTl.iY;
382 aRect.iBr.iX = aRect.iTl.iX + dy;
383 aRect.iBr.iY = aRect.iTl.iY + dx;
385 const int tmp = aRect.iTl.iX;
386 aRect.iTl.iX = aRect.iTl.iY;
387 aRect.iTl.iY = tmp;
390 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
392 if(iTargetAddr == NULL)
394 iTargetAddr = LockHwSurface();
397 TUint8* target = iTargetAddr;
398 if(target == NULL)
399 return EFalse;
401 TRect sourceRect = aRect;
402 TRect updateRect = aUpdateRect;
404 if(iSourceMode != DisplayMode() || aRect != aUpdateRect)
406 ClipCopy(target, aBits, aUpdateRect, aRect);
408 else
410 const int byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
411 Mem::Copy(target, aBits, byteCount);
414 return ETrue;
417 void CDsa::UpdateSwSurface()
419 iTargetAddr = NULL;
420 UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
423 void CDsa::DoStop()
425 if(IsDsaAvailable())
426 iStateFlags |= ESdlThreadExplicitStop;
427 Stop();
430 void CDsa::Stop()
432 iStateFlags &= ~ERunning;
435 void CDsa::Start()
437 iStateFlags |= ERunning;
439 iStateFlags &= ~ESdlThreadExplicitStop;
441 if(iStateFlags & ESdlThreadSuspend)
443 EpocSdlEnv::Resume();
444 iStateFlags &= ~ ESdlThreadSuspend;
446 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);
449 RWindow* CDsa::Window()
451 return iWindow;
454 CDsa* CDsa::CreateGlesDsaL()
456 CDsa* dsa = new (ELeave) CDsaGles(Session());
457 CWsScreenDevice* dummy = NULL;
458 dsa->ConstructL(*Window(), *dummy);
459 Free();
460 delete this;
461 return dsa;
464 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
466 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes, int)
468 TUint32* target = aTarget;
469 const TUint32* endt = target + aBytes;
470 const TUint8* source = aSource;
471 while(target < endt)
473 *target++ = aDsa.iLut256[*source++];
477 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, int aBytes, int)
479 const TUint32* src = reinterpret_cast<const TUint32*>(aSource);
480 Mem::Copy(aTarget, src, aBytes << 2);
483 class MRgbCopy
485 public:
486 virtual void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes, TBool aReversed) = 0;
487 virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, int aBytes, int aLineLen, TBool aReversed) = 0;
490 template <class T>
491 class TRgbCopy : public MRgbCopy
493 public:
494 TRgbCopy(TDisplayMode aMode);
495 void* operator new(TUint aBytes, TAny* aMem);
496 void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes, TBool aReversed);
497 void FlipCopy(TUint32* aTarget, const TUint8* aSource, int aBytes, int aLineLen, TBool aReversed);
498 static TUint32 Gray256(const TUint8& aPixel);
499 static TUint32 Color256(const TUint8& aPixel);
500 static TUint32 Color4K(const TUint16& aPixel);
501 static TUint32 Color64K(const TUint16& aPixel);
502 static TUint32 Color16M(const TUint32& aPixel);
503 static TUint32 Color16MU(const TUint32& aPixel);
504 static TUint32 Color16MA(const TUint32& aPixel);
505 private:
506 typedef TUint32 (*TRgbFunc) (const T& aValue);
507 TRgbFunc iFunc;
510 template <class T>
511 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
513 return aMem;
516 template <class T>
517 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
519 switch(aMode)
521 case EGray256 : iFunc = (TRgbFunc) Gray256; break;
522 case EColor256 : iFunc = (TRgbFunc) Color256; break;
523 case EColor4K : iFunc = (TRgbFunc) Color4K; break;
524 case EColor64K : iFunc = (TRgbFunc) Color64K; break;
525 case EColor16M : iFunc = (TRgbFunc) Color16M; break;
526 case EColor16MU : iFunc = (TRgbFunc) Color16MU; break;
527 case EColor16MA : iFunc = (TRgbFunc) Color16MA; break;
528 default:
529 PANIC(KErrNotSupported);
533 template <class T>
534 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, int aBytes, TBool aReversed)
536 const T* source = reinterpret_cast<const T*>(aSource);
537 TUint32* target = aTarget;
538 TUint32* endt = target + aBytes;
540 if(aReversed)
542 while(target < endt)
544 const T value = *source++;
545 *(--endt) = iFunc(value);
548 else
550 while(target < endt)
552 const T value = *source++;
553 *target++ = iFunc(value);
558 template <class T>
559 void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, int aBytes, int aLineLen, TBool aReversed)
561 const T* column = reinterpret_cast<const T*>(aSource);
562 TUint32* target = aTarget;
563 TUint32* endt = target + aBytes;
565 if(aReversed)
567 while(target < endt)
569 *(--endt) = iFunc(*column);
570 column += aLineLen;
573 else
575 while(target < endt)
577 *target++ = iFunc(*column);
578 column += aLineLen;
583 template <class T>
584 TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
586 const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
587 return px;
590 template <class T>
591 TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
593 return TRgb::Color256(aPixel).Value();
596 template <class T>
597 TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
599 TUint32 col = (aPixel & 0xF00) << 12;
600 col |= (aPixel & 0xF00) << 8;
602 col |= (aPixel & 0x0F0) << 8;
603 col |= (aPixel & 0x0F0);
605 col |= (aPixel & 0x00F) << 4;
606 col |= (aPixel & 0x00F);
608 return col;
611 template <class T>
612 TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
614 TUint32 col = (aPixel & 0xF800)<< 8;
615 col |= (aPixel & 0xE000) << 3;
617 col |= (aPixel & 0x07E0) << 5;
618 col |= (aPixel & 0xC0) >> 1;
620 col |= (aPixel & 0x07E0) << 3;
621 col |= (aPixel & 0x1C) >> 2;
623 return col;
626 template <class T>
627 TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
629 return TRgb::Color16M(aPixel).Value();
632 template <class T>
633 TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
635 return TRgb::Color16MU(aPixel).Value();
638 template <class T>
639 TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
641 return TRgb::Color16MA(aPixel).Value();
644 typedef TUint64 TStackMem;
646 static MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
648 if(aMode == EColor256 || aMode == EGray256)
650 return new (mem) TRgbCopy<TUint8>(aMode);
652 if(aMode == EColor4K || aMode == EColor64K)
654 return new (mem) TRgbCopy<TUint16>(aMode);
656 if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
658 return new (mem) TRgbCopy<TUint32>(aMode);
660 PANIC(KErrNotSupported);
661 return NULL;
664 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes, int)
666 TStackMem mem = 0;
667 GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);