diff -r 4816d766a08a -r f345bda72bc4 Symbian3/PDK/Source/GUID-8DF46A11-874A-52E5-9298-C083EA633BA0.dita --- a/Symbian3/PDK/Source/GUID-8DF46A11-874A-52E5-9298-C083EA633BA0.dita Tue Mar 30 11:42:04 2010 +0100 +++ b/Symbian3/PDK/Source/GUID-8DF46A11-874A-52E5-9298-C083EA633BA0.dita Tue Mar 30 11:56:28 2010 +0100 @@ -1,293 +1,293 @@ - - - - - -Implementing -Dynamic DSA AllocationThis topic describes how device creators can allocate the Direct -Screen Access (DSA) buffer dynamically. This feature is new in Symbian^3 (S^3). -

Target audience: Device creators.

-
Overview

Before the introduction of ScreenPlay, -applications (such as video and EGL games) that required high frame rates -used Direct Screen Access (DSA) to bypass the Window Server and draw directly -to the frame buffer (video memory). However, some interaction with the Window -Server was necessary in order to prevent the application from drawing over -other applications' data. The frame buffer was allocated at device startup -and was never freed.

In ScreenPlay, applications that require a high -frame rate can render directly to composition -surfaces. In ScreenPlay the Window Server's content is also rendered -to a composition surface, which is known as the UI surface. This means -that the Window Server and its render stages do not render directly to the -frame buffer. However, DSA is still supported in order to provide backwards -compatibility.

The DSA buffer is now just another buffer (known as -the DSA buffer), which the Window Server process makes use of only -when a client uses DSA on a visible window. This means that it is no longer -necessary to allocate the DSA buffer at startup and not free it. In fact to -do so in ScreenPlay is wasteful of resources.

For this reason, it -is now possible to allocate the DSA buffer as a shared -chunk and free it when it is not in use. This requires changes in the -implementation of the LCD Driver (also known as the LCD -Extension). For example, in order to free the DSA buffer when it is -no longer in use, the LCD Driver must keep track of the processes that use -the buffer and when they finish with it. These changes can be implemented -regardless whether ScreenPlay is in use.

Note: Semi-transparent -UI content over content provided by Direct Screen Access (DSA) has never been -supported and ScreenPlay does not change this.

-
DSA client-side API changes

To use DSA, the client -creates an instance of CDirectScreenAccess. This allows -the client to draw directly to the DSA buffer and to determine the visible -area of its window and be notified when the visible area changes. DSA is typically -performed by using the CFbsScreenDevice returned by CDirectScreenAccess::ScreenDevice().

However, -applications can call the HAL user-side API (described below) to allocate -the DSA buffer (if not already allocated) and obtain the DSA buffer's address -directly. Clients that do this can now use DSA simply in order to be notified -when the visible area changes and not for accessing the DSA buffer itself. -This is called region-tracking DSA. (CFbsScreenDevice also -obtains the DSA address through the use of the HAL user-side API.)

To -use region-tracking DSA, call the following overload of the CDirectScreenAccess::NewL() function -and pass ETrue as the final argument:

CDirectScreenAccess::NewL(RWsSession&,CWsScreenDevice&,RWindowBase&,MDirectScreenAccess&,TBool)

This does not allocate a screen device and graphics context. It -therefore does not cause the DSA buffer to be allocated.

Here is an -example that shows how to create a CDirectScreenAccess object -to track visible regions only:

CDirectScreenAccess * cDsa = NULL; - -// Specify additional parameter to NewL to indicate region tracking only. -cDsa = CDirectScreenAccess::NewL(TheClient->iWs,*TheClient->iScreen,*win, - *this, ETrue); - -// In this mode, the client cannot get a screen device or graphics -// context from the DSA object. -CFbsScreenDevice sd = cDsa->ScreenDevice(); -CFbsBitGc gc = cDsa->Gc(); - -ASSERT(sd == NULL) -ASSERT(gc == NULL) -
-
User-side HAL API changes

The user-side HAL API -is a set of static functions that get and set the hardware attributes of the -device. For general information about the interface to HAL, see User-Side -Hardware Abstraction Technology.

The HAL::Get() function -is used to obtain information about the DSA buffer memory.

static IMPORT_C TInt Get(TAttribute aAttribute, TInt &aValue); -static IMPORT_C TInt Get(TInt aDeviceNumber, TAttribute aAttribute, - TInt &aValue);

In versions earlier than S^3, in order -to obtain the memory address of the DSA buffer, a client calls HAL::Get() with -an attribute of HALData::EDisplayMemoryAddress. If successful, -the call returns KErrNone and sets the aValue parameter -to the virtual address of the DSA buffer in the caller’s process. If the DSA -buffer cannot be allocated, the call returns KErrNoMemory and -sets the aValue parameter to NULL.

From S^3 onwards, -a client can obtain a handle to the DSA buffer by calling HAL::Get() with -an attribute of HALData::EDisplayMemoryHandle. If successful, -the call returns KErrNone and sets the aValue parameter -to the value of an RChunk handle in the caller’s process. -If the DSA buffer cannot be allocated, the call returns KErrNoMemory and -sets the aValue parameter to 0.

The advantage of -using a handle is twofold:

    -
  • The memory chunk exists -for as long as the handle is open.

  • -
  • The handle is automatically -closed by the kernel if the process holding it exits prematurely.

  • -

When possible, legacy clients should be changed to take advantage -of the new HALData::EDisplayMemoryHandle attribute. This -means that you need to modify HAL::Get(EDisplayMemoryAddress) calls -to use HALData::EDisplayMemoryHandle to obtain a handle -to the DSA's shared chunk. You also need to add code to close this handle -when the memory is no longer required.

For example, replace the following -code:

err = HAL::Get(screenId, HALData::EDisplayMemoryAddress, dsaAddr);

With something like this:

err = HAL::Get(screenId, HALData::EDisplayMemoryHandle, val); -if (err == KErrNone) - { - RChunk chunk; - err = chunk.SetReturnedHandle(val); - if (err == KErrNone) - { - iDSAChunk = chunk; - err = iDSAChunk.Duplicate(RThread(), EOwnerProcess); - chunk.Close(); - if (err == KErrNone) - { - dsaAddr = (TInt) iDSAChunk.Base(); - } -else if (err == KErrNotSupported) - { - err = HAL::Get(screenId, HALData::EDisplayMemoryAddress, dsaAddr); - } -
-
Kernel-side HAL changes

HAL requests are handled -on the kernel side by HAL handlers. A single HAL handler deals with all the -HAL attributes defined in a particular HAL group. Each HAL group has a one-to-one -relationship with a HAL handler. EHalGroupDisplay identifies -the group associated with the HAL display attributes.

In S^3 the TDisplayHalFunction enum -has two new attributes—EDisplayHalGetDisplayMemoryAddress and EDisplayHalGetDisplayMemoryHandle. -These allow the generic user-side HAL code to obtain the DSA buffer's address -and handle independently of all of the other display attributes.

-
Handling HAL::Get(EDisplayMemoryAddress)

In versions -earlier than S^3, the DSA buffer address is returned from the HAL handler -as part of a TVideoInfoV01 class in response to an EDisplayHalCurrentModeInfo request. -The user-side HAL code then extracts the address from the TVideoInfoV01 structure -and returns it.

Configuration file setting

The HAL -configuration file config.hcf therefore includes the -following:

EDisplayMemoryAddress=ProcessDisplayCurrentModeInfo

Modifications -to generic HAL code

In S^3 the switch case for EDisplayMemoryAddress in ProcessDisplayCurrentModeInfo() is as follows:

case HAL::EDisplayMemoryAddress: - -// If the address is zero, the actual address -// is returned by EDisplayHalGetDisplayMemoryAddress -if (info.iVideoAddress == 0) - { - r = UserSvr::HalFunction(EHalGroupDisplay, - EDisplayHalGetDisplayMemoryAddress, - aInOut, (TAny*)EFalse, aDeviceNumber); - } -else - { - *(TInt*)aInOut = info.iVideoAddress; - } -break; -

Dealing with HAL::GetAll()

HAL::GetAll() sets -the input parameters passed to the HAL handler to -1. You can use this in -the LCD Driver to determine whether the call for the DSA buffer's address -is from HAL::GetAll() and if it is, to not allocate the memory. -For example:

case EDisplayHalGetDisplayMemoryAddress: - { - TInt val = 0; - TInt passedIn = 0; - kumemget32(&passedIn, a1, sizeof(TInt)); - - // Not from a GetAll(). - if (passedIn != -1) - { - r = DisplayMemoryAddress(aDeviceNumber, val); - } - else - { - r = KErrNone; - } - - // Write the value returned back to the user side. - kumemput32(a1, &val, sizeof(TInt)); - } - break; -

Keeping track of processes that call HAL::Get(EDisplayMemoryAddress)

Legacy -DSA clients request the DSA buffer address rather than the handle and assume -that the address will remain valid for the lifetime of the process. The LCD -Driver needs to keep track of processes that call HAL::Get(EDisplayMemoryAddress) and -free the DSA buffer when the last of these processes has exited.

The -LCD Driver must therefore maintain a list of the relevant processes and the -address of the DSA buffer for each one. When the number of processes using -a buffer address returns to zero, the buffer is freed.

To track the -usage, the LCD Driver creates a new shared chunk for each process that calls HAL::Get(EDisplayMemoryAddress). -The LCD Driver then calls Kern::MakeHandleAndOpen() to -create a user handle to the shared chunk for the calling process. The LCD -Driver closes the kernel-side handle to the chunk.

There is then a -handle to the shared chunk in the user process, which means that the shared -chunk stays open for as long as the process exists. When the user process -exits, the kernel closes any open handles that the process owns. This causes -the deletion of the shared chunk and its Deferred Function Call (DFC) to run. -The DFC removes the process from the list and decrements the reference count -of users of the DSA memory.

Here is the sequence when a process calls HAL::Get(EDisplayMemoryAddress) for -the first time:

    -
  1. Legacy process X implicitly -calls HAL::Get(EDisplayMemoryAddress) for the first time -by creating a DSA session that creates a CFbsScreenDevice.

  2. -
  3. The driver looks for -process X in the list of processes and addresses and does not find -it.

  4. -
  5. The driver creates a -shared chunk for process X with a destruction DFC.

  6. -
  7. The driver creates a -user-side handle to the shared chunk.

  8. -
  9. The driver closes its DChunk handle -to the shared chunk.

  10. -
  11. The driver calls TUint8* -Kern::ChunkUserBase(DChunk* aChunk, DThread* aThread) to -get the address of the shared chunk in the user process .

  12. -
  13. The driver stores the -calling process's ID and the address of the shared chunk in a table.

  14. -
  15. The driver returns the -address of the shared chunk to the calling process.

  16. -

Here is the sequence when the same process calls HAL::Get(EDisplayMemoryAddress) again:

    -
  1. Legacy process X implicitly -calls HAL::Get(EDisplayMemoryAddress) again by creating a -DSA session that creates a CFbsScreenDevice.

  2. -
  3. The driver looks for -the process in the list of processes and addresses.

  4. -
  5. The driver returns the -address previously given to the process.

  6. -

Here is the sequence when the same process exits:

    -
  1. The kernel cleans up -any open handles for the exiting process.

  2. -
  3. The shared chunk destruction -DFC executes and removes the process from the list and decrements the DSA -usage count.

  4. -
  5. The DFC checks the DSA -usage count and if it is zero, the DFC frees the DSA memory.

  6. -
-
Handling HAL::Get(EDisplayMemoryHandle)

In S^3 -there is a new GetDisplayMemoryHandle() function in the user-side -HAL implementation. This function is the handler for the new EDisplayMemoryHandle attribute.

Configuration -file setting

The following line therefore needs to be added to -the config.hcf file:

EDisplayMemoryHandle=GetDisplayMemoryHandle

Dealing with HAL::GetAll()

HAL::GetAll() sets -the input parameters passed to the HAL handler to -1. You can use this in -the LCD Driver to determine whether the call for the DSA buffer's address -handle is from HAL::GetAll() and to take appropriate action. -For example:

case EDisplayHalGetDisplayMemoryHandle: - { - TInt val = 0; - TInt passedIn = 0; - kumemget32(&passedIn, a1, sizeof(TInt)); - - // Not from a GetAll(). - if (passedIn != -1) - { - r = CreateNewChunkToRepresentDSABuffer(aDeviceNumber, val); - } - else - { - r = KErrNone; - } - - - kumemput32(a1, &val, sizeof(TInt)); - } - break; -

Keeping track of processes that call HAL::Get(EDisplayMemoryHandle)

New -DSA clients request the DSA buffer handle rather than the address. After a -process obtains the handle, the DSA buffer is in use for this process until -the handle is closed or the process exits (which implicitly closes the handle).

To -track the usage, the LCD Driver creates a new shared chunk every time a process -calls HAL::Get(EDisplayMemoryHandle). The LCD Driver then -calls Kern::MakeHandleAndOpen() to create a user handle -to the shared chunk for the calling process. The LCD Driver closes the kernel-side -handle to the shared chunk and returns the user-side handle to the calling -process.

When the user process closes the handle, the shared chunk -is deleted and its deletion DFC runs. The DFC decrements the reference count -of users of the DSA memory.

Here is the sequence when a process calls HAL::Get(EDisplayMemoryHandle) for -the first time:

    -
  1. The driver creates a -new shared chunk for this process with a destruction DFC.

  2. -
  3. The driver creates a -user-side handle to the shared chunk.

  4. -
  5. The driver closes its DChunk handle -to the shared chunk.

  6. -
  7. The driver returns the -user-side handle to the calling process.

  8. -

Here is the sequence when a process closes the DSA buffer:

    -
  1. The shared chunk destruction -DFC executes and decrements the DSA usage count.

  2. -
  3. The DFC checks the DSA -usage count and if it is zero, the DFC frees the DSA memory.

  4. -
-
-LCD Extension - -Shared Chunks - -User-Side -Hardware Abstraction Technology -Display Driver -Component + + + + + +Implementing +Dynamic DSA AllocationThis topic describes how device creators can allocate the Direct +Screen Access (DSA) buffer dynamically. This feature is new in Symbian^3 (S^3). +

Target audience: Device creators.

+
Overview

Before the introduction of ScreenPlay, +applications (such as video and EGL games) that required high frame rates +used Direct Screen Access (DSA) to bypass the Window Server and draw directly +to the frame buffer (video memory). However, some interaction with the Window +Server was necessary in order to prevent the application from drawing over +other applications' data. The frame buffer was allocated at device startup +and was never freed.

In ScreenPlay, applications that require a high +frame rate can render directly to composition +surfaces. In ScreenPlay the Window Server's content is also rendered +to a composition surface, which is known as the UI surface. This means +that the Window Server and its render stages do not render directly to the +frame buffer. However, DSA is still supported in order to provide backwards +compatibility.

The DSA buffer is now just another buffer (known as +the DSA buffer), which the Window Server process makes use of only +when a client uses DSA on a visible window. This means that it is no longer +necessary to allocate the DSA buffer at startup and not free it. In fact to +do so in ScreenPlay is wasteful of resources.

For this reason, it +is now possible to allocate the DSA buffer as a shared +chunk and free it when it is not in use. This requires changes in the +implementation of the LCD Driver (also known as the LCD +Extension). For example, in order to free the DSA buffer when it is +no longer in use, the LCD Driver must keep track of the processes that use +the buffer and when they finish with it. These changes can be implemented +regardless whether ScreenPlay is in use.

Note: Semi-transparent +UI content over content provided by Direct Screen Access (DSA) has never been +supported and ScreenPlay does not change this.

+
DSA client-side API changes

To use DSA, the client +creates an instance of CDirectScreenAccess. This allows +the client to draw directly to the DSA buffer and to determine the visible +area of its window and be notified when the visible area changes. DSA is typically +performed by using the CFbsScreenDevice returned by CDirectScreenAccess::ScreenDevice().

However, +applications can call the HAL user-side API (described below) to allocate +the DSA buffer (if not already allocated) and obtain the DSA buffer's address +directly. Clients that do this can now use DSA simply in order to be notified +when the visible area changes and not for accessing the DSA buffer itself. +This is called region-tracking DSA. (CFbsScreenDevice also +obtains the DSA address through the use of the HAL user-side API.)

To +use region-tracking DSA, call the following overload of the CDirectScreenAccess::NewL() function +and pass ETrue as the final argument:

CDirectScreenAccess::NewL(RWsSession&,CWsScreenDevice&,RWindowBase&,MDirectScreenAccess&,TBool)

This does not allocate a screen device and graphics context. It +therefore does not cause the DSA buffer to be allocated.

Here is an +example that shows how to create a CDirectScreenAccess object +to track visible regions only:

CDirectScreenAccess * cDsa = NULL; + +// Specify additional parameter to NewL to indicate region tracking only. +cDsa = CDirectScreenAccess::NewL(TheClient->iWs,*TheClient->iScreen,*win, + *this, ETrue); + +// In this mode, the client cannot get a screen device or graphics +// context from the DSA object. +CFbsScreenDevice sd = cDsa->ScreenDevice(); +CFbsBitGc gc = cDsa->Gc(); + +ASSERT(sd == NULL) +ASSERT(gc == NULL) +
+
User-side HAL API changes

The user-side HAL API +is a set of static functions that get and set the hardware attributes of the +device. For general information about the interface to HAL, see User-Side +Hardware Abstraction Technology.

The HAL::Get() function +is used to obtain information about the DSA buffer memory.

static IMPORT_C TInt Get(TAttribute aAttribute, TInt &aValue); +static IMPORT_C TInt Get(TInt aDeviceNumber, TAttribute aAttribute, + TInt &aValue);

In versions earlier than S^3, in order +to obtain the memory address of the DSA buffer, a client calls HAL::Get() with +an attribute of HALData::EDisplayMemoryAddress. If successful, +the call returns KErrNone and sets the aValue parameter +to the virtual address of the DSA buffer in the caller’s process. If the DSA +buffer cannot be allocated, the call returns KErrNoMemory and +sets the aValue parameter to NULL.

From S^3 onwards, +a client can obtain a handle to the DSA buffer by calling HAL::Get() with +an attribute of HALData::EDisplayMemoryHandle. If successful, +the call returns KErrNone and sets the aValue parameter +to the value of an RChunk handle in the caller’s process. +If the DSA buffer cannot be allocated, the call returns KErrNoMemory and +sets the aValue parameter to 0.

The advantage of +using a handle is twofold:

    +
  • The memory chunk exists +for as long as the handle is open.

  • +
  • The handle is automatically +closed by the kernel if the process holding it exits prematurely.

  • +

When possible, legacy clients should be changed to take advantage +of the new HALData::EDisplayMemoryHandle attribute. This +means that you need to modify HAL::Get(EDisplayMemoryAddress) calls +to use HALData::EDisplayMemoryHandle to obtain a handle +to the DSA's shared chunk. You also need to add code to close this handle +when the memory is no longer required.

For example, replace the following +code:

err = HAL::Get(screenId, HALData::EDisplayMemoryAddress, dsaAddr);

With something like this:

err = HAL::Get(screenId, HALData::EDisplayMemoryHandle, val); +if (err == KErrNone) + { + RChunk chunk; + err = chunk.SetReturnedHandle(val); + if (err == KErrNone) + { + iDSAChunk = chunk; + err = iDSAChunk.Duplicate(RThread(), EOwnerProcess); + chunk.Close(); + if (err == KErrNone) + { + dsaAddr = (TInt) iDSAChunk.Base(); + } +else if (err == KErrNotSupported) + { + err = HAL::Get(screenId, HALData::EDisplayMemoryAddress, dsaAddr); + } +
+
Kernel-side HAL changes

HAL requests are handled +on the kernel side by HAL handlers. A single HAL handler deals with all the +HAL attributes defined in a particular HAL group. Each HAL group has a one-to-one +relationship with a HAL handler. EHalGroupDisplay identifies +the group associated with the HAL display attributes.

In S^3 the TDisplayHalFunction enum +has two new attributes—EDisplayHalGetDisplayMemoryAddress and EDisplayHalGetDisplayMemoryHandle. +These allow the generic user-side HAL code to obtain the DSA buffer's address +and handle independently of all of the other display attributes.

+
Handling HAL::Get(EDisplayMemoryAddress)

In versions +earlier than S^3, the DSA buffer address is returned from the HAL handler +as part of a TVideoInfoV01 class in response to an EDisplayHalCurrentModeInfo request. +The user-side HAL code then extracts the address from the TVideoInfoV01 structure +and returns it.

Configuration file setting

The HAL +configuration file config.hcf therefore includes the +following:

EDisplayMemoryAddress=ProcessDisplayCurrentModeInfo

Modifications +to generic HAL code

In S^3 the switch case for EDisplayMemoryAddress in ProcessDisplayCurrentModeInfo() is as follows:

case HAL::EDisplayMemoryAddress: + +// If the address is zero, the actual address +// is returned by EDisplayHalGetDisplayMemoryAddress +if (info.iVideoAddress == 0) + { + r = UserSvr::HalFunction(EHalGroupDisplay, + EDisplayHalGetDisplayMemoryAddress, + aInOut, (TAny*)EFalse, aDeviceNumber); + } +else + { + *(TInt*)aInOut = info.iVideoAddress; + } +break; +

Dealing with HAL::GetAll()

HAL::GetAll() sets +the input parameters passed to the HAL handler to -1. You can use this in +the LCD Driver to determine whether the call for the DSA buffer's address +is from HAL::GetAll() and if it is, to not allocate the memory. +For example:

case EDisplayHalGetDisplayMemoryAddress: + { + TInt val = 0; + TInt passedIn = 0; + kumemget32(&passedIn, a1, sizeof(TInt)); + + // Not from a GetAll(). + if (passedIn != -1) + { + r = DisplayMemoryAddress(aDeviceNumber, val); + } + else + { + r = KErrNone; + } + + // Write the value returned back to the user side. + kumemput32(a1, &val, sizeof(TInt)); + } + break; +

Keeping track of processes that call HAL::Get(EDisplayMemoryAddress)

Legacy +DSA clients request the DSA buffer address rather than the handle and assume +that the address will remain valid for the lifetime of the process. The LCD +Driver needs to keep track of processes that call HAL::Get(EDisplayMemoryAddress) and +free the DSA buffer when the last of these processes has exited.

The +LCD Driver must therefore maintain a list of the relevant processes and the +address of the DSA buffer for each one. When the number of processes using +a buffer address returns to zero, the buffer is freed.

To track the +usage, the LCD Driver creates a new shared chunk for each process that calls HAL::Get(EDisplayMemoryAddress). +The LCD Driver then calls Kern::MakeHandleAndOpen() to +create a user handle to the shared chunk for the calling process. The LCD +Driver closes the kernel-side handle to the chunk.

There is then a +handle to the shared chunk in the user process, which means that the shared +chunk stays open for as long as the process exists. When the user process +exits, the kernel closes any open handles that the process owns. This causes +the deletion of the shared chunk and its Deferred Function Call (DFC) to run. +The DFC removes the process from the list and decrements the reference count +of users of the DSA memory.

Here is the sequence when a process calls HAL::Get(EDisplayMemoryAddress) for +the first time:

    +
  1. Legacy process X implicitly +calls HAL::Get(EDisplayMemoryAddress) for the first time +by creating a DSA session that creates a CFbsScreenDevice.

  2. +
  3. The driver looks for +process X in the list of processes and addresses and does not find +it.

  4. +
  5. The driver creates a +shared chunk for process X with a destruction DFC.

  6. +
  7. The driver creates a +user-side handle to the shared chunk.

  8. +
  9. The driver closes its DChunk handle +to the shared chunk.

  10. +
  11. The driver calls TUint8* +Kern::ChunkUserBase(DChunk* aChunk, DThread* aThread) to +get the address of the shared chunk in the user process .

  12. +
  13. The driver stores the +calling process's ID and the address of the shared chunk in a table.

  14. +
  15. The driver returns the +address of the shared chunk to the calling process.

  16. +

Here is the sequence when the same process calls HAL::Get(EDisplayMemoryAddress) again:

    +
  1. Legacy process X implicitly +calls HAL::Get(EDisplayMemoryAddress) again by creating a +DSA session that creates a CFbsScreenDevice.

  2. +
  3. The driver looks for +the process in the list of processes and addresses.

  4. +
  5. The driver returns the +address previously given to the process.

  6. +

Here is the sequence when the same process exits:

    +
  1. The kernel cleans up +any open handles for the exiting process.

  2. +
  3. The shared chunk destruction +DFC executes and removes the process from the list and decrements the DSA +usage count.

  4. +
  5. The DFC checks the DSA +usage count and if it is zero, the DFC frees the DSA memory.

  6. +
+
Handling HAL::Get(EDisplayMemoryHandle)

In S^3 +there is a new GetDisplayMemoryHandle() function in the user-side +HAL implementation. This function is the handler for the new EDisplayMemoryHandle attribute.

Configuration +file setting

The following line therefore needs to be added to +the config.hcf file:

EDisplayMemoryHandle=GetDisplayMemoryHandle

Dealing with HAL::GetAll()

HAL::GetAll() sets +the input parameters passed to the HAL handler to -1. You can use this in +the LCD Driver to determine whether the call for the DSA buffer's address +handle is from HAL::GetAll() and to take appropriate action. +For example:

case EDisplayHalGetDisplayMemoryHandle: + { + TInt val = 0; + TInt passedIn = 0; + kumemget32(&passedIn, a1, sizeof(TInt)); + + // Not from a GetAll(). + if (passedIn != -1) + { + r = CreateNewChunkToRepresentDSABuffer(aDeviceNumber, val); + } + else + { + r = KErrNone; + } + + + kumemput32(a1, &val, sizeof(TInt)); + } + break; +

Keeping track of processes that call HAL::Get(EDisplayMemoryHandle)

New +DSA clients request the DSA buffer handle rather than the address. After a +process obtains the handle, the DSA buffer is in use for this process until +the handle is closed or the process exits (which implicitly closes the handle).

To +track the usage, the LCD Driver creates a new shared chunk every time a process +calls HAL::Get(EDisplayMemoryHandle). The LCD Driver then +calls Kern::MakeHandleAndOpen() to create a user handle +to the shared chunk for the calling process. The LCD Driver closes the kernel-side +handle to the shared chunk and returns the user-side handle to the calling +process.

When the user process closes the handle, the shared chunk +is deleted and its deletion DFC runs. The DFC decrements the reference count +of users of the DSA memory.

Here is the sequence when a process calls HAL::Get(EDisplayMemoryHandle) for +the first time:

    +
  1. The driver creates a +new shared chunk for this process with a destruction DFC.

  2. +
  3. The driver creates a +user-side handle to the shared chunk.

  4. +
  5. The driver closes its DChunk handle +to the shared chunk.

  6. +
  7. The driver returns the +user-side handle to the calling process.

  8. +

Here is the sequence when a process closes the DSA buffer:

    +
  1. The shared chunk destruction +DFC executes and decrements the DSA usage count.

  2. +
  3. The DFC checks the DSA +usage count and if it is zero, the DFC frees the DSA memory.

  4. +
+
+LCD Extension + +Shared Chunks + +User-Side +Hardware Abstraction Technology +Display Driver +Component
\ No newline at end of file