Mercurial > sdl-ios-xcode
comparison src/video/symbian/EKA2/dsa.cpp @ 3975:e85e65aec22f SDL-1.2
Added S60 port.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sun, 24 Jun 2007 18:26:35 +0000 |
parents | |
children | ce8046809062 |
comparison
equal
deleted
inserted
replaced
3974:42578e98a295 | 3975:e85e65aec22f |
---|---|
1 #include "dsa.h" | |
2 #include "sdlepocapi.h" | |
3 #include <cdsb.h> | |
4 | |
5 | |
6 LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) | |
7 { | |
8 return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; | |
9 } | |
10 | |
11 | |
12 | |
13 | |
14 template<class T> | |
15 class CBitmapSurface : public T | |
16 { | |
17 public: | |
18 CBitmapSurface(RWsSession& aSession); | |
19 private: | |
20 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); | |
21 ~CBitmapSurface(); | |
22 TUint8* LockSurface(); | |
23 void UnlockHwSurface(); | |
24 void CreateSurfaceL(); | |
25 void Wipe(TInt aLength); | |
26 void Free(); | |
27 void Update(CFbsBitmap& aBmp); | |
28 TInt ExternalUpdate(); | |
29 private: | |
30 CFbsBitmap* iBmp; | |
31 CFbsBitmap* iCopyBmp; | |
32 }; | |
33 | |
34 | |
35 template<class T> | |
36 void CBitmapSurface<T>::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) | |
37 { | |
38 delete iCopyBmp; | |
39 iCopyBmp = NULL; | |
40 iCopyBmp = new (ELeave) CFbsBitmap(); | |
41 T::ConstructL(aWindow, aDevice); | |
42 } | |
43 | |
44 template<class T> | |
45 CBitmapSurface<T>::CBitmapSurface(RWsSession& aSession) : T(aSession) | |
46 { | |
47 } | |
48 | |
49 template<class T> | |
50 void CBitmapSurface<T>::Free() | |
51 { | |
52 delete iBmp; | |
53 iBmp = NULL; | |
54 T::Free(); | |
55 } | |
56 | |
57 template<class T> | |
58 CBitmapSurface<T>::~CBitmapSurface() | |
59 { | |
60 __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady)); | |
61 delete iCopyBmp; | |
62 } | |
63 | |
64 template<class T> | |
65 TUint8* CBitmapSurface<T>::LockSurface() | |
66 { | |
67 iBmp->LockHeap(); | |
68 return reinterpret_cast<TUint8*>(iBmp->DataAddress()); | |
69 } | |
70 | |
71 | |
72 template<class T> | |
73 void CBitmapSurface<T>::UnlockHwSurface() | |
74 { | |
75 iBmp->UnlockHeap(); | |
76 T::SetUpdating(EFalse); | |
77 Update(*iBmp); | |
78 } | |
79 | |
80 | |
81 template<class T> | |
82 void CBitmapSurface<T>::Update(CFbsBitmap& aBmp) | |
83 { | |
84 if(!T::Blitter(aBmp)) | |
85 { | |
86 if(T::SwSize() == T::HwRect().Size()) | |
87 T::Gc().BitBlt(T::HwRect().iTl, &aBmp); | |
88 else | |
89 T::Gc().DrawBitmap(T::HwRect(), &aBmp); | |
90 } | |
91 T::DrawOverlays(); | |
92 T::CompleteUpdate(); | |
93 } | |
94 | |
95 template<class T> | |
96 void CBitmapSurface<T>::CreateSurfaceL() | |
97 { | |
98 Free(); | |
99 iBmp = new (ELeave) CFbsBitmap(); | |
100 User::LeaveIfError(iBmp->Create(T::SwSize(), T::DisplayMode())); | |
101 T::CreateSurfaceL(*iBmp); | |
102 } | |
103 | |
104 template<class T> | |
105 void CBitmapSurface<T>::Wipe(TInt aLength) //dont call in drawing | |
106 { | |
107 iBmp->LockHeap(); | |
108 Mem::FillZ(iBmp->DataAddress(), aLength); | |
109 iBmp->UnlockHeap(); | |
110 } | |
111 | |
112 template<class T> | |
113 TInt CBitmapSurface<T>::ExternalUpdate() | |
114 { | |
115 if(iCopyBmp->Handle() == 0) | |
116 { | |
117 const TInt err = iCopyBmp->Duplicate(iBmp->Handle()); | |
118 if(err != KErrNone) | |
119 return err; | |
120 } | |
121 Update(*iCopyBmp); | |
122 return KErrNone; | |
123 } | |
124 | |
125 | |
126 ////////////////////////////////////////////////////////////////////// | |
127 | |
128 | |
129 | |
130 NONSHARABLE_CLASS(CDsaBitgdi) : public CDsa | |
131 { | |
132 public: | |
133 CDsaBitgdi(RWsSession& aSession); | |
134 protected: | |
135 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); | |
136 CBitmapContext& Gc(); | |
137 void CompleteUpdate(); | |
138 ~CDsaBitgdi(); | |
139 void CreateSurfaceL(CFbsBitmap& aBmp); | |
140 void Free(); | |
141 void UnlockHWSurfaceRequestComplete(); | |
142 private: | |
143 void Resume(); | |
144 | |
145 CFbsBitGc* iGc; | |
146 CFbsDevice* iDevice; | |
147 CFbsBitmap* iBitGdiBmp; | |
148 CWindowGc* iWinGc; | |
149 RWindow* iWindow; | |
150 TInt iHandle; | |
151 }; | |
152 | |
153 | |
154 CDsaBitgdi::CDsaBitgdi(RWsSession& aSession) : CDsa(aSession) | |
155 { | |
156 } | |
157 | |
158 CDsaBitgdi::~CDsaBitgdi() | |
159 { | |
160 delete iWinGc; | |
161 delete iBitGdiBmp; | |
162 } | |
163 | |
164 void CDsaBitgdi::CompleteUpdate() | |
165 { | |
166 EpocSdlEnv::Request(CDsa::ERequestUpdate); | |
167 } | |
168 | |
169 | |
170 void CDsaBitgdi::UnlockHWSurfaceRequestComplete() | |
171 { | |
172 if(iHandle == 0) | |
173 return; | |
174 | |
175 if(iBitGdiBmp == NULL) | |
176 { | |
177 iBitGdiBmp = new CFbsBitmap(); | |
178 if(iBitGdiBmp == NULL) | |
179 return; | |
180 iBitGdiBmp->Duplicate(iHandle); | |
181 } | |
182 | |
183 iWindow->Invalidate(); | |
184 | |
185 iWindow->BeginRedraw(); | |
186 iWinGc->Activate(*iWindow); | |
187 iWinGc->BitBlt(TPoint(0, 0), iBitGdiBmp); | |
188 iWinGc->Deactivate(); | |
189 iWindow->EndRedraw(); | |
190 } | |
191 | |
192 void CDsaBitgdi::Resume() | |
193 { | |
194 Start(); | |
195 } | |
196 | |
197 CBitmapContext& CDsaBitgdi::Gc() | |
198 { | |
199 return *iGc; | |
200 } | |
201 | |
202 void CDsaBitgdi::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) | |
203 { | |
204 | |
205 delete iBitGdiBmp; | |
206 iBitGdiBmp = NULL; | |
207 delete iWinGc; | |
208 iWinGc = NULL; | |
209 iHandle = 0; | |
210 | |
211 iWindow = &aWindow; | |
212 User::LeaveIfError(aDevice.CreateContext(iWinGc)); | |
213 CDsa::ConstructL(aWindow, aDevice); | |
214 Start(); | |
215 } | |
216 | |
217 void CDsaBitgdi::CreateSurfaceL(CFbsBitmap& aBmp) | |
218 { | |
219 iDevice = CFbsBitmapDevice::NewL(&aBmp); | |
220 User::LeaveIfError(iDevice->CreateContext(iGc)); | |
221 iHandle = aBmp.Handle(); | |
222 } | |
223 | |
224 void CDsaBitgdi::Free() | |
225 { | |
226 delete iGc; | |
227 iGc = NULL; | |
228 delete iDevice; | |
229 iDevice = NULL; | |
230 } | |
231 | |
232 //////////////////////////////////////////////////////////////////////// | |
233 /////////////////////////////////////////////////////////////////////// | |
234 | |
235 NONSHARABLE_CLASS(CDsaBase) : public CDsa, public MDirectScreenAccess | |
236 { | |
237 protected: | |
238 inline CDirectScreenAccess& Dsa() const; | |
239 CDsaBase(RWsSession& aSession); | |
240 ~CDsaBase(); | |
241 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); | |
242 void Stop(); | |
243 void Resume(); | |
244 CBitmapContext& Gc(); | |
245 protected: | |
246 CDirectScreenAccess* iDsa; | |
247 private: | |
248 void AbortNow(RDirectScreenAccess::TTerminationReasons aReason); | |
249 void Restart(RDirectScreenAccess::TTerminationReasons aReason); | |
250 private: | |
251 void RestartL(); | |
252 }; | |
253 | |
254 | |
255 inline CDirectScreenAccess& CDsaBase::Dsa() const | |
256 { | |
257 return *iDsa; | |
258 } | |
259 | |
260 | |
261 CDsaBase::CDsaBase(RWsSession& aSession) : CDsa(aSession) | |
262 { | |
263 } | |
264 | |
265 CBitmapContext& CDsaBase::Gc() | |
266 { | |
267 return *Dsa().Gc(); | |
268 } | |
269 | |
270 void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) | |
271 { | |
272 CDsa::ConstructL(aWindow, aDevice); | |
273 if(iDsa != NULL) | |
274 { | |
275 iDsa->Cancel(); | |
276 delete iDsa; | |
277 iDsa = NULL; | |
278 } | |
279 | |
280 iDsa = CDirectScreenAccess::NewL( | |
281 Session(), | |
282 aDevice, | |
283 aWindow, | |
284 *this); | |
285 RestartL(); | |
286 } | |
287 | |
288 void CDsaBase::Resume() | |
289 { | |
290 if(Stopped()) | |
291 Restart(RDirectScreenAccess::ETerminateRegion); | |
292 } | |
293 | |
294 CDsaBase::~CDsaBase() | |
295 { | |
296 if(iDsa != NULL) | |
297 { | |
298 iDsa->Cancel(); | |
299 } | |
300 delete iDsa; | |
301 } | |
302 | |
303 | |
304 void CDsaBase::RestartL() | |
305 { | |
306 | |
307 | |
308 iDsa->StartL(); | |
309 | |
310 const RRegion* r = iDsa->DrawingRegion(); | |
311 const TRect rect = r->BoundingRect(); | |
312 iDsa->Gc()->SetClippingRegion(r); | |
313 | |
314 if(rect != ScreenRect()) | |
315 { | |
316 return ; | |
317 } | |
318 | |
319 | |
320 SetTargetRect(); | |
321 RecreateL(); | |
322 | |
323 Start(); | |
324 | |
325 | |
326 } | |
327 | |
328 void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/) | |
329 { | |
330 Stop(); | |
331 } | |
332 | |
333 void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons aReason) | |
334 { | |
335 if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart | |
336 { | |
337 TRAPD(err, RestartL()); | |
338 PANIC_IF_ERROR(err); | |
339 } | |
340 } | |
341 | |
342 | |
343 void CDsaBase::Stop() | |
344 { | |
345 CDsa::Stop(); | |
346 iDsa->Cancel(); | |
347 } | |
348 | |
349 | |
350 /////////////////////////////////////////////////////////////////////// | |
351 /////////////////////////////////////////////////////////////////////// | |
352 NONSHARABLE_CLASS(TDsa) | |
353 { | |
354 public: | |
355 inline TDsa(const CDsa& aDsa); | |
356 inline TBool IsFlip() const; | |
357 inline TBool IsTurn() const; | |
358 inline const TSize& SwSize() const; | |
359 inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const; | |
360 private: | |
361 const CDsa& iDsa; | |
362 }; | |
363 | |
364 | |
365 | |
366 | |
367 inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa) | |
368 { | |
369 } | |
370 | |
371 inline TBool TDsa::IsTurn() const | |
372 { | |
373 return iDsa.iStateFlags & CDsa::EOrientation90; | |
374 } | |
375 | |
376 inline TBool TDsa::IsFlip() const | |
377 { | |
378 return iDsa.iStateFlags & CDsa::EOrientation180; | |
379 } | |
380 | |
381 inline const TSize& TDsa::SwSize() const | |
382 { | |
383 return iDsa.SwSize(); | |
384 } | |
385 | |
386 inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const | |
387 { | |
388 iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight); | |
389 } | |
390 | |
391 template<class T, class S> | |
392 void ClipCopy(const TDsa& iDsa, TUint8* aTarget, | |
393 const TUint8* aSource, | |
394 const TRect& aUpdateRect, | |
395 const TRect& aSourceRect) | |
396 { | |
397 const S* source = reinterpret_cast<const S*>(aSource); | |
398 const TInt lineWidth = aSourceRect.Width(); | |
399 | |
400 source += (aUpdateRect.iTl.iY * lineWidth); | |
401 const TInt sourceStartOffset = aUpdateRect.iTl.iX; | |
402 source += sourceStartOffset; | |
403 | |
404 T* targetPtr = reinterpret_cast<T*>(aTarget); | |
405 | |
406 const TInt scanLineWidth = iDsa.SwSize().iWidth; | |
407 | |
408 targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth; | |
409 const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX); | |
410 | |
411 targetPtr += targetStartOffset; | |
412 | |
413 | |
414 const TInt height = aUpdateRect.Height(); | |
415 | |
416 const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth; | |
417 const TInt copyLen = aUpdateRect.Width(); | |
418 | |
419 | |
420 if(iDsa.IsFlip()) | |
421 { | |
422 | |
423 targetPtr += scanLineWidth * (height - 1); | |
424 | |
425 for(TInt i = 0; i < height; i++) //source is always smaller | |
426 { | |
427 iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height); | |
428 source += lineMove; | |
429 targetPtr -= scanLineWidth; | |
430 } | |
431 } | |
432 else | |
433 { | |
434 | |
435 | |
436 for(TInt i = 0; i < height; i++) //source is always smaller | |
437 { | |
438 iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height); | |
439 source += lineMove; | |
440 targetPtr += scanLineWidth; // >> 2; | |
441 } | |
442 } | |
443 | |
444 } | |
445 | |
446 | |
447 | |
448 NONSHARABLE_CLASS(CDsaA) : public CDsaBase | |
449 { | |
450 public: | |
451 CDsaA(RWsSession& aSession); | |
452 protected: | |
453 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); | |
454 void CompleteUpdate(); | |
455 void CreateSurfaceL(CFbsBitmap& aBmp); | |
456 void Free(); | |
457 void UnlockHWSurfaceRequestComplete(); | |
458 }; | |
459 | |
460 | |
461 CDsaA::CDsaA(RWsSession& aSession) : CDsaBase(aSession) | |
462 { | |
463 } | |
464 | |
465 | |
466 void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) | |
467 { | |
468 CDsaBase::ConstructL(aWindow, aDevice); | |
469 } | |
470 | |
471 void CDsaA::CompleteUpdate() | |
472 { | |
473 iDsa->ScreenDevice()->Update(); | |
474 } | |
475 | |
476 void CDsaA::CreateSurfaceL(CFbsBitmap& /*aBmp*/) | |
477 { | |
478 } | |
479 | |
480 void CDsaA::Free() | |
481 { | |
482 | |
483 } | |
484 | |
485 void CDsaA::UnlockHWSurfaceRequestComplete() | |
486 { | |
487 PANIC(KErrNotSupported); | |
488 } | |
489 | |
490 | |
491 | |
492 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
493 | |
494 NONSHARABLE_CLASS(MDsbObs) | |
495 { | |
496 public: | |
497 virtual void SurfaceReady() = 0; | |
498 virtual CDirectScreenBitmap& Dsb() = 0; | |
499 }; | |
500 | |
501 NONSHARABLE_CLASS(CDsbSurface) : public CActive | |
502 { | |
503 public: | |
504 CDsbSurface(MDsbObs& aDsb); | |
505 TUint8* Address(); | |
506 void Complete(); | |
507 ~CDsbSurface(); | |
508 private: | |
509 void RunL(); | |
510 void DoCancel(); | |
511 private: | |
512 MDsbObs& iDsb; | |
513 TUint8* iAddress; | |
514 }; | |
515 | |
516 CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb) | |
517 { | |
518 CActiveScheduler::Add(this); | |
519 } | |
520 | |
521 CDsbSurface::~CDsbSurface() | |
522 { | |
523 Cancel(); | |
524 } | |
525 | |
526 void CDsbSurface::Complete() | |
527 { | |
528 if(iAddress != NULL && !IsActive()) | |
529 { | |
530 iAddress = NULL; | |
531 SetActive(); | |
532 iDsb.Dsb().EndUpdate(iStatus); | |
533 } | |
534 } | |
535 | |
536 TUint8* CDsbSurface::Address() | |
537 { | |
538 if(iAddress == NULL && !IsActive()) | |
539 { | |
540 TAcceleratedBitmapInfo info; | |
541 if(KErrNone == iDsb.Dsb().BeginUpdate(info)) | |
542 iAddress = info.iAddress; | |
543 } | |
544 return iAddress; | |
545 } | |
546 | |
547 void CDsbSurface::RunL() | |
548 { | |
549 iDsb.SurfaceReady(); | |
550 } | |
551 | |
552 void CDsbSurface::DoCancel() | |
553 { | |
554 //empty | |
555 } | |
556 | |
557 NONSHARABLE_CLASS(CDsaB) : public CDsaBase, | |
558 public MDsbObs | |
559 { | |
560 public: | |
561 CDsaB(RWsSession& aSession, TInt aFlags); | |
562 private: | |
563 ~CDsaB(); | |
564 TUint8* LockSurface(); | |
565 void UnlockHWSurfaceRequestComplete(); | |
566 void UnlockHwSurface(); | |
567 void CreateSurfaceL(); | |
568 void Wipe(TInt aLength); | |
569 void RecreateL(); | |
570 void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); | |
571 CDirectScreenBitmap& Dsb(); | |
572 void SurfaceReady(); | |
573 TInt ExternalUpdate(); | |
574 private: | |
575 CDsbSurface* iSurface1; | |
576 CDsbSurface* iSurface2; | |
577 CDirectScreenBitmap* iDsb; | |
578 TInt iType; | |
579 }; | |
580 | |
581 CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsaBase(aSession), iType(aFlags) | |
582 { | |
583 } | |
584 | |
585 | |
586 | |
587 void CDsaB::UnlockHWSurfaceRequestComplete() | |
588 { | |
589 iSurface1->Complete(); | |
590 if(iSurface2 != NULL) | |
591 iSurface2->Complete(); | |
592 } | |
593 | |
594 void CDsaB::CreateSurfaceL() | |
595 { | |
596 __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported)); | |
597 } | |
598 | |
599 void CDsaB::Wipe(TInt aLength) //dont call in drawing | |
600 { | |
601 TUint8* addr = LockSurface(); | |
602 if(addr != NULL) | |
603 { | |
604 Mem::FillZ(addr, aLength); | |
605 UnlockHwSurface(); | |
606 } | |
607 } | |
608 | |
609 | |
610 void CDsaB::UnlockHwSurface() | |
611 { | |
612 EpocSdlEnv::Request(CDsa::ERequestUpdate); | |
613 } | |
614 | |
615 TUint8* CDsaB::LockSurface() | |
616 { | |
617 TUint8* addr = iSurface1->Address(); | |
618 if(addr == NULL && iSurface2 != NULL) | |
619 addr = iSurface2->Address(); | |
620 SetUpdating(addr == NULL); | |
621 return addr; | |
622 } | |
623 | |
624 void CDsaB::SurfaceReady() | |
625 { | |
626 SetUpdating(EFalse); | |
627 } | |
628 | |
629 CDirectScreenBitmap& CDsaB::Dsb() | |
630 { | |
631 return *iDsb; | |
632 } | |
633 | |
634 void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) | |
635 { | |
636 if(iDsb == NULL) | |
637 iDsb = CDirectScreenBitmap::NewL(); | |
638 CDsaBase::ConstructL(aWindow, aDevice); | |
639 if(iSurface1 == NULL) | |
640 iSurface1 = new (ELeave) CDsbSurface(*this); | |
641 if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer) | |
642 iSurface2 = new (ELeave) CDsbSurface(*this); | |
643 } | |
644 | |
645 CDsaB::~CDsaB() | |
646 { | |
647 delete iSurface1; | |
648 delete iSurface2; | |
649 delete iDsb; | |
650 } | |
651 | |
652 void CDsaB::RecreateL() | |
653 { | |
654 iDsb->Close(); | |
655 iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType)); | |
656 } | |
657 | |
658 TInt CDsaB::ExternalUpdate() | |
659 { | |
660 if(LockSurface()) | |
661 { | |
662 UnlockHWSurfaceRequestComplete(); | |
663 return KErrNone; | |
664 } | |
665 return KErrNotReady; | |
666 } | |
667 | |
668 | |
669 ///////////////////////////////////////////////////////////////////////////////////////////////////// | |
670 | |
671 | |
672 | |
673 CDsa* CDsa::CreateL(RWsSession& aSession) | |
674 { | |
675 if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)) | |
676 { | |
677 TInt flags = CDirectScreenBitmap::ENone; | |
678 if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer)) | |
679 flags |= CDirectScreenBitmap::EDoubleBuffer; | |
680 if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrementalUpdate)) | |
681 flags |= CDirectScreenBitmap::EIncrementalUpdate; | |
682 return new (ELeave) CDsaB(aSession, flags); | |
683 } | |
684 else if(EpocSdlEnv::Flags(CSDL::EDrawModeGdi)) | |
685 { | |
686 return new (ELeave) CBitmapSurface<CDsaBitgdi>(aSession); | |
687 } | |
688 else | |
689 { | |
690 return new (ELeave) CBitmapSurface<CDsaA>(aSession); | |
691 } | |
692 } | |
693 | |
694 | |
695 void CDsa::RecreateL() | |
696 { | |
697 } | |
698 | |
699 void CDsa::Free() | |
700 { | |
701 } | |
702 | |
703 TSize CDsa::WindowSize() const | |
704 { | |
705 TSize size = iSwSize; | |
706 if(iStateFlags & EOrientation90) | |
707 { | |
708 const TInt tmp = size.iWidth; | |
709 size.iWidth = size.iHeight; | |
710 size.iHeight = tmp; | |
711 } | |
712 return size; | |
713 } | |
714 | |
715 void CDsa::SetSuspend() | |
716 { | |
717 iStateFlags |= ESdlThreadSuspend; | |
718 } | |
719 | |
720 | |
721 void CDsa::SetUpdating(TBool aUpdate) | |
722 { | |
723 if(aUpdate) | |
724 iStateFlags |= EUpdating; | |
725 else | |
726 iStateFlags &= ~EUpdating; | |
727 } | |
728 | |
729 | |
730 TBool CDsa::Stopped() const | |
731 { | |
732 return (iStateFlags & ESdlThreadExplicitStop); | |
733 } | |
734 | |
735 void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation) | |
736 { | |
737 TInt flags = 0; | |
738 switch(aOrientation) | |
739 { | |
740 case CSDL::EOrientation90: | |
741 flags = EOrientation90; | |
742 break; | |
743 case CSDL::EOrientation180: | |
744 flags = EOrientation180; | |
745 break; | |
746 case CSDL::EOrientation270: | |
747 flags = EOrientation90 | EOrientation180; | |
748 break; | |
749 case CSDL::EOrientation0: | |
750 flags = 0; | |
751 break; | |
752 } | |
753 if(flags != (iStateFlags & EOrientationFlags)) | |
754 { | |
755 iStateFlags |= EOrientationChanged; | |
756 iNewFlags = flags; //cannot be set during drawing... | |
757 } | |
758 } | |
759 | |
760 CDsa::~CDsa() | |
761 { | |
762 iOverlays.Close(); | |
763 User::Free(iLut256); | |
764 } | |
765 | |
766 void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/) | |
767 { | |
768 if(iLut256 == NULL) | |
769 iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32)); | |
770 iTargetMode = aWindow.DisplayMode(); | |
771 iTargetBpp = BytesPerPixel(DisplayMode()); | |
772 iScreenRect = TRect(aWindow.Position(), aWindow.Size()); | |
773 SetTargetRect(); | |
774 } | |
775 | |
776 void CDsa::DrawOverlays() | |
777 { | |
778 const TInt last = iOverlays.Count() - 1; | |
779 for(TInt i = last; i >= 0 ; i--) | |
780 iOverlays[i].iOverlay->Draw(Gc(), HwRect(), SwSize()); | |
781 } | |
782 | |
783 TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority) | |
784 { | |
785 TInt i; | |
786 for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++) | |
787 {} | |
788 const TOverlay overlay = {&aOverlay, aPriority}; | |
789 return iOverlays.Insert(overlay, i); | |
790 } | |
791 | |
792 TInt CDsa::RemoveOverlay(MOverlay& aOverlay) | |
793 { | |
794 for(TInt i = 0; i < iOverlays.Count(); i++) | |
795 { | |
796 if(iOverlays[i].iOverlay == &aOverlay) | |
797 { | |
798 iOverlays.Remove(i); | |
799 return KErrNone; | |
800 } | |
801 } | |
802 return KErrNotFound; | |
803 } | |
804 | |
805 void CDsa::LockPalette(TBool aLock) | |
806 { | |
807 if(aLock) | |
808 iStateFlags |= EPaletteLocked; | |
809 else | |
810 iStateFlags &= ~EPaletteLocked; | |
811 } | |
812 TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette) | |
813 { | |
814 if(iLut256 == NULL) | |
815 return KErrNotFound; | |
816 const TInt count = aCount - aFirst; | |
817 if(count > 256) | |
818 return KErrArgument; | |
819 if(iStateFlags & EPaletteLocked) | |
820 return KErrNone; | |
821 for(TInt i = aFirst; i < count; i++) //not so busy here:-) | |
822 { | |
823 iLut256[i] = aPalette[i]; | |
824 } | |
825 return KErrNone; | |
826 } | |
827 | |
828 | |
829 | |
830 | |
831 | |
832 CDsa::CDsa(RWsSession& aSession) : | |
833 iSession(aSession), | |
834 iStateFlags(0) | |
835 { | |
836 // CActiveScheduler::Add(this); | |
837 iCFTable[0] = CopyMem; | |
838 iCFTable[1] = CopyMemFlipReversed; | |
839 iCFTable[2] = CopyMemReversed; | |
840 iCFTable[3] = CopyMemFlip; | |
841 | |
842 iCFTable[4] = Copy256; | |
843 iCFTable[5] = Copy256FlipReversed; | |
844 iCFTable[6] = Copy256Reversed; | |
845 iCFTable[7] = Copy256Flip; | |
846 | |
847 | |
848 iCFTable[8] = CopySlow; | |
849 iCFTable[9] = CopySlowFlipReversed; | |
850 iCFTable[10] = CopySlowReversed; | |
851 iCFTable[11] = CopySlowFlip; | |
852 } | |
853 | |
854 RWsSession& CDsa::Session() | |
855 { | |
856 return iSession; | |
857 } | |
858 | |
859 TInt CDsa::RedrawRequest() | |
860 { | |
861 if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning))) | |
862 { | |
863 return ExternalUpdate(); | |
864 } | |
865 return KErrNotReady; | |
866 } | |
867 | |
868 TUint8* CDsa::LockHwSurface() | |
869 { | |
870 if((iStateFlags & EUpdating) == 0) //else frame is skipped | |
871 { | |
872 return LockSurface(); | |
873 } | |
874 return NULL; | |
875 } | |
876 | |
877 /* | |
878 void CDsa::RunL() | |
879 { | |
880 iStateFlags &= ~EUpdating; | |
881 } | |
882 | |
883 | |
884 void CDsa::DoCancel() | |
885 { | |
886 iStateFlags &= ~EUpdating; | |
887 //nothing can do, just wait? | |
888 } | |
889 */ | |
890 | |
891 | |
892 TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode) | |
893 { | |
894 if(aHwSurface && aMode != DisplayMode()) | |
895 return KErrArgument; | |
896 | |
897 iSourceMode = aMode; | |
898 | |
899 iSourceBpp = BytesPerPixel(aMode); | |
900 | |
901 const TSize size = WindowSize(); | |
902 if(aSize.iWidth > size.iWidth) | |
903 return KErrTooBig; | |
904 if(aSize.iHeight > size.iHeight) | |
905 return KErrTooBig; | |
906 | |
907 TRAPD(err, CreateSurfaceL()); | |
908 if(err != KErrNone) | |
909 return err; | |
910 | |
911 SetCopyFunction(); | |
912 | |
913 return KErrNone; | |
914 } | |
915 | |
916 | |
917 void CDsa::CreateZoomerL(const TSize& aSize) | |
918 { | |
919 iSwSize = aSize; | |
920 iStateFlags |= EResizeRequest; | |
921 CreateSurfaceL(); | |
922 SetTargetRect(); | |
923 } | |
924 | |
925 | |
926 /* | |
927 void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode) | |
928 { | |
929 CFbsBitmap* s = new CFbsBitmap(); | |
930 s->Create(aSz, aMode); | |
931 s->LockHeap(); | |
932 TUint32* addr = s->DataAddress(); | |
933 Mem::Copy(addr, aData, aLength); | |
934 s->UnlockHeap(); | |
935 s->Save(aName); | |
936 s->Reset(); | |
937 delete s; | |
938 } | |
939 | |
940 void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz) | |
941 { | |
942 CFbsBitmap* s = new CFbsBitmap(); | |
943 s->Create(aSz, EColor64K); | |
944 TBitmapUtil bmp(s); | |
945 bmp.Begin(TPoint(0, 0)); | |
946 for(TInt j = 0; j < aSz.iHeight; j++) | |
947 { | |
948 bmp.SetPos(TPoint(0, j)); | |
949 for(TInt i = 0; i < aSz.iWidth; i++) | |
950 { | |
951 bmp.SetPixel(*aData); | |
952 aData++; | |
953 bmp.IncXPos(); | |
954 } | |
955 } | |
956 bmp.End(); | |
957 s->Save(aName); | |
958 s->Reset(); | |
959 delete s; | |
960 } | |
961 | |
962 TBuf<16> FooName(TInt aFoo) | |
963 { | |
964 TBuf<16> b; | |
965 b.Format(_L("C:\\pic%d.mbm"), aFoo); | |
966 return b; | |
967 } | |
968 | |
969 */ | |
970 | |
971 | |
972 void CDsa::ClipCopy(TUint8* aTarget, | |
973 const TUint8* aSource, | |
974 const TRect& aUpdateRect, | |
975 const TRect& aSourceRect) const | |
976 { | |
977 const TDsa dsa(*this); | |
978 switch(iSourceBpp) | |
979 { | |
980 case 1: | |
981 ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect); | |
982 break; | |
983 case 2: | |
984 ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect); | |
985 break; | |
986 case 4: | |
987 ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect); | |
988 break; | |
989 } | |
990 } | |
991 | |
992 | |
993 void CDsa::Wipe() //dont call in drawing | |
994 { | |
995 if(IsDsaAvailable()) | |
996 Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight); | |
997 } | |
998 | |
999 void CDsa::SetCopyFunction() | |
1000 { | |
1001 //calculate offset to correct function in iCFTable according to given parameters | |
1002 TInt function = 0; | |
1003 const TInt KCopyFunctions = 4; | |
1004 const TInt KOffsetToNative = 0; | |
1005 const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions; | |
1006 const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions; | |
1007 const TInt KOffsetTo90Functions = 1; | |
1008 const TInt KOffsetTo180Functions = 2; | |
1009 | |
1010 if(iSourceMode == DisplayMode()) | |
1011 function = KOffsetToNative; //0 | |
1012 else if(iSourceMode == EColor256) | |
1013 function = KOffsetTo256; //4 | |
1014 else | |
1015 function = KOffsetToOtherModes; //8 | |
1016 | |
1017 if(iStateFlags & EOrientation90) | |
1018 function += KOffsetTo90Functions; // + 1 | |
1019 if(iStateFlags & EOrientation180) | |
1020 function += KOffsetTo180Functions; //+ 2 | |
1021 | |
1022 iCopyFunction = iCFTable[function]; | |
1023 | |
1024 Wipe(); | |
1025 } | |
1026 | |
1027 inline void Rotate(TRect& aRect) | |
1028 { | |
1029 const TInt dx = aRect.iBr.iX - aRect.iTl.iX; | |
1030 const TInt dy = aRect.iBr.iY - aRect.iTl.iY; | |
1031 | |
1032 aRect.iBr.iX = aRect.iTl.iX + dy; | |
1033 aRect.iBr.iY = aRect.iTl.iY + dx; | |
1034 | |
1035 const TInt tmp = aRect.iTl.iX; | |
1036 aRect.iTl.iX = aRect.iTl.iY; | |
1037 aRect.iTl.iY = tmp; | |
1038 } | |
1039 | |
1040 /* | |
1041 int bar = 0; | |
1042 */ | |
1043 | |
1044 TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect) | |
1045 { | |
1046 | |
1047 if(iStateFlags & EOrientationChanged) | |
1048 { | |
1049 iStateFlags &= ~EOrientationFlags; | |
1050 iStateFlags |= iNewFlags; | |
1051 SetCopyFunction(); | |
1052 iStateFlags &= ~EOrientationChanged; | |
1053 EpocSdlEnv::WaitDeviceChange(); | |
1054 return EFalse; //skip this frame as data is may be changed | |
1055 } | |
1056 | |
1057 if(iTargetAddr == NULL) | |
1058 { | |
1059 iTargetAddr = LockHwSurface(); | |
1060 } | |
1061 | |
1062 TUint8* target = iTargetAddr; | |
1063 if(target == NULL) | |
1064 return EFalse; | |
1065 | |
1066 | |
1067 TRect targetRect = TRect(TPoint(0, 0), SwSize()); | |
1068 | |
1069 TRect sourceRect = aRect; | |
1070 TRect updateRect = aUpdateRect; | |
1071 | |
1072 // TPoint move(0, 0); | |
1073 | |
1074 | |
1075 if(iStateFlags & EOrientation90) | |
1076 { | |
1077 Rotate(sourceRect); | |
1078 Rotate(updateRect); | |
1079 } | |
1080 | |
1081 if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0)) | |
1082 { | |
1083 sourceRect.Intersection(targetRect); //so source always smaller or equal than target | |
1084 //updateRect.Intersection(targetRect); | |
1085 ClipCopy(target, aBits, updateRect, sourceRect); | |
1086 } | |
1087 else | |
1088 { | |
1089 const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored | |
1090 Mem::Copy(target, aBits, byteCount); | |
1091 } | |
1092 | |
1093 return ETrue; | |
1094 } | |
1095 | |
1096 | |
1097 void CDsa::UpdateSwSurface() | |
1098 { | |
1099 iTargetAddr = NULL; | |
1100 UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed | |
1101 } | |
1102 | |
1103 | |
1104 | |
1105 | |
1106 void CDsa::DoStop() | |
1107 { | |
1108 if(IsDsaAvailable()) | |
1109 iStateFlags |= ESdlThreadExplicitStop; | |
1110 Stop(); | |
1111 } | |
1112 | |
1113 | |
1114 void CDsa::Stop() | |
1115 { | |
1116 iStateFlags &= ~ERunning; | |
1117 } | |
1118 | |
1119 void CDsa::Start() | |
1120 { | |
1121 iStateFlags |= ERunning; | |
1122 | |
1123 iStateFlags &= ~ESdlThreadExplicitStop; | |
1124 | |
1125 if(iStateFlags & ESdlThreadSuspend) | |
1126 { | |
1127 EpocSdlEnv::Resume(); | |
1128 iStateFlags &= ~ ESdlThreadSuspend; | |
1129 } | |
1130 EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved); | |
1131 } | |
1132 | |
1133 | |
1134 TBool CDsa::Blitter(CFbsBitmap& aBmp) | |
1135 { | |
1136 return iBlitter && iBlitter->BitBlt(Gc(), aBmp, HwRect(), SwSize()); | |
1137 } | |
1138 | |
1139 void CDsa::SetBlitter(MBlitter* aBlitter) | |
1140 { | |
1141 iBlitter = aBlitter; | |
1142 } | |
1143 | |
1144 | |
1145 TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const | |
1146 { | |
1147 TPoint pos = aPoint - iScreenRect.iTl; | |
1148 const TSize asz = iScreenRect.Size(); | |
1149 if(iStateFlags & EOrientation180) | |
1150 { | |
1151 pos.iX = asz.iWidth - pos.iX; | |
1152 pos.iY = asz.iHeight - pos.iY; | |
1153 } | |
1154 if(iStateFlags & EOrientation90) | |
1155 { | |
1156 pos.iX = aPoint.iY; | |
1157 pos.iY = aPoint.iX; | |
1158 } | |
1159 pos.iX <<= 16; | |
1160 pos.iY <<= 16; | |
1161 pos.iX /= asz.iWidth; | |
1162 pos.iY /= asz.iHeight; | |
1163 pos.iX *= iSwSize.iWidth; | |
1164 pos.iY *= iSwSize.iHeight; | |
1165 pos.iX >>= 16; | |
1166 pos.iY >>= 16; | |
1167 return pos; | |
1168 } | |
1169 | |
1170 void CDsa::SetTargetRect() | |
1171 { | |
1172 iTargetRect = iScreenRect; | |
1173 if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio)) | |
1174 { | |
1175 const TSize asz = iScreenRect.Size(); | |
1176 const TSize sz = iSwSize; | |
1177 | |
1178 TRect rect; | |
1179 | |
1180 const TInt dh = (sz.iHeight << 16) / sz.iWidth; | |
1181 | |
1182 if((asz.iWidth * dh ) >> 16 <= asz.iHeight) | |
1183 { | |
1184 rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16)); | |
1185 } | |
1186 else | |
1187 { | |
1188 const TInt dw = (sz.iWidth << 16) / sz.iHeight; | |
1189 rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight)); | |
1190 } | |
1191 rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1); | |
1192 | |
1193 iTargetRect = rect; | |
1194 iTargetRect.Move(iScreenRect.iTl); | |
1195 | |
1196 } | |
1197 if(!(iStateFlags & EResizeRequest)) | |
1198 iSwSize = iScreenRect.Size(); | |
1199 | |
1200 } | |
1201 | |
1202 | |
1203 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
1204 | |
1205 void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) | |
1206 { | |
1207 TUint32* target = aTarget; | |
1208 const TUint32* endt = target + aBytes; | |
1209 const TUint8* source = aSource; | |
1210 while(target < endt) | |
1211 { | |
1212 *target++ = aDsa.iLut256[*source++]; | |
1213 } | |
1214 } | |
1215 | |
1216 void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) | |
1217 { | |
1218 const TUint32* target = aTarget; | |
1219 TUint32* endt = aTarget + aBytes; | |
1220 const TUint8* source = aSource; | |
1221 while(target < endt) | |
1222 { | |
1223 *(--endt) = aDsa.iLut256[*source++]; | |
1224 } | |
1225 } | |
1226 | |
1227 void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) | |
1228 { | |
1229 TUint32* target = aTarget; | |
1230 const TUint32* endt = target + aBytes; | |
1231 const TUint8* column = aSource; | |
1232 | |
1233 while(target < endt) | |
1234 { | |
1235 *target++ = aDsa.iLut256[*column]; | |
1236 column += aLineLen; | |
1237 } | |
1238 } | |
1239 | |
1240 void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) | |
1241 { | |
1242 const TUint32* target = aTarget; | |
1243 TUint32* endt = aTarget + aBytes; | |
1244 const TUint8* column = aSource; | |
1245 | |
1246 while(target < endt) | |
1247 { | |
1248 *(--endt) = aDsa.iLut256[*column]; | |
1249 column += aLineLen; | |
1250 } | |
1251 } | |
1252 | |
1253 void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) | |
1254 { | |
1255 const TUint32* src = reinterpret_cast<const TUint32*>(aSource); | |
1256 Mem::Copy(aTarget, src, aBytes << 2); | |
1257 } | |
1258 | |
1259 void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) | |
1260 { | |
1261 TUint32* target = aTarget; | |
1262 const TUint32* endt = target + aBytes; | |
1263 const TUint32* column = reinterpret_cast<const TUint32*>(aSource); | |
1264 | |
1265 while(target < endt) | |
1266 { | |
1267 *target++ = *column; | |
1268 column += aLineLen; | |
1269 } | |
1270 } | |
1271 | |
1272 void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) | |
1273 { | |
1274 const TUint32* target = aTarget; | |
1275 TUint32* endt = aTarget + aBytes; | |
1276 const TUint32* source = reinterpret_cast<const TUint32*>(aSource); | |
1277 while(target < endt) | |
1278 { | |
1279 *(--endt) = *source++; | |
1280 } | |
1281 } | |
1282 | |
1283 | |
1284 void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) | |
1285 { | |
1286 const TUint32* target = aTarget; | |
1287 TUint32* endt = aTarget + aBytes; | |
1288 const TUint32* column = reinterpret_cast<const TUint32*>(aSource); | |
1289 | |
1290 while(target < endt) | |
1291 { | |
1292 *(--endt) = *column; | |
1293 column += aLineLen; | |
1294 } | |
1295 } | |
1296 | |
1297 /* | |
1298 | |
1299 LOCAL_C TRgb rgb16MA(TInt aValue) | |
1300 { | |
1301 return TRgb::Color16MA(aValue); | |
1302 } | |
1303 */ | |
1304 NONSHARABLE_CLASS(MRgbCopy) | |
1305 { | |
1306 public: | |
1307 virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0; | |
1308 virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0; | |
1309 }; | |
1310 | |
1311 template <class T> | |
1312 NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy | |
1313 { | |
1314 public: | |
1315 TRgbCopy(TDisplayMode aMode); | |
1316 void* operator new(TUint aBytes, TAny* aMem); | |
1317 void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed); | |
1318 void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed); | |
1319 static TUint32 Gray256(const TUint8& aPixel); | |
1320 static TUint32 Color256(const TUint8& aPixel); | |
1321 static TUint32 Color4K(const TUint16& aPixel); | |
1322 static TUint32 Color64K(const TUint16& aPixel); | |
1323 static TUint32 Color16M(const TUint32& aPixel); | |
1324 static TUint32 Color16MU(const TUint32& aPixel); | |
1325 static TUint32 Color16MA(const TUint32& aPixel); | |
1326 private: | |
1327 typedef TUint32 (*TRgbFunc) (const T& aValue); | |
1328 TRgbFunc iFunc; | |
1329 }; | |
1330 | |
1331 | |
1332 template <class T> | |
1333 void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem) | |
1334 { | |
1335 return aMem; | |
1336 } | |
1337 | |
1338 template <class T> | |
1339 TRgbCopy<T>::TRgbCopy(TDisplayMode aMode) | |
1340 { | |
1341 switch(aMode) | |
1342 { | |
1343 case EGray256 : iFunc = (TRgbFunc) Gray256; break; | |
1344 case EColor256 : iFunc = (TRgbFunc) Color256; break; | |
1345 case EColor4K : iFunc = (TRgbFunc) Color4K; break; | |
1346 case EColor64K : iFunc = (TRgbFunc) Color64K; break; | |
1347 case EColor16M : iFunc = (TRgbFunc) Color16M; break; | |
1348 case EColor16MU : iFunc = (TRgbFunc) Color16MU; break; | |
1349 case EColor16MA : iFunc = (TRgbFunc) Color16MA; break; | |
1350 default: | |
1351 PANIC(KErrNotSupported); | |
1352 } | |
1353 } | |
1354 | |
1355 template <class T> | |
1356 void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) | |
1357 { | |
1358 const T* source = reinterpret_cast<const T*>(aSource); | |
1359 TUint32* target = aTarget; | |
1360 TUint32* endt = target + aBytes; | |
1361 | |
1362 if(aReversed) | |
1363 { | |
1364 while(target < endt) | |
1365 { | |
1366 const T value = *source++; | |
1367 *(--endt) = iFunc(value);//iFunc(value).Value(); | |
1368 } | |
1369 } | |
1370 else | |
1371 { | |
1372 while(target < endt) | |
1373 { | |
1374 const T value = *source++; | |
1375 *target++ = iFunc(value);//iFunc(value).Value(); | |
1376 } | |
1377 } | |
1378 } | |
1379 | |
1380 template <class T> | |
1381 void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) | |
1382 { | |
1383 const T* column = reinterpret_cast<const T*>(aSource); | |
1384 TUint32* target = aTarget; | |
1385 TUint32* endt = target + aBytes; | |
1386 | |
1387 if(aReversed) | |
1388 { | |
1389 while(target < endt) | |
1390 { | |
1391 *(--endt) = iFunc(*column); | |
1392 column += aLineLen; | |
1393 } | |
1394 } | |
1395 else | |
1396 { | |
1397 while(target < endt) | |
1398 { | |
1399 *target++ = iFunc(*column); | |
1400 column += aLineLen; | |
1401 } | |
1402 } | |
1403 } | |
1404 | |
1405 template <class T> TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel) | |
1406 { | |
1407 const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel; | |
1408 return px; | |
1409 } | |
1410 | |
1411 template <class T> TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel) | |
1412 { | |
1413 return TRgb::Color256(aPixel).Value(); | |
1414 } | |
1415 | |
1416 template <class T> TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel) | |
1417 { | |
1418 TUint32 col = (aPixel & 0xF00) << 12; | |
1419 col |= (aPixel & 0xF00) << 8; | |
1420 | |
1421 col |= (aPixel & 0x0F0) << 8; | |
1422 col |= (aPixel & 0x0F0); | |
1423 | |
1424 col |= (aPixel & 0x00F) << 4; | |
1425 col |= (aPixel & 0x00F); | |
1426 | |
1427 return col; | |
1428 } | |
1429 | |
1430 template <class T> TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel) | |
1431 { | |
1432 TUint32 col = (aPixel & 0xF800)<< 8; | |
1433 col |= (aPixel & 0xE000) << 3; | |
1434 | |
1435 col |= (aPixel & 0x07E0) << 5; | |
1436 col |= (aPixel & 0xC0) >> 1; | |
1437 | |
1438 col |= (aPixel & 0x07E0) << 3; | |
1439 col |= (aPixel & 0x1C) >> 2; | |
1440 | |
1441 return col; | |
1442 } | |
1443 | |
1444 template <class T> TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel) | |
1445 { | |
1446 return TRgb::Color16M(aPixel).Value(); | |
1447 } | |
1448 | |
1449 template <class T> TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel) | |
1450 { | |
1451 return TRgb::Color16MU(aPixel).Value(); | |
1452 } | |
1453 | |
1454 template <class T> TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel) | |
1455 { | |
1456 return TRgb::Color16MA(aPixel).Value(); | |
1457 } | |
1458 | |
1459 typedef TUint64 TStackMem; | |
1460 | |
1461 LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode) | |
1462 { | |
1463 if(aMode == EColor256 || aMode == EGray256) | |
1464 { | |
1465 return new (mem) TRgbCopy<TUint8>(aMode); | |
1466 } | |
1467 if(aMode == EColor4K || aMode == EColor64K) | |
1468 { | |
1469 return new (mem) TRgbCopy<TUint16>(aMode); | |
1470 } | |
1471 if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA) | |
1472 { | |
1473 return new (mem) TRgbCopy<TUint32>(aMode); | |
1474 } | |
1475 PANIC(KErrNotSupported); | |
1476 return NULL; | |
1477 } | |
1478 | |
1479 | |
1480 void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) | |
1481 { | |
1482 TStackMem mem = 0; | |
1483 GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue); | |
1484 } | |
1485 | |
1486 void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) | |
1487 { | |
1488 TStackMem mem = 0; | |
1489 GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse); | |
1490 } | |
1491 | |
1492 void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) | |
1493 { | |
1494 TStackMem mem = 0; | |
1495 GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse); | |
1496 } | |
1497 | |
1498 void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) | |
1499 { | |
1500 TStackMem mem = 0; | |
1501 GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); | |
1502 } | |
1503 | |
1504 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////7 |