15 Jamie Gennis, Google Inc. (jgennis 'at' google.com)
23 Version 3, December 13, 2012
33 This extension is written against the wording of the EGL 1.4 Specification
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
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
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.
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.
66 * EGLsizeiANDROID is a signed integer type for representing the size of a
69 #include <khrplatform.h>
70 typedef khronos_ssize_t EGLsizeiANDROID;
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
77 typedef void (*EGLSetBlobFuncANDROID) (const void* key,
78 EGLsizeiANDROID keySize, const void* value, EGLsizeiANDROID valueSize)
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
85 typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void* key,
86 EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize)
88 New Procedures and Functions
90 void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
91 EGLSetBlobFuncANDROID set,
92 EGLGetBlobFuncANDROID get);
98 Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
100 Add a new subsection after Section 3.8, page 50
101 (Synchronization Primitives)
103 "3.9 Persistent Caching
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
110 void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
111 EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
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
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.
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.
135 3.9.1 Cache Operations
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
141 void (*set) (const void* key, EGLsizeiANDROID keySize,
142 const void* value, EGLsizeiANDROID valueSize)
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>,
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.
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
160 EGLsizeiANDROID (*get) (const void* key, EGLsizeiANDROID keySize,
161 void* value, EGLsizeiANDROID valueSize)
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.
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
175 1. How should errors be handled in the callback functions?
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.
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?
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
195 3. How much data can be stored in the cache?
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. :)
203 #3 (Jon Leech, December 13, 2012)
204 - Fix typo in New Functions section & assign extension #.
206 #2 (Jamie Gennis, April 25, 2011)
207 - Swapped the order of the size and pointer arguments to the get and set
210 #1 (Jamie Gennis, April 22, 2011)