1Name
2
3    ANDROID_blob_cache
4
5Name Strings
6
7    EGL_ANDROID_blob_cache
8
9Contributors
10
11    Jamie Gennis
12
13Contact
14
15    Jamie Gennis, Google Inc. (jgennis 'at' google.com)
16
17Status
18
19    Draft.
20
21Version
22
23    Version 1, April 22, 2011
24
25Number
26
27    EGL Extension #XXX
28
29Dependencies
30
31    Requires EGL 1.0
32
33    This extension is written against the wording of the EGL 1.4 Specification
34
35Overview
36
37    Shader compilation and optimization has been a troublesome aspect of OpenGL
38    programming for a long time.  It can consume seconds of CPU cycles during
39    application start-up.  Additionally, state-based re-compiles done
40    internally by the drivers add an unpredictable element to application
41    performance tuning, often leading to occasional pauses in otherwise smooth
42    animations.
43
44    This extension provides a mechanism through which client API
45    implementations may cache shader binaries after they are compiled.  It may
46    then retrieve those cached shaders during subsequent executions of the same
47    program.  The management of the cache is handled by the application (or
48    middleware), allowing it to be tuned to a particular platform or
49    environment.
50
51    While the focus of this extension is on providing a persistent cache for
52    shader binaries, it may also be useful for caching other data.  This is
53    perfectly acceptable, but the guarantees provided (or lack thereof) were
54    designed around the shader use case.
55
56    Note that although this extension is written as if the application
57    implements the caching functionality, on the Android OS it is implemented
58    as part of the Android EGL module.  This extension is not exposed to
59    applications on Android, but will be used automatically in every
60    application that uses EGL if it is supported by the underlying
61    device-specific EGL implementation.
62
63New Types
64
65    /*
66     * EGLsizeiANDROID is a signed integer type for representing the size of a
67     * memory buffer.
68     */
69    #include <khrplatform.h>
70    typedef khronos_ssize_t EGLsizeiANDROID;
71
72    /*
73     * EGLSetBlobFunc is a pointer to an application-provided function that a
74     * client API implementation may use to insert a key/value pair into the
75     * cache.
76     */
77    typedef void (*EGLSetBlobFuncANDROID) (const void* key,
78        EGLsizeiANDROID keySize, const void* value, EGLsizeiANDROID valueSize)
79
80    /*
81     * EGLGetBlobFunc is a pointer to an application-provided function that a
82     * client API implementation may use to retrieve a cached value from the
83     * cache.
84     */
85    typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void* key,
86        EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize)
87
88New Procedures and Functions
89
90    void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
91                                     EGLSetBlobFunc set,
92                                     EGLGetBlobFunc get);
93
94New Tokens
95
96    None.
97
98Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
99
100    Add a new subsection after Section 3.8, page 50
101    (Synchronization Primitives)
102
103    "3.9 Persistent Caching
104
105    In order to facilitate persistent caching of internal client API state that
106    is slow to compute or collect, the application may specify callback
107    function pointers through which the client APIs can request data be cached
108    and retrieved.  The command
109
110        void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
111            EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
112
113    sets the callback function pointers that client APIs associated with
114    display <dpy> can use to interact with caching functionality provided by
115    the application.  <set> points to a function that inserts a new value into
116    the cache and associates it with the given key.  <get> points to a function
117    that retrieves from the cache the value associated with a given key.  The
118    semantics of these callback functions are described in Section 3.9.1 (Cache
119    Operations).
120
121    Cache functions may only be specified once during the lifetime of an
122    EGLDisplay.  The <set> and <get> functions may be called at any time and
123    from any thread from the time at which eglSetBlobCacheFuncsANDROID is
124    called until the time that the last resource associated with <dpy> is
125    deleted and <dpy> itself is terminated.  Concurrent calls to these
126    functions from different threads is also allowed.
127
128    If eglSetBlobCacheFuncsANDROID generates an error then all client APIs must
129    behave as though eglSetBlobCacheFuncsANDROID was not called for the display
130    <dpy>.  If <set> or <get> is NULL then an EGL_BAD_PARAMETER error is
131    generated.  If a successful eglSetBlobCacheFuncsANDROID call was already
132    made for <dpy> and the display has not since been terminated then an
133    EGL_BAD_PARAMETER error is generated.
134
135    3.9.1 Cache Operations
136
137    To insert a new binary value into the cache and associate it with a given
138    key, a client API implementation can call the application-provided callback
139    function
140
141        void (*set) (const void* key, EGLsizeiANDROID keySize,
142            const void* value, EGLsizeiANDROID valueSize)
143
144    <key> and <value> are pointers to the beginning of the key and value,
145    respectively, that are to be inserted.  <keySize> and <valueSize> specify
146    the size in bytes of the data pointed to by <key> and <value>,
147    respectively.
148
149    No guarantees are made as to whether a given key/value pair is present in
150    the cache after the set call.  If a different value has been associated
151    with the given key in the past then it is undefined which value, if any, is
152    associated with the key after the set call.  Note that while there are no
153    guarantees, the cache implementation should attempt to cache the most
154    recently set value for a given key.
155
156    To retrieve the binary value associated with a given key from the cache, a
157    client API implementation can call the application-provided callback
158    function
159
160        EGLsizeiANDROID (*get) (const void* key, EGLsizeiANDROID keySize,
161            void* value, EGLsizeiANDROID valueSize)
162
163    <key> is a pointer to the beginning of the key.  <keySize> specifies the
164    size in bytes of the binary key pointed to by <key>.  If the cache contains
165    a value associated with the given key then the size of that binary value in
166    bytes is returned.  Otherwise 0 is returned.
167
168    If the cache contains a value for the given key and its size in bytes is
169    less than or equal to <valueSize> then the value is written to the memory
170    pointed to by <value>.  Otherwise nothing is written to the memory pointed
171    to by <value>.
172
173Issues
174
175    1. How should errors be handled in the callback functions?
176
177    RESOLVED: No guarantees are made about the presence of values in the cache,
178    so there should not be a need to return error information to the client API
179    implementation.  The cache implementation can simply drop a value if it
180    encounters an error during the 'set' callback.  Similarly, it can simply
181    return 0 if it encouters an error in a 'get' callback.
182
183    2. When a client API driver gets updated, that may need to invalidate
184    previously cached entries.  How can the driver handle this situation?
185
186    RESPONSE: There are a number of ways the driver can handle this situation.
187    The recommended way is to include the driver version in all cache keys.
188    That way each driver version will use a set of cache keys that are unique
189    to that version, and conflicts should never occur.  Updating the driver
190    could then leave a number of values in the cache that will never be
191    requested again.  If needed, the cache implementation can handle those
192    values in some way, but the driver does not need to take any special
193    action.
194
195    3. How much data can be stored in the cache?
196
197    RESPONSE: This is entirely dependent upon the cache implementation.
198    Presumably it will be tuned to store enough data to be useful, but not
199    enough to become problematic. :)
200
201Revision History
202
203#2 (Jamie Gennis, April 25, 2011)
204    - Swapped the order of the size and pointer arguments to the get and set
205      functions.
206
207#1 (Jamie Gennis, April 22, 2011)
208    - Initial draft.
209