Symbian3/PDK/Source/GUID-8DF46A11-874A-52E5-9298-C083EA633BA0.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-8DF46A11-874A-52E5-9298-C083EA633BA0" xml:lang="en"><title>Implementing
       
    13 Dynamic DSA Allocation</title><shortdesc>This topic describes how device creators can allocate the Direct
       
    14 Screen Access (DSA) buffer dynamically. This feature is new in Symbian^3 (S^3). </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <p> <b>Target audience</b>: Device creators. </p>
       
    16 <section><title>Overview</title> <p>Before the introduction of ScreenPlay,
       
    17 applications (such as video and EGL games) that required high frame rates
       
    18 used Direct Screen Access (DSA) to bypass the Window Server and draw directly
       
    19 to the frame buffer (video memory). However, some interaction with the Window
       
    20 Server was necessary in order to prevent the application from drawing over
       
    21 other applications' data. The frame buffer was allocated at device startup
       
    22 and was never freed. </p> <p>In ScreenPlay, applications that require a high
       
    23 frame rate can render directly to <xref href="GUID-ADA8CECB-0E70-5B9C-8F36-0714AAF0CD13.dita">composition
       
    24 surfaces</xref>. In ScreenPlay the Window Server's content is also rendered
       
    25 to a composition surface, which is known as the <b>UI surface</b>. This means
       
    26 that the Window Server and its render stages do not render directly to the
       
    27 frame buffer. However, DSA is still supported in order to provide backwards
       
    28 compatibility. </p> <p>The DSA buffer is now just another buffer (known as
       
    29 the <b>DSA buffer</b>), which the Window Server process makes use of only
       
    30 when a client uses DSA on a visible window. This means that it is no longer
       
    31 necessary to allocate the DSA buffer at startup and not free it. In fact to
       
    32 do so in ScreenPlay is wasteful of resources. </p> <p>For this reason, it
       
    33 is now possible to allocate the DSA buffer as a <xref href="GUID-51514A4B-0220-557B-9F7A-FB110CEFEF10.dita">shared
       
    34 chunk</xref> and free it when it is not in use. This requires changes in the
       
    35 implementation of the LCD Driver (also known as the <xref href="GUID-8C22AF20-EE0E-5AD2-BEFD-FED5A7DBB09B.dita">LCD
       
    36 Extension</xref>). For example, in order to free the DSA buffer when it is
       
    37 no longer in use, the LCD Driver must keep track of the processes that use
       
    38 the buffer and when they finish with it. These changes can be implemented
       
    39 regardless whether ScreenPlay is in use. </p> <p> <i>Note</i>: Semi-transparent
       
    40 UI content over content provided by Direct Screen Access (DSA) has never been
       
    41 supported and ScreenPlay does not change this. </p> </section>
       
    42 <section><title>DSA client-side API changes</title> <p>To use DSA, the client
       
    43 creates an instance of <xref href="GUID-24C7AE25-B44A-3B6F-AA05-EA90A8D36129.dita"><apiname>CDirectScreenAccess</apiname></xref>. This allows
       
    44 the client to draw directly to the DSA buffer and to determine the visible
       
    45 area of its window and be notified when the visible area changes. DSA is typically
       
    46 performed by using the <xref href="GUID-B229156F-2344-3F46-8542-AC65882D80DE.dita"><apiname>CFbsScreenDevice</apiname></xref> returned by <xref href="GUID-24C7AE25-B44A-3B6F-AA05-EA90A8D36129.dita#GUID-24C7AE25-B44A-3B6F-AA05-EA90A8D36129/GUID-9528CBFF-7D01-3B62-81B1-7F9B2C799C14"><apiname>CDirectScreenAccess::ScreenDevice()</apiname></xref>. </p> <p>However,
       
    47 applications can call the HAL user-side API (described below) to allocate
       
    48 the DSA buffer (if not already allocated) and obtain the DSA buffer's address
       
    49 directly. Clients that do this can now use DSA simply in order to be notified
       
    50 when the visible area changes and not for accessing the DSA buffer itself.
       
    51 This is called <b>region-tracking DSA</b>. (<xref href="GUID-B229156F-2344-3F46-8542-AC65882D80DE.dita"><apiname>CFbsScreenDevice</apiname></xref> also
       
    52 obtains the DSA address through the use of the HAL user-side API.) </p> <p>To
       
    53 use region-tracking DSA, call the following overload of the <codeph>CDirectScreenAccess::NewL()</codeph> function
       
    54 and pass <codeph>ETrue</codeph> as the final argument: </p> <p> <xref href="GUID-24C7AE25-B44A-3B6F-AA05-EA90A8D36129.dita#GUID-24C7AE25-B44A-3B6F-AA05-EA90A8D36129/GUID-6C26D5CD-0B55-3D30-B365-9C431BDD3721"><apiname>CDirectScreenAccess::NewL(RWsSession&amp;,CWsScreenDevice&amp;,RWindowBase&amp;,MDirectScreenAccess&amp;,TBool)</apiname></xref> </p> <p>This does not allocate a screen device and graphics context. It
       
    55 therefore does not cause the DSA buffer to be allocated. </p> <p>Here is an
       
    56 example that shows how to create a <xref href="GUID-24C7AE25-B44A-3B6F-AA05-EA90A8D36129.dita"><apiname>CDirectScreenAccess</apiname></xref> object
       
    57 to track visible regions only: </p> <codeblock id="GUID-E378E1D5-C700-5AC6-AE3B-6CF9DA993671" xml:space="preserve">CDirectScreenAccess * cDsa = NULL;
       
    58     
       
    59 // Specify additional parameter to NewL to indicate region tracking only.
       
    60 cDsa = CDirectScreenAccess::NewL(TheClient-&gt;iWs,*TheClient-&gt;iScreen,*win,
       
    61            *this, ETrue); 
       
    62    
       
    63 // In this mode, the client cannot get a screen device or graphics 
       
    64 // context from the DSA object.
       
    65 CFbsScreenDevice sd = cDsa-&gt;ScreenDevice();
       
    66 CFbsBitGc gc = cDsa-&gt;Gc();
       
    67     
       
    68 ASSERT(sd == NULL)
       
    69 ASSERT(gc == NULL)
       
    70 </codeblock> </section>
       
    71 <section> <title>User-side HAL API changes</title> <p>The user-side HAL API
       
    72 is a set of static functions that get and set the hardware attributes of the
       
    73 device. For general information about the interface to HAL, see <xref href="GUID-9AE254D4-AA60-579E-8D9D-F2797106A413.dita">User-Side
       
    74 Hardware Abstraction Technology</xref>. </p> <p>The <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-573C49D6-7763-37AE-B2B2-4C8FB1327E21"><apiname>HAL::Get()</apiname></xref> function
       
    75 is used to obtain information about the DSA buffer memory. </p> <codeblock id="GUID-A50C3B6C-364C-58B8-B5FC-6472C5C8FF09" xml:space="preserve">static IMPORT_C TInt Get(TAttribute aAttribute, TInt &amp;aValue); 
       
    76 static IMPORT_C TInt Get(TInt aDeviceNumber, TAttribute aAttribute, 
       
    77      TInt &amp;aValue);</codeblock> <p>In versions earlier than S^3, in order
       
    78 to obtain the memory address of the DSA buffer, a client calls <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-573C49D6-7763-37AE-B2B2-4C8FB1327E21"><apiname>HAL::Get()</apiname></xref> with
       
    79 an attribute of <xref href="GUID-8BE90160-2C60-3582-82C8-4A108C7C0317.dita#GUID-8BE90160-2C60-3582-82C8-4A108C7C0317/GUID-4702237B-185B-33B1-B0B6-DE388DBDE294"><apiname>HALData::EDisplayMemoryAddress</apiname></xref>. If successful,
       
    80 the call returns <codeph>KErrNone</codeph> and sets the <codeph>aValue</codeph> parameter
       
    81 to the virtual address of the DSA buffer in the caller’s process. If the DSA
       
    82 buffer cannot be allocated, the call returns <codeph>KErrNoMemory</codeph> and
       
    83 sets the <codeph>aValue</codeph> parameter to NULL. </p> <p>From S^3 onwards,
       
    84 a client can obtain a handle to the DSA buffer by calling <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-573C49D6-7763-37AE-B2B2-4C8FB1327E21"><apiname>HAL::Get()</apiname></xref> with
       
    85 an attribute of <xref href="GUID-8BE90160-2C60-3582-82C8-4A108C7C0317.dita#GUID-8BE90160-2C60-3582-82C8-4A108C7C0317/GUID-6124E485-D8A6-3399-AA6C-7021D130591D"><apiname>HALData::EDisplayMemoryHandle</apiname></xref>. If successful,
       
    86 the call returns <codeph>KErrNone</codeph> and sets the <codeph>aValue</codeph> parameter
       
    87 to the value of an <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita"><apiname>RChunk</apiname></xref> handle in the caller’s process.
       
    88 If the DSA buffer cannot be allocated, the call returns <codeph>KErrNoMemory</codeph> and
       
    89 sets the <codeph>aValue</codeph> parameter to 0. </p> <p>The advantage of
       
    90 using a handle is twofold: </p> <ul>
       
    91 <li id="GUID-187317E0-0EED-5C8F-AB31-542D6EA0CBF2"><p>The memory chunk exists
       
    92 for as long as the handle is open. </p> </li>
       
    93 <li id="GUID-7984A11D-F7A2-5C1A-AB11-628911BCA292"><p>The handle is automatically
       
    94 closed by the kernel if the process holding it exits prematurely. </p> </li>
       
    95 </ul> <p>When possible, legacy clients should be changed to take advantage
       
    96 of the new <xref href="GUID-8BE90160-2C60-3582-82C8-4A108C7C0317.dita#GUID-8BE90160-2C60-3582-82C8-4A108C7C0317/GUID-6124E485-D8A6-3399-AA6C-7021D130591D"><apiname>HALData::EDisplayMemoryHandle</apiname></xref> attribute. This
       
    97 means that you need to modify <codeph>HAL::Get(EDisplayMemoryAddress)</codeph> calls
       
    98 to use <xref href="GUID-8BE90160-2C60-3582-82C8-4A108C7C0317.dita#GUID-8BE90160-2C60-3582-82C8-4A108C7C0317/GUID-6124E485-D8A6-3399-AA6C-7021D130591D"><apiname>HALData::EDisplayMemoryHandle</apiname></xref> to obtain a handle
       
    99 to the DSA's shared chunk. You also need to add code to close this handle
       
   100 when the memory is no longer required. </p> <p>For example, replace the following
       
   101 code: </p> <codeblock id="GUID-DAB0136B-A5A9-5B15-9C88-1A37B04804AB" xml:space="preserve">err = HAL::Get(screenId, HALData::EDisplayMemoryAddress, dsaAddr);</codeblock> <p>With something like this: </p> <codeblock id="GUID-BD8049BB-378C-5C56-A19B-96227C71A325" xml:space="preserve">err = HAL::Get(screenId, HALData::EDisplayMemoryHandle, val);
       
   102 if (err == KErrNone)
       
   103     {
       
   104     RChunk chunk;
       
   105     err = chunk.SetReturnedHandle(val);
       
   106     if (err == KErrNone)
       
   107         {
       
   108         iDSAChunk = chunk;
       
   109         err = iDSAChunk.Duplicate(RThread(), EOwnerProcess);
       
   110         chunk.Close();
       
   111         if (err == KErrNone)
       
   112             {
       
   113             dsaAddr = (TInt) iDSAChunk.Base();
       
   114             }
       
   115 else if (err == KErrNotSupported)
       
   116     {
       
   117     err = HAL::Get(screenId, HALData::EDisplayMemoryAddress, dsaAddr);
       
   118     }
       
   119 </codeblock> </section>
       
   120 <section><title>Kernel-side HAL changes</title> <p>HAL requests are handled
       
   121 on the kernel side by HAL handlers. A single HAL handler deals with all the
       
   122 HAL attributes defined in a particular HAL group. Each HAL group has a one-to-one
       
   123 relationship with a HAL handler. <codeph>EHalGroupDisplay</codeph> identifies
       
   124 the group associated with the HAL display attributes. </p> <p>In S^3 the <xref href="GUID-BB011D9B-105F-345C-9FC0-39B0BA509394.dita"><apiname>TDisplayHalFunction</apiname></xref> enum
       
   125 has two new attributes—<codeph>EDisplayHalGetDisplayMemoryAddress</codeph> and <codeph>EDisplayHalGetDisplayMemoryHandle</codeph>.
       
   126 These allow the generic user-side HAL code to obtain the DSA buffer's address
       
   127 and handle independently of all of the other display attributes. </p> </section>
       
   128 <section><title>Handling HAL::Get(EDisplayMemoryAddress)</title> <p>In versions
       
   129 earlier than S^3, the DSA buffer address is returned from the HAL handler
       
   130 as part of a <xref href="GUID-C4712A78-6C58-39ED-AF84-11038DB8571D.dita"><apiname>TVideoInfoV01</apiname></xref> class in response to an <codeph>EDisplayHalCurrentModeInfo</codeph> request.
       
   131 The user-side HAL code then extracts the address from the <xref href="GUID-C4712A78-6C58-39ED-AF84-11038DB8571D.dita"><apiname>TVideoInfoV01</apiname></xref> structure
       
   132 and returns it. </p> <p><b>Configuration file setting </b> </p> <p>The HAL
       
   133 configuration file <filepath>config.hcf</filepath> therefore includes the
       
   134 following: </p> <codeblock id="GUID-F496B803-B7B8-57D4-B083-9219D4F849DB" xml:space="preserve">EDisplayMemoryAddress=ProcessDisplayCurrentModeInfo</codeblock> <p><b>Modifications
       
   135 to generic HAL code </b> </p> <p>In S^3 the switch case for <codeph>EDisplayMemoryAddress</codeph> in <codeph>ProcessDisplayCurrentModeInfo()</codeph> is as follows: </p> <codeblock id="GUID-7E2FC07B-670D-57BA-BF3E-A4432BF83E81" xml:space="preserve">case HAL::EDisplayMemoryAddress:
       
   136     
       
   137 // If the address is zero, the actual address
       
   138 // is returned by EDisplayHalGetDisplayMemoryAddress
       
   139 if (info.iVideoAddress == 0)  
       
   140     {
       
   141     r = UserSvr::HalFunction(EHalGroupDisplay, 
       
   142                              EDisplayHalGetDisplayMemoryAddress, 
       
   143                              aInOut, (TAny*)EFalse, aDeviceNumber);
       
   144     }
       
   145 else
       
   146     {
       
   147     *(TInt*)aInOut = info.iVideoAddress;
       
   148     }
       
   149 break;
       
   150 </codeblock> <p><b>Dealing with HAL::GetAll() </b> </p> <p> <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-EF03B832-E9AA-32CF-903F-DFFA63A3E9AB"><apiname>HAL::GetAll()</apiname></xref> sets
       
   151 the input parameters passed to the HAL handler to -1. You can use this in
       
   152 the LCD Driver to determine whether the call for the DSA buffer's address
       
   153 is from <codeph>HAL::GetAll()</codeph> and if it is, to not allocate the memory.
       
   154 For example: </p> <codeblock id="GUID-8734B0EF-A2A2-5929-972F-56F7E0195940" xml:space="preserve">case EDisplayHalGetDisplayMemoryAddress:
       
   155     {
       
   156     TInt val = 0;
       
   157     TInt passedIn = 0;
       
   158     kumemget32(&amp;passedIn, a1, sizeof(TInt));
       
   159     
       
   160     // Not from a GetAll().
       
   161     if (passedIn != -1)    
       
   162         {
       
   163         r = DisplayMemoryAddress(aDeviceNumber, val);
       
   164         }
       
   165     else
       
   166         {
       
   167         r = KErrNone;
       
   168         }
       
   169     
       
   170     // Write the value returned back to the user side.
       
   171     kumemput32(a1, &amp;val, sizeof(TInt));
       
   172     }
       
   173     break;
       
   174 </codeblock> <p><b>Keeping track of processes that call HAL::Get(EDisplayMemoryAddress) </b> </p> <p>Legacy
       
   175 DSA clients request the DSA buffer address rather than the handle and assume
       
   176 that the address will remain valid for the lifetime of the process. The LCD
       
   177 Driver needs to keep track of processes that call <codeph>HAL::Get(EDisplayMemoryAddress)</codeph> and
       
   178 free the DSA buffer when the last of these processes has exited. </p> <p>The
       
   179 LCD Driver must therefore maintain a list of the relevant processes and the
       
   180 address of the DSA buffer for each one. When the number of processes using
       
   181 a buffer address returns to zero, the buffer is freed. </p> <p>To track the
       
   182 usage, the LCD Driver creates a new shared chunk for each process that calls <codeph>HAL::Get(EDisplayMemoryAddress)</codeph>.
       
   183 The LCD Driver then calls <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-BA56B205-60D8-326E-8340-3F78CCEA3DD1"><apiname>Kern::MakeHandleAndOpen()</apiname></xref> to
       
   184 create a user handle to the shared chunk for the calling process. The LCD
       
   185 Driver closes the kernel-side handle to the chunk. </p> <p>There is then a
       
   186 handle to the shared chunk in the user process, which means that the shared
       
   187 chunk stays open for as long as the process exists. When the user process
       
   188 exits, the kernel closes any open handles that the process owns. This causes
       
   189 the deletion of the shared chunk and its Deferred Function Call (DFC) to run.
       
   190 The DFC removes the process from the list and decrements the reference count
       
   191 of users of the DSA memory. </p> <p>Here is the sequence when a process calls <codeph>HAL::Get(EDisplayMemoryAddress)</codeph> for
       
   192 the first time: </p> <ol id="GUID-DA7B9F91-6F52-532C-8E67-8DE89B1EFD42">
       
   193 <li id="GUID-2055954D-2B13-5307-93A6-78936172416C"><p>Legacy process <i>X</i> implicitly
       
   194 calls <codeph>HAL::Get(EDisplayMemoryAddress)</codeph> for the first time
       
   195 by creating a DSA session that creates a <xref href="GUID-B229156F-2344-3F46-8542-AC65882D80DE.dita"><apiname>CFbsScreenDevice</apiname></xref>. </p> </li>
       
   196 <li id="GUID-33A00E2F-B04C-51CE-9993-661DFF5BE00B"><p>The driver looks for
       
   197 process <i>X</i> in the list of processes and addresses and does not find
       
   198 it. </p> </li>
       
   199 <li id="GUID-A8E33530-C089-5C85-9563-A39BBA9259F2"><p>The driver creates a
       
   200 shared chunk for process <i>X</i> with a destruction DFC. </p> </li>
       
   201 <li id="GUID-19CDF330-315D-5806-AB3D-9AB8857A02A4"><p>The driver creates a
       
   202 user-side handle to the shared chunk. </p> </li>
       
   203 <li id="GUID-E13883F3-6418-5920-A16A-8327744E6AF1"><p>The driver closes its <xref href="GUID-85454082-6734-3F1D-983F-734D4C2AB12D.dita"><apiname>DChunk</apiname></xref> handle
       
   204 to the shared chunk. </p> </li>
       
   205 <li id="GUID-8CF22900-AD3C-528D-B88A-74AC59BAAA20"><p>The driver calls <xref href="GUID-AC098719-7AD6-3B48-9BE3-7DCEADA3530B.dita#GUID-AC098719-7AD6-3B48-9BE3-7DCEADA3530B/GUID-0632CC60-AF0C-36F5-8E8F-3D8AD2568E31"><apiname>TUint8*
       
   206 Kern::ChunkUserBase(DChunk*                 aChunk, DThread* aThread)</apiname></xref> to
       
   207 get the address of the shared chunk in the user process . </p> </li>
       
   208 <li id="GUID-0180A075-BF6B-53E4-8B6F-38BE083C58DA"><p>The driver stores the
       
   209 calling process's ID and the address of the shared chunk in a table. </p> </li>
       
   210 <li id="GUID-3663A069-09FA-55DF-9EA7-F1875B379569"><p>The driver returns the
       
   211 address of the shared chunk to the calling process. </p> </li>
       
   212 </ol> <p>Here is the sequence when the same process calls <codeph>HAL::Get(EDisplayMemoryAddress)</codeph> again: </p> <ol id="GUID-E7D5E120-364C-5CA6-BE4E-56563F58A293">
       
   213 <li id="GUID-57947C06-0BA1-5CB0-AB3F-493D71510A95"><p>Legacy process <i>X</i> implicitly
       
   214 calls <codeph>HAL::Get(EDisplayMemoryAddress)</codeph> again by creating a
       
   215 DSA session that creates a <xref href="GUID-B229156F-2344-3F46-8542-AC65882D80DE.dita"><apiname>CFbsScreenDevice</apiname></xref>. </p> </li>
       
   216 <li id="GUID-493E5ABC-5032-5653-A87B-27441F0AF88E"><p>The driver looks for
       
   217 the process in the list of processes and addresses. </p> </li>
       
   218 <li id="GUID-6CF1A43C-966E-59EF-BA68-BB1D5CA5A4F0"><p>The driver returns the
       
   219 address previously given to the process. </p> </li>
       
   220 </ol> <p>Here is the sequence when the same process exits: </p> <ol id="GUID-388DC71E-FD9B-5A56-8B3D-520159FA8939">
       
   221 <li id="GUID-B95DB340-C730-5419-ADB8-0B5B10F46556"><p>The kernel cleans up
       
   222 any open handles for the exiting process. </p> </li>
       
   223 <li id="GUID-E8654886-77E4-5748-A0BE-A0E3CCCC752A"><p>The shared chunk destruction
       
   224 DFC executes and removes the process from the list and decrements the DSA
       
   225 usage count. </p> </li>
       
   226 <li id="GUID-68624448-1DCF-591E-97EF-F0B46F656FC8"><p>The DFC checks the DSA
       
   227 usage count and if it is zero, the DFC frees the DSA memory. </p> </li>
       
   228 </ol> </section>
       
   229 <section><title>Handling HAL::Get(EDisplayMemoryHandle)</title> <p>In S^3
       
   230 there is a new <codeph>GetDisplayMemoryHandle()</codeph> function in the user-side
       
   231 HAL implementation. This function is the handler for the new <codeph>EDisplayMemoryHandle</codeph> attribute. </p> <p><b>Configuration
       
   232 file setting </b> </p> <p>The following line therefore needs to be added to
       
   233 the <filepath>config.hcf</filepath> file: </p> <codeblock id="GUID-90AEC511-D592-5755-A569-7703A09EE40C" xml:space="preserve">EDisplayMemoryHandle=GetDisplayMemoryHandle</codeblock> <p><b>Dealing with HAL::GetAll() </b> </p> <p> <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-EF03B832-E9AA-32CF-903F-DFFA63A3E9AB"><apiname>HAL::GetAll()</apiname></xref> sets
       
   234 the input parameters passed to the HAL handler to -1. You can use this in
       
   235 the LCD Driver to determine whether the call for the DSA buffer's address
       
   236 handle is from <codeph>HAL::GetAll()</codeph> and to take appropriate action.
       
   237 For example: </p> <codeblock id="GUID-22A22111-1B29-59F4-B3F7-83E43077E0FD" xml:space="preserve">case EDisplayHalGetDisplayMemoryHandle:
       
   238     {
       
   239     TInt val = 0;
       
   240     TInt passedIn = 0;
       
   241     kumemget32(&amp;passedIn, a1, sizeof(TInt));
       
   242     
       
   243     // Not from a GetAll().
       
   244     if (passedIn != -1)    
       
   245         {
       
   246         r = CreateNewChunkToRepresentDSABuffer(aDeviceNumber,  val);
       
   247         }
       
   248     else
       
   249         {
       
   250         r = KErrNone;
       
   251         }
       
   252 
       
   253     
       
   254     kumemput32(a1, &amp;val, sizeof(TInt));
       
   255     }
       
   256     break;
       
   257 </codeblock> <p><b>Keeping track of processes that call HAL::Get(EDisplayMemoryHandle) </b> </p> <p>New
       
   258 DSA clients request the DSA buffer handle rather than the address. After a
       
   259 process obtains the handle, the DSA buffer is in use for this process until
       
   260 the handle is closed or the process exits (which implicitly closes the handle). </p> <p>To
       
   261 track the usage, the LCD Driver creates a new shared chunk every time a process
       
   262 calls <codeph>HAL::Get(EDisplayMemoryHandle)</codeph>. The LCD Driver then
       
   263 calls <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-BA56B205-60D8-326E-8340-3F78CCEA3DD1"><apiname>Kern::MakeHandleAndOpen()</apiname></xref> to create a user handle
       
   264 to the shared chunk for the calling process. The LCD Driver closes the kernel-side
       
   265 handle to the shared chunk and returns the user-side handle to the calling
       
   266 process. </p> <p>When the user process closes the handle, the shared chunk
       
   267 is deleted and its deletion DFC runs. The DFC decrements the reference count
       
   268 of users of the DSA memory. </p> <p>Here is the sequence when a process calls <codeph>HAL::Get(EDisplayMemoryHandle)</codeph> for
       
   269 the first time: </p> <ol id="GUID-A92B09E9-5E76-5B6C-B281-64A4F4A65467">
       
   270 <li id="GUID-0CF94725-F9BA-5C92-9429-4206D38040CF"><p>The driver creates a
       
   271 new shared chunk for this process with a destruction DFC. </p> </li>
       
   272 <li id="GUID-8521F99F-A890-5F82-9EB0-C0C1E9ABDE5B"><p>The driver creates a
       
   273 user-side handle to the shared chunk. </p> </li>
       
   274 <li id="GUID-876EECF6-BC1C-5E57-8555-55D3F5AD01E3"><p>The driver closes its <xref href="GUID-85454082-6734-3F1D-983F-734D4C2AB12D.dita"><apiname>DChunk</apiname></xref> handle
       
   275 to the shared chunk. </p> </li>
       
   276 <li id="GUID-F705B1B9-F9F4-56F2-800B-93E4B8FBE75B"><p>The driver returns the
       
   277 user-side handle to the calling process. </p> </li>
       
   278 </ol> <p>Here is the sequence when a process closes the DSA buffer: </p> <ol id="GUID-2310D2DC-76BA-5B87-A964-DCA01051CB3E">
       
   279 <li id="GUID-65CE3E41-D418-59C5-A0FA-A90195A7FE23"><p>The shared chunk destruction
       
   280 DFC executes and decrements the DSA usage count. </p> </li>
       
   281 <li id="GUID-96386F96-FF1E-5BD3-B98A-E0B180463AFB"><p>The DFC checks the DSA
       
   282 usage count and if it is zero, the DFC frees the DSA memory. </p> </li>
       
   283 </ol> </section>
       
   284 </conbody><related-links>
       
   285 <link href="GUID-8C22AF20-EE0E-5AD2-BEFD-FED5A7DBB09B.dita"><linktext>LCD Extension</linktext>
       
   286 </link>
       
   287 <link href="GUID-51514A4B-0220-557B-9F7A-FB110CEFEF10.dita"><linktext>Shared Chunks</linktext>
       
   288 </link>
       
   289 <link href="GUID-9AE254D4-AA60-579E-8D9D-F2797106A413.dita"><linktext>User-Side
       
   290 Hardware Abstraction Technology</linktext></link>
       
   291 <link href="GUID-4C166A49-31F7-5315-B797-F97DB52600BC.dita"><linktext>Display Driver
       
   292 Component</linktext></link>
       
   293 </related-links></concept>