102f4aeb0Sopenharmony_ciName
202f4aeb0Sopenharmony_ci
302f4aeb0Sopenharmony_ci    ANDROID_blob_cache
402f4aeb0Sopenharmony_ci
502f4aeb0Sopenharmony_ciName Strings
602f4aeb0Sopenharmony_ci
702f4aeb0Sopenharmony_ci    EGL_ANDROID_blob_cache
802f4aeb0Sopenharmony_ci
902f4aeb0Sopenharmony_ciContributors
1002f4aeb0Sopenharmony_ci
1102f4aeb0Sopenharmony_ci    Jamie Gennis
1202f4aeb0Sopenharmony_ci
1302f4aeb0Sopenharmony_ciContact
1402f4aeb0Sopenharmony_ci
1502f4aeb0Sopenharmony_ci    Jamie Gennis, Google Inc. (jgennis 'at' google.com)
1602f4aeb0Sopenharmony_ci
1702f4aeb0Sopenharmony_ciStatus
1802f4aeb0Sopenharmony_ci
1902f4aeb0Sopenharmony_ci    Complete
2002f4aeb0Sopenharmony_ci
2102f4aeb0Sopenharmony_ciVersion
2202f4aeb0Sopenharmony_ci
2302f4aeb0Sopenharmony_ci    Version 3, December 13, 2012
2402f4aeb0Sopenharmony_ci
2502f4aeb0Sopenharmony_ciNumber
2602f4aeb0Sopenharmony_ci
2702f4aeb0Sopenharmony_ci    EGL Extension #48
2802f4aeb0Sopenharmony_ci
2902f4aeb0Sopenharmony_ciDependencies
3002f4aeb0Sopenharmony_ci
3102f4aeb0Sopenharmony_ci    Requires EGL 1.0
3202f4aeb0Sopenharmony_ci
3302f4aeb0Sopenharmony_ci    This extension is written against the wording of the EGL 1.4 Specification
3402f4aeb0Sopenharmony_ci
3502f4aeb0Sopenharmony_ciOverview
3602f4aeb0Sopenharmony_ci
3702f4aeb0Sopenharmony_ci    Shader compilation and optimization has been a troublesome aspect of OpenGL
3802f4aeb0Sopenharmony_ci    programming for a long time.  It can consume seconds of CPU cycles during
3902f4aeb0Sopenharmony_ci    application start-up.  Additionally, state-based re-compiles done
4002f4aeb0Sopenharmony_ci    internally by the drivers add an unpredictable element to application
4102f4aeb0Sopenharmony_ci    performance tuning, often leading to occasional pauses in otherwise smooth
4202f4aeb0Sopenharmony_ci    animations.
4302f4aeb0Sopenharmony_ci
4402f4aeb0Sopenharmony_ci    This extension provides a mechanism through which client API
4502f4aeb0Sopenharmony_ci    implementations may cache shader binaries after they are compiled.  It may
4602f4aeb0Sopenharmony_ci    then retrieve those cached shaders during subsequent executions of the same
4702f4aeb0Sopenharmony_ci    program.  The management of the cache is handled by the application (or
4802f4aeb0Sopenharmony_ci    middleware), allowing it to be tuned to a particular platform or
4902f4aeb0Sopenharmony_ci    environment.
5002f4aeb0Sopenharmony_ci
5102f4aeb0Sopenharmony_ci    While the focus of this extension is on providing a persistent cache for
5202f4aeb0Sopenharmony_ci    shader binaries, it may also be useful for caching other data.  This is
5302f4aeb0Sopenharmony_ci    perfectly acceptable, but the guarantees provided (or lack thereof) were
5402f4aeb0Sopenharmony_ci    designed around the shader use case.
5502f4aeb0Sopenharmony_ci
5602f4aeb0Sopenharmony_ci    Note that although this extension is written as if the application
5702f4aeb0Sopenharmony_ci    implements the caching functionality, on the Android OS it is implemented
5802f4aeb0Sopenharmony_ci    as part of the Android EGL module.  This extension is not exposed to
5902f4aeb0Sopenharmony_ci    applications on Android, but will be used automatically in every
6002f4aeb0Sopenharmony_ci    application that uses EGL if it is supported by the underlying
6102f4aeb0Sopenharmony_ci    device-specific EGL implementation.
6202f4aeb0Sopenharmony_ci
6302f4aeb0Sopenharmony_ciNew Types
6402f4aeb0Sopenharmony_ci
6502f4aeb0Sopenharmony_ci    /*
6602f4aeb0Sopenharmony_ci     * EGLsizeiANDROID is a signed integer type for representing the size of a
6702f4aeb0Sopenharmony_ci     * memory buffer.
6802f4aeb0Sopenharmony_ci     */
6902f4aeb0Sopenharmony_ci    #include <khrplatform.h>
7002f4aeb0Sopenharmony_ci    typedef khronos_ssize_t EGLsizeiANDROID;
7102f4aeb0Sopenharmony_ci
7202f4aeb0Sopenharmony_ci    /*
7302f4aeb0Sopenharmony_ci     * EGLSetBlobFunc is a pointer to an application-provided function that a
7402f4aeb0Sopenharmony_ci     * client API implementation may use to insert a key/value pair into the
7502f4aeb0Sopenharmony_ci     * cache.
7602f4aeb0Sopenharmony_ci     */
7702f4aeb0Sopenharmony_ci    typedef void (*EGLSetBlobFuncANDROID) (const void* key,
7802f4aeb0Sopenharmony_ci        EGLsizeiANDROID keySize, const void* value, EGLsizeiANDROID valueSize)
7902f4aeb0Sopenharmony_ci
8002f4aeb0Sopenharmony_ci    /*
8102f4aeb0Sopenharmony_ci     * EGLGetBlobFunc is a pointer to an application-provided function that a
8202f4aeb0Sopenharmony_ci     * client API implementation may use to retrieve a cached value from the
8302f4aeb0Sopenharmony_ci     * cache.
8402f4aeb0Sopenharmony_ci     */
8502f4aeb0Sopenharmony_ci    typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void* key,
8602f4aeb0Sopenharmony_ci        EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize)
8702f4aeb0Sopenharmony_ci
8802f4aeb0Sopenharmony_ciNew Procedures and Functions
8902f4aeb0Sopenharmony_ci
9002f4aeb0Sopenharmony_ci    void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
9102f4aeb0Sopenharmony_ci                                     EGLSetBlobFuncANDROID set,
9202f4aeb0Sopenharmony_ci                                     EGLGetBlobFuncANDROID get);
9302f4aeb0Sopenharmony_ci
9402f4aeb0Sopenharmony_ciNew Tokens
9502f4aeb0Sopenharmony_ci
9602f4aeb0Sopenharmony_ci    None.
9702f4aeb0Sopenharmony_ci
9802f4aeb0Sopenharmony_ciChanges to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
9902f4aeb0Sopenharmony_ci
10002f4aeb0Sopenharmony_ci    Add a new subsection after Section 3.8, page 50
10102f4aeb0Sopenharmony_ci    (Synchronization Primitives)
10202f4aeb0Sopenharmony_ci
10302f4aeb0Sopenharmony_ci    "3.9 Persistent Caching
10402f4aeb0Sopenharmony_ci
10502f4aeb0Sopenharmony_ci    In order to facilitate persistent caching of internal client API state that
10602f4aeb0Sopenharmony_ci    is slow to compute or collect, the application may specify callback
10702f4aeb0Sopenharmony_ci    function pointers through which the client APIs can request data be cached
10802f4aeb0Sopenharmony_ci    and retrieved.  The command
10902f4aeb0Sopenharmony_ci
11002f4aeb0Sopenharmony_ci        void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
11102f4aeb0Sopenharmony_ci            EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
11202f4aeb0Sopenharmony_ci
11302f4aeb0Sopenharmony_ci    sets the callback function pointers that client APIs associated with
11402f4aeb0Sopenharmony_ci    display <dpy> can use to interact with caching functionality provided by
11502f4aeb0Sopenharmony_ci    the application.  <set> points to a function that inserts a new value into
11602f4aeb0Sopenharmony_ci    the cache and associates it with the given key.  <get> points to a function
11702f4aeb0Sopenharmony_ci    that retrieves from the cache the value associated with a given key.  The
11802f4aeb0Sopenharmony_ci    semantics of these callback functions are described in Section 3.9.1 (Cache
11902f4aeb0Sopenharmony_ci    Operations).
12002f4aeb0Sopenharmony_ci
12102f4aeb0Sopenharmony_ci    Cache functions may only be specified once during the lifetime of an
12202f4aeb0Sopenharmony_ci    EGLDisplay.  The <set> and <get> functions may be called at any time and
12302f4aeb0Sopenharmony_ci    from any thread from the time at which eglSetBlobCacheFuncsANDROID is
12402f4aeb0Sopenharmony_ci    called until the time that the last resource associated with <dpy> is
12502f4aeb0Sopenharmony_ci    deleted and <dpy> itself is terminated.  Concurrent calls to these
12602f4aeb0Sopenharmony_ci    functions from different threads is also allowed.
12702f4aeb0Sopenharmony_ci
12802f4aeb0Sopenharmony_ci    If eglSetBlobCacheFuncsANDROID generates an error then all client APIs must
12902f4aeb0Sopenharmony_ci    behave as though eglSetBlobCacheFuncsANDROID was not called for the display
13002f4aeb0Sopenharmony_ci    <dpy>.  If <set> or <get> is NULL then an EGL_BAD_PARAMETER error is
13102f4aeb0Sopenharmony_ci    generated.  If a successful eglSetBlobCacheFuncsANDROID call was already
13202f4aeb0Sopenharmony_ci    made for <dpy> and the display has not since been terminated then an
13302f4aeb0Sopenharmony_ci    EGL_BAD_PARAMETER error is generated.
13402f4aeb0Sopenharmony_ci
13502f4aeb0Sopenharmony_ci    3.9.1 Cache Operations
13602f4aeb0Sopenharmony_ci
13702f4aeb0Sopenharmony_ci    To insert a new binary value into the cache and associate it with a given
13802f4aeb0Sopenharmony_ci    key, a client API implementation can call the application-provided callback
13902f4aeb0Sopenharmony_ci    function
14002f4aeb0Sopenharmony_ci
14102f4aeb0Sopenharmony_ci        void (*set) (const void* key, EGLsizeiANDROID keySize,
14202f4aeb0Sopenharmony_ci            const void* value, EGLsizeiANDROID valueSize)
14302f4aeb0Sopenharmony_ci
14402f4aeb0Sopenharmony_ci    <key> and <value> are pointers to the beginning of the key and value,
14502f4aeb0Sopenharmony_ci    respectively, that are to be inserted.  <keySize> and <valueSize> specify
14602f4aeb0Sopenharmony_ci    the size in bytes of the data pointed to by <key> and <value>,
14702f4aeb0Sopenharmony_ci    respectively.
14802f4aeb0Sopenharmony_ci
14902f4aeb0Sopenharmony_ci    No guarantees are made as to whether a given key/value pair is present in
15002f4aeb0Sopenharmony_ci    the cache after the set call.  If a different value has been associated
15102f4aeb0Sopenharmony_ci    with the given key in the past then it is undefined which value, if any, is
15202f4aeb0Sopenharmony_ci    associated with the key after the set call.  Note that while there are no
15302f4aeb0Sopenharmony_ci    guarantees, the cache implementation should attempt to cache the most
15402f4aeb0Sopenharmony_ci    recently set value for a given key.
15502f4aeb0Sopenharmony_ci
15602f4aeb0Sopenharmony_ci    To retrieve the binary value associated with a given key from the cache, a
15702f4aeb0Sopenharmony_ci    client API implementation can call the application-provided callback
15802f4aeb0Sopenharmony_ci    function
15902f4aeb0Sopenharmony_ci
16002f4aeb0Sopenharmony_ci        EGLsizeiANDROID (*get) (const void* key, EGLsizeiANDROID keySize,
16102f4aeb0Sopenharmony_ci            void* value, EGLsizeiANDROID valueSize)
16202f4aeb0Sopenharmony_ci
16302f4aeb0Sopenharmony_ci    <key> is a pointer to the beginning of the key.  <keySize> specifies the
16402f4aeb0Sopenharmony_ci    size in bytes of the binary key pointed to by <key>.  If the cache contains
16502f4aeb0Sopenharmony_ci    a value associated with the given key then the size of that binary value in
16602f4aeb0Sopenharmony_ci    bytes is returned.  Otherwise 0 is returned.
16702f4aeb0Sopenharmony_ci
16802f4aeb0Sopenharmony_ci    If the cache contains a value for the given key and its size in bytes is
16902f4aeb0Sopenharmony_ci    less than or equal to <valueSize> then the value is written to the memory
17002f4aeb0Sopenharmony_ci    pointed to by <value>.  Otherwise nothing is written to the memory pointed
17102f4aeb0Sopenharmony_ci    to by <value>.
17202f4aeb0Sopenharmony_ci
17302f4aeb0Sopenharmony_ciIssues
17402f4aeb0Sopenharmony_ci
17502f4aeb0Sopenharmony_ci    1. How should errors be handled in the callback functions?
17602f4aeb0Sopenharmony_ci
17702f4aeb0Sopenharmony_ci    RESOLVED: No guarantees are made about the presence of values in the cache,
17802f4aeb0Sopenharmony_ci    so there should not be a need to return error information to the client API
17902f4aeb0Sopenharmony_ci    implementation.  The cache implementation can simply drop a value if it
18002f4aeb0Sopenharmony_ci    encounters an error during the 'set' callback.  Similarly, it can simply
18102f4aeb0Sopenharmony_ci    return 0 if it encouters an error in a 'get' callback.
18202f4aeb0Sopenharmony_ci
18302f4aeb0Sopenharmony_ci    2. When a client API driver gets updated, that may need to invalidate
18402f4aeb0Sopenharmony_ci    previously cached entries.  How can the driver handle this situation?
18502f4aeb0Sopenharmony_ci
18602f4aeb0Sopenharmony_ci    RESPONSE: There are a number of ways the driver can handle this situation.
18702f4aeb0Sopenharmony_ci    The recommended way is to include the driver version in all cache keys.
18802f4aeb0Sopenharmony_ci    That way each driver version will use a set of cache keys that are unique
18902f4aeb0Sopenharmony_ci    to that version, and conflicts should never occur.  Updating the driver
19002f4aeb0Sopenharmony_ci    could then leave a number of values in the cache that will never be
19102f4aeb0Sopenharmony_ci    requested again.  If needed, the cache implementation can handle those
19202f4aeb0Sopenharmony_ci    values in some way, but the driver does not need to take any special
19302f4aeb0Sopenharmony_ci    action.
19402f4aeb0Sopenharmony_ci
19502f4aeb0Sopenharmony_ci    3. How much data can be stored in the cache?
19602f4aeb0Sopenharmony_ci
19702f4aeb0Sopenharmony_ci    RESPONSE: This is entirely dependent upon the cache implementation.
19802f4aeb0Sopenharmony_ci    Presumably it will be tuned to store enough data to be useful, but not
19902f4aeb0Sopenharmony_ci    enough to become problematic. :)
20002f4aeb0Sopenharmony_ci
20102f4aeb0Sopenharmony_ciRevision History
20202f4aeb0Sopenharmony_ci
20302f4aeb0Sopenharmony_ci#3 (Jon Leech, December 13, 2012)
20402f4aeb0Sopenharmony_ci    - Fix typo in New Functions section & assign extension #.
20502f4aeb0Sopenharmony_ci
20602f4aeb0Sopenharmony_ci#2 (Jamie Gennis, April 25, 2011)
20702f4aeb0Sopenharmony_ci    - Swapped the order of the size and pointer arguments to the get and set
20802f4aeb0Sopenharmony_ci      functions.
20902f4aeb0Sopenharmony_ci
21002f4aeb0Sopenharmony_ci#1 (Jamie Gennis, April 22, 2011)
21102f4aeb0Sopenharmony_ci    - Initial draft.
212