Add support for (scaled down) high resolution modes.
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blob6fdc1dc49b223945c7ba8f198acdcbf01e96859e
1 #include "dsa.h"
2 #include "sdlepocapi.h"
3 #include <cdsb.h>
4 #include <basched.h>
6 class CDsaGles : public CDsa
8 public:
9 CDsaGles(RWsSession& aSession) : CDsa(aSession) {}
11 private:
12 TUint8* LockSurface() { return NULL; }
13 void UnlockHwSurface() {}
14 void CreateSurfaceL() {}
17 //////////////////////////////////////////////////////////////////////
19 class CDsaBase : public CDsa, public MDirectScreenAccess
21 public:
22 CDsaBase(RWsSession& aSession) : CDsa(aSession) { m_updateWholeScreen = false; }
23 ~CDsaBase();
25 private:
26 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
27 void Stop();
29 void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
30 void Restart(RDirectScreenAccess::TTerminationReasons aReason);
31 void RestartL();
33 void Free();
35 TUint8* LockSurface();
36 void UnlockHwSurface();
37 void CreateSurfaceL();
39 CDirectScreenAccess* iDsa;
42 void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
44 CDsa::ConstructL(aWindow, aDevice);
45 if(iDsa != NULL)
47 iDsa->Cancel();
48 delete iDsa;
49 iDsa = NULL;
52 iDsa = CDirectScreenAccess::NewL(Session(), aDevice, aWindow, *this);
53 RestartL();
56 CDsaBase::~CDsaBase()
58 if(iDsa != NULL)
60 iDsa->Cancel();
62 delete iDsa;
65 void CDsaBase::RestartL()
67 iDsa->StartL();
68 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
70 Start();
73 void CDsaBase::Free()
75 delete iBmp;
76 iBmp = NULL;
79 TUint8* CDsaBase::LockSurface()
81 iBmp->LockHeap();
82 return (TUint8*)iBmp->DataAddress();
85 void CDsaBase::UnlockHwSurface()
87 iBmp->UnlockHeap();
88 iDsa->Gc()->BitBlt(TPoint(0, 0), iBmp);
89 iDsa->ScreenDevice()->Update();
92 void CDsaBase::CreateSurfaceL()
94 Free();
95 iBmp = new CFbsBitmap();
96 User::LeaveIfError(iBmp->Create(Window()->Size(), EColor64K));
99 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
101 Stop();
104 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
106 TRAPD(err, RestartL());
107 if(err == KLeaveExit)
109 Stop();
111 else
113 PANIC_IF_ERROR(err);
117 void CDsaBase::Stop()
119 CDsa::Stop();
120 iDsa->Cancel();
124 CDsa* CDsa::CreateL(RWsSession& aSession)
126 return new CDsaBase(aSession);
129 void CDsa::Free()
133 CDsa::~CDsa()
135 delete[] iLut256;
138 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
140 if(iLut256 == NULL)
141 iLut256 = new TUint32[256];
142 iWindow = &aWindow;
145 int CDsa::SetPalette(int aFirst, int aCount, TUint32* aPalette)
147 if(iLut256 == NULL)
148 return KErrNotFound;
149 for(int i = aFirst; i < aFirst + aCount; i++)
151 iLut256[i] = aPalette[i];
153 return KErrNone;
156 CDsa::CDsa(RWsSession& aSession) :
157 iBmp(NULL),
158 iRunning(false),
159 iSession(aSession)
163 RWsSession& CDsa::Session()
165 return iSession;
168 int CDsa::AllocSurface(int bpp)
170 iSourceBpp = bpp;
172 TRAPD(err, CreateSurfaceL());
173 return err;
176 bool CDsa::Blit(const TUint8* aBits, const TSize& aSize)
178 TUint16* target = (TUint16*)LockSurface();
179 if(target == NULL)
180 return false;
182 TSize ss = iBmp->SizeInPixels();
184 if( ss != aSize )
186 memset( target, 0, ss.iWidth * ss.iHeight * 2 );
189 if( aSize.iWidth <= ss.iWidth && aSize.iHeight <= ss.iHeight )
191 TUint16* dst = target
192 + ( ( ss.iHeight - aSize.iHeight ) / 2 ) * ss.iWidth
193 + ( ss.iWidth - aSize.iWidth ) / 2;
194 int skip = ss.iWidth - aSize.iWidth;
196 unsigned int h = aSize.iHeight;
198 switch( iSourceBpp )
200 case 1:
202 TUint8* src = (TUint8*)aBits;
205 unsigned int w = aSize.iWidth;
208 *dst++ = iLut256[*src++];
210 while( --w );
211 dst += skip;
213 while( --h );
215 break;
217 case 2:
219 TUint16* src = (TUint16*)aBits;
222 memcpy( dst, src, aSize.iWidth * 2 );
223 dst += ss.iWidth;
224 src += aSize.iWidth;
226 while( --h );
228 break;
230 case 4:
232 TUint32* src = (TUint32*)aBits;
235 unsigned int w = aSize.iWidth;
238 *dst++ =
239 ( ( *src & 0xF80000 ) >> 8 ) |
240 ( ( *src & 0x00FC00 ) >> 5 ) |
241 ( ( *src & 0x0000F8 ) >> 3 );
242 src++;
244 while( --w );
245 dst += skip;
247 while( --h );
249 break;
251 default:
252 break;
255 else
257 TUint16* dst = target
258 + ( ( ss.iHeight - aSize.iHeight / 2 ) / 2 ) * ss.iWidth
259 + ( ss.iWidth - aSize.iWidth / 2 ) / 2;
260 int skip = ss.iWidth - aSize.iWidth / 2;
262 unsigned int h = aSize.iHeight / 2;
264 switch( iSourceBpp )
266 case 1:
268 TUint8* src1 = (TUint8*)aBits;
269 TUint8* src2 = (TUint8*)aBits + aSize.iWidth;
272 unsigned int w = aSize.iWidth / 2;
275 TUint32 c1 = iLut256[*src1++];
276 TUint32 c2 = iLut256[*src1++];
277 TUint32 c3 = iLut256[*src2++];
278 TUint32 c4 = iLut256[*src2++];
280 c1 = ( c1 & 0xF81F ) | ( ( c1 & 0x07E0 ) << 16 );
281 c2 = ( c2 & 0xF81F ) | ( ( c2 & 0x07E0 ) << 16 );
282 c3 = ( c3 & 0xF81F ) | ( ( c3 & 0x07E0 ) << 16 );
283 c4 = ( c4 & 0xF81F ) | ( ( c4 & 0x07E0 ) << 16 );
285 TUint32 c = ( c1 + c2 + c3 + c4 ) / 4;
286 *dst++ = ( c & 0xF81F ) | ( ( c & 0x07E00000 ) >> 16 );
288 while( --w );
289 dst += skip;
290 src1 += aSize.iWidth;
291 src2 += aSize.iWidth;
293 while( --h );
295 break;
297 case 2:
299 TUint16* src1 = (TUint16*)aBits;
300 TUint16* src2 = (TUint16*)aBits + aSize.iWidth;
303 unsigned int w = aSize.iWidth / 2;
306 TUint32 c1 = ( *src1 & 0xF81F ) | ( ( *src1 & 0x07E0 ) << 16 );
307 src1++;
308 TUint32 c2 = ( *src1 & 0xF81F ) | ( ( *src1 & 0x07E0 ) << 16 );
309 src1++;
310 TUint32 c3 = ( *src2 & 0xF81F ) | ( ( *src2 & 0x07E0 ) << 16 );
311 src2++;
312 TUint32 c4 = ( *src2 & 0xF81F ) | ( ( *src2 & 0x07E0 ) << 16 );
313 src2++;
315 TUint32 c = ( c1 + c2 + c3 + c4 ) / 4;
316 *dst++ = ( c & 0xF81F ) | ( ( c & 0x07E00000 ) >> 16 );
318 while( --w );
319 dst += skip;
320 src1 += aSize.iWidth;
321 src2 += aSize.iWidth;
323 while( --h );
325 break;
327 case 4:
329 TUint32* src1 = (TUint32*)aBits;
330 TUint32* src2 = (TUint32*)aBits + aSize.iWidth;
333 unsigned int w = aSize.iWidth / 2;
336 TUint32 c1 = ( ( *src1 & 0xF80000 ) >> 8 ) |
337 ( ( *src1 & 0x00FC00 ) << 11 ) |
338 ( ( *src1 & 0x0000F8 ) >> 3 );
339 src1++;
340 TUint32 c2 = ( ( *src1 & 0xF80000 ) >> 8 ) |
341 ( ( *src1 & 0x00FC00 ) << 11 ) |
342 ( ( *src1 & 0x0000F8 ) >> 3 );
343 src1++;
344 TUint32 c3 = ( ( *src2 & 0xF80000 ) >> 8 ) |
345 ( ( *src2 & 0x00FC00 ) << 11 ) |
346 ( ( *src2 & 0x0000F8 ) >> 3 );
347 src2++;
348 TUint32 c4 = ( ( *src2 & 0xF80000 ) >> 8 ) |
349 ( ( *src2 & 0x00FC00 ) << 11 ) |
350 ( ( *src2 & 0x0000F8 ) >> 3 );
351 src2++;
353 TUint32 c = ( c1 + c2 + c3 + c4 ) / 4;
354 *dst++ = ( c & 0xF81F ) | ( ( c & 0x07E00000 ) >> 16 );
356 while( --w );
357 dst += skip;
358 src1 += aSize.iWidth;
359 src2 += aSize.iWidth;
361 while( --h );
363 break;
365 default:
366 break;
370 UnlockHwSurface();
372 return true;
375 void CDsa::Stop()
377 iRunning = false;
380 void CDsa::Start()
382 iRunning = true;
385 RWindow* CDsa::Window()
387 return iWindow;
390 CDsa* CDsa::CreateGlesDsaL()
392 CDsa* dsa = new CDsaGles(Session());
393 CWsScreenDevice* dummy = NULL;
394 dsa->ConstructL(*Window(), *dummy);
395 Free();
396 delete this;
397 return dsa;