📄 dsa_new.cpp
字号:
#include "dsa.h"#include "sdlepocapi.h"#include <cdsb.h>LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) { return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; }NONSHARABLE_CLASS(TDsa) { public: inline TDsa(const CDsa& aDsa); inline TBool IsFlip() const; inline TBool IsTurn() const; inline const TSize& SwSize() const; inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const; private: const CDsa& iDsa; };inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa) { }inline TBool TDsa::IsTurn() const { return iDsa.iStateFlags & CDsa::EOrientation90; } inline TBool TDsa::IsFlip() const { return iDsa.iStateFlags & CDsa::EOrientation180; } inline const TSize& TDsa::SwSize() const { return iDsa.SwSize(); } inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const { iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight); } template<class T, class S> void ClipCopy(const TDsa& iDsa, TUint8* aTarget, const TUint8* aSource, const TRect& aUpdateRect, const TRect& aSourceRect) { const S* source = reinterpret_cast<const S*>(aSource); const TInt lineWidth = aSourceRect.Width(); source += (aUpdateRect.iTl.iY * lineWidth); const TInt sourceStartOffset = aUpdateRect.iTl.iX; source += sourceStartOffset; T* targetPtr = reinterpret_cast<T*>(aTarget); const TInt scanLineWidth = iDsa.SwSize().iWidth; targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth; const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX); targetPtr += targetStartOffset; const TInt height = aUpdateRect.Height(); const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth; const TInt copyLen = aUpdateRect.Width(); if(iDsa.IsFlip()) { targetPtr += scanLineWidth * (height - 1); for(TInt i = 0; i < height; i++) //source is always smaller { iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height); source += lineMove; targetPtr -= scanLineWidth; } } else { for(TInt i = 0; i < height; i++) //source is always smaller { iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height); source += lineMove; targetPtr += scanLineWidth; // >> 2; } } } NONSHARABLE_CLASS(CDsaA) : public CDsa { public: CDsaA(RWsSession& aSession); private: ~CDsaA(); TUint8* LockSurface(); void UnlockHWSurfaceRequestComplete(); void UnlockHwSurface(); void CreateSurfaceL(); void Wipe(TInt aLength); void Free(); void Update(CFbsBitmap& aBmp); void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); TInt ExternalUpdate(); // void ExternalUpdate(); protected: CFbsBitmap* iBmp; CFbsBitmap* iCopyBmp; }; CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession) { } void CDsaA::Free() { delete iBmp; iBmp = NULL; }CDsaA::~CDsaA() { __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady)); delete iCopyBmp; } TUint8* CDsaA::LockSurface() { iBmp->LockHeap(); return reinterpret_cast<TUint8*>(iBmp->DataAddress()); }void CDsaA::UnlockHWSurfaceRequestComplete() { PANIC(KErrNotSupported); }void CDsaA::UnlockHwSurface() { iBmp->UnlockHeap(); SetUpdating(EFalse); Update(*iBmp); } void CDsaA::Update(CFbsBitmap& aBmp) { if(!Blitter(aBmp)) { if(SwSize() == HwRect().Size()) Dsa().Gc()->BitBlt(HwRect().iTl, &aBmp); else Dsa().Gc()->DrawBitmap(HwRect(), &aBmp); } DrawOverlays(); Dsa().ScreenDevice()->Update(); }void CDsaA::CreateSurfaceL() { delete iBmp; iBmp = NULL; iBmp = new (ELeave) CFbsBitmap(); User::LeaveIfError(iBmp->Create(SwSize(), DisplayMode())); }void CDsaA::Wipe(TInt aLength) //dont call in drawing { iBmp->LockHeap(); Mem::FillZ(iBmp->DataAddress(), aLength); iBmp->UnlockHeap(); } TInt CDsaA::ExternalUpdate() { if(iCopyBmp->Handle() == 0) { const TInt err = iCopyBmp->Duplicate(iBmp->Handle()); if(err != KErrNone) return err; } Update(*iCopyBmp); return KErrNone; } void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) { iCopyBmp = new (ELeave) CFbsBitmap(); CDsa::ConstructL(aWindow, aDevice); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////NONSHARABLE_CLASS(MDsbObs) { public: virtual void SurfaceReady() = 0; virtual CDirectScreenBitmap& Dsb() = 0; }; NONSHARABLE_CLASS(CDsbSurface) : public CActive { public: CDsbSurface(MDsbObs& aDsb); TUint8* Address(); void Complete(); ~CDsbSurface(); private: void RunL(); void DoCancel(); private: MDsbObs& iDsb; TUint8* iAddress; }; CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb) { CActiveScheduler::Add(this); }CDsbSurface::~CDsbSurface() { Cancel(); } void CDsbSurface::Complete() { if(iAddress != NULL && !IsActive()) { iAddress = NULL; SetActive(); iDsb.Dsb().EndUpdate(iStatus); } } TUint8* CDsbSurface::Address() { if(iAddress == NULL && !IsActive()) { TAcceleratedBitmapInfo info; if(KErrNone == iDsb.Dsb().BeginUpdate(info)) iAddress = info.iAddress; } return iAddress; } void CDsbSurface::RunL() { iDsb.SurfaceReady(); }void CDsbSurface::DoCancel() { //empty } NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs { public: CDsaB(RWsSession& aSession, TInt aFlags); private: ~CDsaB(); TUint8* LockSurface(); void UnlockHWSurfaceRequestComplete(); void UnlockHwSurface(); void CreateSurfaceL(); void Wipe(TInt aLength); void RecreateL(); void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); CDirectScreenBitmap& Dsb(); void SurfaceReady(); TInt ExternalUpdate(); private: CDsbSurface* iSurface1; CDsbSurface* iSurface2; CDirectScreenBitmap* iDsb; TInt iType; };CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsa(aSession), iType(aFlags) { } void CDsaB::UnlockHWSurfaceRequestComplete() { iSurface1->Complete(); if(iSurface2 != NULL) iSurface2->Complete(); } void CDsaB::CreateSurfaceL() { __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported)); } void CDsaB::Wipe(TInt aLength) //dont call in drawing { TUint8* addr = LockSurface(); if(addr != NULL) { Mem::FillZ(addr, aLength); UnlockHwSurface(); } } void CDsaB::UnlockHwSurface() { EpocSdlEnv::Request(CDsa::ERequestUpdate); } TUint8* CDsaB::LockSurface() { TUint8* addr = iSurface1->Address(); if(addr == NULL && iSurface2 != NULL) addr = iSurface2->Address(); SetUpdating(addr == NULL); return addr; } void CDsaB::SurfaceReady() { SetUpdating(EFalse); }CDirectScreenBitmap& CDsaB::Dsb() { return *iDsb; } void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) { if(iDsb == NULL) iDsb = CDirectScreenBitmap::NewL(); CDsa::ConstructL(aWindow, aDevice); if(iSurface1 == NULL) iSurface1 = new (ELeave) CDsbSurface(*this); if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer) iSurface2 = new (ELeave) CDsbSurface(*this); } CDsaB::~CDsaB() { delete iSurface1; delete iSurface2; delete iDsb; } void CDsaB::RecreateL() { iDsb->Close(); iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType)); } TInt CDsaB::ExternalUpdate() { if(LockSurface()) { UnlockHWSurfaceRequestComplete(); return KErrNone; } return KErrNotReady; } ///////////////////////////////////////////////////////////////////////////////////////////////////// CDsa* CDsa::CreateL(RWsSession& aSession) { if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)) { TInt flags = CDirectScreenBitmap::ENone; if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer)) flags |= CDirectScreenBitmap::EDoubleBuffer; if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate)) flags |= CDirectScreenBitmap::EIncrementalUpdate; return new (ELeave) CDsaB(aSession, flags); } else return new (ELeave) CDsaA(aSession); } void CDsa::RecreateL() { }void CDsa::Free() { } TSize CDsa::WindowSize() const { TSize size = iSwSize; if(iStateFlags & EOrientation90) { const TInt tmp = size.iWidth; size.iWidth = size.iHeight; size.iHeight = tmp; } return size; } void CDsa::SetSuspend() { iStateFlags |= ESdlThreadSuspend; }void CDsa::ReleaseStop() { iStateFlags &= ~ESdlThreadExplicitStop; }TBool CDsa::Stopped() const { return (iStateFlags & ESdlThreadExplicitStop); }void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation) { TInt flags = 0; switch(aOrientation) { case CSDL::EOrientation90: flags = EOrientation90; break; case CSDL::EOrientation180: flags = EOrientation180; break; case CSDL::EOrientation270: flags = EOrientation90 | EOrientation180; break; case CSDL::EOrientation0: flags = 0; break; } if(flags != (iStateFlags & EOrientationFlags)) { iStateFlags |= EOrientationChanged; iNewFlags = flags; //cannot be set during drawing... } }CDsa::~CDsa() { if(iDsa != NULL) { iDsa->Cancel(); } iOverlays.Close(); delete iDsa; User::Free(iLut256); } void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) { if(iDsa != NULL) { iDsa->Cancel();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -