Remove CBitmapSurface.
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blob387cd65f539ade5d419fe2217551552e0ddbcbc7
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 //////////////////////////////////////////////////////////////////////
13 class CDsaGles : public CDsa
15 public:
16 CDsaGles(RWsSession& aSession) : CDsa(aSession) {}
18 private:
19 TUint8* LockSurface() { return NULL; }
20 void UnlockHwSurface() {}
21 void CreateSurfaceL(const TSize& aSize) {}
24 //////////////////////////////////////////////////////////////////////
26 class CDsaBase : public CDsa, public MDirectScreenAccess
28 public:
29 CDsaBase(RWsSession& aSession) : CDsa(aSession) { m_updateWholeScreen = false; }
30 ~CDsaBase();
32 protected:
33 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
34 void Stop();
36 CDirectScreenAccess* iDsa;
38 private:
39 void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
40 void Restart(RDirectScreenAccess::TTerminationReasons aReason);
41 void RestartL();
43 void Free();
45 TUint8* LockSurface();
46 void UnlockHwSurface();
47 void CreateSurfaceL(const TSize& aSize);
49 CFbsBitmap* iBmp;
52 void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
54 CDsa::ConstructL(aWindow, aDevice);
55 if(iDsa != NULL)
57 iDsa->Cancel();
58 delete iDsa;
59 iDsa = NULL;
62 iDsa = CDirectScreenAccess::NewL(Session(), aDevice, aWindow, *this);
63 RestartL();
66 CDsaBase::~CDsaBase()
68 if(iDsa != NULL)
70 iDsa->Cancel();
72 delete iDsa;
75 void CDsaBase::RestartL()
77 iDsa->StartL();
78 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
80 Start();
83 void CDsaBase::Free()
85 delete iBmp;
86 iBmp = NULL;
89 TUint8* CDsaBase::LockSurface()
91 iBmp->LockHeap();
92 return reinterpret_cast<TUint8*>(iBmp->DataAddress());
95 void CDsaBase::UnlockHwSurface()
97 iBmp->UnlockHeap();
98 iDsa->Gc()->BitBlt(TPoint(0, 0), iBmp);
99 iDsa->ScreenDevice()->Update();
102 void CDsaBase::CreateSurfaceL(const TSize& aSize)
104 Free();
105 iBmp = new CFbsBitmap();
106 User::LeaveIfError(iBmp->Create(aSize, DisplayMode()));
109 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
111 Stop();
114 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
116 TRAPD(err, RestartL());
117 if(err == KLeaveExit)
119 Stop();
121 else
123 PANIC_IF_ERROR(err);
127 void CDsaBase::Stop()
129 CDsa::Stop();
130 iDsa->Cancel();
133 ///////////////////////////////////////////////////////////////////////
135 class TDsa
137 public:
138 inline TDsa(const CDsa& aDsa) : iDsa(aDsa) {}
139 inline void Copy(TUint32* aTarget, const TUint8* aSrc, int aBytes) const;
140 private:
141 const CDsa& iDsa;
144 inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, int aBytes) const
146 iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes);
149 template<class T, class S>
150 void ClipCopy(const TDsa& iDsa, TUint8* aTarget,
151 const TUint8* aSource,
152 const TRect& aUpdateRect,
153 const TRect& aSourceRect)
155 const S* source = reinterpret_cast<const S*>(aSource);
156 const int lineWidth = aSourceRect.Width();
158 source += (aUpdateRect.iTl.iY * lineWidth);
159 const int sourceStartOffset = aUpdateRect.iTl.iX;
160 source += sourceStartOffset;
162 T* targetPtr = reinterpret_cast<T*>(aTarget);
164 const int scanLineWidth = aSourceRect.iBr.iX;
166 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
167 const int targetStartOffset = aUpdateRect.iTl.iX;
169 targetPtr += targetStartOffset;
171 const int height = aUpdateRect.Height();
173 const int lineMove = lineWidth;
174 const int copyLen = aUpdateRect.Width();
176 for(int i = 0; i < height; i++) //source is always smaller
178 iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen);
179 source += lineMove;
180 targetPtr += scanLineWidth;
184 /////////////////////////////////////////////////////////////////////////////////////////////////////
186 CDsa* CDsa::CreateL(RWsSession& aSession)
188 return new CDsaBase(aSession);
191 void CDsa::Free()
195 CDsa::~CDsa()
197 delete[] iLut256;
200 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
202 if(iLut256 == NULL)
203 iLut256 = new TUint32[256];
204 iTargetMode = aWindow.DisplayMode();
205 iTargetBpp = BytesPerPixel(DisplayMode());
206 iWindow = &aWindow;
209 int CDsa::SetPalette(int aFirst, int aCount, TUint32* aPalette)
211 if(iLut256 == NULL)
212 return KErrNotFound;
213 for(int i = aFirst; i < aFirst + aCount; i++)
215 iLut256[i] = aPalette[i];
217 return KErrNone;
220 CDsa::CDsa(RWsSession& aSession) :
221 iRunning(false),
222 iSession(aSession)
225 iCFTable[0] = CopyMem;
226 iCFTable[1] = Copy256;
227 iCFTable[2] = CopySlow;
230 RWsSession& CDsa::Session()
232 return iSession;
235 int CDsa::AllocSurface(const TSize& aSize, TDisplayMode aMode)
237 iSourceMode = aMode;
238 iSourceBpp = BytesPerPixel(aMode);
240 TRAPD(err, CreateSurfaceL(aSize));
241 if(err != KErrNone)
242 return err;
244 SetCopyFunction();
246 return KErrNone;
249 void CDsa::ClipCopy(TUint8* aTarget,
250 const TUint8* aSource,
251 const TRect& aUpdateRect,
252 const TRect& aSourceRect) const
254 const TDsa dsa(*this);
255 switch(iSourceBpp)
257 case 1:
258 ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
259 break;
260 case 2:
261 ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
262 break;
263 case 4:
264 ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
265 break;
269 void CDsa::SetCopyFunction()
271 if(iSourceMode == DisplayMode())
272 iCopyFunction = iCFTable[0];
273 else if(iSourceMode == EColor256)
274 iCopyFunction = iCFTable[1];
275 else
276 iCopyFunction = iCFTable[2];
279 bool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
281 if(iTargetAddr == NULL)
283 iTargetAddr = LockSurface();
286 TUint8* target = iTargetAddr;
287 if(target == NULL)
288 return false;
290 TRect sourceRect = aRect;
291 TRect updateRect = aUpdateRect;
293 if(iSourceMode != DisplayMode() || aRect != aUpdateRect)
295 ClipCopy(target, aBits, aUpdateRect, aRect);
297 else
299 const int byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
300 memcpy(target, aBits, byteCount);
303 return true;
306 void CDsa::UpdateSwSurface()
308 iTargetAddr = NULL;
309 UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
312 void CDsa::Stop()
314 iRunning = false;
317 void CDsa::Start()
319 iRunning = true;
322 RWindow* CDsa::Window()
324 return iWindow;
327 CDsa* CDsa::CreateGlesDsaL()
329 CDsa* dsa = new CDsaGles(Session());
330 CWsScreenDevice* dummy = NULL;
331 dsa->ConstructL(*Window(), *dummy);
332 Free();
333 delete this;
334 return dsa;
337 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
339 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes)
341 TUint32* target = aTarget;
342 const TUint32* endt = target + aBytes;
343 const TUint8* source = aSource;
344 while(target < endt)
346 *target++ = aDsa.iLut256[*source++];
350 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, int aBytes)
352 memcpy(aTarget, aSource, aBytes << 2);
355 class MRgbCopy
357 public:
358 virtual void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes) = 0;
361 template <class T>
362 class TRgbCopy : public MRgbCopy
364 public:
365 TRgbCopy(TDisplayMode aMode);
366 void* operator new(TUint aBytes, void* aMem);
367 void Copy(TUint32* aTarget, const TUint8* aSource, int aBytes);
368 static TUint32 Gray256(const TUint8& aPixel);
369 static TUint32 Color256(const TUint8& aPixel);
370 static TUint32 Color4K(const TUint16& aPixel);
371 static TUint32 Color64K(const TUint16& aPixel);
372 static TUint32 Color16M(const TUint32& aPixel);
373 static TUint32 Color16MU(const TUint32& aPixel);
374 static TUint32 Color16MA(const TUint32& aPixel);
375 private:
376 typedef TUint32 (*TRgbFunc) (const T& aValue);
377 TRgbFunc iFunc;
380 template <class T>
381 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, void* aMem)
383 return aMem;
386 template <class T>
387 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
389 switch(aMode)
391 case EGray256 : iFunc = (TRgbFunc) Gray256; break;
392 case EColor256 : iFunc = (TRgbFunc) Color256; break;
393 case EColor4K : iFunc = (TRgbFunc) Color4K; break;
394 case EColor64K : iFunc = (TRgbFunc) Color64K; break;
395 case EColor16M : iFunc = (TRgbFunc) Color16M; break;
396 case EColor16MU : iFunc = (TRgbFunc) Color16MU; break;
397 case EColor16MA : iFunc = (TRgbFunc) Color16MA; break;
398 default:
399 PANIC(KErrNotSupported);
403 template <class T>
404 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, int aBytes)
406 const T* source = reinterpret_cast<const T*>(aSource);
407 TUint32* target = aTarget;
408 TUint32* endt = target + aBytes;
410 while(target < endt)
412 const T value = *source++;
413 *target++ = iFunc(value);
417 template <class T>
418 TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
420 const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
421 return px;
424 template <class T>
425 TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
427 return TRgb::Color256(aPixel).Value();
430 template <class T>
431 TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
433 TUint32 col = (aPixel & 0xF00) << 12;
434 col |= (aPixel & 0xF00) << 8;
436 col |= (aPixel & 0x0F0) << 8;
437 col |= (aPixel & 0x0F0);
439 col |= (aPixel & 0x00F) << 4;
440 col |= (aPixel & 0x00F);
442 return col;
445 template <class T>
446 TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
448 TUint32 col = (aPixel & 0xF800)<< 8;
449 col |= (aPixel & 0xE000) << 3;
451 col |= (aPixel & 0x07E0) << 5;
452 col |= (aPixel & 0xC0) >> 1;
454 col |= (aPixel & 0x07E0) << 3;
455 col |= (aPixel & 0x1C) >> 2;
457 return col;
460 template <class T>
461 TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
463 return TRgb::Color16M(aPixel).Value();
466 template <class T>
467 TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
469 return TRgb::Color16MU(aPixel).Value();
472 template <class T>
473 TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
475 return TRgb::Color16MA(aPixel).Value();
478 typedef TUint64 TStackMem;
480 static MRgbCopy* GetCopy(void* mem, TDisplayMode aMode)
482 if(aMode == EColor256 || aMode == EGray256)
484 return new (mem) TRgbCopy<TUint8>(aMode);
486 if(aMode == EColor4K || aMode == EColor64K)
488 return new (mem) TRgbCopy<TUint16>(aMode);
490 if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
492 return new (mem) TRgbCopy<TUint32>(aMode);
494 PANIC(KErrNotSupported);
495 return NULL;
498 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, int aBytes)
500 TStackMem mem = 0;
501 GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes);