1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsdeviceinterface/screendriver/sgeneric/scnew.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,649 @@
1.4 +// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// This module implements the functions that create the screen class depending
1.18 +// on the screen type.
1.19 +// Include files
1.20 +//
1.21 +//
1.22 +
1.23 +/**
1.24 + @file
1.25 +*/
1.26 +/********************************************************************/
1.27 +#include "BITDRAW.H"
1.28 +#include <hal.h>
1.29 +#include "ScreenInfo.h"
1.30 +#include "scdraw.h"
1.31 +#include "scdraw.inl"
1.32 +#include <graphics/gdi/gdiconsts.h>
1.33 +#include <graphics/suerror.h>
1.34 +/**
1.35 +Creates an instance of CFbsDrawDevice class.
1.36 +@param aScreenNo Screen number
1.37 +@param aDispMode Display mode
1.38 +@param aScreenInfo Screen parameters: video memory address and screen size
1.39 +@return A pointer to the created CFbsDrawDevice object
1.40 +@leave System-wide error code including KErrNoMemory
1.41 +@internalComponent
1.42 +*/
1.43 +static CFbsDrawDevice* CreateInstanceL(TInt aScreenNo,
1.44 + TDisplayMode aDispMode,
1.45 + const TScreenInfo& aScreenInfo)
1.46 + {
1.47 + CFbsDrawDevice* drawDevice = NULL;
1.48 +
1.49 + TInt modeCount;
1.50 + TInt matchedMode=-1;
1.51 + //there is some "ambiguity" about 24 and 32 bit modes...
1.52 + //They are both byte per color component, and both actually have 32 bits per pixel memory use.
1.53 + //This ambiguity does not exist between 12 and 16 bit modes,
1.54 + //because they are distinct color component patterns (x444, 565)
1.55 + //but for now 24 and 32 bit modes are considered equivalent here.
1.56 +
1.57 + if (HAL::Get(aScreenNo, HALData::EDisplayNumModes,modeCount)== KErrNone && modeCount>=1)
1.58 + { //If multiple modes are supported then the highest bpp must be found
1.59 +
1.60 + TInt reqBpp= TDisplayModeUtils::NumDisplayModeBitsPerPixel(aDispMode);
1.61 + TInt reqBpp2=reqBpp;
1.62 + if ( reqBpp==24 || reqBpp==32 ) //Best to be specific here. Who knows how likely is 30 or 64 bpp support?
1.63 + {
1.64 + reqBpp2=32+24 - reqBpp; //reflect 24<==>32
1.65 + //Important compile-time decision embedded here: Only one 32-bit mode is supported
1.66 + if(CFbsDrawDevice::DisplayMode16M() != aDispMode)
1.67 + {
1.68 + User::Leave(KErrNotSupported);
1.69 + }
1.70 + }
1.71 + for (TInt mode=0; mode<modeCount; mode++)
1.72 + {
1.73 + TInt modeBpp=mode;
1.74 + if(HAL::Get(aScreenNo, HALData::EDisplayBitsPerPixel, modeBpp) == KErrNone)
1.75 + {
1.76 + if (modeBpp==reqBpp || modeBpp==reqBpp2)
1.77 + {
1.78 + matchedMode=mode;
1.79 + break;
1.80 + }
1.81 + }
1.82 + }
1.83 + }
1.84 + if (matchedMode==-1)
1.85 + { //This is the expected error code
1.86 + User::Leave(KErrNotSupported);
1.87 + }
1.88 + //Switch the display mode, call the constructor of the class defined
1.89 + switch(aDispMode)
1.90 + {
1.91 + /** Monochrome display mode (1 bpp) */
1.92 + case EGray2:
1.93 + {
1.94 + CDrawOneBppScreenBitmap* drawDeviceX = new (ELeave) CDrawOneBppScreenBitmap;
1.95 + drawDevice=drawDeviceX;
1.96 + CleanupStack::PushL(drawDevice) ;
1.97 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.98 + aScreenNo,
1.99 + aScreenInfo.iAddress,
1.100 + aScreenInfo.iSize,matchedMode));
1.101 + }
1.102 + break;
1.103 + /** Four grayscales display mode (2 bpp) */
1.104 + case EGray4:
1.105 + {
1.106 + CDrawTwoBppScreenBitmap* drawDeviceX = new (ELeave) CDrawTwoBppScreenBitmap;
1.107 + drawDevice=drawDeviceX;
1.108 + CleanupStack::PushL(drawDevice) ;
1.109 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.110 + aScreenNo,
1.111 + aScreenInfo.iAddress,
1.112 + aScreenInfo.iSize,matchedMode));
1.113 + }
1.114 + break;
1.115 + /** 16 grayscales display mode (4 bpp) */
1.116 + case EGray16:
1.117 + {
1.118 + CDrawFourBppScreenBitmapGray* drawDeviceX = new (ELeave) CDrawFourBppScreenBitmapGray;
1.119 + drawDevice=drawDeviceX;
1.120 + CleanupStack::PushL(drawDevice) ;
1.121 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.122 + aScreenNo,
1.123 + aScreenInfo.iAddress,
1.124 + aScreenInfo.iSize,matchedMode));
1.125 + }
1.126 + break;
1.127 + /** 256 grayscales display mode (8 bpp) */
1.128 + case EGray256:
1.129 + {
1.130 + CDrawEightBppScreenBitmapGray* drawDeviceX = new (ELeave) CDrawEightBppScreenBitmapGray;
1.131 + drawDevice=drawDeviceX;
1.132 + CleanupStack::PushL(drawDevice) ;
1.133 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.134 + aScreenNo,
1.135 + aScreenInfo.iAddress,
1.136 + aScreenInfo.iSize,matchedMode));
1.137 + }
1.138 + break;
1.139 + /** Low colour EGA 16 colour display mode (4 bpp) */
1.140 + case EColor16:
1.141 + {
1.142 + CDrawFourBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawFourBppScreenBitmapColor;
1.143 + drawDevice=drawDeviceX;
1.144 + CleanupStack::PushL(drawDevice) ;
1.145 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.146 + aScreenNo,
1.147 + aScreenInfo.iAddress,
1.148 + aScreenInfo.iSize,matchedMode));
1.149 + }
1.150 + break;
1.151 + /** 256 colour display mode (8 bpp) */
1.152 + case EColor256:
1.153 + {
1.154 + CDrawEightBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawEightBppScreenBitmapColor;
1.155 + drawDevice=drawDeviceX;
1.156 + CleanupStack::PushL(drawDevice) ;
1.157 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.158 + aScreenNo,
1.159 + aScreenInfo.iAddress,
1.160 + aScreenInfo.iSize,matchedMode));
1.161 + }
1.162 + break;
1.163 + /** 4,000 colour display mode (16 bpp) */
1.164 + case EColor4K: // 12 Bpp color mode
1.165 + {
1.166 + CDrawTwelveBppScreenBitmapColor* drawDeviceX = new (ELeave) CDrawTwelveBppScreenBitmapColor;
1.167 + drawDevice=drawDeviceX;
1.168 + CleanupStack::PushL(drawDevice) ;
1.169 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.170 + aScreenNo,
1.171 + aScreenInfo.iAddress,
1.172 + aScreenInfo.iSize,matchedMode));
1.173 + }
1.174 + break;
1.175 +
1.176 + case EColor64K: // 16 Bpp color mode
1.177 + {
1.178 + CDrawSixteenBppScreenBitmap* drawDeviceX = new (ELeave) CDrawSixteenBppScreenBitmap;
1.179 + drawDevice=drawDeviceX;
1.180 + CleanupStack::PushL(drawDevice) ;
1.181 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.182 + aScreenNo,
1.183 + aScreenInfo.iAddress,
1.184 + aScreenInfo.iSize,matchedMode));
1.185 + }
1.186 + break;
1.187 + case EColor16MU:
1.188 + {
1.189 + CDrawUTwentyFourBppScreenBitmap* drawDeviceX = new (ELeave) CDrawUTwentyFourBppScreenBitmap;
1.190 + drawDevice=drawDeviceX;
1.191 + CleanupStack::PushL(drawDevice) ;
1.192 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.193 + aScreenNo,
1.194 + aScreenInfo.iAddress,
1.195 + aScreenInfo.iSize,matchedMode));
1.196 + }
1.197 + break;
1.198 + case EColor16MA:
1.199 + {
1.200 + CDrawThirtyTwoBppScreenBitmapAlpha* drawDeviceX = new (ELeave) CDrawThirtyTwoBppScreenBitmapAlpha;
1.201 + drawDevice=drawDeviceX;
1.202 + CleanupStack::PushL(drawDevice) ;
1.203 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.204 + aScreenNo,
1.205 + aScreenInfo.iAddress,
1.206 + aScreenInfo.iSize,matchedMode));
1.207 + }
1.208 + break;
1.209 + case EColor16MAP:
1.210 + {
1.211 + CDrawThirtyTwoBppScreenBitmapAlphaPM* drawDeviceX = new (ELeave) CDrawThirtyTwoBppScreenBitmapAlphaPM;
1.212 + drawDevice=drawDeviceX;
1.213 + CleanupStack::PushL(drawDevice) ;
1.214 + User::LeaveIfError(drawDeviceX->ConstructScreen(
1.215 + aScreenNo,
1.216 + aScreenInfo.iAddress,
1.217 + aScreenInfo.iSize,matchedMode));
1.218 + }
1.219 + break;
1.220 + default:
1.221 + User::Leave(KErrNotSupported);
1.222 + }
1.223 +
1.224 + CleanupStack::Pop(drawDevice);
1.225 + return drawDevice;
1.226 + }
1.227 +
1.228 +
1.229 +/********************************************************************/
1.230 +/* Implementation of CFbsDrawDevice class */
1.231 +/********************************************************************/
1.232 +
1.233 +/**
1.234 +This function calls the correct constructor in function of the display mode.
1.235 +@param aInfo, Structure of the LCD info
1.236 +@param aDispMode, display mode
1.237 +@return A pointer to just created screen device, which implements CFbsDrawDevice interface
1.238 +@deprecated Use CFbsDrawDevice::NewScreenDeviceL(TInt aScreenNo, TDisplayMode aDispMode)
1.239 +*/
1.240 +EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewScreenDeviceL(TScreenInfoV01 aInfo, TDisplayMode aDispMode)
1.241 + {
1.242 + __ASSERT_ALWAYS(aInfo.iScreenAddressValid, Panic(EScreenDriverPanicInvalidWindowHandle));
1.243 + TScreenInfo screenInfo(aInfo.iScreenAddress, aInfo.iScreenSize);
1.244 + return ::CreateInstanceL(KDefaultScreenNo, aDispMode, screenInfo);
1.245 + }
1.246 +
1.247 +
1.248 +
1.249 +/**
1.250 +Creates a new screen device instance, which implements CFbsDrawDevice interface.
1.251 +The method has to be implemented for each type of supported video hardware.
1.252 +@param aScreenNo Screen number
1.253 +@param aDispMode Requested display mode
1.254 +@return A pointer to just created screen device, which implements CFbsDrawDevice interface
1.255 +@leave KErrNoMemory Not enough memory
1.256 + KErrNotSupported The requested screen device type is not supported
1.257 +*/
1.258 +EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewScreenDeviceL(TInt aScreenNo,
1.259 + TDisplayMode aDispMode)
1.260 + {
1.261 + TInt width = 0, height = 0;
1.262 + User::LeaveIfError(HAL::Get(aScreenNo, HALData::EDisplayXPixels, width));
1.263 + User::LeaveIfError(HAL::Get(aScreenNo, HALData::EDisplayYPixels, height));
1.264 + __ASSERT_ALWAYS(width > 0 && height > 0, Panic(EScreenDriverPanicInvalidHalValue));
1.265 +
1.266 + TUint8* address = 0;
1.267 +
1.268 + TScreenInfo screenInfo(address, TSize(width, height));
1.269 + return ::CreateInstanceL(aScreenNo, aDispMode, screenInfo);
1.270 + }
1.271 +
1.272 +/**
1.273 + Depending on the current graphics hardware this
1.274 + will return one of the 16M video modes defined in
1.275 + TDisplayMode, or ENone if a 16M video mode is not supported.
1.276 + The method has to be implemented on all hardware platforms.
1.277 + @return a 16M display mode or ENone.
1.278 + ENone - it means that current hardware doesn't have 16M color mode.
1.279 +*/
1.280 +EXPORT_C TDisplayMode CFbsDrawDevice::DisplayMode16M()
1.281 + {
1.282 + return EColor16MA;
1.283 + }
1.284 +
1.285 +
1.286 +/**
1.287 +Complete construction of the helper object.
1.288 +@param aScreenNo The screen number, starting from 0.
1.289 +@param aPixelFormat Pixel format UID or 0 for default based on bpp
1.290 +@return KErrNone or a system wide error value.
1.291 +*/
1.292 +TInt CScreenDeviceHelper::Construct(TInt aScreenNo, TUidPixelFormat aPixelFormat, TUint aHalMode)
1.293 + {
1.294 + iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField] = aScreenNo; // Screen number
1.295 + iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] = aHalMode; // Rotation and hal mode index
1.296 + iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeGuidField] = aPixelFormat; //May be zero for non-GCE modes
1.297 + iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeClassField]
1.298 + = ((TUint32)(TSurfaceId::EScreenSurface) << TSurfaceId::TScreenSurfaceUsage::ETypeClassShift); // Type
1.299 + iAssignedOrientation = EDeviceOrientationNormal; // Actual rotation is held seperately from surface ID
1.300 +
1.301 + TInt val = 0;
1.302 + iHasChunk = EFalse;
1.303 + TInt ret = HAL::Get(aScreenNo,HALData::EDisplayMemoryHandle,val);
1.304 + if (ret == KErrNone)
1.305 + {
1.306 + __ASSERT_DEBUG(val != 0, Panic(EScreenDriverPanicInvalidHalValue));
1.307 + RChunk chunk;
1.308 + ret = chunk.SetReturnedHandle(val);
1.309 + if (ret != KErrNone)
1.310 + {
1.311 + return ret;
1.312 + }
1.313 + iChunk = chunk;
1.314 + ret = iChunk.Duplicate(RThread(), EOwnerProcess);
1.315 + // Close before checking for errors, as we don't want to leave the
1.316 + // temporary chunk handle floating about.
1.317 + chunk.Close();
1.318 + if (ret != KErrNone)
1.319 + {
1.320 + return ret;
1.321 + }
1.322 + iHasChunk = ETrue;
1.323 + }
1.324 + // KErrNotSupported is returned if we can't get the Handle because it's not a driver
1.325 + // that supports the concept. We don't return that error, since it's perfectly valid
1.326 + // to not support this.
1.327 + else if (ret != KErrNotSupported)
1.328 + {
1.329 + return ret;
1.330 + }
1.331 + return iSurfaceUpdateSession.Connect();
1.332 + }
1.333 +
1.334 +CScreenDeviceHelper::~CScreenDeviceHelper()
1.335 + {
1.336 +
1.337 + iSurfaceUpdateSession.Close();
1.338 + iChunk.Close();
1.339 + }
1.340 +
1.341 +void CScreenDeviceHelper::NotifyWhenAvailable(TRequestStatus& aStatus)
1.342 + {
1.343 + iSurfaceUpdateSession.NotifyWhenAvailable(aStatus);
1.344 + }
1.345 +
1.346 +void CScreenDeviceHelper::CancelUpdateNotification()
1.347 + {
1.348 + iSurfaceUpdateSession.CancelAllUpdateNotifications();
1.349 + }
1.350 +
1.351 +/**
1.352 +Implementation of corresponding function in CDrawDevice, utilizing a tracked
1.353 +update region. Updates the screen from the surface, if the update region is
1.354 +not empty.
1.355 +*/
1.356 +void CScreenDeviceHelper::Update()
1.357 + {
1.358 + TRequestStatus updateComplete = KRequestPending;
1.359 + Update(updateComplete);
1.360 + User::WaitForRequest(updateComplete);
1.361 + }
1.362 +
1.363 +void CScreenDeviceHelper::Update(TRequestStatus& aStatus)
1.364 + {
1.365 + if (!iUpdateRegion.IsEmpty())
1.366 + {
1.367 + iSurfaceUpdateSession.NotifyWhenAvailable(aStatus);
1.368 + iSurfaceUpdateSession.SubmitUpdate(KAllScreens, iSurface, 0, &iUpdateRegion);
1.369 + iUpdateRegion.Clear();
1.370 + }
1.371 + else
1.372 + {
1.373 + TRequestStatus* pComplete=&aStatus;
1.374 + User::RequestComplete(pComplete,KErrNone);
1.375 + }
1.376 + }
1.377 +
1.378 +
1.379 +/**
1.380 +Implementation of corresponding function in CDrawDevice, utilizing a tracked
1.381 +update region. Adds the given rectangle to the update region.
1.382 +@param aRect Rectangle to be added to the update region.
1.383 +*/
1.384 +void CScreenDeviceHelper::UpdateRegion(const TRect& aRect)
1.385 + {
1.386 + if (aRect.IsEmpty())
1.387 + {
1.388 + // Adding an empty rectangle should have no effect.
1.389 + return;
1.390 + }
1.391 +
1.392 + if (iUpdateRegion.CheckError())
1.393 + {
1.394 + // Try to ensure the region doesn't keep an error forever.
1.395 + iUpdateRegion.Clear();
1.396 + }
1.397 +
1.398 + TRect bounds(iUpdateRegion.BoundingRect());
1.399 + iUpdateRegion.AddRect(aRect);
1.400 +
1.401 + // If the region fills up, start again with the old bounding box plus this
1.402 + // rectangle.
1.403 + if (iUpdateRegion.CheckError())
1.404 + {
1.405 + iUpdateRegion.Clear();
1.406 + iUpdateRegion.AddRect(bounds);
1.407 + iUpdateRegion.AddRect(aRect);
1.408 + }
1.409 + }
1.410 +
1.411 +/**
1.412 +Reset the update region to be empty without submitting any outstanding updates.
1.413 +*/
1.414 +void CScreenDeviceHelper::ResetUpdateRegion()
1.415 + {
1.416 + iUpdateRegion.Clear();
1.417 + }
1.418 +
1.419 +/**
1.420 +This function returns the current surface in use for this screen.
1.421 +@param aSurface The identifier to be updated with the current screen surface.
1.422 +*/
1.423 +void CScreenDeviceHelper::GetSurface(TSurfaceId& aSid) const
1.424 + {
1.425 + aSid = iSurface;
1.426 + }
1.427 +
1.428 +/**
1.429 +This function is used to request the device orientations supported by the
1.430 +screen device.
1.431 +@return A bitwise combination of one or more TDeviceOrientation enumerated
1.432 +values indicating the device orientations that are supported by this device.
1.433 +*/
1.434 +TUint CScreenDeviceHelper::DeviceOrientationsAvailable(const TSize& aScreenSize) const
1.435 + {
1.436 + //All that can be reported here is what the CScreenDevice can support via HAL
1.437 + //With generic driver, the runtime can be further restricted by the GCE
1.438 + if ( aScreenSize.iWidth && aScreenSize.iWidth==aScreenSize.iHeight )
1.439 + {
1.440 + return EDeviceOrientationNormal | EDeviceOrientation90CW |
1.441 + EDeviceOrientation180 | EDeviceOrientation270CW;
1.442 + }
1.443 + //Query base HAL for rotated view support
1.444 + TInt offset1=iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField]|TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
1.445 + if ( HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, offset1)==KErrNone
1.446 + && offset1!=0)
1.447 + {
1.448 + return EDeviceOrientationNormal | EDeviceOrientation90CW |
1.449 + EDeviceOrientation180 | EDeviceOrientation270CW;
1.450 + }
1.451 + else
1.452 + return EDeviceOrientationNormal | EDeviceOrientation180;
1.453 + }
1.454 +
1.455 +/**
1.456 +This function selects the surface and device buffer to use in the screen
1.457 +driver for this screen. Normal and 180° rotations will generally use the same
1.458 +surface, while 90° and 270° will use another. The surfaces may have different
1.459 +width, height, stride and surface ID, so functions that make use of any of
1.460 +these may be affected after a change in surface orientation, and the return
1.461 +value should be checked for this reason.
1.462 +
1.463 +This call does not change the way rendering is performed, but may operate on
1.464 +the underlying memory using a new shape. The call does not change the display
1.465 +controller's settings, as this is handled via the GCE. All this changes are the
1.466 +internal attributes of the screen device and driver objects. A CFbsBitGc object
1.467 +activated on the device should be reactivated, to update its own attributes, or
1.468 +drawing may be corrupted.
1.469 +
1.470 +Note: while TDeviceOrientation values do not directly correspond to
1.471 +CFbsBitGc::TGraphicsOrientation values, and cannot be used interchangeably, it
1.472 +is simple to generate the former from the latter using the left-shift operator
1.473 +(i.e. device == (1 << graphics)). In particular a device orientation of
1.474 +90 degrees clockwise is equivalent to a content orientation of 90 degrees anti-
1.475 +clockwise, which is what TGraphicsOrientation refers to for the equivalent
1.476 +setting. The letters "CW" in the TDeviceOrientation enumeration refer
1.477 +to a clockwise device rotation, so EDeviceOrientation90CW is a 90 degree
1.478 +clockwise rotation of the device.
1.479 +
1.480 +@param aOrientation The new device orientation, relative to the normal physical
1.481 +screen orientation.
1.482 +@param aNewSize The new pixel dimensions of the surface to be used.
1.483 +@return ETrue is returned if any of the surface, width, height or stride
1.484 +attributes of the screen device have changed as a result of the call or EFalse
1.485 +if none of the attributes have changed.
1.486 +*/
1.487 +TBool CScreenDeviceHelper::SetDeviceOrientation(TDeviceOrientation aOrientation, TSize& aNewSize)
1.488 + {
1.489 + // Check only one orientation bit is set
1.490 + if (((TInt)aOrientation - 1) & aOrientation)
1.491 + {
1.492 + Panic(EScreenDriverPanicInvalidParameter);
1.493 + }
1.494 +
1.495 + // Check the orientation is supported
1.496 + if ((DeviceOrientationsAvailable(aNewSize) & aOrientation) == 0)
1.497 + {
1.498 + Panic(EScreenDriverPanicInvalidParameter);
1.499 + }
1.500 +
1.501 + iAssignedOrientation=aOrientation;
1.502 +
1.503 + return SetDeviceFlipMode(ConvertFlip(aOrientation),aNewSize);
1.504 + }
1.505 +/** Sets or clears the flipped flag indicating that the width and height have been swapped for a +/-90 deg rotation
1.506 + * Rotation is not required for square displays unless the Hal wants one.
1.507 + **/
1.508 +TBool CScreenDeviceHelper::SetDeviceFlipMode(TBool aFlip, TSize& aNewSize)
1.509 + {
1.510 + //This is now a private method that doesn't validate aFlip
1.511 + TInt newFlipMode= iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
1.512 + if (aFlip)
1.513 + {
1.514 + newFlipMode|=TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
1.515 + }
1.516 + else
1.517 + {
1.518 + newFlipMode&=~TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
1.519 + }
1.520 + if (newFlipMode == iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField])
1.521 + {
1.522 + // No change to mode requested.
1.523 + return EFalse;
1.524 + }
1.525 + TInt err=0;
1.526 + err|=HAL::Get(ScreenNumber(), HALData::EDisplayXPixels, aNewSize.iWidth);
1.527 + err|=HAL::Get(ScreenNumber(), HALData::EDisplayYPixels, aNewSize.iHeight);
1.528 + __ASSERT_ALWAYS(err==KErrNone,Panic(EScreenDriverPanicInvalidHalValue));
1.529 + if (aNewSize.iWidth==aNewSize.iHeight)
1.530 + { //Attempt optimisation to not flip if the screen is square, so avoid recomposition.
1.531 + TInt stride1=iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
1.532 + TInt stride2=stride1^TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag;
1.533 + TInt offset1=stride1;
1.534 + TInt offset2=stride2;
1.535 + //Does the rotated mode have any other attributes that differ?
1.536 + //It is just about possible to imagine that the rotated display
1.537 + //wants to use a different setting for the flipped legacy buffer for optimisation purposes.
1.538 + err|=HAL::Get(ScreenNumber(), HALData::EDisplayOffsetToFirstPixel, offset1);
1.539 + err|=HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, stride1);
1.540 + //The existing mode settings should not fail... we are already in this mode!
1.541 + __ASSERT_ALWAYS(err==KErrNone,Panic(EScreenDriverPanicInvalidHalValue));
1.542 +
1.543 + TInt rotatedErr = HAL::Get(ScreenNumber(), HALData::EDisplayOffsetToFirstPixel, offset2);
1.544 + rotatedErr |= HAL::Get(ScreenNumber(), HALData::EDisplayOffsetBetweenLines, stride2);
1.545 + //The HAL may indicate rotation is not required by failing to return data or returning the same data
1.546 + if ( rotatedErr!=KErrNone || stride2==0 ) //Offset can legitimately be zero.
1.547 + {
1.548 + // No change to mode supported.
1.549 + return EFalse;
1.550 + }
1.551 + if ( stride1==stride2 && offset1==offset2 )
1.552 + {
1.553 + // No change to mode needed.
1.554 + return EFalse;
1.555 + }
1.556 + }
1.557 +
1.558 + iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] = newFlipMode;
1.559 + if (aFlip)
1.560 + {
1.561 + // Swap width and height in the alternate orientation.
1.562 + aNewSize.SetSize(aNewSize.iHeight, aNewSize.iWidth);
1.563 + }
1.564 + return ETrue;
1.565 + }
1.566 +/** Returns the stride for the given mode.
1.567 + * This method must not panic if it should fail!
1.568 + **/
1.569 +TUint CScreenDeviceHelper::BytesPerScanline() const
1.570 + {
1.571 + TInt linepitchInBytes = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
1.572 + TInt ret = HAL::Get(ScreenNumber(),HALData::EDisplayOffsetBetweenLines,linepitchInBytes);
1.573 + if (ret!=KErrNone)
1.574 + {
1.575 + return 0;
1.576 + }
1.577 + return linepitchInBytes ;
1.578 + }
1.579 +/** Returns the address for the image data
1.580 + * This method must not panic if it should fail!
1.581 + **/
1.582 +void* CScreenDeviceHelper::AddressFirstPixel() const
1.583 + {
1.584 + TInt bufferStartAddress = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
1.585 + TInt ret = KErrNone;
1.586 + if (iHasChunk)
1.587 + {
1.588 + // The "chunk" way to do this is to get the handle of the chunk, and then the base address of the
1.589 + // chunk itself.
1.590 + bufferStartAddress = (TInt)iChunk.Base();
1.591 + }
1.592 + else
1.593 + {
1.594 + // Chunk not supported, use older HAL call to get the buffer address.
1.595 + ret = HAL::Get(ScreenNumber(),HALData::EDisplayMemoryAddress,bufferStartAddress);
1.596 + if (ret!=KErrNone)
1.597 + {
1.598 + return 0;
1.599 + }
1.600 + }
1.601 + TInt bufferOffsetFirstPixel = iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
1.602 + ret = HAL::Get(ScreenNumber(),HALData::EDisplayOffsetToFirstPixel,bufferOffsetFirstPixel);
1.603 + if (ret!=KErrNone)
1.604 + {
1.605 + return 0;
1.606 + }
1.607 + return (void*)(bufferStartAddress+bufferOffsetFirstPixel);
1.608 + }
1.609 +
1.610 +/**
1.611 +Returns the current device width/height flip state of this surface, representing a +/-90 deg rotation.
1.612 +**/
1.613 +TBool CScreenDeviceHelper::DeviceFlipped() const
1.614 + {
1.615 + return (iSurface.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField] & TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag) != 0; //!=0 forces true --> 1
1.616 + }
1.617 +
1.618 +
1.619 +/**
1.620 +Returns the current device orientation.
1.621 +*/
1.622 +TDeviceOrientation CScreenDeviceHelper::DeviceOrientation() const
1.623 + {
1.624 + return iAssignedOrientation;
1.625 + }
1.626 +/** Returns an accurate scaling factor between twips and pixels in width.
1.627 +
1.628 + **/
1.629 +TInt CScreenDeviceHelper::HorzTwipsPerThousandPixels(const TSize& aPixels)const
1.630 + {
1.631 + __ASSERT_DEBUG(aPixels.iWidth, Panic(EScreenDriverPanicInvalidSize));
1.632 +
1.633 + TInt width = 0;
1.634 + TInt r = HAL::Get(ScreenNumber(), SecondIfFlipped(HAL::EDisplayXTwips,HAL::EDisplayYTwips), width);
1.635 + __ASSERT_DEBUG(r==KErrNone && width!=0, Panic(EScreenDriverPanicInvalidHalValue));
1.636 +
1.637 + return (width * 1000) / aPixels.iWidth;
1.638 + }
1.639 +/** Returns an accurate scaling factor between twips and pixels in height.
1.640 + **/
1.641 +TInt CScreenDeviceHelper::VertTwipsPerThousandPixels(const TSize& aPixels)const
1.642 + {
1.643 + __ASSERT_DEBUG(aPixels.iHeight, Panic(EScreenDriverPanicInvalidSize));
1.644 +
1.645 + TInt height = 0;
1.646 + TInt r = HAL::Get(ScreenNumber(), SecondIfFlipped(HAL::EDisplayYTwips,HAL::EDisplayXTwips), height);
1.647 + __ASSERT_DEBUG(r==KErrNone && height!=0, Panic(EScreenDriverPanicInvalidHalValue));
1.648 +
1.649 + return (height * 1000) / aPixels.iHeight;
1.650 + }
1.651 +
1.652 +