os/graphics/graphicsdeviceinterface/screendriver/sgeneric/scnew.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2010 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 // This module implements the functions that create the screen class depending
    15 // on the screen type.
    16 // Include files                                                   
    17 // 
    18 //
    19 
    20 /**
    21  @file
    22 */
    23 /********************************************************************/
    24 #include "BITDRAW.H"
    25 #include <hal.h>
    26 #include "ScreenInfo.h"
    27 #include "scdraw.h"
    28 #include "scdraw.inl"
    29 #include <graphics/gdi/gdiconsts.h>
    30 #include <graphics/suerror.h>
    31 /**
    32 Creates an instance of CFbsDrawDevice class.
    33 @param aScreenNo Screen number
    34 @param aDispMode Display mode
    35 @param aScreenInfo Screen parameters: video memory address and screen size
    36 @return A pointer to the created CFbsDrawDevice object
    37 @leave System-wide error code including KErrNoMemory
    38 @internalComponent
    39 */
    40 static CFbsDrawDevice* CreateInstanceL(TInt aScreenNo,
    41 									   TDisplayMode aDispMode,
    42 									   const TScreenInfo& aScreenInfo)
    43 	{
    44 	CFbsDrawDevice* drawDevice = NULL;
    45 
    46 	TInt modeCount;
    47 	TInt matchedMode=-1;
    48 	//there is some "ambiguity" about 24 and 32 bit modes... 
    49 	//They are both byte per color component, and both actually have 32 bits per pixel memory use.
    50 	//This ambiguity does not exist between 12 and 16 bit modes,
    51 	//because they are distinct color component patterns (x444, 565)
    52 	//but for now 24 and 32 bit modes are considered equivalent here.
    53 
    54 	if (HAL::Get(aScreenNo, HALData::EDisplayNumModes,modeCount)== KErrNone && modeCount>=1)
    55 		{	//If multiple modes are supported then the highest bpp must be found
    56 		
    57 		TInt reqBpp= TDisplayModeUtils::NumDisplayModeBitsPerPixel(aDispMode);
    58 		TInt reqBpp2=reqBpp;
    59 		if ( reqBpp==24 || reqBpp==32 ) //Best to be specific here. Who knows how likely is 30 or 64 bpp support?
    60 			{
    61 			reqBpp2=32+24 - reqBpp;   //reflect 24<==>32
    62 			//Important compile-time decision embedded here: Only one 32-bit mode is supported
    63 			if(CFbsDrawDevice::DisplayMode16M() != aDispMode)
    64 				{
    65 				User::Leave(KErrNotSupported);
    66 				}
    67 			}
    68 		for (TInt mode=0; mode<modeCount; mode++)
    69 			{
    70 			TInt modeBpp=mode;
    71 			if(HAL::Get(aScreenNo, HALData::EDisplayBitsPerPixel, modeBpp) == KErrNone)
    72 				{
    73 				if (modeBpp==reqBpp || modeBpp==reqBpp2)
    74 					{
    75 					matchedMode=mode;
    76 					break;
    77 					}
    78 				}
    79 			}
    80 		}
    81 	if (matchedMode==-1)
    82 		{	//This is the expected error code
    83 		User::Leave(KErrNotSupported);
    84 		}
    85 	//Switch the display mode, call the constructor of the class defined
    86 	switch(aDispMode)
    87 		{
    88 	/** Monochrome display mode (1 bpp) */
    89 	case EGray2:
    90 		{
    91 		CDrawOneBppScreenBitmap* drawDeviceX = new (ELeave) CDrawOneBppScreenBitmap;
    92 		drawDevice=drawDeviceX;
    93 		CleanupStack::PushL(drawDevice) ;
    94 		User::LeaveIfError(drawDeviceX->ConstructScreen(
    95 	                                                    aScreenNo,
    96 														aScreenInfo.iAddress, 
    97 														aScreenInfo.iSize,matchedMode));
    98 		}
    99 		break;
   100 	/** Four grayscales display mode (2 bpp) */
   101 	case EGray4:
   102 		{
   103 		CDrawTwoBppScreenBitmap* drawDeviceX = new (ELeave) CDrawTwoBppScreenBitmap;
   104 		drawDevice=drawDeviceX;
   105 		CleanupStack::PushL(drawDevice) ;
   106 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   107 	                                                    aScreenNo,
   108 														aScreenInfo.iAddress, 
   109 														aScreenInfo.iSize,matchedMode));
   110 		}
   111 		break;
   112 	/** 16 grayscales display mode (4 bpp) */
   113 	case EGray16:
   114 		{
   115 		CDrawFourBppScreenBitmapGray* drawDeviceX = new (ELeave) CDrawFourBppScreenBitmapGray;
   116 		drawDevice=drawDeviceX;
   117 		CleanupStack::PushL(drawDevice) ;
   118 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   119 	                                                    aScreenNo,
   120 														aScreenInfo.iAddress, 
   121 														aScreenInfo.iSize,matchedMode));
   122 		}
   123 		break;
   124 	/** 256 grayscales display mode (8 bpp) */
   125 	case EGray256:
   126 		{
   127 		CDrawEightBppScreenBitmapGray* drawDeviceX = new (ELeave) CDrawEightBppScreenBitmapGray;
   128 		drawDevice=drawDeviceX;
   129 		CleanupStack::PushL(drawDevice) ;
   130 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   131 	                                                    aScreenNo,
   132 														aScreenInfo.iAddress, 
   133 														aScreenInfo.iSize,matchedMode));
   134 		}
   135 		break;
   136 	/** Low colour EGA 16 colour display mode (4 bpp) */
   137 	case EColor16:
   138 		{
   139 		CDrawFourBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawFourBppScreenBitmapColor;
   140 		drawDevice=drawDeviceX;
   141 		CleanupStack::PushL(drawDevice) ;
   142 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   143 	                                                    aScreenNo,
   144 														aScreenInfo.iAddress, 
   145 														aScreenInfo.iSize,matchedMode));
   146 		}
   147 		break;
   148 	/** 256 colour display mode (8 bpp) */
   149 	case EColor256:
   150 		{
   151 		CDrawEightBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawEightBppScreenBitmapColor;
   152 		drawDevice=drawDeviceX;
   153 		CleanupStack::PushL(drawDevice) ;
   154 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   155 	                                                    aScreenNo,
   156 														aScreenInfo.iAddress, 
   157 														aScreenInfo.iSize,matchedMode));
   158 		}
   159 		break;
   160 	/** 4,000 colour display mode (16 bpp) */
   161 	case EColor4K: // 12 Bpp color mode
   162 		{
   163 		CDrawTwelveBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawTwelveBppScreenBitmapColor;
   164 		drawDevice=drawDeviceX;
   165 		CleanupStack::PushL(drawDevice) ;
   166 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   167 	                                                    aScreenNo,
   168 														aScreenInfo.iAddress, 
   169 														aScreenInfo.iSize,matchedMode));
   170 		}
   171 		break;
   172 
   173 	case EColor64K: // 16 Bpp color mode
   174 		{
   175 		CDrawSixteenBppScreenBitmap* drawDeviceX = new (ELeave) CDrawSixteenBppScreenBitmap;
   176 		drawDevice=drawDeviceX;
   177 		CleanupStack::PushL(drawDevice) ;
   178 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   179 	                                                    aScreenNo,
   180 														aScreenInfo.iAddress, 
   181 														aScreenInfo.iSize,matchedMode));
   182 		}
   183 		break;
   184 	case EColor16MU:
   185 		{
   186 		CDrawUTwentyFourBppScreenBitmap* drawDeviceX = new (ELeave) CDrawUTwentyFourBppScreenBitmap;
   187 		drawDevice=drawDeviceX;
   188 		CleanupStack::PushL(drawDevice) ;
   189 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   190 	                                                    aScreenNo,
   191 														aScreenInfo.iAddress, 
   192 														aScreenInfo.iSize,matchedMode));
   193 		}
   194 		break;
   195 	case EColor16MA:
   196 		{
   197 		CDrawThirtyTwoBppScreenBitmapAlpha* drawDeviceX = new (ELeave) CDrawThirtyTwoBppScreenBitmapAlpha;
   198 		drawDevice=drawDeviceX;
   199 		CleanupStack::PushL(drawDevice) ;
   200 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   201 	                                                    aScreenNo,
   202 														aScreenInfo.iAddress, 
   203 														aScreenInfo.iSize,matchedMode));
   204 		}
   205 		break;
   206 	case EColor16MAP:
   207 		{
   208 		CDrawThirtyTwoBppScreenBitmapAlphaPM* drawDeviceX = new (ELeave) CDrawThirtyTwoBppScreenBitmapAlphaPM;
   209 		drawDevice=drawDeviceX;
   210 		CleanupStack::PushL(drawDevice) ;
   211 		User::LeaveIfError(drawDeviceX->ConstructScreen(
   212 	                                                    aScreenNo,
   213 														aScreenInfo.iAddress, 
   214 														aScreenInfo.iSize,matchedMode));
   215 		}
   216 		break;
   217 	default:
   218 		User::Leave(KErrNotSupported);
   219 		}
   220 
   221 	CleanupStack::Pop(drawDevice);
   222 	return drawDevice;
   223 	}
   224 
   225 
   226 /********************************************************************/
   227 /*  Implementation of CFbsDrawDevice class                          */
   228 /********************************************************************/
   229 
   230 /**
   231 This function calls the correct constructor in function of the display mode.
   232 @param aInfo, Structure of the LCD info
   233 @param aDispMode, display mode   
   234 @return A pointer to just created screen device, which implements CFbsDrawDevice interface
   235 @deprecated Use CFbsDrawDevice::NewScreenDeviceL(TInt aScreenNo, TDisplayMode aDispMode)
   236 */
   237 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewScreenDeviceL(TScreenInfoV01 aInfo, TDisplayMode aDispMode)
   238 	{
   239 	__ASSERT_ALWAYS(aInfo.iScreenAddressValid, Panic(EScreenDriverPanicInvalidWindowHandle));
   240 	TScreenInfo screenInfo(aInfo.iScreenAddress, aInfo.iScreenSize);
   241 	return ::CreateInstanceL(KDefaultScreenNo, aDispMode, screenInfo);
   242 	}
   243 	
   244 	
   245 
   246 /**
   247 Creates a new screen device instance, which implements CFbsDrawDevice interface.
   248 The method has to be implemented for each type of supported video hardware.
   249 @param aScreenNo Screen number
   250 @param aDispMode Requested display mode
   251 @return A pointer to just created screen device, which implements CFbsDrawDevice interface
   252 @leave KErrNoMemory Not enough memory
   253 	   KErrNotSupported The requested screen device type is not supported
   254 */
   255 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewScreenDeviceL(TInt aScreenNo,
   256 														  TDisplayMode aDispMode)
   257 	{
   258 	TInt width = 0, height = 0;
   259 	User::LeaveIfError(HAL::Get(aScreenNo, HALData::EDisplayXPixels, width));
   260 	User::LeaveIfError(HAL::Get(aScreenNo, HALData::EDisplayYPixels, height));
   261 	__ASSERT_ALWAYS(width > 0 && height > 0, Panic(EScreenDriverPanicInvalidHalValue));
   262 	
   263 	TUint8* address = 0;
   264 	
   265 	TScreenInfo screenInfo(address, TSize(width, height));
   266 	return ::CreateInstanceL(aScreenNo, aDispMode, screenInfo);
   267 	}
   268 
   269 /**
   270  Depending on the current graphics hardware this 
   271  will return one of the 16M video modes defined in
   272  TDisplayMode, or ENone if a 16M video mode is not supported.
   273  The method has to be implemented on all hardware platforms.
   274  @return a 16M display mode or ENone.
   275  ENone - it means that current hardware doesn't have 16M color mode.
   276 */
   277 EXPORT_C TDisplayMode CFbsDrawDevice::DisplayMode16M()
   278 	{
   279 	return EColor16MA;
   280 	}
   281 
   282 
   283 /**
   284 Complete construction of the helper object.
   285 @param aScreenNo	The screen number, starting from 0.
   286 @param aPixelFormat	Pixel format UID or 0 for default based on bpp
   287 @return KErrNone or a system wide error value.
   288 */
   289 TInt CScreenDeviceHelper::Construct(TInt aScreenNo, TUidPixelFormat aPixelFormat, TUint aHalMode)
   290 	{
   291 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField] = aScreenNo;		// Screen number
   292 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] = aHalMode;			// Rotation and hal mode index
   293 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeGuidField] = aPixelFormat;	//May be zero for non-GCE modes
   294 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeClassField] 
   295 			= ((TUint32)(TSurfaceId::EScreenSurface) << TSurfaceId::TScreenSurfaceUsage::ETypeClassShift);	// Type
   296 	iAssignedOrientation = EDeviceOrientationNormal; // Actual rotation is held seperately from surface ID
   297 
   298 	TInt val = 0;
   299 	iHasChunk = EFalse;
   300 	TInt ret = HAL::Get(aScreenNo,HALData::EDisplayMemoryHandle,val);
   301 	if (ret == KErrNone)
   302 		{
   303 		__ASSERT_DEBUG(val != 0, Panic(EScreenDriverPanicInvalidHalValue));
   304 		RChunk chunk;
   305 		ret = chunk.SetReturnedHandle(val);
   306 		if (ret != KErrNone)
   307 			{
   308 			return ret;
   309 			}
   310 		iChunk = chunk;
   311 		ret = iChunk.Duplicate(RThread(), EOwnerProcess);
   312 		// Close before checking for errors, as we don't want to leave the
   313 		// temporary chunk handle floating about. 
   314 		chunk.Close();
   315 		if (ret != KErrNone)
   316 			{
   317 			return ret;
   318 			}
   319 		iHasChunk = ETrue;
   320 		}
   321 	// KErrNotSupported is returned if we can't get the Handle because it's not a driver
   322 	// that supports the concept. We don't return that error, since it's perfectly valid
   323 	// to not support this. 
   324 	else if (ret != KErrNotSupported)   
   325 		{
   326 		return ret;
   327 		}
   328 	return iSurfaceUpdateSession.Connect();
   329 	}
   330 
   331 CScreenDeviceHelper::~CScreenDeviceHelper()
   332 	{
   333 	
   334 	iSurfaceUpdateSession.Close();
   335 	iChunk.Close();
   336 	}
   337 
   338 void CScreenDeviceHelper::NotifyWhenAvailable(TRequestStatus& aStatus)
   339 	{
   340 	iSurfaceUpdateSession.NotifyWhenAvailable(aStatus);
   341 	}
   342 
   343 void CScreenDeviceHelper::CancelUpdateNotification()
   344 	{
   345 	iSurfaceUpdateSession.CancelAllUpdateNotifications();
   346 	}
   347 
   348 /**
   349 Implementation of corresponding function in CDrawDevice, utilizing a tracked
   350 update region. Updates the screen from the surface, if the update region is
   351 not empty.
   352 */
   353 void CScreenDeviceHelper::Update()
   354 	{
   355 	TRequestStatus updateComplete = KRequestPending;
   356 	Update(updateComplete);
   357 	User::WaitForRequest(updateComplete);
   358 	}
   359 
   360 void CScreenDeviceHelper::Update(TRequestStatus& aStatus)
   361 	{
   362 	if (!iUpdateRegion.IsEmpty())
   363 		{
   364 		iSurfaceUpdateSession.NotifyWhenAvailable(aStatus);
   365 		iSurfaceUpdateSession.SubmitUpdate(KAllScreens, iSurface, 0, &iUpdateRegion);
   366 		iUpdateRegion.Clear();
   367 		}
   368 	else
   369 		{
   370 		TRequestStatus* pComplete=&aStatus;
   371 		User::RequestComplete(pComplete,KErrNone);	    
   372 		}
   373 	}
   374 
   375 
   376 /**
   377 Implementation of corresponding function in CDrawDevice, utilizing a tracked
   378 update region. Adds the given rectangle to the update region.
   379 @param aRect	Rectangle to be added to the update region.
   380 */
   381 void CScreenDeviceHelper::UpdateRegion(const TRect& aRect)
   382 	{
   383 	if (aRect.IsEmpty())
   384 		{
   385 		// Adding an empty rectangle should have no effect.
   386 		return;
   387 		}
   388 
   389 	if (iUpdateRegion.CheckError())
   390 		{
   391 		// Try to ensure the region doesn't keep an error forever.
   392 		iUpdateRegion.Clear();
   393 		}
   394 
   395 	TRect bounds(iUpdateRegion.BoundingRect());
   396 	iUpdateRegion.AddRect(aRect);
   397 
   398 	// If the region fills up, start again with the old bounding box plus this
   399 	// rectangle.
   400 	if (iUpdateRegion.CheckError())
   401 		{
   402 		iUpdateRegion.Clear();
   403 		iUpdateRegion.AddRect(bounds);
   404 		iUpdateRegion.AddRect(aRect);
   405 		}
   406 	}
   407 
   408 /**
   409 Reset the update region to be empty without submitting any outstanding updates.
   410 */
   411 void CScreenDeviceHelper::ResetUpdateRegion()
   412 	{
   413 	iUpdateRegion.Clear();
   414 	}
   415 
   416 /**
   417 This function returns the current surface in use for this screen.
   418 @param aSurface	The identifier to be updated with the current screen surface.
   419 */
   420 void CScreenDeviceHelper::GetSurface(TSurfaceId& aSid) const
   421 	{
   422 	aSid = iSurface;
   423 	}
   424 
   425 /**
   426 This function is used to request the device orientations supported by the
   427 screen device.
   428 @return A bitwise combination of one or more TDeviceOrientation enumerated
   429 values indicating the device orientations that are supported by this device.
   430 */
   431 TUint CScreenDeviceHelper::DeviceOrientationsAvailable(const TSize& aScreenSize) const
   432 	{
   433 	//All that can be reported here is what the CScreenDevice can support via HAL
   434 	//With generic driver, the runtime can be further restricted by the GCE
   435 	if (	aScreenSize.iWidth	&&	aScreenSize.iWidth==aScreenSize.iHeight	)
   436 		{
   437 		return EDeviceOrientationNormal | EDeviceOrientation90CW |
   438 			EDeviceOrientation180 | EDeviceOrientation270CW;
   439 		}
   440 	//Query base HAL for rotated view support
   441 	TInt	offset1=iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField]|TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
   442 	if (	HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, offset1)==KErrNone
   443 		&&	offset1!=0)
   444 		{
   445 		return EDeviceOrientationNormal | EDeviceOrientation90CW |
   446 			EDeviceOrientation180 | EDeviceOrientation270CW;
   447 		}
   448 	else
   449 		return EDeviceOrientationNormal | EDeviceOrientation180;
   450 	}
   451 
   452 /**
   453 This function selects the surface and device buffer to use in the screen
   454 driver for this screen. Normal and 180° rotations will generally use the same
   455 surface, while 90° and 270° will use another. The surfaces may have different
   456 width, height, stride and surface ID, so functions that make use of any of
   457 these may be affected after a change in surface orientation, and the return
   458 value should be checked for this reason.
   459 
   460 This call does not change the way rendering is performed, but may operate on
   461 the underlying memory using a new shape. The call does not change the display
   462 controller's settings, as this is handled via the GCE. All this changes are the
   463 internal attributes of the screen device and driver objects. A CFbsBitGc object
   464 activated on the device should be reactivated, to update its own attributes, or
   465 drawing may be corrupted.
   466 
   467 Note: while TDeviceOrientation values do not directly correspond to 
   468 CFbsBitGc::TGraphicsOrientation values, and cannot be used interchangeably, it
   469 is simple to generate the former from the latter using the left-shift operator
   470 (i.e. device == (1 &lt;&lt; graphics)). In particular a device orientation of
   471 90 degrees clockwise is equivalent to a content orientation of 90 degrees anti-
   472 clockwise, which is what TGraphicsOrientation refers to for the equivalent
   473 setting. The letters &quot;CW&quot; in the TDeviceOrientation enumeration refer
   474 to a clockwise device rotation, so EDeviceOrientation90CW is a 90 degree
   475 clockwise rotation of the device.
   476 
   477 @param aOrientation	The new device orientation, relative to the normal physical
   478 screen orientation.
   479 @param aNewSize The new pixel dimensions of the surface to be used.
   480 @return ETrue is returned if any of the surface, width, height or stride
   481 attributes of the screen device have changed as a result of the call or EFalse
   482 if none of the attributes have changed.
   483 */
   484 TBool CScreenDeviceHelper::SetDeviceOrientation(TDeviceOrientation aOrientation, TSize& aNewSize)
   485 	{
   486 	// Check only one orientation bit is set
   487 	if (((TInt)aOrientation - 1) & aOrientation)
   488 		{
   489 		Panic(EScreenDriverPanicInvalidParameter);
   490 		}
   491 
   492 	// Check the orientation is supported
   493 	if ((DeviceOrientationsAvailable(aNewSize) & aOrientation) == 0)
   494 		{
   495 		Panic(EScreenDriverPanicInvalidParameter);
   496 		}
   497 
   498 	iAssignedOrientation=aOrientation;
   499 	
   500 	return SetDeviceFlipMode(ConvertFlip(aOrientation),aNewSize);
   501 	}
   502 /** Sets or clears the flipped flag indicating that the width and height have been swapped for a +/-90 deg rotation
   503  *  Rotation is not required for square displays unless the Hal wants one.
   504  **/
   505 TBool CScreenDeviceHelper::SetDeviceFlipMode(TBool aFlip, TSize& aNewSize)
   506 	{
   507 	//This is now a private method that doesn't validate aFlip
   508 	TInt newFlipMode= iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
   509 	if (aFlip)
   510 		{
   511 		newFlipMode|=TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
   512 		}
   513 	else
   514 		{
   515 		newFlipMode&=~TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
   516 		}
   517 	if (newFlipMode == iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField])
   518 		{
   519 		// No change to mode requested.
   520 		return EFalse;
   521 		}
   522 	TInt err=0;
   523 	err|=HAL::Get(ScreenNumber(), HALData::EDisplayXPixels, aNewSize.iWidth);
   524 	err|=HAL::Get(ScreenNumber(), HALData::EDisplayYPixels, aNewSize.iHeight);
   525 	__ASSERT_ALWAYS(err==KErrNone,Panic(EScreenDriverPanicInvalidHalValue));
   526 	 if (aNewSize.iWidth==aNewSize.iHeight)
   527 		{	//Attempt optimisation to not flip if the screen is square, so avoid recomposition.
   528 		TInt	stride1=iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
   529 		TInt	stride2=stride1^TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
   530 		TInt	offset1=stride1;
   531 		TInt	offset2=stride2;
   532 		//Does the rotated mode have any other attributes that differ?
   533 		//It is just about possible to imagine that the rotated display 
   534 		//wants to use a different setting for the flipped legacy buffer for optimisation purposes.
   535 		err|=HAL::Get(ScreenNumber(), HALData::EDisplayOffsetToFirstPixel, offset1);
   536 		err|=HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, stride1);
   537 		//The existing mode settings should not fail... we are already in this mode!
   538 		__ASSERT_ALWAYS(err==KErrNone,Panic(EScreenDriverPanicInvalidHalValue));
   539 		
   540 		TInt rotatedErr =	HAL::Get(ScreenNumber(), HALData::EDisplayOffsetToFirstPixel, offset2);
   541 		rotatedErr |=		HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, stride2);
   542 		//The HAL may indicate rotation is not required by failing to return data or returning the same data
   543 		if ( rotatedErr!=KErrNone || stride2==0 ) //Offset can legitimately be zero.
   544 			{	
   545 			// No change to mode supported.
   546 			return EFalse;
   547 			}
   548 		if ( stride1==stride2 && offset1==offset2 )
   549 			{
   550 			// No change to mode needed.
   551 			return EFalse;
   552 			}
   553 		}
   554 
   555 	iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] = newFlipMode;
   556 	if (aFlip)
   557 		{
   558 		// Swap width and height in the alternate orientation.
   559 		aNewSize.SetSize(aNewSize.iHeight, aNewSize.iWidth);
   560 		}
   561 	return ETrue;
   562 	}
   563 /**	Returns the stride for the given mode.
   564  *  This method must not panic if it should fail!
   565  **/
   566 TUint CScreenDeviceHelper::BytesPerScanline() const
   567 	{
   568 	TInt linepitchInBytes = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
   569 	TInt ret = HAL::Get(ScreenNumber(),HALData::EDisplayOffsetBetweenLines,linepitchInBytes);
   570 	if (ret!=KErrNone)
   571 		{
   572 		return 0;
   573 		}
   574 	return linepitchInBytes ;
   575 	}
   576 /** Returns the address for the image data
   577  *  This method must not panic if it should fail!
   578  **/
   579 void* CScreenDeviceHelper::AddressFirstPixel() const
   580 	{
   581 	TInt bufferStartAddress = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
   582 	TInt ret = KErrNone;
   583 	if (iHasChunk)
   584 		{
   585 		// The "chunk" way to do this is to get the handle of the chunk, and then the base address of the 
   586 		// chunk itself. 
   587 		bufferStartAddress = (TInt)iChunk.Base();
   588 		}	 
   589 	else 
   590 		{
   591 		// Chunk not supported, use older HAL call to get the buffer address. 
   592 		ret = HAL::Get(ScreenNumber(),HALData::EDisplayMemoryAddress,bufferStartAddress);	
   593 		if (ret!=KErrNone)
   594 			{
   595 			return 0;
   596 			}
   597 		}
   598 	TInt bufferOffsetFirstPixel = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
   599 	ret = HAL::Get(ScreenNumber(),HALData::EDisplayOffsetToFirstPixel,bufferOffsetFirstPixel);
   600 	if (ret!=KErrNone)
   601 		{
   602 		return 0;
   603 		}
   604 	return (void*)(bufferStartAddress+bufferOffsetFirstPixel);
   605 	}
   606 
   607 /**
   608 Returns the current device width/height flip state of this surface, representing a +/-90 deg rotation.
   609 **/
   610 TBool	CScreenDeviceHelper::DeviceFlipped() const
   611 	{
   612 	return  (iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] & TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag) != 0;	//!=0 forces true --> 1
   613 	}
   614 
   615 
   616 /**
   617 Returns the current device orientation.
   618 */
   619 TDeviceOrientation CScreenDeviceHelper::DeviceOrientation() const
   620 	{
   621 	return iAssignedOrientation;
   622 	}
   623 /**	Returns an accurate scaling factor between twips and pixels in width.
   624 
   625  **/
   626 TInt	CScreenDeviceHelper::HorzTwipsPerThousandPixels(const TSize& aPixels)const
   627 	{
   628 	__ASSERT_DEBUG(aPixels.iWidth, Panic(EScreenDriverPanicInvalidSize));
   629 	
   630 	TInt width = 0;
   631 	TInt r = HAL::Get(ScreenNumber(), SecondIfFlipped(HAL::EDisplayXTwips,HAL::EDisplayYTwips), width);
   632 	__ASSERT_DEBUG(r==KErrNone && width!=0, Panic(EScreenDriverPanicInvalidHalValue));
   633    
   634 	return (width * 1000) / aPixels.iWidth;
   635 	}
   636 /**	Returns an accurate scaling factor between twips and pixels in height.
   637  **/
   638 TInt	CScreenDeviceHelper::VertTwipsPerThousandPixels(const TSize& aPixels)const
   639 	{
   640 	__ASSERT_DEBUG(aPixels.iHeight, Panic(EScreenDriverPanicInvalidSize));
   641 
   642 	TInt height = 0;
   643 	TInt r = HAL::Get(ScreenNumber(), SecondIfFlipped(HAL::EDisplayYTwips,HAL::EDisplayXTwips), height);
   644 	__ASSERT_DEBUG(r==KErrNone && height!=0, Panic(EScreenDriverPanicInvalidHalValue));
   645 
   646 	return (height * 1000) / aPixels.iHeight;
   647 	} 
   648 
   649