os/graphics/windowing/windowserverplugins/openwfc/src/rendertarget.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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