Remove window size check from AllocSurface.
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blob980e259e3b2751ead9e60bc39447d820e42b4a0b
1 #include "dsa.h"
2 #include "sdlepocapi.h"
3 #include <cdsb.h>
4 #include <basched.h>
6 LOCAL_C int BytesPerPixel(TDisplayMode aMode)
8 return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1;
11 template<class T>
12 NONSHARABLE_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();
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()
78 Free();
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
88 public:
89 CDsaGles(RWsSession& aSession) : CDsa(aSession) {}
91 private:
92 TUint8* LockSurface() { return NULL; }
93 void UnlockHwSurface() {}
94 void Resume() {}
95 void CreateSurfaceL() {}
98 //////////////////////////////////////////////////////////////////////
100 NONSHARABLE_CLASS(CDsaBase) : public CDsa, public MDirectScreenAccess
102 protected:
103 CDsaBase(RWsSession& aSession) : CDsa(aSession) { m_updateWholeScreen = false; }
104 ~CDsaBase();
105 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
106 void Stop();
107 void Resume();
108 void CompleteUpdate();
109 void DoBlt(CFbsBitmap& aBmp);
110 void CreateSurfaceL(CFbsBitmap& aBmp) {};
112 CDirectScreenAccess* iDsa;
114 private:
115 void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
116 void Restart(RDirectScreenAccess::TTerminationReasons aReason);
117 void RestartL();
120 void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
122 CDsa::ConstructL(aWindow, aDevice);
123 if(iDsa != NULL)
125 iDsa->Cancel();
126 delete iDsa;
127 iDsa = NULL;
130 iDsa = CDirectScreenAccess::NewL(Session(), aDevice, aWindow, *this);
131 RestartL();
134 void CDsaBase::Resume()
136 if(Stopped())
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);
149 else
150 iDsa->Gc()->DrawBitmap(HwRect(), &aBmp);
153 CDsaBase::~CDsaBase()
155 if(iDsa != NULL)
157 iDsa->Cancel();
159 delete iDsa;
162 void CDsaBase::RestartL()
164 iDsa->StartL();
165 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
167 SetTargetRect();
169 Start();
172 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
174 Stop();
177 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
179 TRAPD(err, RestartL());
180 if(err == KLeaveExit)
182 Stop();
184 else
186 PANIC_IF_ERROR(err);
190 void CDsaBase::Stop()
192 CDsa::Stop();
193 iDsa->Cancel();
196 ///////////////////////////////////////////////////////////////////////
198 NONSHARABLE_CLASS(TDsa)
200 public:
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;
204 private:
205 const CDsa& iDsa;
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);
245 source += lineMove;
246 targetPtr += scanLineWidth; // >> 2;
250 /////////////////////////////////////////////////////////////////////////////////////////////////////
252 CDsa* CDsa::CreateL(RWsSession& aSession)
254 return new (ELeave) CBitmapSurface<CDsaBase>(aSession);
257 void CDsa::Free()
261 void CDsa::SetSuspend()
263 iStateFlags |= ESdlThreadSuspend;
267 void CDsa::SetUpdating(TBool aUpdate)
269 if(aUpdate)
270 iStateFlags |= EUpdating;
271 else
272 iStateFlags &= ~EUpdating;
275 TBool CDsa::Stopped() const
277 return (iStateFlags & ESdlThreadExplicitStop);
280 CDsa::~CDsa()
282 delete[] iLut256;
285 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
287 if(iLut256 == NULL)
288 iLut256 = new TUint32[256];
289 iTargetMode = aWindow.DisplayMode();
290 iTargetBpp = BytesPerPixel(DisplayMode());
291 iScreenRect = TRect(aWindow.Position(), aWindow.Size());
292 SetTargetRect();
293 iWindow = &aWindow;
296 void CDsa::DoBlt(CFbsBitmap& /*aBmp*/)
300 void CDsa::LockPalette(TBool aLock)
302 if(aLock)
303 iStateFlags |= EPaletteLocked;
304 else
305 iStateFlags &= ~EPaletteLocked;
308 int CDsa::SetPalette(int aFirst, int aCount, TUint32* aPalette)
310 if(iLut256 == NULL)
311 return KErrNotFound;
312 if(iStateFlags & EPaletteLocked)
313 return KErrNone;
314 for(int i = aFirst; i < aFirst + aCount; i++)
316 iLut256[i] = aPalette[i];
318 return KErrNone;
321 CDsa::CDsa(RWsSession& aSession) :
322 iStateFlags(0),
323 iSession(aSession)
326 iCFTable[0] = CopyMem;
327 iCFTable[1] = Copy256;
328 iCFTable[2] = CopySlow;
331 RWsSession& CDsa::Session()
333 return iSession;
336 TUint8* CDsa::LockHwSurface()
338 if((iStateFlags & EUpdating) == 0) //else frame is skipped
340 return LockSurface();
342 return NULL;
345 int CDsa::AllocSurface(const TSize& aSize, TDisplayMode aMode)
347 iSourceMode = aMode;
349 iSourceBpp = BytesPerPixel(aMode);
351 TRAPD(err, CreateSurfaceL());
352 if(err != KErrNone)
353 return err;
355 SetCopyFunction();
357 return KErrNone;
360 void CDsa::ClipCopy(TUint8* aTarget,
361 const TUint8* aSource,
362 const TRect& aUpdateRect,
363 const TRect& aSourceRect) const
365 const TDsa dsa(*this);
366 switch(iSourceBpp)
368 case 1:
369 ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
370 break;
371 case 2:
372 ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
373 break;
374 case 4:
375 ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
376 break;
380 void CDsa::SetCopyFunction()
382 //calculate offset to correct function in iCFTable according to given parameters
383 int function = 0;
384 const int KCopyFunctions = 1;
385 const int KOffsetToNative = 0;
386 const int KOffsetTo256 = KOffsetToNative + KCopyFunctions;
387 const int KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
389 if(iSourceMode == DisplayMode())
390 function = KOffsetToNative;
391 else if(iSourceMode == EColor256)
392 function = KOffsetTo256;
393 else
394 function = KOffsetToOtherModes;
396 iCopyFunction = iCFTable[function];
399 inline void Rotate(TRect& aRect)
401 const int dx = aRect.iBr.iX - aRect.iTl.iX;
402 const int dy = aRect.iBr.iY - aRect.iTl.iY;
404 aRect.iBr.iX = aRect.iTl.iX + dy;
405 aRect.iBr.iY = aRect.iTl.iY + dx;
407 const int tmp = aRect.iTl.iX;
408 aRect.iTl.iX = aRect.iTl.iY;
409 aRect.iTl.iY = tmp;
412 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
414 if(iTargetAddr == NULL)
416 iTargetAddr = LockHwSurface();
419 TUint8* target = iTargetAddr;
420 if(target == NULL)
421 return EFalse;
424 TRect targetRect = TRect(TPoint(0, 0), SwSize());
426 TRect sourceRect = aRect;
427 TRect updateRect = aUpdateRect;
429 if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect)
431 sourceRect.Intersection(targetRect); //so source always smaller or equal than target
432 ClipCopy(target, aBits, updateRect, sourceRect);
434 else
436 const int byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
437 Mem::Copy(target, aBits, byteCount);
440 return ETrue;
443 void CDsa::UpdateSwSurface()
445 iTargetAddr = NULL;
446 UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
449 void CDsa::DoStop()
451 if(IsDsaAvailable())
452 iStateFlags |= ESdlThreadExplicitStop;
453 Stop();
456 void CDsa::Stop()
458 iStateFlags &= ~ERunning;
461 void CDsa::Start()
463 iStateFlags |= ERunning;
465 iStateFlags &= ~ESdlThreadExplicitStop;
467 if(iStateFlags & ESdlThreadSuspend)
469 EpocSdlEnv::Resume();
470 iStateFlags &= ~ ESdlThreadSuspend;
472 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);
475 void CDsa::SetTargetRect()
477 iTargetRect = iScreenRect;
478 iSwSize = iScreenRect.Size();
481 RWindow* CDsa::Window()
483 return iWindow;
486 CDsa* CDsa::CreateGlesDsaL()
488 CDsa* dsa = new (ELeave) CDsaGles(Session());
489 CWsScreenDevice* dummy = NULL;
490 dsa->ConstructL(*Window(), *dummy);
491 Free();
492 delete this;
493 return dsa;
496 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
498 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes, int)
500 TUint32* target = aTarget;
501 const TUint32* endt = target + aBytes;
502 const TUint8* source = aSource;
503 while(target < endt)
505 *target++ = aDsa.iLut256[*source++];
509 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, int aBytes, int)
511 const TUint32* src = reinterpret_cast<const TUint32*>(aSource);
512 Mem::Copy(aTarget, src, aBytes << 2);
515 NONSHARABLE_CLASS(MRgbCopy)
517 public:
518 virtual void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes, TBool aReversed) = 0;
519 virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, int aBytes, int aLineLen, TBool aReversed) = 0;
522 template <class T>
523 NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
525 public:
526 TRgbCopy(TDisplayMode aMode);
527 void* operator new(TUint aBytes, TAny* aMem);
528 void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes, TBool aReversed);
529 void FlipCopy(TUint32* aTarget, const TUint8* aSource, int aBytes, int aLineLen, TBool aReversed);
530 static TUint32 Gray256(const TUint8& aPixel);
531 static TUint32 Color256(const TUint8& aPixel);
532 static TUint32 Color4K(const TUint16& aPixel);
533 static TUint32 Color64K(const TUint16& aPixel);
534 static TUint32 Color16M(const TUint32& aPixel);
535 static TUint32 Color16MU(const TUint32& aPixel);
536 static TUint32 Color16MA(const TUint32& aPixel);
537 private:
538 typedef TUint32 (*TRgbFunc) (const T& aValue);
539 TRgbFunc iFunc;
542 template <class T>
543 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
545 return aMem;
548 template <class T>
549 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
551 switch(aMode)
553 case EGray256 : iFunc = (TRgbFunc) Gray256; break;
554 case EColor256 : iFunc = (TRgbFunc) Color256; break;
555 case EColor4K : iFunc = (TRgbFunc) Color4K; break;
556 case EColor64K : iFunc = (TRgbFunc) Color64K; break;
557 case EColor16M : iFunc = (TRgbFunc) Color16M; break;
558 case EColor16MU : iFunc = (TRgbFunc) Color16MU; break;
559 case EColor16MA : iFunc = (TRgbFunc) Color16MA; break;
560 default:
561 PANIC(KErrNotSupported);
565 template <class T>
566 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, int aBytes, TBool aReversed)
568 const T* source = reinterpret_cast<const T*>(aSource);
569 TUint32* target = aTarget;
570 TUint32* endt = target + aBytes;
572 if(aReversed)
574 while(target < endt)
576 const T value = *source++;
577 *(--endt) = iFunc(value);
580 else
582 while(target < endt)
584 const T value = *source++;
585 *target++ = iFunc(value);
590 template <class T>
591 void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, int aBytes, int aLineLen, TBool aReversed)
593 const T* column = reinterpret_cast<const T*>(aSource);
594 TUint32* target = aTarget;
595 TUint32* endt = target + aBytes;
597 if(aReversed)
599 while(target < endt)
601 *(--endt) = iFunc(*column);
602 column += aLineLen;
605 else
607 while(target < endt)
609 *target++ = iFunc(*column);
610 column += aLineLen;
615 template <class T>
616 TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
618 const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
619 return px;
622 template <class T>
623 TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
625 return TRgb::Color256(aPixel).Value();
628 template <class T>
629 TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
631 TUint32 col = (aPixel & 0xF00) << 12;
632 col |= (aPixel & 0xF00) << 8;
634 col |= (aPixel & 0x0F0) << 8;
635 col |= (aPixel & 0x0F0);
637 col |= (aPixel & 0x00F) << 4;
638 col |= (aPixel & 0x00F);
640 return col;
643 template <class T>
644 TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
646 TUint32 col = (aPixel & 0xF800)<< 8;
647 col |= (aPixel & 0xE000) << 3;
649 col |= (aPixel & 0x07E0) << 5;
650 col |= (aPixel & 0xC0) >> 1;
652 col |= (aPixel & 0x07E0) << 3;
653 col |= (aPixel & 0x1C) >> 2;
655 return col;
658 template <class T>
659 TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
661 return TRgb::Color16M(aPixel).Value();
664 template <class T>
665 TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
667 return TRgb::Color16MU(aPixel).Value();
670 template <class T>
671 TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
673 return TRgb::Color16MA(aPixel).Value();
676 typedef TUint64 TStackMem;
678 LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
680 if(aMode == EColor256 || aMode == EGray256)
682 return new (mem) TRgbCopy<TUint8>(aMode);
684 if(aMode == EColor4K || aMode == EColor64K)
686 return new (mem) TRgbCopy<TUint16>(aMode);
688 if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
690 return new (mem) TRgbCopy<TUint32>(aMode);
692 PANIC(KErrNotSupported);
693 return NULL;
696 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes, int)
698 TStackMem mem = 0;
699 GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);