First public contribution.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "rendertarget.h"
17 #include <graphics/directgdidriver.h>
18 #include <graphics/sgutils.h>
20 #include <bitdraworigin.h>
21 #include <bitdrawinterfaceid.h>
23 #if defined(__WINS__) && defined(_DEBUG)
27 RWsOffScreenImageTarget::RWsOffScreenImageTarget()
31 void RWsOffScreenImageTarget::OpenL(TUint32 aUsage, TSgCpuAccess aCpuAccess, TUidPixelFormat aPixelFormat, const TSize& aSize, TInt aScreenNumber)
33 CDirectGdiDriver* theDGdiDriver = CDirectGdiDriver::Static();
36 User::Leave(KErrNotReady);
38 iImageInfos[CRenderTarget::ENormalAspectRatio].iUsage = aUsage;
39 iImageInfos[CRenderTarget::ENormalAspectRatio].iPixelFormat = aPixelFormat;
40 iImageInfos[CRenderTarget::ENormalAspectRatio].iSizeInPixels = aSize;
41 iImageInfos[CRenderTarget::ENormalAspectRatio].iCpuAccess = aCpuAccess;
42 iImageInfos[CRenderTarget::ENormalAspectRatio].iScreenId = aScreenNumber;
44 iImageInfos[CRenderTarget::EInvertedAspectRatio] = iImageInfos[CRenderTarget::ENormalAspectRatio];
45 iImageInfos[CRenderTarget::EInvertedAspectRatio].iSizeInPixels.SetSize(aSize.iHeight, aSize.iWidth);
47 const TInt KImageCount = 1;
48 User::LeaveIfError(RSgImageCollection::Create(iImageInfos, KImageCount, iImageCollections, CRenderTarget::EAspectRatioCount));
50 for(TInt ii = 0; ii < CRenderTarget::EAspectRatioCount; ii++)
52 User::LeaveIfError(iImageCollections[ii].GetInfo(iImageInfos[ii])); //should be the same as requested, this is just belt and braces
53 User::LeaveIfError(iImageCollections[ii].OpenImage(0, iImages[ii]));
54 iImageTargets[ii] = RDirectGdiImageTarget(*theDGdiDriver);
55 User::LeaveIfError(iImageTargets[ii].Create(iImages[ii]));
59 void RWsOffScreenImageTarget::Close()
61 for(TInt ii = 0; ii < CRenderTarget::EAspectRatioCount; ii++)
63 iImageTargets[ii].Close();
65 iImageCollections[ii].Close();
70 Create and construct render target. The function creates RSgImage and target associated with it.
71 DirectGc wrapper will also be created at this stage.
73 CRenderTarget* CRenderTarget::NewL(MWsIniFile* aIniFile, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber)
75 CRenderTarget* self=new(ELeave) CRenderTarget();
76 CleanupStack::PushL(self);
77 self->ConstructL(aIniFile, aUsage, aCpuAccess, aDisplayMode, aSize, aScreenNumber);
78 CleanupStack::Pop(self);
82 inline CRenderTarget::CRenderTarget()
83 : iCurrentAspectRatio(ENormalAspectRatio)
86 CRenderTarget::~CRenderTarget()
88 delete iDirectGdiGcWrapper;
90 #if defined(__WINS__) && defined(_DEBUG)
96 Construct render target. The function creates RSgImage and target associated with it.
97 DirectGc wrapper will also be created at this stage.
99 #if defined(__WINS__) && defined(_DEBUG)
100 void CRenderTarget::ConstructL(MWsIniFile* aIniFile, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber)
102 void CRenderTarget::ConstructL(MWsIniFile* /*aIniFile*/, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber)
105 CDirectGdiDriver* theDGdiDriver = CDirectGdiDriver::Static();
108 User::Leave(KErrNotReady);
110 iTarget.OpenL(aUsage, aCpuAccess, SgUtils::DisplayModeToPixelFormat(aDisplayMode), aSize, aScreenNumber);
111 iDirectGdiGcWrapper = CDirectGdiGcWrapper::NewL();
112 User::LeaveIfError(iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]));
114 #if defined(__WINS__) && defined(_DEBUG)
115 _LIT(KDebugOsb, "DEBUGOSB");
116 if(aIniFile->FindVar(aScreenNumber, KDebugOsb))
118 _LIT(KDebugOsbTitleFormatBackBuffer, "Screen %d, back buffer ");
119 _LIT(KDebugOsbTitleFormatScreen, "Screen %d, display buffer");
121 title.Format(((aUsage & ESgUsageScreenSource) ? KDebugOsbTitleFormatScreen : KDebugOsbTitleFormatBackBuffer), aScreenNumber);
122 iOsbWin = CDebugOsbWin::NewL(title, aSize);
127 TAny* CRenderTarget::ResolveObjectInterface(TUint aTypeId)
131 case MWsUiBuffer::EWsObjectInterfaceId:
132 return static_cast<MWsUiBuffer*>(this);
134 return DirectGdiGc()->ResolveObjectInterface(aTypeId);
137 TInt CRenderTarget::MapReadWrite(TAny*& aDataAddress, TInt& aDataStride)
139 CDirectGdiDriver* driver = CDirectGdiDriver::Static();
142 return Image().MapReadWrite(aDataAddress, aDataStride);
145 TInt CRenderTarget::MapWriteOnly(TAny*& aDataAddress, TInt& aDataStride)
147 CDirectGdiDriver* driver = CDirectGdiDriver::Static();
150 return Image().MapWriteOnly(aDataAddress, aDataStride);
153 TInt CRenderTarget::MapReadOnly(const TAny*& aDataAddress, TInt& aDataStride) const
155 CDirectGdiDriver* driver = CDirectGdiDriver::Static();
158 return Image().MapReadOnly(aDataAddress, aDataStride);
161 TInt CRenderTarget::Unmap()
163 return Image().Unmap();
166 TInt CRenderTarget::Unmap() const
168 return Image().Unmap();
171 TUidPixelFormat CRenderTarget::PixelFormat() const
173 return ImageInfo().iPixelFormat;
176 TSize CRenderTarget::SizeInPixels() const
178 return ImageInfo().iSizeInPixels;
181 TDisplayMode CRenderTarget::DisplayMode() const
183 return SgUtils::PixelFormatToDisplayMode(PixelFormat());
186 const TSurfaceId& CRenderTarget::SurfaceId() const
188 return ImageCollection().SurfaceId();
191 const TSgDrawableId& CRenderTarget::ImageId(TAspectRatio aAspectRatio) const
193 return iTarget.iImages[aAspectRatio].Id();
196 void CRenderTarget::SetAspectRatio(TAspectRatio aAspectRatio)
198 STD_ASSERT_DEBUG(aAspectRatio == ENormalAspectRatio || aAspectRatio == EInvertedAspectRatio, EPluginPanicTemp);
199 if(aAspectRatio != iCurrentAspectRatio)
201 iCurrentAspectRatio = aAspectRatio;
202 iDirectGdiGcWrapper->Reset();
204 iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]);
207 TInt CRenderTarget::SetDrawDeviceOffset(TPoint& aOrigin)
209 //set the offset on both wrappers
210 MDrawDeviceOrigin* originInterface=NULL;
211 TInt result= iDirectGdiGcWrapper->DirectGdiGc().GetInterface(TUid::Uid(KDrawDeviceOriginInterfaceID),reinterpret_cast<TAny*&>(originInterface));
212 if (result>=KErrNone && originInterface!=NULL)
214 result=originInterface->Set(aOrigin);
217 if (result>=KErrNone)
220 iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]);
225 TInt CRenderTarget::AllocNewTarget(RWsOffScreenImageTarget& aNewTarget, const TSize& aNewSize)
229 iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iUsage,
230 iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iCpuAccess,
231 iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iPixelFormat,
233 iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iScreenId))
237 void CRenderTarget::SwitchTarget(RWsOffScreenImageTarget& aNewTarget)
240 iTarget = aNewTarget;
241 iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]);
244 void CRenderTarget::GetPixel(TRgb& aColor, const TPoint& aPixel) const
246 const TAny* dataAddress = NULL;
248 const TInt err = MapReadOnly(dataAddress, dataStride);
251 const TUidPixelFormat pixelFormat = PixelFormat();
252 const TInt bpp = SgUtils::MinDataStride(1, pixelFormat);
253 const TUint32 offset = aPixel.iY * dataStride / bpp + aPixel.iX;
256 case EUidPixelFormatARGB_8888_PRE:
257 case EUidPixelFormatARGB_8888:
259 const TInt32* dataAddress1 = static_cast<const TInt32*>(dataAddress) + offset;
260 const TInt32 colValue = *dataAddress1;
261 aColor.SetInternal(colValue);
264 case EUidPixelFormatRGB_565:
266 const TInt16* dataAddress1 = static_cast<const TInt16*>(dataAddress) + offset;
267 const TInt16 colValue = *dataAddress1;
268 aColor = TRgb::Color64K((TInt)colValue);
276 void CRenderTarget::GetScanLine(TDes8& aScanLine, const TPoint& aStartPixel, TInt aPixelLength, TDisplayMode aDispMode) const
278 TRect rectSrc(aStartPixel, TSize(aPixelLength, 1));
279 const TRect rectClientArea(SizeInPixels());
280 rectSrc.Intersection(rectClientArea);
281 if(rectSrc.IsEmpty())
283 const TUidPixelFormat pixelFormatSource = PixelFormat();
284 const TUidPixelFormat pixelFormatDest = SgUtils::DisplayModeToPixelFormat(aDispMode);
285 if((pixelFormatSource == EUidPixelFormatUnknown) || (pixelFormatDest == EUidPixelFormatUnknown))
288 aPixelLength = rectSrc.Width();
289 const TInt dataStrideDest = SgUtils::MinDataStride(aPixelLength, pixelFormatDest);
290 if(dataStrideDest <= 0)
292 const TAny* dataAddressSource = NULL;
293 TInt dataStrideSource;
294 const TInt err = MapReadOnly(dataAddressSource, dataStrideSource);
297 aScanLine.SetLength(dataStrideDest);
298 SgUtils::TransferPixels(const_cast<TUint8*>(aScanLine.Ptr()), dataStrideDest, pixelFormatDest,
299 dataAddressSource, dataStrideSource, pixelFormatSource, rectSrc);
304 TBool CRenderTarget::RectCompare(const TRect& aRect1, const TRect& aRect2) const
306 const TAny* startDataAddress = NULL;
309 const TRect clientRect(SizeInPixels());
310 TRect rect1 = aRect1;
311 TRect rect2 = aRect2;
313 rect1.Intersection(clientRect);
314 rect2.Intersection(clientRect);
315 if(rect1.IsEmpty() || rect2.IsEmpty() || (rect1 != aRect1) || (rect2 != aRect2) ||
316 (rect1.Width() != rect2.Width()) || (rect1.Height() != rect2.Height()))
319 TUidPixelFormat pixelFormat = PixelFormat();
320 if(pixelFormat == EUidPixelFormatUnknown)
323 TInt bpp = SgUtils::MinDataStride(1, pixelFormat);
327 TInt err = MapReadOnly(startDataAddress, dataStride);
331 TPoint startPoint1 = rect1.iTl;
332 TPoint startPoint2 = rect2.iTl;
333 const TInt length1 = SgUtils::MinDataStride(rect1.Width(), pixelFormat);
334 const TInt length2 = SgUtils::MinDataStride(rect2.Width(), pixelFormat);
336 for(; (startPoint1.iY < rect1.iBr.iY) && (startPoint2.iY < rect2.iBr.iY); startPoint1.iY++, startPoint2.iY++)
338 const TUint8* dataAddress1 = DataAddress(startDataAddress, startPoint1, dataStride, bpp);
339 const TUint8* dataAddress2 = DataAddress(startDataAddress, startPoint2, dataStride, bpp);
341 if(Mem::Compare(dataAddress1, length1, dataAddress2, length2) != 0)
352 void CRenderTarget::CopyToBitmapL(CFbsBitmap* aBitmap, const TRect& aRect) const
354 const TUidPixelFormat pixelFormatDest = SgUtils::DisplayModeToPixelFormat(aBitmap->DisplayMode());
355 const TUidPixelFormat pixelFormatSrc = PixelFormat();
356 if((pixelFormatSrc == EUidPixelFormatUnknown) || (pixelFormatDest == EUidPixelFormatUnknown))
357 User::LeaveIfError(KErrNotSupported);
359 aBitmap->BeginDataAccess();
360 const TSize sizeDest = aBitmap->SizeInPixels();
361 TRect rectSrc = aRect;
362 rectSrc.Intersection(TRect(SizeInPixels()));
363 if(rectSrc.IsEmpty())
365 if(rectSrc.Height() > sizeDest.iHeight)
367 rectSrc.SetHeight(sizeDest.iHeight);
369 if(rectSrc.Width() > sizeDest.iWidth)
371 rectSrc.SetWidth(sizeDest.iWidth);
374 const TAny* dataAddressSrc = NULL;
376 User::LeaveIfError(MapReadOnly(dataAddressSrc, dataStrideSrc));
378 SgUtils::TransferPixels(aBitmap->DataAddress(), aBitmap->DataStride(), pixelFormatDest,
379 dataAddressSrc, dataStrideSrc, pixelFormatSrc, rectSrc);
381 aBitmap->EndDataAccess();
386 Helper function to obtain the address of the buffer
388 const TUint8* CRenderTarget::DataAddress(const TAny* aStartDataAddress, const TPoint& aStartPoint, TInt aDataStride, TInt aBpp) const
390 const TInt offset = aStartPoint.iX * aBpp + aStartPoint.iY * aDataStride;
391 const TUint8* dataAddress = static_cast<TUint8*>(const_cast<TAny*> (aStartDataAddress));
393 return(dataAddress + offset);
396 #if defined(__WINS__) && defined(_DEBUG)
397 void CRenderTarget::UpdateDebugWin()
401 const TAny* dataAddress = NULL;
403 const TInt err = MapReadOnly(dataAddress, dataStride);
406 const TUint32* dataAddress1 = static_cast<const TUint32*>(dataAddress);
407 iOsbWin->Refresh(SizeInPixels(), DisplayMode(), dataAddress1);