e14743d1 |
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 | NONSHARABLE_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 | iStateFlags(0), |
834 | iSession(aSession) |
835 | |
836 | { |
837 | // CActiveScheduler::Add(this); |
838 | iCFTable[0] = CopyMem; |
839 | iCFTable[1] = CopyMemFlipReversed; |
840 | iCFTable[2] = CopyMemReversed; |
841 | iCFTable[3] = CopyMemFlip; |
842 | |
843 | iCFTable[4] = Copy256; |
844 | iCFTable[5] = Copy256FlipReversed; |
845 | iCFTable[6] = Copy256Reversed; |
846 | iCFTable[7] = Copy256Flip; |
847 | |
848 | |
849 | iCFTable[8] = CopySlow; |
850 | iCFTable[9] = CopySlowFlipReversed; |
851 | iCFTable[10] = CopySlowReversed; |
852 | iCFTable[11] = CopySlowFlip; |
853 | } |
854 | |
855 | RWsSession& CDsa::Session() |
856 | { |
857 | return iSession; |
858 | } |
859 | |
860 | TInt CDsa::RedrawRequest() |
861 | { |
862 | if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning))) |
863 | { |
864 | return ExternalUpdate(); |
865 | } |
866 | return KErrNotReady; |
867 | } |
868 | |
869 | TUint8* CDsa::LockHwSurface() |
870 | { |
871 | if((iStateFlags & EUpdating) == 0) //else frame is skipped |
872 | { |
873 | return LockSurface(); |
874 | } |
875 | return NULL; |
876 | } |
877 | |
878 | /* |
879 | void CDsa::RunL() |
880 | { |
881 | iStateFlags &= ~EUpdating; |
882 | } |
883 | |
884 | |
885 | void CDsa::DoCancel() |
886 | { |
887 | iStateFlags &= ~EUpdating; |
888 | //nothing can do, just wait? |
889 | } |
890 | */ |
891 | |
892 | |
893 | TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode) |
894 | { |
895 | if(aHwSurface && aMode != DisplayMode()) |
896 | return KErrArgument; |
897 | |
898 | iSourceMode = aMode; |
899 | |
900 | iSourceBpp = BytesPerPixel(aMode); |
901 | |
902 | const TSize size = WindowSize(); |
903 | if(aSize.iWidth > size.iWidth) |
904 | return KErrTooBig; |
905 | if(aSize.iHeight > size.iHeight) |
906 | return KErrTooBig; |
907 | |
908 | TRAPD(err, CreateSurfaceL()); |
909 | if(err != KErrNone) |
910 | return err; |
911 | |
912 | SetCopyFunction(); |
913 | |
914 | return KErrNone; |
915 | } |
916 | |
917 | |
918 | void CDsa::CreateZoomerL(const TSize& aSize) |
919 | { |
920 | iSwSize = aSize; |
921 | iStateFlags |= EResizeRequest; |
922 | CreateSurfaceL(); |
923 | SetTargetRect(); |
924 | } |
925 | |
926 | |
927 | /* |
928 | void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode) |
929 | { |
930 | CFbsBitmap* s = new CFbsBitmap(); |
931 | s->Create(aSz, aMode); |
932 | s->LockHeap(); |
933 | TUint32* addr = s->DataAddress(); |
934 | Mem::Copy(addr, aData, aLength); |
935 | s->UnlockHeap(); |
936 | s->Save(aName); |
937 | s->Reset(); |
938 | delete s; |
939 | } |
940 | |
941 | void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz) |
942 | { |
943 | CFbsBitmap* s = new CFbsBitmap(); |
944 | s->Create(aSz, EColor64K); |
945 | TBitmapUtil bmp(s); |
946 | bmp.Begin(TPoint(0, 0)); |
947 | for(TInt j = 0; j < aSz.iHeight; j++) |
948 | { |
949 | bmp.SetPos(TPoint(0, j)); |
950 | for(TInt i = 0; i < aSz.iWidth; i++) |
951 | { |
952 | bmp.SetPixel(*aData); |
953 | aData++; |
954 | bmp.IncXPos(); |
955 | } |
956 | } |
957 | bmp.End(); |
958 | s->Save(aName); |
959 | s->Reset(); |
960 | delete s; |
961 | } |
962 | |
963 | TBuf<16> FooName(TInt aFoo) |
964 | { |
965 | TBuf<16> b; |
966 | b.Format(_L("C:\\pic%d.mbm"), aFoo); |
967 | return b; |
968 | } |
969 | |
970 | */ |
971 | |
972 | |
973 | void CDsa::ClipCopy(TUint8* aTarget, |
974 | const TUint8* aSource, |
975 | const TRect& aUpdateRect, |
976 | const TRect& aSourceRect) const |
977 | { |
978 | const TDsa dsa(*this); |
979 | switch(iSourceBpp) |
980 | { |
981 | case 1: |
982 | ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect); |
983 | break; |
984 | case 2: |
985 | ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect); |
986 | break; |
987 | case 4: |
988 | ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect); |
989 | break; |
990 | } |
991 | } |
992 | |
993 | |
994 | void CDsa::Wipe() //dont call in drawing |
995 | { |
996 | if(IsDsaAvailable()) |
997 | Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight); |
998 | } |
999 | |
1000 | void CDsa::SetCopyFunction() |
1001 | { |
1002 | //calculate offset to correct function in iCFTable according to given parameters |
1003 | TInt function = 0; |
1004 | const TInt KCopyFunctions = 4; |
1005 | const TInt KOffsetToNative = 0; |
1006 | const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions; |
1007 | const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions; |
1008 | const TInt KOffsetTo90Functions = 1; |
1009 | const TInt KOffsetTo180Functions = 2; |
1010 | |
1011 | if(iSourceMode == DisplayMode()) |
1012 | function = KOffsetToNative; //0 |
1013 | else if(iSourceMode == EColor256) |
1014 | function = KOffsetTo256; //4 |
1015 | else |
1016 | function = KOffsetToOtherModes; //8 |
1017 | |
1018 | if(iStateFlags & EOrientation90) |
1019 | function += KOffsetTo90Functions; // + 1 |
1020 | if(iStateFlags & EOrientation180) |
1021 | function += KOffsetTo180Functions; //+ 2 |
1022 | |
1023 | iCopyFunction = iCFTable[function]; |
1024 | |
1025 | Wipe(); |
1026 | } |
1027 | |
1028 | inline void Rotate(TRect& aRect) |
1029 | { |
1030 | const TInt dx = aRect.iBr.iX - aRect.iTl.iX; |
1031 | const TInt dy = aRect.iBr.iY - aRect.iTl.iY; |
1032 | |
1033 | aRect.iBr.iX = aRect.iTl.iX + dy; |
1034 | aRect.iBr.iY = aRect.iTl.iY + dx; |
1035 | |
1036 | const TInt tmp = aRect.iTl.iX; |
1037 | aRect.iTl.iX = aRect.iTl.iY; |
1038 | aRect.iTl.iY = tmp; |
1039 | } |
1040 | |
1041 | /* |
1042 | int bar = 0; |
1043 | */ |
1044 | |
1045 | TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect) |
1046 | { |
1047 | |
1048 | if(iStateFlags & EOrientationChanged) |
1049 | { |
1050 | iStateFlags &= ~EOrientationFlags; |
1051 | iStateFlags |= iNewFlags; |
1052 | SetCopyFunction(); |
1053 | iStateFlags &= ~EOrientationChanged; |
1054 | EpocSdlEnv::WaitDeviceChange(); |
1055 | return EFalse; //skip this frame as data is may be changed |
1056 | } |
1057 | |
1058 | if(iTargetAddr == NULL) |
1059 | { |
1060 | iTargetAddr = LockHwSurface(); |
1061 | } |
1062 | |
1063 | TUint8* target = iTargetAddr; |
1064 | if(target == NULL) |
1065 | return EFalse; |
1066 | |
1067 | |
1068 | TRect targetRect = TRect(TPoint(0, 0), SwSize()); |
1069 | |
1070 | TRect sourceRect = aRect; |
1071 | TRect updateRect = aUpdateRect; |
1072 | |
1073 | // TPoint move(0, 0); |
1074 | |
1075 | |
1076 | if(iStateFlags & EOrientation90) |
1077 | { |
1078 | Rotate(sourceRect); |
1079 | Rotate(updateRect); |
1080 | } |
1081 | |
1082 | if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0)) |
1083 | { |
1084 | sourceRect.Intersection(targetRect); //so source always smaller or equal than target |
1085 | //updateRect.Intersection(targetRect); |
1086 | ClipCopy(target, aBits, updateRect, sourceRect); |
1087 | } |
1088 | else |
1089 | { |
1090 | const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored |
1091 | Mem::Copy(target, aBits, byteCount); |
1092 | } |
1093 | |
1094 | return ETrue; |
1095 | } |
1096 | |
1097 | |
1098 | void CDsa::UpdateSwSurface() |
1099 | { |
1100 | iTargetAddr = NULL; |
1101 | UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed |
1102 | } |
1103 | |
1104 | |
1105 | |
1106 | |
1107 | void CDsa::DoStop() |
1108 | { |
1109 | if(IsDsaAvailable()) |
1110 | iStateFlags |= ESdlThreadExplicitStop; |
1111 | Stop(); |
1112 | } |
1113 | |
1114 | |
1115 | void CDsa::Stop() |
1116 | { |
1117 | iStateFlags &= ~ERunning; |
1118 | } |
1119 | |
1120 | void CDsa::Start() |
1121 | { |
1122 | iStateFlags |= ERunning; |
1123 | |
1124 | iStateFlags &= ~ESdlThreadExplicitStop; |
1125 | |
1126 | if(iStateFlags & ESdlThreadSuspend) |
1127 | { |
1128 | EpocSdlEnv::Resume(); |
1129 | iStateFlags &= ~ ESdlThreadSuspend; |
1130 | } |
1131 | EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved); |
1132 | } |
1133 | |
1134 | |
1135 | TBool CDsa::Blitter(CFbsBitmap& aBmp) |
1136 | { |
1137 | return iBlitter && iBlitter->BitBlt(Gc(), aBmp, HwRect(), SwSize()); |
1138 | } |
1139 | |
1140 | void CDsa::SetBlitter(MBlitter* aBlitter) |
1141 | { |
1142 | iBlitter = aBlitter; |
1143 | } |
1144 | |
1145 | |
1146 | TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const |
1147 | { |
1148 | TPoint pos = aPoint - iScreenRect.iTl; |
1149 | const TSize asz = iScreenRect.Size(); |
1150 | if(iStateFlags & EOrientation180) |
1151 | { |
1152 | pos.iX = asz.iWidth - pos.iX; |
1153 | pos.iY = asz.iHeight - pos.iY; |
1154 | } |
1155 | if(iStateFlags & EOrientation90) |
1156 | { |
1157 | pos.iX = aPoint.iY; |
1158 | pos.iY = aPoint.iX; |
1159 | } |
1160 | pos.iX <<= 16; |
1161 | pos.iY <<= 16; |
1162 | pos.iX /= asz.iWidth; |
1163 | pos.iY /= asz.iHeight; |
1164 | pos.iX *= iSwSize.iWidth; |
1165 | pos.iY *= iSwSize.iHeight; |
1166 | pos.iX >>= 16; |
1167 | pos.iY >>= 16; |
1168 | return pos; |
1169 | } |
1170 | |
1171 | void CDsa::SetTargetRect() |
1172 | { |
1173 | iTargetRect = iScreenRect; |
1174 | if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio)) |
1175 | { |
1176 | const TSize asz = iScreenRect.Size(); |
1177 | const TSize sz = iSwSize; |
1178 | |
1179 | TRect rect; |
1180 | |
1181 | const TInt dh = (sz.iHeight << 16) / sz.iWidth; |
1182 | |
1183 | if((asz.iWidth * dh ) >> 16 <= asz.iHeight) |
1184 | { |
1185 | rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16)); |
1186 | } |
1187 | else |
1188 | { |
1189 | const TInt dw = (sz.iWidth << 16) / sz.iHeight; |
1190 | rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight)); |
1191 | } |
1192 | rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1); |
1193 | |
1194 | iTargetRect = rect; |
1195 | iTargetRect.Move(iScreenRect.iTl); |
1196 | |
1197 | } |
1198 | if(!(iStateFlags & EResizeRequest)) |
1199 | iSwSize = iScreenRect.Size(); |
1200 | |
1201 | } |
1202 | |
1203 | |
1204 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
1205 | |
1206 | void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1207 | { |
1208 | TUint32* target = aTarget; |
1209 | const TUint32* endt = target + aBytes; |
1210 | const TUint8* source = aSource; |
1211 | while(target < endt) |
1212 | { |
1213 | *target++ = aDsa.iLut256[*source++]; |
1214 | } |
1215 | } |
1216 | |
1217 | void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1218 | { |
1219 | const TUint32* target = aTarget; |
1220 | TUint32* endt = aTarget + aBytes; |
1221 | const TUint8* source = aSource; |
1222 | while(target < endt) |
1223 | { |
1224 | *(--endt) = aDsa.iLut256[*source++]; |
1225 | } |
1226 | } |
1227 | |
1228 | void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1229 | { |
1230 | TUint32* target = aTarget; |
1231 | const TUint32* endt = target + aBytes; |
1232 | const TUint8* column = aSource; |
1233 | |
1234 | while(target < endt) |
1235 | { |
1236 | *target++ = aDsa.iLut256[*column]; |
1237 | column += aLineLen; |
1238 | } |
1239 | } |
1240 | |
1241 | void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1242 | { |
1243 | const TUint32* target = aTarget; |
1244 | TUint32* endt = aTarget + aBytes; |
1245 | const TUint8* column = aSource; |
1246 | |
1247 | while(target < endt) |
1248 | { |
1249 | *(--endt) = aDsa.iLut256[*column]; |
1250 | column += aLineLen; |
1251 | } |
1252 | } |
1253 | |
1254 | void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1255 | { |
1256 | const TUint32* src = reinterpret_cast<const TUint32*>(aSource); |
1257 | Mem::Copy(aTarget, src, aBytes << 2); |
1258 | } |
1259 | |
1260 | void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1261 | { |
1262 | TUint32* target = aTarget; |
1263 | const TUint32* endt = target + aBytes; |
1264 | const TUint32* column = reinterpret_cast<const TUint32*>(aSource); |
1265 | |
1266 | while(target < endt) |
1267 | { |
1268 | *target++ = *column; |
1269 | column += aLineLen; |
1270 | } |
1271 | } |
1272 | |
1273 | void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1274 | { |
1275 | const TUint32* target = aTarget; |
1276 | TUint32* endt = aTarget + aBytes; |
1277 | const TUint32* source = reinterpret_cast<const TUint32*>(aSource); |
1278 | while(target < endt) |
1279 | { |
1280 | *(--endt) = *source++; |
1281 | } |
1282 | } |
1283 | |
1284 | |
1285 | void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1286 | { |
1287 | const TUint32* target = aTarget; |
1288 | TUint32* endt = aTarget + aBytes; |
1289 | const TUint32* column = reinterpret_cast<const TUint32*>(aSource); |
1290 | |
1291 | while(target < endt) |
1292 | { |
1293 | *(--endt) = *column; |
1294 | column += aLineLen; |
1295 | } |
1296 | } |
1297 | |
1298 | /* |
1299 | |
1300 | LOCAL_C TRgb rgb16MA(TInt aValue) |
1301 | { |
1302 | return TRgb::Color16MA(aValue); |
1303 | } |
1304 | */ |
1305 | NONSHARABLE_CLASS(MRgbCopy) |
1306 | { |
1307 | public: |
1308 | virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0; |
1309 | virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0; |
1310 | }; |
1311 | |
1312 | template <class T> |
1313 | NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy |
1314 | { |
1315 | public: |
1316 | TRgbCopy(TDisplayMode aMode); |
1317 | void* operator new(TUint aBytes, TAny* aMem); |
1318 | void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed); |
1319 | void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed); |
1320 | static TUint32 Gray256(const TUint8& aPixel); |
1321 | static TUint32 Color256(const TUint8& aPixel); |
1322 | static TUint32 Color4K(const TUint16& aPixel); |
1323 | static TUint32 Color64K(const TUint16& aPixel); |
1324 | static TUint32 Color16M(const TUint32& aPixel); |
1325 | static TUint32 Color16MU(const TUint32& aPixel); |
1326 | static TUint32 Color16MA(const TUint32& aPixel); |
1327 | private: |
1328 | typedef TUint32 (*TRgbFunc) (const T& aValue); |
1329 | TRgbFunc iFunc; |
1330 | }; |
1331 | |
1332 | |
1333 | template <class T> |
1334 | void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem) |
1335 | { |
1336 | return aMem; |
1337 | } |
1338 | |
1339 | template <class T> |
1340 | TRgbCopy<T>::TRgbCopy(TDisplayMode aMode) |
1341 | { |
1342 | switch(aMode) |
1343 | { |
1344 | case EGray256 : iFunc = (TRgbFunc) Gray256; break; |
1345 | case EColor256 : iFunc = (TRgbFunc) Color256; break; |
1346 | case EColor4K : iFunc = (TRgbFunc) Color4K; break; |
1347 | case EColor64K : iFunc = (TRgbFunc) Color64K; break; |
1348 | case EColor16M : iFunc = (TRgbFunc) Color16M; break; |
1349 | case EColor16MU : iFunc = (TRgbFunc) Color16MU; break; |
1350 | case EColor16MA : iFunc = (TRgbFunc) Color16MA; break; |
1351 | default: |
1352 | PANIC(KErrNotSupported); |
1353 | } |
1354 | } |
1355 | |
1356 | template <class T> |
1357 | void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) |
1358 | { |
1359 | const T* source = reinterpret_cast<const T*>(aSource); |
1360 | TUint32* target = aTarget; |
1361 | TUint32* endt = target + aBytes; |
1362 | |
1363 | if(aReversed) |
1364 | { |
1365 | while(target < endt) |
1366 | { |
1367 | const T value = *source++; |
1368 | *(--endt) = iFunc(value);//iFunc(value).Value(); |
1369 | } |
1370 | } |
1371 | else |
1372 | { |
1373 | while(target < endt) |
1374 | { |
1375 | const T value = *source++; |
1376 | *target++ = iFunc(value);//iFunc(value).Value(); |
1377 | } |
1378 | } |
1379 | } |
1380 | |
1381 | template <class T> |
1382 | void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) |
1383 | { |
1384 | const T* column = reinterpret_cast<const T*>(aSource); |
1385 | TUint32* target = aTarget; |
1386 | TUint32* endt = target + aBytes; |
1387 | |
1388 | if(aReversed) |
1389 | { |
1390 | while(target < endt) |
1391 | { |
1392 | *(--endt) = iFunc(*column); |
1393 | column += aLineLen; |
1394 | } |
1395 | } |
1396 | else |
1397 | { |
1398 | while(target < endt) |
1399 | { |
1400 | *target++ = iFunc(*column); |
1401 | column += aLineLen; |
1402 | } |
1403 | } |
1404 | } |
1405 | |
1406 | template <class T> TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel) |
1407 | { |
1408 | const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel; |
1409 | return px; |
1410 | } |
1411 | |
1412 | template <class T> TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel) |
1413 | { |
1414 | return TRgb::Color256(aPixel).Value(); |
1415 | } |
1416 | |
1417 | template <class T> TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel) |
1418 | { |
1419 | TUint32 col = (aPixel & 0xF00) << 12; |
1420 | col |= (aPixel & 0xF00) << 8; |
1421 | |
1422 | col |= (aPixel & 0x0F0) << 8; |
1423 | col |= (aPixel & 0x0F0); |
1424 | |
1425 | col |= (aPixel & 0x00F) << 4; |
1426 | col |= (aPixel & 0x00F); |
1427 | |
1428 | return col; |
1429 | } |
1430 | |
1431 | template <class T> TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel) |
1432 | { |
1433 | TUint32 col = (aPixel & 0xF800)<< 8; |
1434 | col |= (aPixel & 0xE000) << 3; |
1435 | |
1436 | col |= (aPixel & 0x07E0) << 5; |
1437 | col |= (aPixel & 0xC0) >> 1; |
1438 | |
1439 | col |= (aPixel & 0x07E0) << 3; |
1440 | col |= (aPixel & 0x1C) >> 2; |
1441 | |
1442 | return col; |
1443 | } |
1444 | |
1445 | template <class T> TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel) |
1446 | { |
1447 | return TRgb::Color16M(aPixel).Value(); |
1448 | } |
1449 | |
1450 | template <class T> TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel) |
1451 | { |
1452 | return TRgb::Color16MU(aPixel).Value(); |
1453 | } |
1454 | |
1455 | template <class T> TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel) |
1456 | { |
1457 | return TRgb::Color16MA(aPixel).Value(); |
1458 | } |
1459 | |
1460 | typedef TUint64 TStackMem; |
1461 | |
1462 | LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode) |
1463 | { |
1464 | if(aMode == EColor256 || aMode == EGray256) |
1465 | { |
1466 | return new (mem) TRgbCopy<TUint8>(aMode); |
1467 | } |
1468 | if(aMode == EColor4K || aMode == EColor64K) |
1469 | { |
1470 | return new (mem) TRgbCopy<TUint16>(aMode); |
1471 | } |
1472 | if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA) |
1473 | { |
1474 | return new (mem) TRgbCopy<TUint32>(aMode); |
1475 | } |
1476 | PANIC(KErrNotSupported); |
1477 | return NULL; |
1478 | } |
1479 | |
1480 | |
1481 | void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1482 | { |
1483 | TStackMem mem = 0; |
1484 | GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue); |
1485 | } |
1486 | |
1487 | void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1488 | { |
1489 | TStackMem mem = 0; |
1490 | GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse); |
1491 | } |
1492 | |
1493 | void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1494 | { |
1495 | TStackMem mem = 0; |
1496 | GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse); |
1497 | } |
1498 | |
1499 | void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1500 | { |
1501 | TStackMem mem = 0; |
1502 | GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); |
1503 | } |
1504 | |
1505 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////7 |