graphicshwdrivers/surfacemgr/src/surfacemanager.cpp
branchbug235_bringup_0
changeset 147 af143508cc47
parent 146 4d1fe4a7ce83
child 148 706129140cfc
equal deleted inserted replaced
146:4d1fe4a7ce83 147:af143508cc47
     1 // Copyright (c) 2006-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 /**
       
    17 @file
       
    18 @publishedPartner
       
    19 @prototype
       
    20 
       
    21 */
       
    22 
       
    23 #include "surfacemanager.h"
       
    24 #include <e32base.h>
       
    25 #include "surfacemanagerdriver.h"
       
    26 
       
    27 
       
    28 /**
       
    29 Default constructor
       
    30 */
       
    31 EXPORT_C RSurfaceManager::RSurfaceManager()
       
    32 	{
       
    33 	__ASSERT_COMPILE(sizeof(RSurfaceManagerDriver) <= sizeof(iDriverBuf));
       
    34 	new(iDriverBuf) RSurfaceManagerDriver();
       
    35 	}
       
    36 
       
    37 /**
       
    38 Opens a connection to the Surface Manager.
       
    39 
       
    40 The connection needs to be closed by calling Close() when it is no longer required.
       
    41 @return Returns KErrNone if successful, otherwise a system wide error code.
       
    42 */
       
    43 EXPORT_C TInt RSurfaceManager::Open()
       
    44 	{
       
    45 	TInt err = User::LoadLogicalDevice( RSurfaceManagerDriver::Name() );
       
    46 	if(! ((KErrNone == err) || (KErrAlreadyExists == err)))
       
    47 		{
       
    48 		return err;
       
    49 		}
       
    50 	return Driver().Open();
       
    51 	}
       
    52 
       
    53 /**
       
    54 Closes the connection to the Surface Manager.
       
    55 
       
    56 Cleanup is performed by the Surface Manager when a client process exits or
       
    57 closes its last connection. It is not guaranteed that the resources held by the
       
    58 Surface Manager are going to be released synchronously.
       
    59 */
       
    60 EXPORT_C void RSurfaceManager::Close()
       
    61 	{
       
    62 	Driver().Close();
       
    63 	}
       
    64 
       
    65 /**
       
    66 Returns information specific to the Surface Manager implementation.
       
    67 @param aAttrib Attribute to retrieve
       
    68 @param aValue Output parameter set to the value for the specified attribute
       
    69 @return KErrNone if successful, KErrNotReady if the Surface Manager hasn't been
       
    70 opened, KErrArgument if the attribute UID is not recognized, otherwise a system
       
    71 wide error code.
       
    72 */
       
    73 EXPORT_C TInt RSurfaceManager::GetSurfaceManagerAttrib(TSurfaceManagerAttrib aAttrib, TInt& aValue)
       
    74 	{
       
    75 	return Driver().GetSurfaceManagerAttrib(aAttrib, aValue);
       
    76 	}
       
    77 
       
    78 /**
       
    79 Opens a surface.
       
    80 
       
    81 If the surface is already open in this process, this call increments the
       
    82 reference count for the surface for this process. If the surface hasn't been opened
       
    83 in this process, it opens the surface in this process and sets the reference count
       
    84 to 1 for this process.
       
    85 
       
    86 A surface will be deleted when all its reference counts are 0.
       
    87 @param aSurfaceId  The surface id originally returned when the surface was created.
       
    88 @pre The surface id is for an existing surface.
       
    89 @post The surface is open in this process.
       
    90 @return KErrNone if successful otherwise a system wide error code.
       
    91 */
       
    92 EXPORT_C TInt RSurfaceManager::OpenSurface(const TSurfaceId& aSurfaceId)
       
    93 	{
       
    94 	return Driver().OpenSurface(aSurfaceId);
       
    95 	}
       
    96 
       
    97 /**
       
    98 Creates a surface and returns its global unique identifier.
       
    99 
       
   100 Depending on the implementation, this method will allocate the surface in a new
       
   101 shared chunk or in external memory. Surfaces created in external memory cannot
       
   102 be mapped (see TSurfaceInfoV01::iMappable for more information). If the creation
       
   103 succeeds, the surface will be opened with a reference count of 1 in the calling
       
   104 process.
       
   105 
       
   106 The Surface Manager implementation should validate at least the following:
       
   107 	-	The alignment is 1, 2, 4, 8, 16, 32, 64 or TPageAlignment::EPageAligned.
       
   108 	-	The offset to first buffer is correctly aligned.
       
   109 	-	The width and height are both greater than zero.
       
   110 	-	There is at least one buffer.
       
   111 	-	The calculated chunk size isn't so big that it will exceed a signed int.
       
   112 	-	The caching attribute is valid
       
   113 	-	If the offset between the start of one buffer and the next is specified
       
   114 		(not zero), it must be correctly aligned and at least as big as the 
       
   115 		buffer size calculated from the height and stride.
       
   116 	-	A surface hint key of zero is allowed when creating a surface, it is ignored
       
   117 
       
   118 The Surface Manager implementation will treat iStride, iOffsetToFirstBuffer, and
       
   119 iOffsetBetweenBuffers as minimum values as opposed to required values. The caller
       
   120 of this method must not rely on the passed values as it is not guaranteed that
       
   121 they remain the same after surface creation (SurfaceInfo() and GetBufferOffset()
       
   122 should be used instead).
       
   123 
       
   124 If iOffsetBetweenBuffers is zero, the Surface Manager implementation will layout
       
   125 buffer at its own discretion. Although, a buffer's offset must remain constant
       
   126 during the surface's lifetime.
       
   127 
       
   128 If iMappable is EFalse the surface won't be mappable, hence calls to MapSurface()
       
   129 will fail.
       
   130 
       
   131 @param aReqs Input parameter, specifies attributes of the surface required.
       
   132 @param aSurfaceId Output parameter, the surface ID, set if the call succeeds.
       
   133 @pre The Surface Manager has been successfully opened.
       
   134 @post The surface is created and opened in the creating process.
       
   135 @return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect,
       
   136 KErrNoMemory if the surface cannot be created due to out of memory, KErrOverflow if
       
   137 the chunk limit has been exceeded in the moving memory model, otherwise a standard
       
   138 Symbian error code.
       
   139 */
       
   140 EXPORT_C TInt RSurfaceManager::CreateSurface(const TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId)
       
   141 	{
       
   142 	return Driver().CreateSurface(aReqs,aSurfaceId);
       
   143 	}
       
   144 
       
   145 /**
       
   146 Creates a surface in an existing shared chunk specified by the caller and returns
       
   147 its global unique identifier.
       
   148 
       
   149 If the creation succeeds, the surface will be opened with a reference count of 1 in the calling
       
   150 process.
       
   151 
       
   152 The Surface Manager implementation should validate at least the following:
       
   153 	-	The alignment is 1, 2, 4, 8, 16, 32, 64 or TPageAlignment::EPageAligned.
       
   154 	-	The offset to first buffer is correctly aligned.
       
   155 	-	The width and height are both greater than zero.
       
   156 	-	There is at least one buffer.
       
   157 	-	The calculated chunk size isn't so big that it will exceed a signed int.
       
   158 	-	The caching attribute is valid
       
   159 	-	If the offset between the start of one buffer and the next is specified
       
   160 		(not zero), it must be correctly aligned and at least as big as the 
       
   161 		buffer size calculated from the height and stride.
       
   162 	-	A surface hint key of zero is allowed when creating a surface, it is ignored
       
   163 
       
   164 If iOffsetBetweenBuffers is zero, the Surface Manager implementation will layout
       
   165 buffer at its own discretion. Although, a buffer's offset must remain constant
       
   166 during the surface's lifetime.
       
   167 
       
   168 The attributes iContiguous and iCacheAttribute are ignored for existing chunks.
       
   169 
       
   170 Also, note that surface manager will not do any rounding for offset to first
       
   171 buffer and offset between buffers. It is up to the user, to give exact aligned
       
   172 values for this attributes, otherwise surface creation will fail.
       
   173 
       
   174 If iMappable is EFalse the surface won't be mappable, hence calls to MapSurface()
       
   175 will fail.
       
   176 
       
   177 @param aReqs Input parameter, specifies attributes of the surface required.
       
   178 @param aSurfaceId Output parameter, the surface ID, set if the call succeeds.
       
   179 @param aChunkHandle Handle of the existing shared chunk.
       
   180 @pre The Surface Manager has been successfully opened.
       
   181 @pre A valid shared chunk exists. The shared chunk type should be Shared Kernel
       
   182 multiple and should be right the size, i.e. the size should be calculated as
       
   183 Offset to first buffer + (the number of buffers * ((stride * height *
       
   184 pixel depth in bytes) rounded up to the specified alignment) all rounded to a page size
       
   185 @post The Surface Manager has opened the chunk.
       
   186 @post The surface is created and opened in the creating process.
       
   187 @return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect. 
       
   188 KErrNotReady if the handle is of an invalid shared chunk memory
       
   189 */ 
       
   190 EXPORT_C TInt RSurfaceManager::CreateSurface(const TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId, const RChunk& aChunkHandle)
       
   191 	{
       
   192 	return Driver().CreateSurface(aReqs,aSurfaceId,aChunkHandle);
       
   193 	}
       
   194 
       
   195 /**
       
   196 Closes the surface. Decrements the reference count for the surface for the calling
       
   197 process.
       
   198 
       
   199 If the surface has other owners, it will not be deleted from memory. If this is
       
   200 the last process to close the surface, the surface will be deleted and the
       
   201 surface ID will become invalid. Resources associated with the surface are not
       
   202 guaranteed to be released synchronously.
       
   203 @param aSurfaceId The surface identifier originally returned when the surface was created.
       
   204 @pre The surface is open.
       
   205 @post The surface is closed.
       
   206 @return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
       
   207 KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
       
   208 error code.
       
   209 */
       
   210 EXPORT_C TInt RSurfaceManager::CloseSurface(const TSurfaceId& aSurfaceId)
       
   211 	{
       
   212 	return Driver().CloseSurface(aSurfaceId);
       
   213 	}
       
   214 
       
   215 /**
       
   216 Maps the surface into the current client process address space.
       
   217 
       
   218 The actual memory will remain mapped into the calling process for as long as
       
   219 the RChunk handle aChunk is open.
       
   220 
       
   221 Whether or not a surface is mappable is determined at creation time, see 
       
   222 TSurfaceCreationAttributes::iMappable.
       
   223 
       
   224 The address of the pixel data in buffer N is chunk.Base() + GetBufferOffset(N).
       
   225 
       
   226 Surfaces created with existing shared chunks will get the same chunk handle.
       
   227 
       
   228 The RChunk handle is owned by the calling thread, so will need to be duplicated
       
   229 if passed to other threads in the process.
       
   230 @param aSurfaceId The surface identifier originally returned when the surface was created.
       
   231 @param aHandle Output parameter, handle to the implementation specific Shared Chunk.
       
   232 @pre The surface is open.
       
   233 @post The surface memory will be mapped into the calling process's address space.
       
   234 The surface is mapped.
       
   235 @return KErrNone if successful, KErrArgument if the surface ID does not refer to a
       
   236 surface, KErrAccessDenied if the surface is not open in the current process,
       
   237 KErrNotSupported if the surface is not mappable, KErrOverflow if the chunk limit has been
       
   238 exceeded in the moving memory model, otherwise a system wide error code.
       
   239 @see RChunk
       
   240 @see RHandleBase::Duplicate
       
   241 @see TSurfaceCreationAttributes::iMappable
       
   242 */
       
   243 EXPORT_C TInt RSurfaceManager::MapSurface(const TSurfaceId& aSurfaceId, RChunk& aHandle)
       
   244 	{
       
   245 	return Driver().MapSurface(aSurfaceId,aHandle);
       
   246 	}
       
   247 
       
   248 /**
       
   249 Returns information about a particular surface identified by its surface ID.
       
   250 @param aSurfaceId The surface identifier originally returned when the surface
       
   251 was created.
       
   252 @param aInfo TInfoBuf to receive the information about the surface.
       
   253 @pre The surface is open in the calling process.
       
   254 @return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
       
   255 KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
       
   256 error code.
       
   257 */
       
   258 EXPORT_C TInt RSurfaceManager::SurfaceInfo(const TSurfaceId& aSurfaceId, TInfoBuf& aInfo)
       
   259 	{
       
   260 	return Driver().SurfaceInfo(aSurfaceId,aInfo);
       
   261 	}
       
   262 
       
   263 /**
       
   264 This function ensures the memory is updated consistently before and/or after
       
   265 triggering non CPU hardware access. Also ensures the CPU cache and the physical
       
   266 memory are in a consistent state before and after non CPU hardware or DMA access
       
   267 to the physical memory.
       
   268 @param aSurfaceId The surface identifier originally returned when the surface
       
   269 was created.
       
   270 @param aBuffer The buffer number indexed from 0 within the surface whose memory
       
   271 region is to be flushed. 
       
   272 @param aOperation Specifies the sync operation as before non CPU hardware reads
       
   273 or before non CPU hardware writes or after non CPU hardware writes between
       
   274 physical memory of the surface and the cache contents.
       
   275 @pre The surface is open in the calling process.
       
   276 @post The surface buffer memory will be synchronized properly with cache contents.
       
   277 @return KErrNone if successful, KErrArgument if the surface ID is invalid or
       
   278 buffer number is invalid, KErrAccessDenied if the surface is not open in this
       
   279 process, otherwise a system wide error code.
       
   280 */ 
       
   281 EXPORT_C TInt RSurfaceManager::SynchronizeCache(const TSurfaceId& aSurfaceId, TInt aBuffer, TSyncOperation aOperation)
       
   282 	{
       
   283 	return Driver().SynchronizeCache(aSurfaceId,aBuffer,aOperation);
       
   284 	}
       
   285 
       
   286 /**
       
   287 Get the surface hint value for the given surface ID and hint pair key.
       
   288 @param aSurfaceId  The surface identifier originally returned when the surface
       
   289 was created.
       
   290 @param aHint The hint value for the requested hint pair key.
       
   291 @pre The surface is open in the calling process.
       
   292 @pre Hint key should be a key for a hint set for this surface.
       
   293 @post The hint value will be updated in the hint pair.
       
   294 @return KErrNone if successful, KErrArgument if the surface ID is invalid or
       
   295 invalid hint pair key used, KErrAccessDenied if the surface is not open in the
       
   296 current process, otherwise a system wide error code.
       
   297 */ 
       
   298 EXPORT_C TInt RSurfaceManager::GetSurfaceHint(const TSurfaceId& aSurfaceId, THintPair& aHint)
       
   299 	{
       
   300 	return Driver().GetSurfaceHint(aSurfaceId,aHint);
       
   301 	}
       
   302 
       
   303 /**
       
   304 Set the surface hint value for the surface ID.
       
   305 @param aSurfaceId The surface identifier originally returned when the surface
       
   306 was created.
       
   307 @param aHint The value of the hint pair to set.
       
   308 @pre The surface is open in the calling process.
       
   309 @pre The hint key should be a key for a hint set for this surface.
       
   310 @pre Only mutable hints can be updated.
       
   311 @post The hint value will be updated in the surface hint pair.
       
   312 @return KErrNone if successful, KErrArgument if the surface ID is invalid or if invalid
       
   313 hint key used, KErrAccessDenied if the hint pair is immutable or the surface is not open
       
   314 in the current process, otherwise a system wide error code.
       
   315 */
       
   316 EXPORT_C TInt RSurfaceManager::SetSurfaceHint(const TSurfaceId& aSurfaceId, const THintPair& aHint)
       
   317 	{
       
   318 	return Driver().SetSurfaceHint(aSurfaceId,aHint);
       
   319 	}
       
   320 
       
   321 /**
       
   322 Adds a new surface hint to the surface.
       
   323 
       
   324 This function will fail if the surface already has its maximum number of hints 
       
   325 or if the hint key is a duplicate or invalid.
       
   326 @param aSurfaceId The surface identifier originally returned when the surface
       
   327 was created.
       
   328 @param aHint The value of the hint pair to add.
       
   329 @pre The surface is open in the calling process.
       
   330 @pre At least one free space to add a hint pair.
       
   331 @pre The new hint key should be non zero and unique for this surface.
       
   332 @post New hint pair will be added in the surface.
       
   333 @return Returns KErrNone if successful, KErrArgument if the surface ID is invalid or the
       
   334 hint pair has invalid key UID, KErrAccessDenied if the surface is not open in the current
       
   335 process, KErrAlreadyExists if duplicate hint key used, KErrOverflow if no space to add new
       
   336 pair, otherwise a system wide error code.
       
   337 */
       
   338 EXPORT_C TInt RSurfaceManager::AddSurfaceHint(const TSurfaceId& aSurfaceId, const THintPair& aHint)
       
   339 	{
       
   340 	return Driver().AddSurfaceHint(aSurfaceId,aHint);
       
   341 	}
       
   342 
       
   343 /**
       
   344 Get the offset of the specified buffer from the base address of the underlying
       
   345 chunk.
       
   346 
       
   347 To obtain the address of the buffer, the offset returned must be added onto the
       
   348 base address of the RChunk returned in a call to MapSurface(). Note that
       
   349 buffer offsets are immutable during the lifetime of the surface.
       
   350 @param aSurfaceId The surface identifier originally returned when the surface
       
   351 was created.
       
   352 @param aBuffer The buffer for which the offset is requested. Indexed from 0.
       
   353 @param aOffset Output parameter set to the offset within the chunk.
       
   354 @pre The surface is open in the calling process.
       
   355 @return KErrNone if successful, KErrArgument if aSurfaceId or aBuffer are invalid,
       
   356 KErrAccessDenied if the surface is not open in the current process, KErrNotSupported if
       
   357 the surface is not mappable, otherwise a system wide error code.
       
   358 */
       
   359 EXPORT_C TInt RSurfaceManager::GetBufferOffset(const TSurfaceId& aSurfaceId, TInt aBuffer, TInt& aOffset)
       
   360 	{
       
   361 	return Driver().GetBufferOffset(aSurfaceId, aBuffer, aOffset);
       
   362 	}
       
   363 
       
   364 /**
       
   365 Get a reference of the implementation of the surface manager.
       
   366 @return reference of the implementation of the surface manager
       
   367 */
       
   368 inline RSurfaceManagerDriver& RSurfaceManager::Driver()
       
   369 	{
       
   370 	return reinterpret_cast<RSurfaceManagerDriver&>(*iDriverBuf);
       
   371 	}
       
   372