Add the spec for EGL_ANDROID_blob_cache.
Change-Id: Ibaff52fee5c856283536ad37251cc80a9f3f938b
This commit is contained in:
parent
6a90b3a3d7
commit
34d3f3810d
208
opengl/specs/EGL_ANDROID_blob_cache.txt
Normal file
208
opengl/specs/EGL_ANDROID_blob_cache.txt
Normal file
@ -0,0 +1,208 @@
|
||||
Name
|
||||
|
||||
ANDROID_blob_cache
|
||||
|
||||
Name Strings
|
||||
|
||||
EGL_ANDROID_blob_cache
|
||||
|
||||
Contributors
|
||||
|
||||
Jamie Gennis
|
||||
|
||||
Contact
|
||||
|
||||
Jamie Gennis, Google Inc. (jgennis 'at' google.com)
|
||||
|
||||
Status
|
||||
|
||||
Draft.
|
||||
|
||||
Version
|
||||
|
||||
Version 1, April 22, 2011
|
||||
|
||||
Number
|
||||
|
||||
EGL Extension #XXX
|
||||
|
||||
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
|
||||
|
||||
/*
|
||||
* EGLsizei is a signed integer type for representing the size of a memory
|
||||
* buffer.
|
||||
*/
|
||||
#include <khrplatform.h>
|
||||
typedef khronos_ssize_t EGLsizei;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize,
|
||||
const void* value, EGLsizei valueSize)
|
||||
|
||||
/*
|
||||
* EGLGetBlobFunc is a pointer to an application-provided function that a
|
||||
* client API implementation may use to retrieve a cached value from the
|
||||
* cache.
|
||||
*/
|
||||
typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize,
|
||||
void* value, EGLsizei valueSize)
|
||||
|
||||
New Procedures and Functions
|
||||
|
||||
void eglSetBlobCacheFuncs(EGLDisplay dpy,
|
||||
EGLSetBlobFunc set,
|
||||
EGLGetBlobFunc get);
|
||||
|
||||
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
|
||||
|
||||
void eglSetBlobCacheFuncs(EGLDisplay dpy,
|
||||
EGLSetBlobFunc set, EGLGetBlobFunc get);
|
||||
|
||||
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
|
||||
from any thread from the time at which eglSetBlobCacheFuncs 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 eglSetBlobCacheFuncs generates an error then all client APIs must behave
|
||||
as though eglSetBlobCacheFuncs was not called for the display <dpy>. If
|
||||
<set> or <get> is NULL then an EGL_BAD_PARAMETER error is generated. If a
|
||||
successful eglSetBlobCacheFuncs call was already made for <dpy> and the
|
||||
display has not since been terminated then an EGL_BAD_PARAMETER error is
|
||||
generated.
|
||||
|
||||
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
|
||||
|
||||
void (*set) (const void* key, EGLsizei keySize, const void* value,
|
||||
EGLsizei valueSize)
|
||||
|
||||
<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
|
||||
|
||||
EGLsizei (*get) (const void* key, EGLsizei keySize, void* value,
|
||||
EGLsizei valueSize)
|
||||
|
||||
<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
|
||||
|
||||
#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.
|
Loading…
Reference in New Issue
Block a user