2011-07-08 20:59:43 +00:00
|
|
|
Name
|
|
|
|
|
|
|
|
ANDROID_blob_cache
|
|
|
|
|
|
|
|
Name Strings
|
|
|
|
|
|
|
|
EGL_ANDROID_blob_cache
|
|
|
|
|
|
|
|
Contributors
|
|
|
|
|
|
|
|
Jamie Gennis
|
|
|
|
|
|
|
|
Contact
|
|
|
|
|
|
|
|
Jamie Gennis, Google Inc. (jgennis 'at' google.com)
|
|
|
|
|
|
|
|
Status
|
|
|
|
|
2012-11-29 23:58:45 +00:00
|
|
|
Complete
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
Version
|
|
|
|
|
2012-12-14 17:58:45 +00:00
|
|
|
Version 3, December 13, 2012
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
Number
|
|
|
|
|
2012-12-14 17:58:45 +00:00
|
|
|
EGL Extension #48
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
Dependencies
|
|
|
|
|
|
|
|
Requires EGL 1.0
|
|
|
|
|
|
|
|
This extension is written against the wording of the EGL 1.4 Specification
|
|
|
|
|
|
|
|
Overview
|
|
|
|
|
|
|
|
Shader compilation and optimization has been a troublesome aspect of OpenGL
|
|
|
|
programming for a long time. It can consume seconds of CPU cycles during
|
|
|
|
application start-up. Additionally, state-based re-compiles done
|
|
|
|
internally by the drivers add an unpredictable element to application
|
|
|
|
performance tuning, often leading to occasional pauses in otherwise smooth
|
|
|
|
animations.
|
|
|
|
|
|
|
|
This extension provides a mechanism through which client API
|
|
|
|
implementations may cache shader binaries after they are compiled. It may
|
|
|
|
then retrieve those cached shaders during subsequent executions of the same
|
|
|
|
program. The management of the cache is handled by the application (or
|
|
|
|
middleware), allowing it to be tuned to a particular platform or
|
|
|
|
environment.
|
|
|
|
|
|
|
|
While the focus of this extension is on providing a persistent cache for
|
|
|
|
shader binaries, it may also be useful for caching other data. This is
|
|
|
|
perfectly acceptable, but the guarantees provided (or lack thereof) were
|
|
|
|
designed around the shader use case.
|
|
|
|
|
|
|
|
Note that although this extension is written as if the application
|
|
|
|
implements the caching functionality, on the Android OS it is implemented
|
|
|
|
as part of the Android EGL module. This extension is not exposed to
|
|
|
|
applications on Android, but will be used automatically in every
|
|
|
|
application that uses EGL if it is supported by the underlying
|
|
|
|
device-specific EGL implementation.
|
|
|
|
|
|
|
|
New Types
|
|
|
|
|
|
|
|
/*
|
2011-11-09 23:35:34 +00:00
|
|
|
* EGLsizeiANDROID is a signed integer type for representing the size of a
|
|
|
|
* memory buffer.
|
2011-07-08 20:59:43 +00:00
|
|
|
*/
|
|
|
|
#include <khrplatform.h>
|
2011-11-09 23:35:34 +00:00
|
|
|
typedef khronos_ssize_t EGLsizeiANDROID;
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* EGLSetBlobFunc is a pointer to an application-provided function that a
|
|
|
|
* client API implementation may use to insert a key/value pair into the
|
|
|
|
* cache.
|
|
|
|
*/
|
2011-11-09 23:35:34 +00:00
|
|
|
typedef void (*EGLSetBlobFuncANDROID) (const void* key,
|
|
|
|
EGLsizeiANDROID keySize, const void* value, EGLsizeiANDROID valueSize)
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* EGLGetBlobFunc is a pointer to an application-provided function that a
|
|
|
|
* client API implementation may use to retrieve a cached value from the
|
|
|
|
* cache.
|
|
|
|
*/
|
2011-11-09 23:35:34 +00:00
|
|
|
typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void* key,
|
|
|
|
EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize)
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
New Procedures and Functions
|
|
|
|
|
2011-11-09 23:35:34 +00:00
|
|
|
void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
|
2012-12-14 17:58:45 +00:00
|
|
|
EGLSetBlobFuncANDROID set,
|
|
|
|
EGLGetBlobFuncANDROID get);
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
New Tokens
|
|
|
|
|
|
|
|
None.
|
|
|
|
|
|
|
|
Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
|
|
|
|
|
|
|
|
Add a new subsection after Section 3.8, page 50
|
|
|
|
(Synchronization Primitives)
|
|
|
|
|
|
|
|
"3.9 Persistent Caching
|
|
|
|
|
|
|
|
In order to facilitate persistent caching of internal client API state that
|
|
|
|
is slow to compute or collect, the application may specify callback
|
|
|
|
function pointers through which the client APIs can request data be cached
|
|
|
|
and retrieved. The command
|
|
|
|
|
2011-11-09 23:35:34 +00:00
|
|
|
void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
|
|
|
|
EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
sets the callback function pointers that client APIs associated with
|
|
|
|
display <dpy> can use to interact with caching functionality provided by
|
|
|
|
the application. <set> points to a function that inserts a new value into
|
|
|
|
the cache and associates it with the given key. <get> points to a function
|
|
|
|
that retrieves from the cache the value associated with a given key. The
|
|
|
|
semantics of these callback functions are described in Section 3.9.1 (Cache
|
|
|
|
Operations).
|
|
|
|
|
|
|
|
Cache functions may only be specified once during the lifetime of an
|
|
|
|
EGLDisplay. The <set> and <get> functions may be called at any time and
|
2011-11-09 23:35:34 +00:00
|
|
|
from any thread from the time at which eglSetBlobCacheFuncsANDROID is
|
|
|
|
called until the time that the last resource associated with <dpy> is
|
|
|
|
deleted and <dpy> itself is terminated. Concurrent calls to these
|
|
|
|
functions from different threads is also allowed.
|
|
|
|
|
|
|
|
If eglSetBlobCacheFuncsANDROID generates an error then all client APIs must
|
|
|
|
behave as though eglSetBlobCacheFuncsANDROID was not called for the display
|
|
|
|
<dpy>. If <set> or <get> is NULL then an EGL_BAD_PARAMETER error is
|
|
|
|
generated. If a successful eglSetBlobCacheFuncsANDROID call was already
|
|
|
|
made for <dpy> and the display has not since been terminated then an
|
|
|
|
EGL_BAD_PARAMETER error is generated.
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
3.9.1 Cache Operations
|
|
|
|
|
|
|
|
To insert a new binary value into the cache and associate it with a given
|
|
|
|
key, a client API implementation can call the application-provided callback
|
|
|
|
function
|
|
|
|
|
2011-11-09 23:35:34 +00:00
|
|
|
void (*set) (const void* key, EGLsizeiANDROID keySize,
|
|
|
|
const void* value, EGLsizeiANDROID valueSize)
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
<key> and <value> are pointers to the beginning of the key and value,
|
|
|
|
respectively, that are to be inserted. <keySize> and <valueSize> specify
|
|
|
|
the size in bytes of the data pointed to by <key> and <value>,
|
|
|
|
respectively.
|
|
|
|
|
|
|
|
No guarantees are made as to whether a given key/value pair is present in
|
|
|
|
the cache after the set call. If a different value has been associated
|
|
|
|
with the given key in the past then it is undefined which value, if any, is
|
|
|
|
associated with the key after the set call. Note that while there are no
|
|
|
|
guarantees, the cache implementation should attempt to cache the most
|
|
|
|
recently set value for a given key.
|
|
|
|
|
|
|
|
To retrieve the binary value associated with a given key from the cache, a
|
|
|
|
client API implementation can call the application-provided callback
|
|
|
|
function
|
|
|
|
|
2011-11-09 23:35:34 +00:00
|
|
|
EGLsizeiANDROID (*get) (const void* key, EGLsizeiANDROID keySize,
|
|
|
|
void* value, EGLsizeiANDROID valueSize)
|
2011-07-08 20:59:43 +00:00
|
|
|
|
|
|
|
<key> is a pointer to the beginning of the key. <keySize> specifies the
|
|
|
|
size in bytes of the binary key pointed to by <key>. If the cache contains
|
|
|
|
a value associated with the given key then the size of that binary value in
|
|
|
|
bytes is returned. Otherwise 0 is returned.
|
|
|
|
|
|
|
|
If the cache contains a value for the given key and its size in bytes is
|
|
|
|
less than or equal to <valueSize> then the value is written to the memory
|
|
|
|
pointed to by <value>. Otherwise nothing is written to the memory pointed
|
|
|
|
to by <value>.
|
|
|
|
|
|
|
|
Issues
|
|
|
|
|
|
|
|
1. How should errors be handled in the callback functions?
|
|
|
|
|
|
|
|
RESOLVED: No guarantees are made about the presence of values in the cache,
|
|
|
|
so there should not be a need to return error information to the client API
|
|
|
|
implementation. The cache implementation can simply drop a value if it
|
|
|
|
encounters an error during the 'set' callback. Similarly, it can simply
|
|
|
|
return 0 if it encouters an error in a 'get' callback.
|
|
|
|
|
|
|
|
2. When a client API driver gets updated, that may need to invalidate
|
|
|
|
previously cached entries. How can the driver handle this situation?
|
|
|
|
|
|
|
|
RESPONSE: There are a number of ways the driver can handle this situation.
|
|
|
|
The recommended way is to include the driver version in all cache keys.
|
|
|
|
That way each driver version will use a set of cache keys that are unique
|
|
|
|
to that version, and conflicts should never occur. Updating the driver
|
|
|
|
could then leave a number of values in the cache that will never be
|
|
|
|
requested again. If needed, the cache implementation can handle those
|
|
|
|
values in some way, but the driver does not need to take any special
|
|
|
|
action.
|
|
|
|
|
|
|
|
3. How much data can be stored in the cache?
|
|
|
|
|
|
|
|
RESPONSE: This is entirely dependent upon the cache implementation.
|
|
|
|
Presumably it will be tuned to store enough data to be useful, but not
|
|
|
|
enough to become problematic. :)
|
|
|
|
|
|
|
|
Revision History
|
|
|
|
|
2012-12-14 17:58:45 +00:00
|
|
|
#3 (Jon Leech, December 13, 2012)
|
|
|
|
- Fix typo in New Functions section & assign extension #.
|
|
|
|
|
2011-07-08 20:59:43 +00:00
|
|
|
#2 (Jamie Gennis, April 25, 2011)
|
|
|
|
- Swapped the order of the size and pointer arguments to the get and set
|
|
|
|
functions.
|
|
|
|
|
|
|
|
#1 (Jamie Gennis, April 22, 2011)
|
|
|
|
- Initial draft.
|