Drop support for dirty rectangles.
[SDL.s60v3.git] / src / video / symbian / dsa.cpp
blob61bd0226ff2704de4464a437b0b69747961eabb4
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 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(const TSize& aSize);
39 CFbsBitmap* iBmp;
40 CDirectScreenAccess* iDsa;
43 void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
45 CDsa::ConstructL(aWindow, aDevice);
46 if(iDsa != NULL)
48 iDsa->Cancel();
49 delete iDsa;
50 iDsa = NULL;
53 iDsa = CDirectScreenAccess::NewL(Session(), aDevice, aWindow, *this);
54 RestartL();
57 CDsaBase::~CDsaBase()
59 if(iDsa != NULL)
61 iDsa->Cancel();
63 delete iDsa;
66 void CDsaBase::RestartL()
68 iDsa->StartL();
69 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
71 Start();
74 void CDsaBase::Free()
76 delete iBmp;
77 iBmp = NULL;
80 TUint8* CDsaBase::LockSurface()
82 iBmp->LockHeap();
83 return (TUint8*)iBmp->DataAddress();
86 void CDsaBase::UnlockHwSurface()
88 iBmp->UnlockHeap();
89 iDsa->Gc()->BitBlt(TPoint(0, 0), iBmp);
90 iDsa->ScreenDevice()->Update();
93 void CDsaBase::CreateSurfaceL(const TSize& aSize)
95 Free();
96 iBmp = new CFbsBitmap();
97 User::LeaveIfError(iBmp->Create(aSize, EColor64K));
100 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
102 Stop();
105 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
107 TRAPD(err, RestartL());
108 if(err == KLeaveExit)
110 Stop();
112 else
114 PANIC_IF_ERROR(err);
118 void CDsaBase::Stop()
120 CDsa::Stop();
121 iDsa->Cancel();
124 ///////////////////////////////////////////////////////////////////////
126 void ClipCopy1(const CDsa& iDsa, TUint8* aTarget,
127 const TUint8* aSource,
128 const TRect& aUpdateRect,
129 const TRect& aSourceRect)
131 const TUint8* source = (const TUint8*)aSource;
132 const int lineWidth = aSourceRect.Width();
134 source += (aUpdateRect.iTl.iY * lineWidth);
135 const int sourceStartOffset = aUpdateRect.iTl.iX;
136 source += sourceStartOffset;
138 TUint16* targetPtr = (TUint16*)aTarget;
140 int scanLineWidth = aSourceRect.iBr.iX;
142 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
143 const int targetStartOffset = aUpdateRect.iTl.iX;
145 targetPtr += targetStartOffset;
147 const int height = aUpdateRect.Height();
149 const int copyLen = aUpdateRect.Width();
150 const int lineMove = lineWidth - copyLen;
151 scanLineWidth -= copyLen;
153 for(int i = 0; i < height; i++) //source is always smaller
155 int w = copyLen;
158 *targetPtr++ = iDsa.iLut256[*source++];
160 while(--w);
162 source += lineMove;
163 targetPtr += scanLineWidth;
167 void ClipCopy2(const CDsa& iDsa, TUint8* aTarget,
168 const TUint8* aSource,
169 const TRect& aUpdateRect,
170 const TRect& aSourceRect)
172 const TUint16* source = (const TUint16*)aSource;
173 const int lineWidth = aSourceRect.Width();
175 source += (aUpdateRect.iTl.iY * lineWidth);
176 const int sourceStartOffset = aUpdateRect.iTl.iX;
177 source += sourceStartOffset;
179 TUint16* targetPtr = (TUint16*)aTarget;
181 const int scanLineWidth = aSourceRect.iBr.iX;
183 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
184 const int targetStartOffset = aUpdateRect.iTl.iX;
186 targetPtr += targetStartOffset;
188 const int height = aUpdateRect.Height();
190 const int lineMove = lineWidth;
191 const int copyLen = aUpdateRect.Width() * 2;
193 for(int i = 0; i < height; i++) //source is always smaller
195 memcpy( targetPtr, source, copyLen );
196 source += lineMove;
197 targetPtr += scanLineWidth;
201 void ClipCopy4(const CDsa& iDsa, TUint8* aTarget,
202 const TUint8* aSource,
203 const TRect& aUpdateRect,
204 const TRect& aSourceRect)
206 const TUint32* source = (const TUint32*)aSource;
207 const int lineWidth = aSourceRect.Width();
209 source += (aUpdateRect.iTl.iY * lineWidth);
210 const int sourceStartOffset = aUpdateRect.iTl.iX;
211 source += sourceStartOffset;
213 TUint16* targetPtr = (TUint16*)aTarget;
215 int scanLineWidth = aSourceRect.iBr.iX;
217 targetPtr += aUpdateRect.iTl.iY * scanLineWidth;
218 const int targetStartOffset = aUpdateRect.iTl.iX;
220 targetPtr += targetStartOffset;
222 const int height = aUpdateRect.Height();
224 const int copyLen = aUpdateRect.Width();
225 const int lineMove = lineWidth - copyLen;
226 scanLineWidth -= copyLen;
228 for(int i = 0; i < height; i++) //source is always smaller
230 int w = copyLen;
233 *targetPtr++ =
234 ( ( *source & 0xF80000 ) >> 8 ) |
235 ( ( *source & 0x00FC00 ) >> 5 ) |
236 ( ( *source & 0x0000F8 ) >> 3 );
237 source++;
239 while(--w);
241 source += lineMove;
242 targetPtr += scanLineWidth;
246 /////////////////////////////////////////////////////////////////////////////////////////////////////
248 CDsa* CDsa::CreateL(RWsSession& aSession)
250 return new CDsaBase(aSession);
253 void CDsa::Free()
257 CDsa::~CDsa()
259 delete[] iLut256;
262 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
264 if(iLut256 == NULL)
265 iLut256 = new TUint32[256];
266 iWindow = &aWindow;
269 int CDsa::SetPalette(int aFirst, int aCount, TUint32* aPalette)
271 if(iLut256 == NULL)
272 return KErrNotFound;
273 for(int i = aFirst; i < aFirst + aCount; i++)
275 iLut256[i] = aPalette[i];
277 return KErrNone;
280 CDsa::CDsa(RWsSession& aSession) :
281 iRunning(false),
282 iSession(aSession)
287 RWsSession& CDsa::Session()
289 return iSession;
292 int CDsa::AllocSurface(const TSize& aSize, int bpp)
294 iSourceBpp = bpp;
296 TRAPD(err, CreateSurfaceL(aSize));
297 if(err != KErrNone)
298 return err;
300 return KErrNone;
303 void CDsa::ClipCopy(TUint8* aTarget,
304 const TUint8* aSource,
305 const TRect& aUpdateRect,
306 const TRect& aSourceRect) const
308 switch(iSourceBpp)
310 case 1:
311 ::ClipCopy1(*this, aTarget, aSource, aUpdateRect, aSourceRect);
312 break;
313 case 2:
314 ::ClipCopy2(*this, aTarget, aSource, aUpdateRect, aSourceRect);
315 break;
316 case 4:
317 ::ClipCopy4(*this, aTarget, aSource, aUpdateRect, aSourceRect);
318 break;
322 bool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
324 if(iTargetAddr == NULL)
326 iTargetAddr = LockSurface();
329 TUint8* target = iTargetAddr;
330 if(target == NULL)
331 return false;
333 TRect sourceRect = aRect;
334 TRect updateRect = aUpdateRect;
336 ClipCopy(target, aBits, aUpdateRect, aRect);
338 return true;
341 void CDsa::UpdateSwSurface()
343 iTargetAddr = NULL;
344 UnlockHwSurface();
347 void CDsa::Stop()
349 iRunning = false;
352 void CDsa::Start()
354 iRunning = true;
357 RWindow* CDsa::Window()
359 return iWindow;
362 CDsa* CDsa::CreateGlesDsaL()
364 CDsa* dsa = new CDsaGles(Session());
365 CWsScreenDevice* dummy = NULL;
366 dsa->ConstructL(*Window(), *dummy);
367 Free();
368 delete this;
369 return dsa;
372 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
374 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, int aBytes)
376 memcpy(aTarget, aSource, aBytes << 2);