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