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 1506