windowing/windowserverplugins/openwfc/src/rendertarget.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "rendertarget.h"
       
    17 #include <graphics/directgdidriver.h>
       
    18 #include <graphics/sgutils.h>
       
    19 #include "panic.h"
       
    20 #include <bitdraworigin.h>
       
    21 #include <bitdrawinterfaceid.h>
       
    22 #include "utils.h"
       
    23 #if defined(__WINS__) && defined(_DEBUG)
       
    24 #include "osbwin.h"
       
    25 #endif
       
    26 
       
    27 RWsOffScreenImageTarget::RWsOffScreenImageTarget()
       
    28 	{
       
    29 	}
       
    30 
       
    31 void RWsOffScreenImageTarget::OpenL(TUint32 aUsage, TSgCpuAccess aCpuAccess, TUidPixelFormat aPixelFormat, const TSize& aSize, TInt aScreenNumber)
       
    32 	{
       
    33 	CDirectGdiDriver* theDGdiDriver = CDirectGdiDriver::Static();
       
    34 	if(!theDGdiDriver)
       
    35 		{
       
    36 		User::Leave(KErrNotReady);
       
    37 		}
       
    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;
       
    43 	
       
    44 	iImageInfos[CRenderTarget::EInvertedAspectRatio] = iImageInfos[CRenderTarget::ENormalAspectRatio];
       
    45 	iImageInfos[CRenderTarget::EInvertedAspectRatio].iSizeInPixels.SetSize(aSize.iHeight, aSize.iWidth);
       
    46 
       
    47 	const TInt KImageCount = 1;
       
    48 	User::LeaveIfError(RSgImageCollection::Create(iImageInfos, KImageCount, iImageCollections, CRenderTarget::EAspectRatioCount));
       
    49 	
       
    50 	for(TInt ii = 0; ii < CRenderTarget::EAspectRatioCount; ii++)
       
    51 		{
       
    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]));
       
    56 		}
       
    57 	}
       
    58 
       
    59 void RWsOffScreenImageTarget::Close()
       
    60 	{
       
    61 	for(TInt ii = 0; ii < CRenderTarget::EAspectRatioCount; ii++)
       
    62 		{
       
    63 		iImageTargets[ii].Close();
       
    64 		iImages[ii].Close();
       
    65 		iImageCollections[ii].Close();
       
    66 		}
       
    67 	}
       
    68 
       
    69 /**
       
    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. 
       
    72  */ 
       
    73 CRenderTarget* CRenderTarget::NewL(MWsIniFile* aIniFile, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber)
       
    74 	{
       
    75 	CRenderTarget* self=new(ELeave) CRenderTarget();
       
    76 	CleanupStack::PushL(self);
       
    77 	self->ConstructL(aIniFile, aUsage, aCpuAccess, aDisplayMode, aSize, aScreenNumber);
       
    78 	CleanupStack::Pop(self);
       
    79 	return self;
       
    80 	}
       
    81 
       
    82 inline CRenderTarget::CRenderTarget()
       
    83 	: iCurrentAspectRatio(ENormalAspectRatio)
       
    84 	{}
       
    85 
       
    86 CRenderTarget::~CRenderTarget()
       
    87 	{
       
    88 	delete iDirectGdiGcWrapper;
       
    89 	iTarget.Close();
       
    90 #if defined(__WINS__) && defined(_DEBUG)
       
    91 	delete iOsbWin;
       
    92 #endif	
       
    93 	}
       
    94 
       
    95 /**
       
    96  Construct render target. The function creates RSgImage and target associated with it.
       
    97  DirectGc wrapper will also be created at this stage. 
       
    98  */ 
       
    99 #if defined(__WINS__) && defined(_DEBUG)
       
   100 void CRenderTarget::ConstructL(MWsIniFile* aIniFile, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber)
       
   101 #else
       
   102 void CRenderTarget::ConstructL(MWsIniFile* /*aIniFile*/, TUint32 aUsage, TSgCpuAccess aCpuAccess, TDisplayMode aDisplayMode, const TSize& aSize, TInt aScreenNumber)
       
   103 #endif
       
   104 	{
       
   105 	CDirectGdiDriver* theDGdiDriver = CDirectGdiDriver::Static();
       
   106 	if(!theDGdiDriver)
       
   107 		{
       
   108 		User::Leave(KErrNotReady);
       
   109 		}
       
   110 	iTarget.OpenL(aUsage, aCpuAccess, SgUtils::DisplayModeToPixelFormat(aDisplayMode), aSize, aScreenNumber);
       
   111 	iDirectGdiGcWrapper = CDirectGdiGcWrapper::NewL();
       
   112 	User::LeaveIfError(iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]));
       
   113 
       
   114 #if defined(__WINS__) && defined(_DEBUG)
       
   115 	_LIT(KDebugOsb, "DEBUGOSB");
       
   116 	if(aIniFile->FindVar(aScreenNumber, KDebugOsb))
       
   117 		{
       
   118 		_LIT(KDebugOsbTitleFormatBackBuffer, "Screen %d, back buffer   ");
       
   119 		_LIT(KDebugOsbTitleFormatScreen,     "Screen %d, display buffer");
       
   120 		TBuf<32> title;
       
   121 		title.Format(((aUsage & ESgUsageScreenSource) ? KDebugOsbTitleFormatScreen : KDebugOsbTitleFormatBackBuffer), aScreenNumber);
       
   122 		iOsbWin = CDebugOsbWin::NewL(title, aSize);
       
   123 		}
       
   124 #endif
       
   125 	}
       
   126 
       
   127 TAny* CRenderTarget::ResolveObjectInterface(TUint aTypeId)
       
   128 	{
       
   129 	switch(aTypeId)
       
   130 		{
       
   131 	case MWsUiBuffer::EWsObjectInterfaceId:
       
   132 		return static_cast<MWsUiBuffer*>(this);
       
   133 		}
       
   134 	return DirectGdiGc()->ResolveObjectInterface(aTypeId);
       
   135 	}
       
   136 
       
   137 TInt CRenderTarget::MapReadWrite(TAny*& aDataAddress, TInt& aDataStride)
       
   138 	{
       
   139 	CDirectGdiDriver* driver = CDirectGdiDriver::Static();
       
   140 	if(driver)
       
   141 		driver->Finish();
       
   142 	return Image().MapReadWrite(aDataAddress, aDataStride);
       
   143 	}
       
   144 
       
   145 TInt CRenderTarget::MapWriteOnly(TAny*& aDataAddress, TInt& aDataStride)
       
   146 	{
       
   147 	CDirectGdiDriver* driver = CDirectGdiDriver::Static();
       
   148 	if(driver)
       
   149 		driver->Finish();
       
   150 	return Image().MapWriteOnly(aDataAddress, aDataStride);
       
   151 	}
       
   152 
       
   153 TInt CRenderTarget::MapReadOnly(const TAny*& aDataAddress, TInt& aDataStride) const
       
   154 	{
       
   155 	CDirectGdiDriver* driver = CDirectGdiDriver::Static();
       
   156 	if(driver)
       
   157 		driver->Finish();
       
   158 	return Image().MapReadOnly(aDataAddress, aDataStride);
       
   159 	}
       
   160 
       
   161 TInt CRenderTarget::Unmap()
       
   162 	{
       
   163 	return Image().Unmap();
       
   164 	}
       
   165 
       
   166 TInt CRenderTarget::Unmap() const
       
   167 	{
       
   168 	return Image().Unmap();
       
   169 	}
       
   170 
       
   171 TUidPixelFormat CRenderTarget::PixelFormat() const
       
   172 	{
       
   173 	return ImageInfo().iPixelFormat;
       
   174 	}
       
   175 
       
   176 TSize CRenderTarget::SizeInPixels() const
       
   177 	{
       
   178 	return ImageInfo().iSizeInPixels;
       
   179 	}
       
   180 
       
   181 TDisplayMode CRenderTarget::DisplayMode() const
       
   182 	{
       
   183 	return SgUtils::PixelFormatToDisplayMode(PixelFormat());
       
   184 	}
       
   185 
       
   186 const TSurfaceId& CRenderTarget::SurfaceId() const
       
   187 	{
       
   188 	return ImageCollection().SurfaceId();
       
   189 	}
       
   190 
       
   191 const TSgDrawableId& CRenderTarget::ImageId(TAspectRatio aAspectRatio) const
       
   192 	{
       
   193 	return iTarget.iImages[aAspectRatio].Id();
       
   194 	}
       
   195 
       
   196 void CRenderTarget::SetAspectRatio(TAspectRatio aAspectRatio)
       
   197 	{
       
   198 	STD_ASSERT_DEBUG(aAspectRatio == ENormalAspectRatio || aAspectRatio == EInvertedAspectRatio, EPluginPanicTemp);
       
   199 	if(aAspectRatio != iCurrentAspectRatio)
       
   200 		{
       
   201 		iCurrentAspectRatio = aAspectRatio;
       
   202 		iDirectGdiGcWrapper->Reset();
       
   203 		}
       
   204 	iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]);
       
   205 	}
       
   206 
       
   207 TInt CRenderTarget::SetDrawDeviceOffset(TPoint& aOrigin)
       
   208 	{
       
   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)
       
   213 		{
       
   214 		result=originInterface->Set(aOrigin);
       
   215 		}
       
   216 
       
   217 	if (result>=KErrNone)
       
   218 		{
       
   219 		iOffset=aOrigin;
       
   220 		iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]);
       
   221 		}
       
   222 	return result;
       
   223 	}
       
   224 
       
   225 TInt CRenderTarget::AllocNewTarget(RWsOffScreenImageTarget& aNewTarget, const TSize& aNewSize)
       
   226 	{
       
   227 	TRAPD(err,
       
   228 		aNewTarget.OpenL(
       
   229 				iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iUsage,
       
   230 				iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iCpuAccess,
       
   231 				iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iPixelFormat,
       
   232 				aNewSize,
       
   233 				iTarget.iImageInfos[CRenderTarget::ENormalAspectRatio].iScreenId))
       
   234 	return err;
       
   235 	}
       
   236 
       
   237 void CRenderTarget::SwitchTarget(RWsOffScreenImageTarget& aNewTarget)
       
   238 	{
       
   239 	iTarget.Close();
       
   240 	iTarget = aNewTarget;
       
   241 	iDirectGdiGcWrapper->DirectGdiGc().Activate(iTarget.iImageTargets[iCurrentAspectRatio]);
       
   242 	}
       
   243 
       
   244 void CRenderTarget::GetPixel(TRgb& aColor, const TPoint& aPixel) const
       
   245 	{
       
   246 	const TAny* dataAddress = NULL; 
       
   247 	TInt dataStride;
       
   248 	const TInt err = MapReadOnly(dataAddress, dataStride);
       
   249 	if(!err)
       
   250 		{
       
   251 		const TUidPixelFormat pixelFormat = PixelFormat();
       
   252 		const TInt bpp = SgUtils::MinDataStride(1, pixelFormat);
       
   253 		const TUint32 offset = aPixel.iY * dataStride / bpp + aPixel.iX; 
       
   254 		switch(pixelFormat)
       
   255 			{
       
   256 		case EUidPixelFormatARGB_8888_PRE:
       
   257 		case EUidPixelFormatARGB_8888:
       
   258 			{
       
   259 			const TInt32* dataAddress1 = static_cast<const TInt32*>(dataAddress) + offset; 
       
   260 			const TInt32 colValue = *dataAddress1;
       
   261 			aColor.SetInternal(colValue);
       
   262 			}
       
   263 			break;
       
   264 		case EUidPixelFormatRGB_565:
       
   265 			{
       
   266 			const TInt16* dataAddress1 = static_cast<const TInt16*>(dataAddress) + offset;
       
   267 			const TInt16 colValue = *dataAddress1;
       
   268 			aColor = TRgb::Color64K((TInt)colValue);
       
   269 			}
       
   270 			break;
       
   271 			}
       
   272 		Unmap();
       
   273 		}
       
   274 	}
       
   275 
       
   276 void CRenderTarget::GetScanLine(TDes8& aScanLine, const TPoint& aStartPixel, TInt aPixelLength, TDisplayMode aDispMode) const
       
   277 	{
       
   278 	TRect rectSrc(aStartPixel, TSize(aPixelLength, 1)); 
       
   279 	const TRect  rectClientArea(SizeInPixels()); 
       
   280 	rectSrc.Intersection(rectClientArea);
       
   281 	if(rectSrc.IsEmpty())
       
   282 		return;
       
   283 	const TUidPixelFormat pixelFormatSource = PixelFormat();
       
   284 	const TUidPixelFormat pixelFormatDest = SgUtils::DisplayModeToPixelFormat(aDispMode);
       
   285 	if((pixelFormatSource == EUidPixelFormatUnknown) || (pixelFormatDest == EUidPixelFormatUnknown))
       
   286 		return;
       
   287 	
       
   288 	aPixelLength = rectSrc.Width();
       
   289 	const TInt dataStrideDest = SgUtils::MinDataStride(aPixelLength, pixelFormatDest);
       
   290 	if(dataStrideDest <= 0)
       
   291 		return;
       
   292 	const TAny* dataAddressSource = NULL; 
       
   293 	TInt dataStrideSource;
       
   294 	const TInt err = MapReadOnly(dataAddressSource, dataStrideSource);
       
   295 	if(!err)
       
   296 		{
       
   297 		aScanLine.SetLength(dataStrideDest);
       
   298 		SgUtils::TransferPixels(const_cast<TUint8*>(aScanLine.Ptr()), dataStrideDest, pixelFormatDest, 
       
   299 				dataAddressSource, dataStrideSource, pixelFormatSource, rectSrc);
       
   300 		Unmap();
       
   301 		}
       
   302 	}
       
   303 
       
   304 TBool CRenderTarget::RectCompare(const TRect& aRect1, const TRect& aRect2) const
       
   305 	{
       
   306 	const TAny* startDataAddress = NULL; 
       
   307 	TInt dataStride;
       
   308 	
       
   309 	const TRect clientRect(SizeInPixels());
       
   310 	TRect rect1 = aRect1;
       
   311 	TRect rect2 = aRect2;
       
   312 	
       
   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()))
       
   317 		return EFalse;
       
   318 
       
   319 	TUidPixelFormat pixelFormat = PixelFormat();
       
   320 	if(pixelFormat == EUidPixelFormatUnknown)
       
   321 		return EFalse;
       
   322 		
       
   323 	TInt bpp = SgUtils::MinDataStride(1, pixelFormat);
       
   324 	if(bpp == 0)
       
   325 		return EFalse;
       
   326 	
       
   327 	TInt err = MapReadOnly(startDataAddress, dataStride);
       
   328 	if(err != KErrNone)
       
   329 		return EFalse;
       
   330 	TBool res = ETrue;
       
   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);
       
   335 		
       
   336 	for(; (startPoint1.iY < rect1.iBr.iY) && (startPoint2.iY < rect2.iBr.iY); startPoint1.iY++, startPoint2.iY++)
       
   337 		{
       
   338 		const TUint8* dataAddress1 = DataAddress(startDataAddress, startPoint1, dataStride, bpp); 
       
   339 		const TUint8* dataAddress2 = DataAddress(startDataAddress, startPoint2, dataStride, bpp); 
       
   340 		
       
   341 		if(Mem::Compare(dataAddress1, length1, dataAddress2, length2) != 0)
       
   342 			{
       
   343 			res = EFalse; 
       
   344 			break;
       
   345 			}
       
   346 		}
       
   347 	Unmap();
       
   348 	
       
   349 	return res;
       
   350 	}
       
   351 
       
   352 void CRenderTarget::CopyToBitmapL(CFbsBitmap* aBitmap, const TRect& aRect) const
       
   353 	{
       
   354 	const TUidPixelFormat pixelFormatDest = SgUtils::DisplayModeToPixelFormat(aBitmap->DisplayMode());
       
   355 	const TUidPixelFormat pixelFormatSrc = PixelFormat();
       
   356 	if((pixelFormatSrc == EUidPixelFormatUnknown) || (pixelFormatDest == EUidPixelFormatUnknown))
       
   357 		User::LeaveIfError(KErrNotSupported);
       
   358 	
       
   359 	aBitmap->BeginDataAccess();
       
   360 	const TSize sizeDest = aBitmap->SizeInPixels();
       
   361 	TRect rectSrc = aRect;
       
   362 	rectSrc.Intersection(TRect(SizeInPixels()));
       
   363 	if(rectSrc.IsEmpty())
       
   364 		return;
       
   365 	if(rectSrc.Height() > sizeDest.iHeight)
       
   366 		{
       
   367 		rectSrc.SetHeight(sizeDest.iHeight);
       
   368 		}
       
   369 	if(rectSrc.Width() > sizeDest.iWidth)
       
   370 		{
       
   371 		rectSrc.SetWidth(sizeDest.iWidth);
       
   372 		}
       
   373 
       
   374 	const TAny* dataAddressSrc = NULL; 
       
   375 	TInt dataStrideSrc;
       
   376 	User::LeaveIfError(MapReadOnly(dataAddressSrc, dataStrideSrc));
       
   377 
       
   378 	SgUtils::TransferPixels(aBitmap->DataAddress(), aBitmap->DataStride(), pixelFormatDest,  
       
   379 			dataAddressSrc, dataStrideSrc, pixelFormatSrc, rectSrc);
       
   380 
       
   381 	aBitmap->EndDataAccess();
       
   382 	Unmap();
       
   383 	}
       
   384 
       
   385 /*
       
   386  Helper function to obtain the address of the buffer   
       
   387  */
       
   388 const TUint8* CRenderTarget::DataAddress(const TAny* aStartDataAddress, const TPoint& aStartPoint, TInt aDataStride, TInt aBpp) const
       
   389 	{
       
   390 	const TInt offset = aStartPoint.iX * aBpp + aStartPoint.iY * aDataStride;  
       
   391 	const TUint8* dataAddress = static_cast<TUint8*>(const_cast<TAny*> (aStartDataAddress)); 
       
   392 
       
   393 	return(dataAddress + offset);
       
   394 	}
       
   395 
       
   396 #if defined(__WINS__) && defined(_DEBUG)
       
   397 void CRenderTarget::UpdateDebugWin()
       
   398 	{
       
   399 	if (iOsbWin)
       
   400 		{
       
   401 		const TAny* dataAddress = NULL; 
       
   402 		TInt dataStride;
       
   403 		const TInt err = MapReadOnly(dataAddress, dataStride);
       
   404 		if(!err)
       
   405 			{
       
   406 			const TUint32* dataAddress1 = static_cast<const TUint32*>(dataAddress); 
       
   407 			iOsbWin->Refresh(SizeInPixels(), DisplayMode(), dataAddress1);
       
   408 			Unmap();
       
   409 			}
       
   410 		}
       
   411 	}
       
   412 #endif