Add the spec for EGL_ANDROID_blob_cache.

Change-Id: Ibaff52fee5c856283536ad37251cc80a9f3f938b
diff --git a/opengl/specs/EGL_ANDROID_blob_cache.txt b/opengl/specs/EGL_ANDROID_blob_cache.txt
new file mode 100644
index 0000000..55dc900
--- /dev/null
+++ b/opengl/specs/EGL_ANDROID_blob_cache.txt
@@ -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.