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