Remove mouse pointer related event handling.
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blob3062431e45d64ca0e5bdedb88663f1e698c77325
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 TSize CDsa::WindowSize() const
263 return iSwSize;
266 void CDsa::SetSuspend()
268 iStateFlags |= ESdlThreadSuspend;
272 void CDsa::SetUpdating(TBool aUpdate)
274 if(aUpdate)
275 iStateFlags |= EUpdating;
276 else
277 iStateFlags &= ~EUpdating;
280 TBool CDsa::Stopped() const
282 return (iStateFlags & ESdlThreadExplicitStop);
285 CDsa::~CDsa()
287 delete[] iLut256;
290 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
292 if(iLut256 == NULL)
293 iLut256 = new TUint32[256];
294 iTargetMode = aWindow.DisplayMode();
295 iTargetBpp = BytesPerPixel(DisplayMode());
296 iScreenRect = TRect(aWindow.Position(), aWindow.Size());
297 SetTargetRect();
298 iWindow = &aWindow;
301 void CDsa::DoBlt(CFbsBitmap& /*aBmp*/)
305 void CDsa::LockPalette(TBool aLock)
307 if(aLock)
308 iStateFlags |= EPaletteLocked;
309 else
310 iStateFlags &= ~EPaletteLocked;
313 int CDsa::SetPalette(int aFirst, int aCount, TUint32* aPalette)
315 if(iLut256 == NULL)
316 return KErrNotFound;
317 if(iStateFlags & EPaletteLocked)
318 return KErrNone;
319 for(int i = aFirst; i < aFirst + aCount; i++)
321 iLut256[i] = aPalette[i];
323 return KErrNone;
326 CDsa::CDsa(RWsSession& aSession) :
327 iStateFlags(0),
328 iSession(aSession)
331 iCFTable[0] = CopyMem;
332 iCFTable[1] = Copy256;
333 iCFTable[2] = CopySlow;
336 RWsSession& CDsa::Session()
338 return iSession;
341 TUint8* CDsa::LockHwSurface()
343 if((iStateFlags & EUpdating) == 0) //else frame is skipped
345 return LockSurface();
347 return NULL;
350 int CDsa::AllocSurface(const TSize& aSize, TDisplayMode aMode)
352 iSourceMode = aMode;
354 iSourceBpp = BytesPerPixel(aMode);
356 const TSize size = WindowSize();
357 if(aSize.iWidth > size.iWidth)
358 return KErrTooBig;
359 if(aSize.iHeight > size.iHeight)
360 return KErrTooBig;
362 TRAPD(err, CreateSurfaceL());
363 if(err != KErrNone)
364 return err;
366 SetCopyFunction();
368 return KErrNone;
371 void CDsa::ClipCopy(TUint8* aTarget,
372 const TUint8* aSource,
373 const TRect& aUpdateRect,
374 const TRect& aSourceRect) const
376 const TDsa dsa(*this);
377 switch(iSourceBpp)
379 case 1:
380 ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
381 break;
382 case 2:
383 ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
384 break;
385 case 4:
386 ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
387 break;
391 void CDsa::SetCopyFunction()
393 //calculate offset to correct function in iCFTable according to given parameters
394 int function = 0;
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;
404 else
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;
420 aRect.iTl.iY = tmp;
423 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
425 if(iTargetAddr == NULL)
427 iTargetAddr = LockHwSurface();
430 TUint8* target = iTargetAddr;
431 if(target == NULL)
432 return EFalse;
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);
445 else
447 const int byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
448 Mem::Copy(target, aBits, byteCount);
451 return ETrue;
454 void CDsa::UpdateSwSurface()
456 iTargetAddr = NULL;
457 UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
460 void CDsa::DoStop()
462 if(IsDsaAvailable())
463 iStateFlags |= ESdlThreadExplicitStop;
464 Stop();
467 void CDsa::Stop()
469 iStateFlags &= ~ERunning;
472 void CDsa::Start()
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()
494 return iWindow;
497 CDsa* CDsa::CreateGlesDsaL()
499 CDsa* dsa = new (ELeave) CDsaGles(Session());
500 CWsScreenDevice* dummy = NULL;
501 dsa->ConstructL(*Window(), *dummy);
502 Free();
503 delete this;
504 return dsa;
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;
514 while(target < endt)
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)
528 public:
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;
533 template <class T>
534 NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
536 public:
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);
548 private:
549 typedef TUint32 (*TRgbFunc) (const T& aValue);
550 TRgbFunc iFunc;
553 template <class T>
554 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
556 return aMem;
559 template <class T>
560 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
562 switch(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;
571 default:
572 PANIC(KErrNotSupported);
576 template <class T>
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;
583 if(aReversed)
585 while(target < endt)
587 const T value = *source++;
588 *(--endt) = iFunc(value);
591 else
593 while(target < endt)
595 const T value = *source++;
596 *target++ = iFunc(value);
601 template <class T>
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;
608 if(aReversed)
610 while(target < endt)
612 *(--endt) = iFunc(*column);
613 column += aLineLen;
616 else
618 while(target < endt)
620 *target++ = iFunc(*column);
621 column += aLineLen;
626 template <class T>
627 TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
629 const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
630 return px;
633 template <class T>
634 TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
636 return TRgb::Color256(aPixel).Value();
639 template <class T>
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);
651 return col;
654 template <class T>
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;
666 return col;
669 template <class T>
670 TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
672 return TRgb::Color16M(aPixel).Value();
675 template <class T>
676 TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
678 return TRgb::Color16MU(aPixel).Value();
681 template <class T>
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);
704 return NULL;
707 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes, int)
709 TStackMem mem = 0;
710 GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);