sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "rendertarget.h" sl@0: #include sl@0: #include sl@0: #include "panic.h" sl@0: #include sl@0: #include sl@0: #include "utils.h" sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: #include "osbwin.h" sl@0: #endif sl@0: sl@0: RWsOffScreenImageTarget::RWsOffScreenImageTarget() sl@0: { sl@0: } sl@0: sl@0: void RWsOffScreenImageTarget::OpenL(TUint32 aUsage, TSgCpuAccess aCpuAccess, TUidPixelFormat aPixelFormat, const TSize& aSize, TInt aScreenNumber) sl@0: { sl@0: CDirectGdiDriver* theDGdiDriver = CDirectGdiDriver::Static(); sl@0: if(!theDGdiDriver) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: iImageInfos[CRenderTarget::ENormalAspectRatio].iUsage = aUsage; sl@0: iImageInfos[CRenderTarget::ENormalAspectRatio].iPixelFormat = aPixelFormat; sl@0: iImageInfos[CRenderTarget::ENormalAspectRatio].iSizeInPixels = aSize; sl@0: iImageInfos[CRenderTarget::ENormalAspectRatio].iCpuAccess = aCpuAccess; sl@0: iImageInfos[CRenderTarget::ENormalAspectRatio].iScreenId = aScreenNumber; sl@0: sl@0: iImageInfos[CRenderTarget::EInvertedAspectRatio] = iImageInfos[CRenderTarget::ENormalAspectRatio]; sl@0: iImageInfos[CRenderTarget::EInvertedAspectRatio].iSizeInPixels.SetSize(aSize.iHeight, aSize.iWidth); sl@0: sl@0: const TInt KImageCount = 1; sl@0: User::LeaveIfError(RSgImageCollection::Create(iImageInfos, KImageCount, iImageCollections, CRenderTarget::EAspectRatioCount)); sl@0: sl@0: for(TInt ii = 0; ii < CRenderTarget::EAspectRatioCount; ii++) sl@0: { sl@0: User::LeaveIfError(iImageCollections[ii].GetInfo(iImageInfos[ii])); //should be the same as requested, this is just belt and braces sl@0: User::LeaveIfError(iImageCollections[ii].OpenImage(0, iImages[ii])); sl@0: iImageTargets[ii] = RDirectGdiImageTarget(*theDGdiDriver); sl@0: User::LeaveIfError(iImageTargets[ii].Create(iImages[ii])); sl@0: } sl@0: } sl@0: sl@0: void RWsOffScreenImageTarget::Close() sl@0: { sl@0: for(TInt ii = 0; ii < CRenderTarget::EAspectRatioCount; ii++) sl@0: { sl@0: iImageTargets[ii].Close(); sl@0: iImages[ii].Close(); sl@0: iImageCollections[ii].Close(); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Create and construct render target. The function creates RSgImage and target associated with it. sl@0: DirectGc wrapper will also be created at this stage. sl@0: */ sl@0: CRenderTarget* CRenderTarget::NewL(MWsIniFile* aIniFile, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber) sl@0: { sl@0: CRenderTarget* self=new(ELeave) CRenderTarget(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aIniFile, aUsage, aCpuAccess, aDisplayMode, aSize, aScreenNumber); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: inline CRenderTarget::CRenderTarget() sl@0: : iCurrentAspectRatio(ENormalAspectRatio) sl@0: {} sl@0: sl@0: CRenderTarget::~CRenderTarget() sl@0: { sl@0: delete iDirectGdiGcWrapper; sl@0: iTarget.Close(); sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: delete iOsbWin; sl@0: #endif sl@0: } sl@0: sl@0: /** sl@0: Construct render target. The function creates RSgImage and target associated with it. sl@0: DirectGc wrapper will also be created at this stage. sl@0: */ sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: void CRenderTarget::ConstructL(MWsIniFile* aIniFile, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber) sl@0: #else sl@0: void CRenderTarget::ConstructL(MWsIniFile* /*aIniFile*/, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber) sl@0: #endif sl@0: { sl@0: CDirectGdiDriver* theDGdiDriver = CDirectGdiDriver::Static(); sl@0: if(!theDGdiDriver) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: iTarget.OpenL(aUsage, aCpuAccess, SgUtils::DisplayModeToPixelFormat(aDisplayMode), aSize, aScreenNumber); sl@0: iDirectGdiGcWrapper = CDirectGdiGcWrapper::NewL(); sl@0: User::LeaveIfError(iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio])); sl@0: sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: _LIT(KDebugOsb, "DEBUGOSB"); sl@0: if(aIniFile->FindVar(aScreenNumber, KDebugOsb)) sl@0: { sl@0: _LIT(KDebugOsbTitleFormatBackBuffer, "Screen %d, back buffer "); sl@0: _LIT(KDebugOsbTitleFormatScreen, "Screen %d, display buffer"); sl@0: TBuf<32> title; sl@0: title.Format(((aUsage & ESgUsageScreenSource) ? KDebugOsbTitleFormatScreen : KDebugOsbTitleFormatBackBuffer), aScreenNumber); sl@0: iOsbWin = CDebugOsbWin::NewL(title, aSize); sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: TAny* CRenderTarget::ResolveObjectInterface(TUint aTypeId) sl@0: { sl@0: switch(aTypeId) sl@0: { sl@0: case MWsUiBuffer::EWsObjectInterfaceId: sl@0: return static_cast(this); sl@0: } sl@0: return DirectGdiGc()->ResolveObjectInterface(aTypeId); sl@0: } sl@0: sl@0: TInt CRenderTarget::MapReadWrite(TAny*& aDataAddress, TInt& aDataStride) sl@0: { sl@0: CDirectGdiDriver* driver = CDirectGdiDriver::Static(); sl@0: if(driver) sl@0: driver->Finish(); sl@0: return Image().MapReadWrite(aDataAddress, aDataStride); sl@0: } sl@0: sl@0: TInt CRenderTarget::MapWriteOnly(TAny*& aDataAddress, TInt& aDataStride) sl@0: { sl@0: CDirectGdiDriver* driver = CDirectGdiDriver::Static(); sl@0: if(driver) sl@0: driver->Finish(); sl@0: return Image().MapWriteOnly(aDataAddress, aDataStride); sl@0: } sl@0: sl@0: TInt CRenderTarget::MapReadOnly(const TAny*& aDataAddress, TInt& aDataStride) const sl@0: { sl@0: CDirectGdiDriver* driver = CDirectGdiDriver::Static(); sl@0: if(driver) sl@0: driver->Finish(); sl@0: return Image().MapReadOnly(aDataAddress, aDataStride); sl@0: } sl@0: sl@0: TInt CRenderTarget::Unmap() sl@0: { sl@0: return Image().Unmap(); sl@0: } sl@0: sl@0: TInt CRenderTarget::Unmap() const sl@0: { sl@0: return Image().Unmap(); sl@0: } sl@0: sl@0: TUidPixelFormat CRenderTarget::PixelFormat() const sl@0: { sl@0: return ImageInfo().iPixelFormat; sl@0: } sl@0: sl@0: TSize CRenderTarget::SizeInPixels() const sl@0: { sl@0: return ImageInfo().iSizeInPixels; sl@0: } sl@0: sl@0: TDisplayMode CRenderTarget::DisplayMode() const sl@0: { sl@0: return SgUtils::PixelFormatToDisplayMode(PixelFormat()); sl@0: } sl@0: sl@0: const TSurfaceId& CRenderTarget::SurfaceId() const sl@0: { sl@0: return ImageCollection().SurfaceId(); sl@0: } sl@0: sl@0: const TSgDrawableId& CRenderTarget::ImageId(TAspectRatio aAspectRatio) const sl@0: { sl@0: return iTarget.iImages[aAspectRatio].Id(); sl@0: } sl@0: sl@0: void CRenderTarget::SetAspectRatio(TAspectRatio aAspectRatio) sl@0: { sl@0: STD_ASSERT_DEBUG(aAspectRatio == ENormalAspectRatio || aAspectRatio == EInvertedAspectRatio, EPluginPanicTemp); sl@0: if(aAspectRatio != iCurrentAspectRatio) sl@0: { sl@0: iCurrentAspectRatio = aAspectRatio; sl@0: iDirectGdiGcWrapper->Reset(); sl@0: } sl@0: iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]); sl@0: } sl@0: sl@0: TInt CRenderTarget::SetDrawDeviceOffset(TPoint& aOrigin) sl@0: { sl@0: //set the offset on both wrappers sl@0: MDrawDeviceOrigin* originInterface=NULL; sl@0: TInt result= iDirectGdiGcWrapper->DirectGdiGc().GetInterface(TUid::Uid(KDrawDeviceOriginInterfaceID),reinterpret_cast(originInterface)); sl@0: if (result>=KErrNone && originInterface!=NULL) sl@0: { sl@0: result=originInterface->Set(aOrigin); sl@0: } sl@0: sl@0: if (result>=KErrNone) sl@0: { sl@0: iOffset=aOrigin; sl@0: iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]); sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: TInt CRenderTarget::AllocNewTarget(RWsOffScreenImageTarget& aNewTarget, const TSize& aNewSize) sl@0: { sl@0: TRAPD(err, sl@0: aNewTarget.OpenL( sl@0: iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iUsage, sl@0: iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iCpuAccess, sl@0: iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iPixelFormat, sl@0: aNewSize, sl@0: iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iScreenId)) sl@0: return err; sl@0: } sl@0: sl@0: void CRenderTarget::SwitchTarget(RWsOffScreenImageTarget& aNewTarget) sl@0: { sl@0: iTarget.Close(); sl@0: iTarget = aNewTarget; sl@0: iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]); sl@0: } sl@0: sl@0: void CRenderTarget::GetPixel(TRgb& aColor, const TPoint& aPixel) const sl@0: { sl@0: const TAny* dataAddress = NULL; sl@0: TInt dataStride; sl@0: const TInt err = MapReadOnly(dataAddress, dataStride); sl@0: if(!err) sl@0: { sl@0: const TUidPixelFormat pixelFormat = PixelFormat(); sl@0: const TInt bpp = SgUtils::MinDataStride(1, pixelFormat); sl@0: const TUint32 offset = aPixel.iY * dataStride / bpp + aPixel.iX; sl@0: switch(pixelFormat) sl@0: { sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: const TInt32* dataAddress1 = static_cast(dataAddress) + offset; sl@0: const TInt32 colValue = *dataAddress1; sl@0: aColor.SetInternal(colValue); sl@0: } sl@0: break; sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: const TInt16* dataAddress1 = static_cast(dataAddress) + offset; sl@0: const TInt16 colValue = *dataAddress1; sl@0: aColor = TRgb::Color64K((TInt)colValue); sl@0: } sl@0: break; sl@0: } sl@0: Unmap(); sl@0: } sl@0: } sl@0: sl@0: void CRenderTarget::GetScanLine(TDes8& aScanLine, const TPoint& aStartPixel, TInt aPixelLength, TDisplayMode aDispMode) const sl@0: { sl@0: TRect rectSrc(aStartPixel, TSize(aPixelLength, 1)); sl@0: const TRect rectClientArea(SizeInPixels()); sl@0: rectSrc.Intersection(rectClientArea); sl@0: if(rectSrc.IsEmpty()) sl@0: return; sl@0: const TUidPixelFormat pixelFormatSource = PixelFormat(); sl@0: const TUidPixelFormat pixelFormatDest = SgUtils::DisplayModeToPixelFormat(aDispMode); sl@0: if((pixelFormatSource == EUidPixelFormatUnknown) || (pixelFormatDest == EUidPixelFormatUnknown)) sl@0: return; sl@0: sl@0: aPixelLength = rectSrc.Width(); sl@0: const TInt dataStrideDest = SgUtils::MinDataStride(aPixelLength, pixelFormatDest); sl@0: if(dataStrideDest <= 0) sl@0: return; sl@0: const TAny* dataAddressSource = NULL; sl@0: TInt dataStrideSource; sl@0: const TInt err = MapReadOnly(dataAddressSource, dataStrideSource); sl@0: if(!err) sl@0: { sl@0: aScanLine.SetLength(dataStrideDest); sl@0: SgUtils::TransferPixels(const_cast(aScanLine.Ptr()), dataStrideDest, pixelFormatDest, sl@0: dataAddressSource, dataStrideSource, pixelFormatSource, rectSrc); sl@0: Unmap(); sl@0: } sl@0: } sl@0: sl@0: TBool CRenderTarget::RectCompare(const TRect& aRect1, const TRect& aRect2) const sl@0: { sl@0: const TAny* startDataAddress = NULL; sl@0: TInt dataStride; sl@0: sl@0: const TRect clientRect(SizeInPixels()); sl@0: TRect rect1 = aRect1; sl@0: TRect rect2 = aRect2; sl@0: sl@0: rect1.Intersection(clientRect); sl@0: rect2.Intersection(clientRect); sl@0: if(rect1.IsEmpty() || rect2.IsEmpty() || (rect1 != aRect1) || (rect2 != aRect2) || sl@0: (rect1.Width() != rect2.Width()) || (rect1.Height() != rect2.Height())) sl@0: return EFalse; sl@0: sl@0: TUidPixelFormat pixelFormat = PixelFormat(); sl@0: if(pixelFormat == EUidPixelFormatUnknown) sl@0: return EFalse; sl@0: sl@0: TInt bpp = SgUtils::MinDataStride(1, pixelFormat); sl@0: if(bpp == 0) sl@0: return EFalse; sl@0: sl@0: TInt err = MapReadOnly(startDataAddress, dataStride); sl@0: if(err != KErrNone) sl@0: return EFalse; sl@0: TBool res = ETrue; sl@0: TPoint startPoint1 = rect1.iTl; sl@0: TPoint startPoint2 = rect2.iTl; sl@0: const TInt length1 = SgUtils::MinDataStride(rect1.Width(), pixelFormat); sl@0: const TInt length2 = SgUtils::MinDataStride(rect2.Width(), pixelFormat); sl@0: sl@0: for(; (startPoint1.iY < rect1.iBr.iY) && (startPoint2.iY < rect2.iBr.iY); startPoint1.iY++, startPoint2.iY++) sl@0: { sl@0: const TUint8* dataAddress1 = DataAddress(startDataAddress, startPoint1, dataStride, bpp); sl@0: const TUint8* dataAddress2 = DataAddress(startDataAddress, startPoint2, dataStride, bpp); sl@0: sl@0: if(Mem::Compare(dataAddress1, length1, dataAddress2, length2) != 0) sl@0: { sl@0: res = EFalse; sl@0: break; sl@0: } sl@0: } sl@0: Unmap(); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: void CRenderTarget::CopyToBitmapL(CFbsBitmap* aBitmap, const TRect& aRect) const sl@0: { sl@0: const TUidPixelFormat pixelFormatDest = SgUtils::DisplayModeToPixelFormat(aBitmap->DisplayMode()); sl@0: const TUidPixelFormat pixelFormatSrc = PixelFormat(); sl@0: if((pixelFormatSrc == EUidPixelFormatUnknown) || (pixelFormatDest == EUidPixelFormatUnknown)) sl@0: User::LeaveIfError(KErrNotSupported); sl@0: sl@0: aBitmap->BeginDataAccess(); sl@0: const TSize sizeDest = aBitmap->SizeInPixels(); sl@0: TRect rectSrc = aRect; sl@0: rectSrc.Intersection(TRect(SizeInPixels())); sl@0: if(rectSrc.IsEmpty()) sl@0: return; sl@0: if(rectSrc.Height() > sizeDest.iHeight) sl@0: { sl@0: rectSrc.SetHeight(sizeDest.iHeight); sl@0: } sl@0: if(rectSrc.Width() > sizeDest.iWidth) sl@0: { sl@0: rectSrc.SetWidth(sizeDest.iWidth); sl@0: } sl@0: sl@0: const TAny* dataAddressSrc = NULL; sl@0: TInt dataStrideSrc; sl@0: User::LeaveIfError(MapReadOnly(dataAddressSrc, dataStrideSrc)); sl@0: sl@0: SgUtils::TransferPixels(aBitmap->DataAddress(), aBitmap->DataStride(), pixelFormatDest, sl@0: dataAddressSrc, dataStrideSrc, pixelFormatSrc, rectSrc); sl@0: sl@0: aBitmap->EndDataAccess(); sl@0: Unmap(); sl@0: } sl@0: sl@0: /* sl@0: Helper function to obtain the address of the buffer sl@0: */ sl@0: const TUint8* CRenderTarget::DataAddress(const TAny* aStartDataAddress, const TPoint& aStartPoint, TInt aDataStride, TInt aBpp) const sl@0: { sl@0: const TInt offset = aStartPoint.iX * aBpp + aStartPoint.iY * aDataStride; sl@0: const TUint8* dataAddress = static_cast(const_cast (aStartDataAddress)); sl@0: sl@0: return(dataAddress + offset); sl@0: } sl@0: sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: void CRenderTarget::UpdateDebugWin() sl@0: { sl@0: if (iOsbWin) sl@0: { sl@0: const TAny* dataAddress = NULL; sl@0: TInt dataStride; sl@0: const TInt err = MapReadOnly(dataAddress, dataStride); sl@0: if(!err) sl@0: { sl@0: const TUint32* dataAddress1 = static_cast(dataAddress); sl@0: iOsbWin->Refresh(SizeInPixels(), DisplayMode(), dataAddress1); sl@0: Unmap(); sl@0: } sl@0: } sl@0: } sl@0: #endif