Force hardware pixel format to 565.
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blobfcb7e330b4843e224f0c673a3ea73a8a832a3513
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(const TSize& aSize) {}
17 //////////////////////////////////////////////////////////////////////
19 class CDsaBase : public CDsa, public MDirectScreenAccess
21 public:
22 CDsaBase(RWsSession& aSession) : CDsa(aSession), iBmp( NULL ) { m_updateWholeScreen = false; }
23 ~CDsaBase();
25 protected:
26 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
27 void Stop();
29 CDirectScreenAccess* iDsa;
31 private:
32 void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
33 void Restart(RDirectScreenAccess::TTerminationReasons aReason);
34 void RestartL();
36 void Free();
38 TUint8* LockSurface();
39 void UnlockHwSurface();
40 void CreateSurfaceL(const TSize& aSize);
42 CFbsBitmap* iBmp;
45 void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
47 CDsa::ConstructL(aWindow, aDevice);
48 if(iDsa != NULL)
50 iDsa->Cancel();
51 delete iDsa;
52 iDsa = NULL;
55 iDsa = CDirectScreenAccess::NewL(Session(), aDevice, aWindow, *this);
56 RestartL();
59 CDsaBase::~CDsaBase()
61 if(iDsa != NULL)
63 iDsa->Cancel();
65 delete iDsa;
68 void CDsaBase::RestartL()
70 iDsa->StartL();
71 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
73 Start();
76 void CDsaBase::Free()
78 delete iBmp;
79 iBmp = NULL;
82 TUint8* CDsaBase::LockSurface()
84 iBmp->LockHeap();
85 return (TUint8*)iBmp->DataAddress();
88 void CDsaBase::UnlockHwSurface()
90 iBmp->UnlockHeap();
91 iDsa->Gc()->BitBlt(TPoint(0, 0), iBmp);
92 iDsa->ScreenDevice()->Update();
95 void CDsaBase::CreateSurfaceL(const TSize& aSize)
97 Free();
98 iBmp = new CFbsBitmap();
99 User::LeaveIfError(iBmp->Create(aSize, EColor64K));
102 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
104 Stop();
107 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
109 TRAPD(err, RestartL());
110 if(err == KLeaveExit)
112 Stop();
114 else
116 PANIC_IF_ERROR(err);
120 void CDsaBase::Stop()
122 CDsa::Stop();
123 iDsa->Cancel();
126 ///////////////////////////////////////////////////////////////////////
128 void ClipCopy1(const CDsa& iDsa, TUint8* aTarget,
129 const TUint8* aSource,
130 const TRect& aUpdateRect,
131 const TRect& aSourceRect)
133 const TUint8* source = (const TUint8*)aSource;
134 const int lineWidth = aSourceRect.Width();
136 source += (aUpdateRect.iTl.iY * lineWidth);
137 const int sourceStartOffset = aUpdateRect.iTl.iX;
138 source += sourceStartOffset;
140 TUint16* targetPtr = (TUint16*)aTarget;
142 int scanLineWidth = aSourceRect.iBr.iX;
144 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
145 const int targetStartOffset = aUpdateRect.iTl.iX;
147 targetPtr += targetStartOffset;
149 const int height = aUpdateRect.Height();
151 const int copyLen = aUpdateRect.Width();
152 const int lineMove = lineWidth - copyLen;
153 scanLineWidth -= copyLen;
155 for(int i = 0; i < height; i++) //source is always smaller
157 int w = copyLen;
160 *targetPtr++ = iDsa.iLut256[*source++];
162 while(--w);
164 source += lineMove;
165 targetPtr += scanLineWidth;
169 void ClipCopy2(const CDsa& iDsa, TUint8* aTarget,
170 const TUint8* aSource,
171 const TRect& aUpdateRect,
172 const TRect& aSourceRect)
174 const TUint16* source = (const TUint16*)aSource;
175 const int lineWidth = aSourceRect.Width();
177 source += (aUpdateRect.iTl.iY * lineWidth);
178 const int sourceStartOffset = aUpdateRect.iTl.iX;
179 source += sourceStartOffset;
181 TUint16* targetPtr = (TUint16*)aTarget;
183 const int scanLineWidth = aSourceRect.iBr.iX;
185 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
186 const int targetStartOffset = aUpdateRect.iTl.iX;
188 targetPtr += targetStartOffset;
190 const int height = aUpdateRect.Height();
192 const int lineMove = lineWidth;
193 const int copyLen = aUpdateRect.Width() * 2;
195 for(int i = 0; i < height; i++) //source is always smaller
197 memcpy( targetPtr, source, copyLen );
198 source += lineMove;
199 targetPtr += scanLineWidth;
203 void ClipCopy4(const CDsa& iDsa, TUint8* aTarget,
204 const TUint8* aSource,
205 const TRect& aUpdateRect,
206 const TRect& aSourceRect)
208 const TUint32* source = (const TUint32*)aSource;
209 const int lineWidth = aSourceRect.Width();
211 source += (aUpdateRect.iTl.iY * lineWidth);
212 const int sourceStartOffset = aUpdateRect.iTl.iX;
213 source += sourceStartOffset;
215 TUint16* targetPtr = (TUint16*)aTarget;
217 int scanLineWidth = aSourceRect.iBr.iX;
219 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
220 const int targetStartOffset = aUpdateRect.iTl.iX;
222 targetPtr += targetStartOffset;
224 const int height = aUpdateRect.Height();
226 const int copyLen = aUpdateRect.Width();
227 const int lineMove = lineWidth - copyLen;
228 scanLineWidth -= copyLen;
230 for(int i = 0; i < height; i++) //source is always smaller
232 int w = copyLen;
235 *targetPtr++ =
236 ( ( *source & 0xF80000 ) >> 8 ) |
237 ( ( *source & 0x00FC00 ) >> 5 ) |
238 ( ( *source & 0x0000F8 ) >> 3 );
239 source++;
241 while(--w);
243 source += lineMove;
244 targetPtr += scanLineWidth;
248 /////////////////////////////////////////////////////////////////////////////////////////////////////
250 CDsa* CDsa::CreateL(RWsSession& aSession)
252 return new CDsaBase(aSession);
255 void CDsa::Free()
259 CDsa::~CDsa()
261 delete[] iLut256;
264 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
266 if(iLut256 == NULL)
267 iLut256 = new TUint32[256];
268 iWindow = &aWindow;
271 int CDsa::SetPalette(int aFirst, int aCount, TUint32* aPalette)
273 if(iLut256 == NULL)
274 return KErrNotFound;
275 for(int i = aFirst; i < aFirst + aCount; i++)
277 iLut256[i] = aPalette[i];
279 return KErrNone;
282 CDsa::CDsa(RWsSession& aSession) :
283 iRunning(false),
284 iSession(aSession)
289 RWsSession& CDsa::Session()
291 return iSession;
294 int CDsa::AllocSurface(const TSize& aSize, int bpp)
296 iSourceBpp = bpp;
298 TRAPD(err, CreateSurfaceL(aSize));
299 if(err != KErrNone)
300 return err;
302 return KErrNone;
305 void CDsa::ClipCopy(TUint8* aTarget,
306 const TUint8* aSource,
307 const TRect& aUpdateRect,
308 const TRect& aSourceRect) const
310 switch(iSourceBpp)
312 case 1:
313 ::ClipCopy1(*this, aTarget, aSource, aUpdateRect, aSourceRect);
314 break;
315 case 2:
316 ::ClipCopy2(*this, aTarget, aSource, aUpdateRect, aSourceRect);
317 break;
318 case 4:
319 ::ClipCopy4(*this, aTarget, aSource, aUpdateRect, aSourceRect);
320 break;
324 bool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
326 if(iTargetAddr == NULL)
328 iTargetAddr = LockSurface();
331 TUint8* target = iTargetAddr;
332 if(target == NULL)
333 return false;
335 TRect sourceRect = aRect;
336 TRect updateRect = aUpdateRect;
338 ClipCopy(target, aBits, aUpdateRect, aRect);
340 return true;
343 void CDsa::UpdateSwSurface()
345 iTargetAddr = NULL;
346 UnlockHwSurface();
349 void CDsa::Stop()
351 iRunning = false;
354 void CDsa::Start()
356 iRunning = true;
359 RWindow* CDsa::Window()
361 return iWindow;
364 CDsa* CDsa::CreateGlesDsaL()
366 CDsa* dsa = new CDsaGles(Session());
367 CWsScreenDevice* dummy = NULL;
368 dsa->ConstructL(*Window(), *dummy);
369 Free();
370 delete this;
371 return dsa;
374 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
376 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, int aBytes)
378 memcpy(aTarget, aSource, aBytes << 2);