3975
+ − 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 }