e14743d1 |
1 | #include "dsa.h" |
2 | #include "sdlepocapi.h" |
3 | #include <cdsb.h> |
4 | |
5 | LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) |
6 | { |
7 | return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; |
8 | } |
9 | |
10 | |
11 | //////////////////////////////////////////////////////////////////////////////////////////////// |
12 | |
13 | NONSHARABLE_CLASS(CDsaA) : public CDsa |
14 | { |
15 | public: |
16 | CDsaA(RWsSession& aSession); |
17 | private: |
18 | ~CDsaA(); |
19 | TUint8* LockSurface(); |
20 | void UnlockHWSurfaceRequestComplete(); |
21 | void UnlockHwSurface(); |
22 | void CreateSurfaceL(); |
23 | void Wipe(TInt aLength); |
24 | void RecreateL(); |
25 | void Free(); |
26 | TInt ExternalUpdate() {return 0;} |
27 | private: |
28 | CFbsBitmap* iBmp; |
29 | }; |
30 | |
31 | |
32 | CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession) |
33 | { |
34 | } |
35 | |
36 | void CDsaA::Free() |
37 | { |
38 | delete iBmp; |
39 | iBmp = NULL; |
40 | } |
41 | |
42 | CDsaA::~CDsaA() |
43 | { |
44 | __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady)); |
45 | } |
46 | |
47 | TUint8* CDsaA::LockSurface() |
48 | { |
49 | iBmp->LockHeap(); |
50 | return reinterpret_cast<TUint8*>(iBmp->DataAddress()); |
51 | } |
52 | |
53 | void CDsaA::UnlockHWSurfaceRequestComplete() |
54 | { |
55 | PANIC(KErrNotSupported); |
56 | } |
57 | |
58 | void CDsaA::UnlockHwSurface() |
59 | { |
60 | iBmp->UnlockHeap(); |
61 | SetUpdating(EFalse); |
62 | Dsa().Gc()->BitBlt(HwRect().iTl, iBmp); |
63 | Dsa().ScreenDevice()->Update(); |
64 | } |
65 | |
66 | void CDsaA::CreateSurfaceL() |
67 | { |
68 | delete iBmp; |
69 | iBmp = NULL; |
70 | iBmp = new (ELeave) CFbsBitmap(); |
71 | User::LeaveIfError(iBmp->Create(HwRect().Size(), DisplayMode())); |
72 | } |
73 | |
74 | void CDsaA::Wipe(TInt aLength) //dont call in drawing |
75 | { |
76 | iBmp->LockHeap(); |
77 | Mem::FillZ(iBmp->DataAddress(), aLength); |
78 | iBmp->UnlockHeap(); |
79 | } |
80 | |
81 | void CDsaA::RecreateL() |
82 | { |
83 | } |
84 | |
85 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
86 | |
87 | NONSHARABLE_CLASS(MDsbObs) |
88 | { |
89 | public: |
90 | virtual void SurfaceReady() = 0; |
91 | virtual CDirectScreenBitmap& Dsb() = 0; |
92 | }; |
93 | |
94 | NONSHARABLE_CLASS(CDsbSurface) : public CActive |
95 | { |
96 | public: |
97 | CDsbSurface(MDsbObs& aDsb); |
98 | TUint8* Address(); |
99 | void Complete(); |
100 | ~CDsbSurface(); |
101 | private: |
102 | void RunL(); |
103 | void DoCancel(); |
104 | private: |
105 | MDsbObs& iDsb; |
106 | TUint8* iAddress; |
107 | }; |
108 | |
109 | CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb) |
110 | { |
111 | CActiveScheduler::Add(this); |
112 | } |
113 | |
114 | CDsbSurface::~CDsbSurface() |
115 | { |
116 | Cancel(); |
117 | } |
118 | |
119 | void CDsbSurface::Complete() |
120 | { |
121 | if(iAddress != NULL && !IsActive()) |
122 | { |
123 | iAddress = NULL; |
124 | SetActive(); |
125 | iDsb.Dsb().EndUpdate(iStatus); |
126 | } |
127 | } |
128 | |
129 | TUint8* CDsbSurface::Address() |
130 | { |
131 | if(iAddress == NULL && !IsActive()) |
132 | { |
133 | TAcceleratedBitmapInfo info; |
134 | if(KErrNone == iDsb.Dsb().BeginUpdate(info)) |
135 | iAddress = info.iAddress; |
136 | } |
137 | return iAddress; |
138 | } |
139 | |
140 | void CDsbSurface::RunL() |
141 | { |
142 | iDsb.SurfaceReady(); |
143 | } |
144 | |
145 | void CDsbSurface::DoCancel() |
146 | { |
147 | //empty |
148 | } |
149 | |
150 | NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs |
151 | { |
152 | public: |
153 | CDsaB(RWsSession& aSession); |
154 | private: |
155 | ~CDsaB(); |
156 | TUint8* LockSurface(); |
157 | void UnlockHWSurfaceRequestComplete(); |
158 | void UnlockHwSurface(); |
159 | void CreateSurfaceL(); |
160 | void Wipe(TInt aLength); |
161 | void RecreateL(); |
162 | void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); |
163 | void Free(); |
164 | CDirectScreenBitmap& Dsb(); |
165 | void SurfaceReady(); |
166 | TInt ExternalUpdate() {return 0;} |
167 | private: |
168 | CDsbSurface* iSurface1; |
169 | CDsbSurface* iSurface2; |
170 | CDirectScreenBitmap* iDsb; |
171 | }; |
172 | |
173 | CDsaB::CDsaB(RWsSession& aSession) : CDsa(aSession) |
174 | { |
175 | } |
176 | |
177 | void CDsaB::Free() |
178 | { |
179 | } |
180 | |
181 | void CDsaB::UnlockHWSurfaceRequestComplete() |
182 | { |
183 | iSurface1->Complete(); |
184 | iSurface2->Complete(); |
185 | } |
186 | |
187 | void CDsaB::CreateSurfaceL() |
188 | { |
189 | } |
190 | |
191 | void CDsaB::Wipe(TInt aLength) //dont call in drawing |
192 | { |
193 | TUint8* addr = LockSurface(); |
194 | if(addr != NULL) |
195 | { |
196 | Mem::FillZ(addr, aLength); |
197 | UnlockHwSurface(); |
198 | } |
199 | } |
200 | |
201 | void CDsaB::UnlockHwSurface() |
202 | { |
203 | EpocSdlEnv::Request(CDsa::ERequestUpdate); |
204 | } |
205 | |
206 | TUint8* CDsaB::LockSurface() |
207 | { |
208 | TUint8* addr = iSurface1->Address(); |
209 | if(addr == NULL) |
210 | addr = iSurface2->Address(); |
211 | SetUpdating(addr == NULL); |
212 | return addr; |
213 | } |
214 | |
215 | void CDsaB::SurfaceReady() |
216 | { |
217 | SetUpdating(EFalse); |
218 | } |
219 | |
220 | CDirectScreenBitmap& CDsaB::Dsb() |
221 | { |
222 | return *iDsb; |
223 | } |
224 | |
225 | void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) |
226 | { |
227 | if(iDsb == NULL) |
228 | iDsb = CDirectScreenBitmap::NewL(); |
229 | CDsa::ConstructL(aWindow, aDevice); |
230 | iSurface1 = new (ELeave) CDsbSurface(*this); |
231 | iSurface2 = new (ELeave) CDsbSurface(*this); |
232 | } |
233 | |
234 | CDsaB::~CDsaB() |
235 | { |
236 | delete iSurface1; |
237 | delete iSurface2; |
238 | delete iDsb; |
239 | } |
240 | |
241 | void CDsaB::RecreateL() |
242 | { |
243 | iDsb->Close(); |
244 | iDsb->Create(HwRect(), CDirectScreenBitmap::EDoubleBuffer); |
245 | } |
246 | |
247 | ///////////////////////////////////////////////////////////////////////////////////////////////////// |
248 | |
249 | |
250 | TSize CDsa::WindowSize() const |
251 | { |
252 | TSize size = HwRect().Size(); |
253 | if(iStateFlags & EOrientation90) |
254 | { |
255 | const TInt tmp = size.iWidth; |
256 | size.iWidth = size.iHeight; |
257 | size.iHeight = tmp; |
258 | } |
259 | return size; |
260 | } |
261 | |
262 | void CDsa::SetSuspend() |
263 | { |
264 | iStateFlags |= ESdlThreadSuspend; |
265 | } |
266 | |
267 | void CDsa::ReleaseStop() |
268 | { |
269 | iStateFlags &= ~ESdlThreadExplicitStop; |
270 | } |
271 | |
272 | |
273 | TBool CDsa::Stopped() const |
274 | { |
275 | return (iStateFlags & ESdlThreadExplicitStop); |
276 | } |
277 | |
278 | void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation) |
279 | { |
280 | TInt flags = 0; |
281 | switch(aOrientation) |
282 | { |
283 | case CSDL::EOrientation90: |
284 | flags = EOrientation90; |
285 | break; |
286 | case CSDL::EOrientation180: |
287 | flags = EOrientation180; |
288 | break; |
289 | case CSDL::EOrientation270: |
290 | flags = EOrientation90 | EOrientation180; |
291 | break; |
292 | case CSDL::EOrientation0: |
293 | flags = 0; |
294 | break; |
295 | } |
296 | if(flags != (iStateFlags & EOrientationFlags)) |
297 | { |
298 | iStateFlags |= EOrientationChanged; |
299 | iNewFlags = flags; //cannot be set during drawing... |
300 | } |
301 | } |
302 | |
303 | CDsa::~CDsa() |
304 | { |
305 | if(iDsa != NULL) |
306 | { |
307 | iDsa->Cancel(); |
308 | } |
309 | delete iDsa; |
310 | User::Free(iLut256); |
311 | } |
312 | |
313 | void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) |
314 | { |
315 | if(iDsa != NULL) |
316 | { |
317 | iDsa->Cancel(); |
318 | delete iDsa; |
319 | iDsa = NULL; |
320 | } |
321 | |
322 | |
323 | iDsa = CDirectScreenAccess::NewL( |
324 | iSession, |
325 | aDevice, |
326 | aWindow, |
327 | *this); |
328 | |
329 | if(iLut256 == NULL) |
330 | iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32)); |
331 | iTargetMode = aWindow.DisplayMode(); |
332 | iTargetBpp = BytesPerPixel(DisplayMode()); |
333 | iTargetRect = TRect(aWindow.Position(), aWindow.Size()); |
334 | RestartL(); |
335 | } |
336 | |
337 | void CDsa::LockPalette(TBool aLock) |
338 | { |
339 | if(aLock) |
340 | iStateFlags |= EPaletteLocked; |
341 | else |
342 | iStateFlags &= ~EPaletteLocked; |
343 | } |
344 | TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette) |
345 | { |
346 | if(iLut256 == NULL) |
347 | return KErrNotFound; |
348 | const TInt count = aCount - aFirst; |
349 | if(count > 256) |
350 | return KErrArgument; |
351 | if(iStateFlags & EPaletteLocked) |
352 | return KErrNone; |
353 | for(TInt i = aFirst; i < count; i++) //not so busy here:-) |
354 | { |
355 | iLut256[i] = aPalette[i]; |
356 | } |
357 | return KErrNone; |
358 | } |
359 | |
360 | |
361 | |
362 | |
363 | void CDsa::RestartL() |
364 | { |
365 | //const TBool active = iDsa->IsActive(); |
366 | |
367 | //if(!active) |
368 | iDsa->StartL(); |
369 | |
370 | RRegion* r = iDsa->DrawingRegion(); |
371 | iDsa->Gc()->SetClippingRegion(r); |
372 | TRect rect = r->BoundingRect(); |
373 | |
374 | if(rect.IsEmpty()) |
375 | { |
376 | return; |
377 | } |
378 | |
379 | iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip |
380 | |
381 | RecreateL(); |
382 | |
383 | iStateFlags |= ERunning; |
384 | // iScanLineWidth = iTargetBpp * HwRect().Width(); |
385 | ReleaseStop(); |
386 | if(iStateFlags & ESdlThreadSuspend) |
387 | { |
388 | EpocSdlEnv::Resume(); |
389 | iStateFlags &= ~ ESdlThreadSuspend; |
390 | } |
391 | } |
392 | |
393 | CDsa::CDsa(RWsSession& aSession) : |
394 | iSession(aSession), |
395 | iStateFlags(0) |
396 | { |
397 | // CActiveScheduler::Add(this); |
398 | iCFTable[0] = CopyMem; |
399 | iCFTable[1] = CopyMemFlipReversed; |
400 | iCFTable[2] = CopyMemReversed; |
401 | iCFTable[3] = CopyMemFlip; |
402 | |
403 | iCFTable[4] = Copy256; |
404 | iCFTable[5] = Copy256FlipReversed; |
405 | iCFTable[6] = Copy256Reversed; |
406 | iCFTable[7] = Copy256Flip; |
407 | |
408 | |
409 | iCFTable[8] = CopySlow; |
410 | iCFTable[9] = CopySlowFlipReversed; |
411 | iCFTable[10] = CopySlowReversed; |
412 | iCFTable[11] = CopySlowFlip; |
413 | } |
414 | |
415 | RWsSession& CDsa::Session() |
416 | { |
417 | return iSession; |
418 | } |
419 | |
420 | |
421 | |
422 | TUint8* CDsa::LockHwSurface() |
423 | { |
424 | if((iStateFlags & EUpdating) == 0) //else frame is skipped |
425 | { |
426 | return LockSurface(); |
427 | } |
428 | return NULL; |
429 | } |
430 | |
431 | /* |
432 | void CDsa::RunL() |
433 | { |
434 | iStateFlags &= ~EUpdating; |
435 | } |
436 | |
437 | |
438 | void CDsa::DoCancel() |
439 | { |
440 | iStateFlags &= ~EUpdating; |
441 | //nothing can do, just wait? |
442 | } |
443 | */ |
444 | |
445 | TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode) |
446 | { |
447 | if(aHwSurface && aMode != DisplayMode()) |
448 | return KErrArgument; |
449 | |
450 | iSourceMode = aMode; |
451 | |
452 | iSourceBpp = BytesPerPixel(aMode); |
453 | |
454 | const TSize size = WindowSize(); |
455 | if(aSize.iWidth > size.iWidth) |
456 | return KErrTooBig; |
457 | if(aSize.iHeight > size.iHeight) |
458 | return KErrTooBig; |
459 | |
460 | TRAPD(err, CreateSurfaceL()); |
461 | if(err != KErrNone) |
462 | return err; |
463 | |
464 | |
465 | SetCopyFunction(); |
466 | |
467 | EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved); |
468 | |
469 | return KErrNone; |
470 | } |
471 | |
472 | |
473 | /* |
474 | void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode) |
475 | { |
476 | CFbsBitmap* s = new CFbsBitmap(); |
477 | s->Create(aSz, aMode); |
478 | s->LockHeap(); |
479 | TUint32* addr = s->DataAddress(); |
480 | Mem::Copy(addr, aData, aLength); |
481 | s->UnlockHeap(); |
482 | s->Save(aName); |
483 | s->Reset(); |
484 | delete s; |
485 | } |
486 | |
487 | void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz) |
488 | { |
489 | CFbsBitmap* s = new CFbsBitmap(); |
490 | s->Create(aSz, EColor64K); |
491 | TBitmapUtil bmp(s); |
492 | bmp.Begin(TPoint(0, 0)); |
493 | for(TInt j = 0; j < aSz.iHeight; j++) |
494 | { |
495 | bmp.SetPos(TPoint(0, j)); |
496 | for(TInt i = 0; i < aSz.iWidth; i++) |
497 | { |
498 | bmp.SetPixel(*aData); |
499 | aData++; |
500 | bmp.IncXPos(); |
501 | } |
502 | } |
503 | bmp.End(); |
504 | s->Save(aName); |
505 | s->Reset(); |
506 | delete s; |
507 | } |
508 | |
509 | TBuf<16> FooName(TInt aFoo) |
510 | { |
511 | TBuf<16> b; |
512 | b.Format(_L("C:\\pic%d.mbm"), aFoo); |
513 | return b; |
514 | } |
515 | */ |
516 | void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TRect& aTargetPos) const |
517 | { |
518 | TUint8* target = aTarget; |
519 | const TUint8* source = aSource; |
520 | const TInt lineWidth = aRect.Width(); |
521 | source += iSourceBpp * (aRect.iTl.iY * lineWidth); |
522 | TInt sourceStartOffset = iSourceBpp * aRect.iTl.iX; |
523 | source += sourceStartOffset; |
524 | target += iTargetBpp * ((aTargetPos.iTl.iY + aRect.iTl.iY ) * lineWidth); |
525 | TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iTl.iX); |
526 | target += targetStartOffset; |
527 | TUint32* targetPtr = reinterpret_cast<TUint32*>(target); |
528 | const TInt targetWidth = HwRect().Size().iWidth; |
529 | const TInt height = aRect.Height(); |
530 | |
531 | TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth; |
532 | |
533 | if(iStateFlags & EOrientation180) |
534 | { |
535 | |
536 | targetPtr += targetWidth * (height - 1); |
537 | |
538 | for(TInt i = 0; i < height; i++) //source is always smaller |
539 | { |
540 | iCopyFunction(*this, targetPtr, source, lineWidth, height); |
541 | source += lineMove; |
542 | targetPtr -= targetWidth; |
543 | } |
544 | } |
545 | else |
546 | { |
547 | |
548 | |
549 | for(TInt i = 0; i < height; i++) //source is always smaller |
550 | { |
551 | iCopyFunction(*this, targetPtr, source, lineWidth, height); |
552 | source += lineMove; |
553 | targetPtr += targetWidth; |
554 | } |
555 | } |
556 | |
557 | } |
558 | |
559 | |
560 | |
561 | |
562 | void CDsa::Wipe() //dont call in drawing |
563 | { |
564 | if(IsDsaAvailable()) |
565 | Wipe(iTargetBpp * iScreenRect.Width() * iScreenRect.Height()); |
566 | } |
567 | |
568 | void CDsa::SetCopyFunction() |
569 | { |
570 | //calculate offset to correct function in iCFTable according to given parameters |
571 | TInt function = 0; |
572 | const TInt KCopyFunctions = 4; |
573 | const TInt KOffsetToNative = 0; |
574 | const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions; |
575 | const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions; |
576 | const TInt KOffsetTo90Functions = 1; |
577 | const TInt KOffsetTo180Functions = 2; |
578 | |
579 | if(iSourceMode == DisplayMode()) |
580 | function = KOffsetToNative; //0 |
581 | else if(iSourceMode == EColor256) |
582 | function = KOffsetTo256; //4 |
583 | else |
584 | function = KOffsetToOtherModes; //8 |
585 | |
586 | if(iStateFlags & EOrientation90) |
587 | function += KOffsetTo90Functions; // + 1 |
588 | if(iStateFlags & EOrientation180) |
589 | function += KOffsetTo180Functions; //+ 2 |
590 | |
591 | iCopyFunction = iCFTable[function]; |
592 | |
593 | Wipe(); |
594 | } |
595 | |
596 | inline void Rotate(TRect& aRect) |
597 | { |
598 | const TInt dx = aRect.iBr.iX - aRect.iTl.iX; |
599 | const TInt dy = aRect.iBr.iY - aRect.iTl.iY; |
600 | |
601 | aRect.iBr.iX = aRect.iTl.iX + dy; |
602 | aRect.iBr.iY = aRect.iTl.iY + dx; |
603 | |
604 | const TInt tmp = aRect.iTl.iX; |
605 | aRect.iTl.iX = aRect.iTl.iY; |
606 | aRect.iTl.iY = tmp; |
607 | } |
608 | |
609 | /* |
610 | int bar = 0; |
611 | */ |
612 | TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect) |
613 | { |
614 | |
615 | if(iStateFlags & EOrientationChanged) |
616 | { |
617 | iStateFlags &= ~EOrientationFlags; |
618 | iStateFlags |= iNewFlags; |
619 | SetCopyFunction(); |
620 | iStateFlags &= ~EOrientationChanged; |
621 | EpocSdlEnv::WaitDeviceChange(); |
622 | return EFalse; //skip this frame as data is may be changed |
623 | } |
624 | |
625 | if(iTargetAddr == NULL) |
626 | { |
627 | iTargetAddr = LockHwSurface(); |
628 | } |
629 | TUint8* target = iTargetAddr; |
630 | if(target == NULL) |
631 | return EFalse; |
632 | |
633 | |
634 | TRect targetRect = HwRect(); |
635 | TRect sourceRect = aRect; |
636 | TRect updateRect = aUpdateRect; |
637 | |
638 | if(iStateFlags & EOrientation90) |
639 | { |
640 | Rotate(sourceRect); |
641 | Rotate(updateRect); |
642 | } |
643 | |
644 | if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0)) |
645 | { |
646 | sourceRect.Intersection(targetRect); //so source always smaller or equal than target |
647 | updateRect.Intersection(targetRect); |
648 | ClipCopy(target, aBits, updateRect, sourceRect); |
649 | } |
650 | else |
651 | { |
652 | const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored |
653 | Mem::Copy(target, aBits, byteCount); |
654 | } |
655 | |
656 | return ETrue; |
657 | } |
658 | |
659 | CDsa* CDsa::CreateL(RWsSession& aSession) |
660 | { |
661 | if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)) |
662 | { |
663 | TInt flags = CDirectScreenBitmap::ENone; |
664 | if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer)) |
665 | flags |= CDirectScreenBitmap::EDoubleBuffer; |
666 | if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate)) |
667 | flags |= CDirectScreenBitmap::EIncrementalUpdate; |
668 | return new (ELeave) CDsaB(aSession); |
669 | } |
670 | else |
671 | return new (ELeave) CDsaA(aSession); |
672 | } |
673 | |
674 | void CDsa::CreateZoomerL(const TSize& aSize) |
675 | { |
676 | iSwSize = aSize; |
677 | iStateFlags |= EResizeRequest; |
678 | CreateSurfaceL(); |
679 | SetTargetRect(); |
680 | } |
681 | |
682 | TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const |
683 | { |
684 | TPoint pos = aPoint - iScreenRect.iTl; |
685 | const TSize asz = iScreenRect.Size(); |
686 | if(iStateFlags & EOrientation180) |
687 | { |
688 | pos.iX = asz.iWidth - pos.iX; |
689 | pos.iY = asz.iHeight - pos.iY; |
690 | } |
691 | if(iStateFlags & EOrientation90) |
692 | { |
693 | pos.iX = aPoint.iY; |
694 | pos.iY = aPoint.iX; |
695 | } |
696 | pos.iX <<= 16; |
697 | pos.iY <<= 16; |
698 | pos.iX /= asz.iWidth; |
699 | pos.iY /= asz.iHeight; |
700 | pos.iX *= iSwSize.iWidth; |
701 | pos.iY *= iSwSize.iHeight; |
702 | pos.iX >>= 16; |
703 | pos.iY >>= 16; |
704 | return pos; |
705 | } |
706 | |
707 | void CDsa::SetTargetRect() |
708 | { |
709 | iTargetRect = iScreenRect; |
710 | if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio)) |
711 | { |
712 | const TSize asz = iScreenRect.Size(); |
713 | const TSize sz = iSwSize; |
714 | |
715 | TRect rect; |
716 | |
717 | const TInt dh = (sz.iHeight << 16) / sz.iWidth; |
718 | |
719 | if((asz.iWidth * dh ) >> 16 <= asz.iHeight) |
720 | { |
721 | rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16)); |
722 | } |
723 | else |
724 | { |
725 | const TInt dw = (sz.iWidth << 16) / sz.iHeight; |
726 | rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight)); |
727 | } |
728 | rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1); |
729 | |
730 | iTargetRect = rect; |
731 | iTargetRect.Move(iScreenRect.iTl); |
732 | |
733 | } |
734 | if(!(iStateFlags & EResizeRequest)) |
735 | iSwSize = iScreenRect.Size(); |
736 | // iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth; |
737 | } |
738 | |
739 | void CDsa::RecreateL() |
740 | { |
741 | } |
742 | |
743 | void CDsa::Free() |
744 | { |
745 | } |
746 | |
747 | void CDsa::UpdateSwSurface() |
748 | { |
749 | iTargetAddr = NULL; |
750 | UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed |
751 | } |
752 | |
753 | void CDsa::SetBlitter(MBlitter* aBlitter) |
754 | { |
755 | iBlitter = aBlitter; |
756 | } |
757 | |
758 | void CDsa::DrawOverlays() |
759 | { |
760 | const TInt last = iOverlays.Count() - 1; |
761 | for(TInt i = last; i >= 0 ; i--) |
762 | iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize()); |
763 | } |
764 | |
765 | TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority) |
766 | { |
767 | TInt i; |
768 | for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++) |
769 | {} |
770 | const TOverlay overlay = {&aOverlay, aPriority}; |
771 | return iOverlays.Insert(overlay, i); |
772 | } |
773 | |
774 | TInt CDsa::RemoveOverlay(MOverlay& aOverlay) |
775 | { |
776 | for(TInt i = 0; i < iOverlays.Count(); i++) |
777 | { |
778 | if(iOverlays[i].iOverlay == &aOverlay) |
779 | { |
780 | iOverlays.Remove(i); |
781 | return KErrNone; |
782 | } |
783 | } |
784 | return KErrNotFound; |
785 | } |
786 | |
787 | TInt CDsa::RedrawRequest() |
788 | { |
789 | if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning))) |
790 | { |
791 | return ExternalUpdate(); |
792 | } |
793 | return KErrNotReady; |
794 | } |
795 | |
796 | |
797 | void CDsa::Resume() |
798 | { |
799 | if(Stopped()) |
800 | Restart(RDirectScreenAccess::ETerminateRegion); |
801 | } |
802 | |
803 | void CDsa::DoStop() |
804 | { |
805 | if(IsDsaAvailable()) |
806 | iStateFlags |= ESdlThreadExplicitStop; |
807 | Stop(); |
808 | } |
809 | |
810 | void CDsa::Stop() |
811 | { |
812 | iStateFlags &= ~ERunning; |
813 | // Cancel(); //can be called only from main! |
814 | iDsa->Cancel(); |
815 | } |
816 | |
817 | void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/) |
818 | { |
819 | // iStateFlags |= EChangeNotify; |
820 | Stop(); |
821 | } |
822 | |
823 | void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason) |
824 | { |
825 | if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart |
826 | { |
827 | TRAPD(err, RestartL()); |
828 | PANIC_IF_ERROR(err); |
829 | } |
830 | } |
831 | /*) |
832 | TBool CDsa::ChangeTrigger() |
833 | { |
834 | const TBool change = iStateFlags & EChangeNotify; |
835 | iStateFlags &= ~EChangeNotify; |
836 | return change; |
837 | } |
838 | */ |
839 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
840 | |
841 | void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
842 | { |
843 | TUint32* target = aTarget; |
844 | const TUint32* endt = target + aBytes; |
845 | const TUint8* source = aSource; |
846 | while(target < endt) |
847 | { |
848 | *target++ = aDsa.iLut256[*source++]; |
849 | } |
850 | } |
851 | |
852 | void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
853 | { |
854 | const TUint32* target = aTarget; |
855 | TUint32* endt = aTarget + aBytes; |
856 | const TUint8* source = aSource; |
857 | while(target < endt) |
858 | { |
859 | *(--endt) = aDsa.iLut256[*source++]; |
860 | } |
861 | } |
862 | |
863 | void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
864 | { |
865 | TUint32* target = aTarget; |
866 | const TUint32* endt = target + aBytes; |
867 | const TUint8* column = aSource; |
868 | |
869 | while(target < endt) |
870 | { |
871 | *target++ = aDsa.iLut256[*column]; |
872 | column += aLineLen; |
873 | } |
874 | } |
875 | |
876 | void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
877 | { |
878 | const TUint32* target = aTarget; |
879 | TUint32* endt = aTarget + aBytes; |
880 | const TUint8* column = aSource; |
881 | |
882 | while(target < endt) |
883 | { |
884 | *(--endt) = aDsa.iLut256[*column]; |
885 | column += aLineLen; |
886 | } |
887 | } |
888 | |
889 | void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
890 | { |
891 | Mem::Copy(aTarget, aSource, aBytes); |
892 | } |
893 | |
894 | void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
895 | { |
896 | TUint32* target = aTarget; |
897 | const TUint32* endt = target + aBytes; |
898 | const TUint32* column = reinterpret_cast<const TUint32*>(aSource); |
899 | |
900 | while(target < endt) |
901 | { |
902 | *target++ = *column; |
903 | column += aLineLen; |
904 | } |
905 | } |
906 | |
907 | void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
908 | { |
909 | const TUint32* target = aTarget; |
910 | TUint32* endt = aTarget + aBytes; |
911 | const TUint32* source = reinterpret_cast<const TUint32*>(aSource); |
912 | while(target < endt) |
913 | { |
914 | *(--endt) = *source++; |
915 | } |
916 | } |
917 | |
918 | |
919 | void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
920 | { |
921 | const TUint32* target = aTarget; |
922 | TUint32* endt = aTarget + aBytes; |
923 | const TUint32* column = reinterpret_cast<const TUint32*>(aSource); |
924 | |
925 | while(target < endt) |
926 | { |
927 | *(--endt) = *column; |
928 | column += aLineLen; |
929 | } |
930 | } |
931 | |
932 | |
933 | typedef TRgb (*TRgbFunc) (TInt aValue); |
934 | |
935 | LOCAL_C TRgb rgb16MA(TInt aValue) |
936 | { |
937 | return TRgb::Color16MA(aValue); |
938 | } |
939 | |
940 | NONSHARABLE_CLASS(MRgbCopy) |
941 | { |
942 | public: |
943 | virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0; |
944 | virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0; |
945 | }; |
946 | template <class T> |
947 | NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy |
948 | { |
949 | public: |
950 | TRgbCopy(TDisplayMode aMode); |
951 | void* operator new(TUint aBytes, TAny* aMem); |
952 | void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed); |
953 | void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed); |
954 | private: |
955 | TRgbFunc iFunc; |
956 | }; |
957 | |
958 | template <class T> |
959 | void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem) |
960 | { |
961 | return aMem; |
962 | } |
963 | |
964 | template <class T> |
965 | TRgbCopy<T>::TRgbCopy(TDisplayMode aMode) |
966 | { |
967 | switch(aMode) |
968 | { |
969 | case EGray256 : iFunc = TRgb::Gray256; break; |
970 | case EColor256 : iFunc = TRgb::Color256; break; |
971 | case EColor4K : iFunc = TRgb::Color4K; break; |
972 | case EColor64K : iFunc = TRgb::Color64K; break; |
973 | case EColor16M : iFunc = TRgb::Color16M; break; |
974 | case EColor16MU : iFunc = TRgb::Color16MU; break; |
975 | case EColor16MA : iFunc = rgb16MA; break; |
976 | default: |
977 | PANIC(KErrNotSupported); |
978 | } |
979 | } |
980 | |
981 | template <class T> |
982 | void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) |
983 | { |
984 | const T* source = reinterpret_cast<const T*>(aSource); |
985 | TUint32* target = aTarget; |
986 | TUint32* endt = target + aBytes; |
987 | |
988 | if(aReversed) |
989 | { |
990 | while(target < endt) |
991 | { |
992 | TUint32 value = *source++; |
993 | *(--endt) = iFunc(value).Value(); |
994 | } |
995 | } |
996 | else |
997 | { |
998 | while(target < endt) |
999 | { |
1000 | TUint32 value = *source++; |
1001 | *target++ = iFunc(value).Value(); |
1002 | } |
1003 | } |
1004 | } |
1005 | |
1006 | template <class T> |
1007 | void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) |
1008 | { |
1009 | const T* column = reinterpret_cast<const T*>(aSource); |
1010 | TUint32* target = aTarget; |
1011 | TUint32* endt = target + aBytes; |
1012 | |
1013 | if(aReversed) |
1014 | { |
1015 | while(target < endt) |
1016 | { |
1017 | *(--endt) = iFunc(*column).Value(); |
1018 | column += aLineLen; |
1019 | } |
1020 | } |
1021 | else |
1022 | { |
1023 | while(target < endt) |
1024 | { |
1025 | *target++ = iFunc(*column).Value(); |
1026 | column += aLineLen; |
1027 | } |
1028 | } |
1029 | } |
1030 | |
1031 | |
1032 | typedef TUint64 TStackMem; |
1033 | |
1034 | LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode) |
1035 | { |
1036 | if(aMode == EColor256 || aMode == EGray256) |
1037 | { |
1038 | return new (mem) TRgbCopy<TUint8>(aMode); |
1039 | } |
1040 | if(aMode == EColor4K || aMode == EColor64K) |
1041 | { |
1042 | return new (mem) TRgbCopy<TUint16>(aMode); |
1043 | } |
1044 | if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA) |
1045 | { |
1046 | return new (mem) TRgbCopy<TUint32>(aMode); |
1047 | } |
1048 | PANIC(KErrNotSupported); |
1049 | return NULL; |
1050 | } |
1051 | |
1052 | |
1053 | void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1054 | { |
1055 | TStackMem mem = 0; |
1056 | GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue); |
1057 | } |
1058 | |
1059 | void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) |
1060 | { |
1061 | TStackMem mem = 0; |
1062 | GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse); |
1063 | } |
1064 | |
1065 | void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1066 | { |
1067 | TStackMem mem = 0; |
1068 | GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse); |
1069 | } |
1070 | |
1071 | void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) |
1072 | { |
1073 | TStackMem mem = 0; |
1074 | GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); |
1075 | } |