1 Name 2 3 ANDROID_blob_cache 4 5 Name Strings 6 7 EGL_ANDROID_blob_cache 8 9 Contributors 10 11 Jamie Gennis 12 13 Contact 14 15 Jamie Gennis, Google Inc. (jgennis 'at' google.com) 16 17 Status 18 19 Draft. 20 21 Version 22 23 Version 1, April 22, 2011 24 25 Number 26 27 EGL Extension #XXX 28 29 Dependencies 30 31 Requires EGL 1.0 32 33 This extension is written against the wording of the EGL 1.4 Specification 34 35 Overview 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 63 New 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 88 New Procedures and Functions 89 90 void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, 91 EGLSetBlobFunc set, 92 EGLGetBlobFunc get); 93 94 New Tokens 95 96 None. 97 98 Changes 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 173 Issues 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 201 Revision 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