15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    OES_get_program_binary
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_OES_get_program_binary
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciContributors
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Acorn Pooley
125bd8deadSopenharmony_ci    Aske Simon Christensen
135bd8deadSopenharmony_ci    David Garcia
145bd8deadSopenharmony_ci    Georg Kolling
155bd8deadSopenharmony_ci    Jason Green
165bd8deadSopenharmony_ci    Jeremy Sandmel
175bd8deadSopenharmony_ci    Joey Blankenship
185bd8deadSopenharmony_ci    Mark Callow
195bd8deadSopenharmony_ci    Robert Simpson
205bd8deadSopenharmony_ci    Tom Olson
215bd8deadSopenharmony_ci
225bd8deadSopenharmony_ciContact
235bd8deadSopenharmony_ci
245bd8deadSopenharmony_ci    Benj Lipchak, AMD (benj.lipchak 'at' amd.com)
255bd8deadSopenharmony_ci
265bd8deadSopenharmony_ciNotice
275bd8deadSopenharmony_ci
285bd8deadSopenharmony_ci    Copyright (c) 2007-2013 The Khronos Group Inc. Copyright terms at
295bd8deadSopenharmony_ci        http://www.khronos.org/registry/speccopyright.html
305bd8deadSopenharmony_ci
315bd8deadSopenharmony_ciSpecification Update Policy
325bd8deadSopenharmony_ci
335bd8deadSopenharmony_ci    Khronos-approved extension specifications are updated in response to
345bd8deadSopenharmony_ci    issues and bugs prioritized by the Khronos OpenGL ES Working Group. For
355bd8deadSopenharmony_ci    extensions which have been promoted to a core Specification, fixes will
365bd8deadSopenharmony_ci    first appear in the latest version of that core Specification, and will
375bd8deadSopenharmony_ci    eventually be backported to the extension document. This policy is
385bd8deadSopenharmony_ci    described in more detail at
395bd8deadSopenharmony_ci        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
405bd8deadSopenharmony_ci
415bd8deadSopenharmony_ciStatus
425bd8deadSopenharmony_ci
435bd8deadSopenharmony_ci    Ratified by the Khronos BOP, May 29, 2008.
445bd8deadSopenharmony_ci
455bd8deadSopenharmony_ciVersion
465bd8deadSopenharmony_ci
475bd8deadSopenharmony_ci    Last Modified Date: June 24, 2020
485bd8deadSopenharmony_ci    Revision: #16
495bd8deadSopenharmony_ci
505bd8deadSopenharmony_ciNumber
515bd8deadSopenharmony_ci
525bd8deadSopenharmony_ci    OpenGL ES Extension #47
535bd8deadSopenharmony_ci
545bd8deadSopenharmony_ciDependencies
555bd8deadSopenharmony_ci
565bd8deadSopenharmony_ci    OpenGL ES 2.0 is required.
575bd8deadSopenharmony_ci
585bd8deadSopenharmony_ci    Written based on the wording of the OpenGL ES 2.0 specification.
595bd8deadSopenharmony_ci
605bd8deadSopenharmony_ciOverview
615bd8deadSopenharmony_ci
625bd8deadSopenharmony_ci    This extension introduces two new commands.  GetProgramBinaryOES empowers an
635bd8deadSopenharmony_ci    application to use the GL itself as an offline compiler.  The resulting
645bd8deadSopenharmony_ci    program binary can be reloaded into the GL via ProgramBinaryOES.  This is a
655bd8deadSopenharmony_ci    very useful path for applications that wish to remain portable by shipping
665bd8deadSopenharmony_ci    pure GLSL source shaders, yet would like to avoid the cost of compiling
675bd8deadSopenharmony_ci    their shaders at runtime.  Instead an application can supply its GLSL source
685bd8deadSopenharmony_ci    shaders during first application run, or even during installation.  The
695bd8deadSopenharmony_ci    application then compiles and links its shaders and reads back the program
705bd8deadSopenharmony_ci    binaries.  On subsequent runs, only the program binaries need be supplied!
715bd8deadSopenharmony_ci    Though the level of optimization may not be identical -- the offline shader
725bd8deadSopenharmony_ci    compiler may have the luxury of more aggressive optimization at its
735bd8deadSopenharmony_ci    disposal -- program binaries generated online by the GL are interchangeable
745bd8deadSopenharmony_ci    with those generated offline by an SDK tool.
755bd8deadSopenharmony_ci
765bd8deadSopenharmony_ci    Note that an implementation supporting this extension need not include an
775bd8deadSopenharmony_ci    online compiler.  That is, it is not required to support loading GLSL shader
785bd8deadSopenharmony_ci    sources via the ShaderSource command.  A query of boolean value
795bd8deadSopenharmony_ci    SHADER_COMPILER can be used to determine if an implementation supports a
805bd8deadSopenharmony_ci    shader compiler.  If not, the GetProgramBinaryOES command is rendered
815bd8deadSopenharmony_ci    virtually useless, but the ProgramBinaryOES command may still be used by
825bd8deadSopenharmony_ci    vendor extensions as a standard method for loading offline-compiled program
835bd8deadSopenharmony_ci    binaries.
845bd8deadSopenharmony_ci
855bd8deadSopenharmony_ci
865bd8deadSopenharmony_ciIssues
875bd8deadSopenharmony_ci
885bd8deadSopenharmony_ci    1. Why introduce a new entrypoint for loading binaries when ShaderBinary
895bd8deadSopenharmony_ci       is already part of the core spec and permits loading binary shader pairs?
905bd8deadSopenharmony_ci
915bd8deadSopenharmony_ci    RESOLVED: There are several reasons:
925bd8deadSopenharmony_ci      - Shader objects are taken out of the equation, since they're not
935bd8deadSopenharmony_ci        relevant to wholesale program object replacement.
945bd8deadSopenharmony_ci      - Implicit links during retrieval are no longer needed since we don't
955bd8deadSopenharmony_ci        need to keep shader object state in sync with program object state.
965bd8deadSopenharmony_ci      - Explicit links during program object reload are no longer needed since
975bd8deadSopenharmony_ci        the program binary is pre-linked and ready to run.
985bd8deadSopenharmony_ci      - The number of API calls needed to load program objects is much fewer.
995bd8deadSopenharmony_ci      - Complex error detection needed by the previous proposal is eliminated.
1005bd8deadSopenharmony_ci      - No change to the retrieval/reload path is needed when new shader stages
1015bd8deadSopenharmony_ci        are introduced by future extensions.
1025bd8deadSopenharmony_ci      - This is a more elegant mapping for what we're trying to achieve!
1035bd8deadSopenharmony_ci
1045bd8deadSopenharmony_ci    2. Do we need to consider state dependencies when using this extension?
1055bd8deadSopenharmony_ci
1065bd8deadSopenharmony_ci    RESOLVED: No more than you do when using GLSL source shaders.  A program
1075bd8deadSopenharmony_ci    binary retrieved with GetProgramBinaryOES can be expected to work regardless
1085bd8deadSopenharmony_ci    of the current GL state in effect at the time it was retrieved with
1095bd8deadSopenharmony_ci    GetProgramBinaryOES, loaded with ProgramBinaryOES, installed as part of
1105bd8deadSopenharmony_ci    render state with UseProgram, or used for drawing with DrawArrays or
1115bd8deadSopenharmony_ci    DrawElements.
1125bd8deadSopenharmony_ci
1135bd8deadSopenharmony_ci    However, some implementations have internal state dependencies that affect
1145bd8deadSopenharmony_ci    both GLSL source shaders and program binaries, causing them to run out of
1155bd8deadSopenharmony_ci    resources when confronted by combinations of certain GL state and certain
1165bd8deadSopenharmony_ci    shader program characteristics.  An application need be concerned no more
1175bd8deadSopenharmony_ci    with these issues when using program binaries than when using GLSL source
1185bd8deadSopenharmony_ci    shaders.
1195bd8deadSopenharmony_ci
1205bd8deadSopenharmony_ci    3. How are shader objects involved, if at all?
1215bd8deadSopenharmony_ci
1225bd8deadSopenharmony_ci    RESOLVED: Any shader objects attached to the program object at the time
1235bd8deadSopenharmony_ci    GetProgramBinaryOES or ProgramBinaryOES is called are ignored.  (See also
1245bd8deadSopenharmony_ci    Issue 4.)
1255bd8deadSopenharmony_ci
1265bd8deadSopenharmony_ci    The program binary retrieved by GetProgramBinaryOES is the one installed
1275bd8deadSopenharmony_ci    during the most recent call to LinkProgram or ProgramBinaryOES, i.e. the one
1285bd8deadSopenharmony_ci    which would go into effect if we were to call UseProgram.  Attaching
1295bd8deadSopenharmony_ci    different shader objects after the most recent call to LinkProgram is
1305bd8deadSopenharmony_ci    inconsequential.
1315bd8deadSopenharmony_ci
1325bd8deadSopenharmony_ci    4. Should we throw an error as a programming aid if there are shader objects
1335bd8deadSopenharmony_ci       attached to the program object when ProgramBinaryOES is called?
1345bd8deadSopenharmony_ci
1355bd8deadSopenharmony_ci    RESOLVED: No, they are irrelevant but harmless, and GL precedent is to throw
1365bd8deadSopenharmony_ci    errors on bad state combinations, not on harmless ones.  Besides, the
1375bd8deadSopenharmony_ci    programmer should discover pretty quickly that they're getting the wrong
1385bd8deadSopenharmony_ci    shader, if they accidentally called ProgramBinaryOES instead of LinkProgram.
1395bd8deadSopenharmony_ci    Also, an app may intentionally leave the attachments in place if it for some
1405bd8deadSopenharmony_ci    reason is switching back and forth between loading a program object with
1415bd8deadSopenharmony_ci    program binaries, and loading it with compiled GLSL shaders.
1425bd8deadSopenharmony_ci
1435bd8deadSopenharmony_ci    5. Where are the binary formats defined and described?
1445bd8deadSopenharmony_ci
1455bd8deadSopenharmony_ci    RESOLVED: This extension provides a common infrastructure for retrieving and
1465bd8deadSopenharmony_ci    loading program binaries.  A vendor extension must also be present in order
1475bd8deadSopenharmony_ci    to define one or more binary formats, thereby populating the list of
1485bd8deadSopenharmony_ci    PROGRAM_BINARY_FORMATS_OES.  The <binaryFormat> returned by
1495bd8deadSopenharmony_ci    GetProgramBinaryOES is always one of the binary formats in this list.  If
1505bd8deadSopenharmony_ci    ProgramBinaryOES is called with a <binaryFormat> not in this list, the
1515bd8deadSopenharmony_ci    implementation will throw an INVALID_ENUM error.
1525bd8deadSopenharmony_ci
1535bd8deadSopenharmony_ci    The beauty of this extension, however, is that an application does not need
1545bd8deadSopenharmony_ci    to be aware of the vendor extension on any given implementation.  It only
1555bd8deadSopenharmony_ci    needs to retrieve a program binary with an anonymous <binaryFormat> and
1565bd8deadSopenharmony_ci    resupply that same <binaryFormat> when loading the program binary.
1575bd8deadSopenharmony_ci
1585bd8deadSopenharmony_ci    6. Under what conditions might a call to ProgramBinaryOES fail?
1595bd8deadSopenharmony_ci
1605bd8deadSopenharmony_ci    RESOLVED: Even if a program binary is successfully retrieved with
1615bd8deadSopenharmony_ci    GetProgramBinaryOES and then in a future run the program binary is
1625bd8deadSopenharmony_ci    resupplied with ProgramBinaryOES, and all of the parameters are correct,
1635bd8deadSopenharmony_ci    the program binary load may still fail.
1645bd8deadSopenharmony_ci
1655bd8deadSopenharmony_ci    This can happen if there has been a change to the hardware or software on
1665bd8deadSopenharmony_ci    the system, such as a hardware upgrade or driver update.  In this case the
1675bd8deadSopenharmony_ci    PROGRAM_BINARY_FORMATS_OES list may no longer contain the binary format
1685bd8deadSopenharmony_ci    associated with the cached program binary, and INVALID_ENUM will be thrown
1695bd8deadSopenharmony_ci    if the cached program binary format is passed into ProgramBinaryOES anyway.
1705bd8deadSopenharmony_ci
1715bd8deadSopenharmony_ci    Even if the cached program binary format is still valid, ProgramBinaryOES
1725bd8deadSopenharmony_ci    may still fail to load the cached binary.  This is the driver's way of
1735bd8deadSopenharmony_ci    signaling to the app that it needs to recompile and recache its program
1745bd8deadSopenharmony_ci    binaries because there has been some important change to the online
1755bd8deadSopenharmony_ci    compiler, such as a bug fix or a significant new optimization.
1765bd8deadSopenharmony_ci
1775bd8deadSopenharmony_ci    7. Can BindAttribLocation be called after ProgramBinaryOES to remap an
1785bd8deadSopenharmony_ci       attribute location used by the program binary?
1795bd8deadSopenharmony_ci
1805bd8deadSopenharmony_ci    RESOLVED: No.  BindAttribLocation only affects the result of a subsequent
1815bd8deadSopenharmony_ci    call to LinkProgram.  LinkProgram operates on the attached shader objects
1825bd8deadSopenharmony_ci    and replaces any program binary loaded prior to LinkProgram.  So there is no
1835bd8deadSopenharmony_ci    mechanism to remap an attribute location after loading a program binary.
1845bd8deadSopenharmony_ci
1855bd8deadSopenharmony_ci    However, an application is free to remap an attribute location prior to
1865bd8deadSopenharmony_ci    retrieving the program binary.  By calling BindAttribLocation followed by
1875bd8deadSopenharmony_ci    LinkProgram, an application can remap the attribute location.  If this is
1885bd8deadSopenharmony_ci    followed by a call to GetProgramBinaryOES, the retrieved program binary will
1895bd8deadSopenharmony_ci    include the desired attribute location assignment.
1905bd8deadSopenharmony_ci
1915bd8deadSopenharmony_ciNew Procedures and Functions
1925bd8deadSopenharmony_ci
1935bd8deadSopenharmony_ci    void GetProgramBinaryOES(uint program, sizei bufSize, sizei *length,
1945bd8deadSopenharmony_ci                             enum *binaryFormat, void *binary);
1955bd8deadSopenharmony_ci
1965bd8deadSopenharmony_ci    void ProgramBinaryOES(uint program, enum binaryFormat,
1975bd8deadSopenharmony_ci                          const void *binary, int length);
1985bd8deadSopenharmony_ci
1995bd8deadSopenharmony_ciNew Tokens
2005bd8deadSopenharmony_ci
2015bd8deadSopenharmony_ci    Accepted by the <pname> parameter of GetProgramiv:
2025bd8deadSopenharmony_ci
2035bd8deadSopenharmony_ci        PROGRAM_BINARY_LENGTH_OES                   0x8741
2045bd8deadSopenharmony_ci
2055bd8deadSopenharmony_ci    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, and
2065bd8deadSopenharmony_ci    GetFloatv:
2075bd8deadSopenharmony_ci
2085bd8deadSopenharmony_ci        NUM_PROGRAM_BINARY_FORMATS_OES              0x87FE
2095bd8deadSopenharmony_ci        PROGRAM_BINARY_FORMATS_OES                  0x87FF
2105bd8deadSopenharmony_ci
2115bd8deadSopenharmony_ciAdditions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL Operation)
2125bd8deadSopenharmony_ci
2135bd8deadSopenharmony_ci    Update section 2.15, replace first sentence of last paragraph with:
2145bd8deadSopenharmony_ci
2155bd8deadSopenharmony_ci    "OpenGL ES 2.0 provides interfaces to directly load pre-compiled shader
2165bd8deadSopenharmony_ci    binaries, to directly load pre-linked program binaries, or to load the
2175bd8deadSopenharmony_ci    shader sources and compile them."
2185bd8deadSopenharmony_ci
2195bd8deadSopenharmony_ci    Add section 2.15.4, Program Binaries
2205bd8deadSopenharmony_ci
2215bd8deadSopenharmony_ci    "The command
2225bd8deadSopenharmony_ci
2235bd8deadSopenharmony_ci        void GetProgramBinaryOES(uint program, sizei bufSize, sizei *length,
2245bd8deadSopenharmony_ci                                 enum *binaryFormat, void *binary);
2255bd8deadSopenharmony_ci
2265bd8deadSopenharmony_ci    returns the program object's executable, henceforth referred to as its
2275bd8deadSopenharmony_ci    program binary.  The maximum number of bytes that may be written into
2285bd8deadSopenharmony_ci    <binary> is specified by <bufSize>.  If <bufSize> is less than the number of
2295bd8deadSopenharmony_ci    bytes in the program binary, then 0 is returned in <length>, and an
2305bd8deadSopenharmony_ci    INVALID_OPERATION error is thrown.  Otherwise, the actual number of bytes
2315bd8deadSopenharmony_ci    written into <binary> is returned in <length> and its format is returned in
2325bd8deadSopenharmony_ci    <binaryFormat>.  If <length> is NULL, then no length is returned.
2335bd8deadSopenharmony_ci
2345bd8deadSopenharmony_ci    The number of bytes in the program binary can be queried by calling
2355bd8deadSopenharmony_ci    GetProgramiv with <pname> PROGRAM_BINARY_LENGTH_OES.  When a program
2365bd8deadSopenharmony_ci    object's LINK_STATUS is FALSE, its program binary length is zero, and a call
2375bd8deadSopenharmony_ci    to GetProgramBinaryOES will generate an INVALID_OPERATION error.
2385bd8deadSopenharmony_ci
2395bd8deadSopenharmony_ci    The command
2405bd8deadSopenharmony_ci
2415bd8deadSopenharmony_ci        void ProgramBinaryOES(uint program, enum binaryFormat,
2425bd8deadSopenharmony_ci                              const void *binary, int length);
2435bd8deadSopenharmony_ci
2445bd8deadSopenharmony_ci    loads a program object with a program binary previously returned from
2455bd8deadSopenharmony_ci    GetProgramBinaryOES.  This is useful for future instantiations of the GL to
2465bd8deadSopenharmony_ci    avoid online compilation, while still using OpenGL Shading Language source
2475bd8deadSopenharmony_ci    shaders as a portable initial format.  <binaryFormat> and <binary> must be
2485bd8deadSopenharmony_ci    those returned by a previous call to GetProgramBinaryOES, and <length> must
2495bd8deadSopenharmony_ci    be the length of the program binary as returned by GetProgramBinaryOES or
2505bd8deadSopenharmony_ci    GetProgramiv with <pname> PROGRAM_BINARY_LENGTH_OES.  The program binary
2515bd8deadSopenharmony_ci    will fail to load if these conditions are not met.
2525bd8deadSopenharmony_ci
2535bd8deadSopenharmony_ci    An implementation may reject a program binary if it determines the program
2545bd8deadSopenharmony_ci    binary was produced by an incompatible or outdated version of the compiler.
2555bd8deadSopenharmony_ci    In this case the application should fall back to providing the original
2565bd8deadSopenharmony_ci    OpenGL Shading Language source shaders, and perhaps again retrieve the
2575bd8deadSopenharmony_ci    program binary for future use.
2585bd8deadSopenharmony_ci
2595bd8deadSopenharmony_ci    A program object's program binary is replaced by calls to LinkProgram or
2605bd8deadSopenharmony_ci    ProgramBinaryOES.  Either command sets the program object's LINK_STATUS to
2615bd8deadSopenharmony_ci    TRUE or FALSE, as queried with GetProgramiv, to reflect success or failure.
2625bd8deadSopenharmony_ci    Either command also updates its information log, queried with
2635bd8deadSopenharmony_ci    GetProgramInfoLog, to provide details about warnings or errors.
2645bd8deadSopenharmony_ci
2655bd8deadSopenharmony_ci    If ProgramBinaryOES failed, any information about a previous link or load of
2665bd8deadSopenharmony_ci    that program object is lost.  Thus, a failed load does not restore the old
2675bd8deadSopenharmony_ci    state of <program>.
2685bd8deadSopenharmony_ci
2695bd8deadSopenharmony_ci    Note that ProgramBinaryOES disregards any shader objects attached to the
2705bd8deadSopenharmony_ci    program object, as these shader objects are used only by LinkProgram.
2715bd8deadSopenharmony_ci
2725bd8deadSopenharmony_ci    Queries of values NUM_PROGRAM_BINARY_FORMATS and PROGRAM_BINARY_FORMATS
2735bd8deadSopenharmony_ci    return the number of program binary formats and the list of program binary
2745bd8deadSopenharmony_ci    format values supported by an implementation.  The <binaryFormat> returned
2755bd8deadSopenharmony_ci    by GetProgramBinaryOES must be present in this list."
2765bd8deadSopenharmony_ci
2775bd8deadSopenharmony_ciGLX Protocol
2785bd8deadSopenharmony_ci
2795bd8deadSopenharmony_ci    None.
2805bd8deadSopenharmony_ci
2815bd8deadSopenharmony_ciErrors
2825bd8deadSopenharmony_ci
2835bd8deadSopenharmony_ci    INVALID_OPERATION error is generated if GetProgramBinaryOES is called when
2845bd8deadSopenharmony_ci    the program object, <program>, does not contain a valid program binary as
2855bd8deadSopenharmony_ci    reflected by its LINK_STATUS state; if <bufSize> is not big enough to
2865bd8deadSopenharmony_ci    contain the entire program binary; or if the value of
2875bd8deadSopenharmony_ci    NUM_PROGRAM_BINARY_FORMATS is zero.
2885bd8deadSopenharmony_ci
2895bd8deadSopenharmony_ciNew State
2905bd8deadSopenharmony_ci
2915bd8deadSopenharmony_ci    (table 6.25, Program Object State) add the following:
2925bd8deadSopenharmony_ci
2935bd8deadSopenharmony_ci    Get Value                  Type  Get Command   Initial Value  Description               Section
2945bd8deadSopenharmony_ci    -------------              ----  -----------   -------------  -----------               -------
2955bd8deadSopenharmony_ci    PROGRAM_BINARY_LENGTH_OES  Z+    GetProgramiv  0              Length of program binary  2.15.4
2965bd8deadSopenharmony_ci
2975bd8deadSopenharmony_ci    (table 6.28, Implementation Dependent Values) add the following:
2985bd8deadSopenharmony_ci
2995bd8deadSopenharmony_ci    Get Value                       Type  Get Command  Minimum Value  Description                        Section
3005bd8deadSopenharmony_ci    -------------                   ----  -----------  -------------  -----------                        -------
3015bd8deadSopenharmony_ci    PROGRAM_BINARY_FORMATS_OES      0+*Z  GetIntegerv  N/A            Enumerated program binary formats  2.15.4
3025bd8deadSopenharmony_ci    NUM_PROGRAM_BINARY_FORMATS_OES  Z     GetIntegerv  0              Number of program binary formats   2.15.4
3035bd8deadSopenharmony_ci
3045bd8deadSopenharmony_ci    (table 6.29, Implementation Dependent Values (cont.)) add the following:
3055bd8deadSopenharmony_ci
3065bd8deadSopenharmony_ci    Get Value      Type  Get Command          Minimum Value  Description             Section
3075bd8deadSopenharmony_ci    -------------  ----  -----------          -------------  -----------             -------
3085bd8deadSopenharmony_ci    Binary format  Z1    GetProgramBinaryOES  N/A            Binary format returned  2.15.2
3095bd8deadSopenharmony_ci
3105bd8deadSopenharmony_ciSample Usage
3115bd8deadSopenharmony_ci
3125bd8deadSopenharmony_ci    void retrieveProgramBinary(const GLchar* vsSource, const GLchar* fsSource,
3135bd8deadSopenharmony_ci                               const char* myBinaryFileName,
3145bd8deadSopenharmony_ci                               GLenum* binaryFormat)
3155bd8deadSopenharmony_ci    {
3165bd8deadSopenharmony_ci        GLuint  newFS, newVS;
3175bd8deadSopenharmony_ci        GLuint  newProgram;
3185bd8deadSopenharmony_ci        GLchar* sources[1];
3195bd8deadSopenharmony_ci        GLint   success;
3205bd8deadSopenharmony_ci
3215bd8deadSopenharmony_ci        //
3225bd8deadSopenharmony_ci        //  Create new shader/program objects and attach them together.
3235bd8deadSopenharmony_ci        //
3245bd8deadSopenharmony_ci        newVS = glCreateShader(GL_VERTEX_SHADER);
3255bd8deadSopenharmony_ci        newFS = glCreateShader(GL_FRAGMENT_SHADER);
3265bd8deadSopenharmony_ci        newProgram = glCreateProgram();
3275bd8deadSopenharmony_ci        glAttachShader(newProgram, newVS);
3285bd8deadSopenharmony_ci        glAttachShader(newProgram, newFS);
3295bd8deadSopenharmony_ci
3305bd8deadSopenharmony_ci        //
3315bd8deadSopenharmony_ci        //  Supply GLSL source shaders, compile, and link them
3325bd8deadSopenharmony_ci        //
3335bd8deadSopenharmony_ci        sources[0] = vsSource;
3345bd8deadSopenharmony_ci        glShaderSource(newVS, 1, sources, NULL);
3355bd8deadSopenharmony_ci        glCompileShader(newVS);
3365bd8deadSopenharmony_ci
3375bd8deadSopenharmony_ci        sources[0] = fsSource;
3385bd8deadSopenharmony_ci        glShaderSource(newFS, 1, sources, NULL);
3395bd8deadSopenharmony_ci        glCompileShader(newFS);
3405bd8deadSopenharmony_ci
3415bd8deadSopenharmony_ci        glLinkProgram(newProgram);
3425bd8deadSopenharmony_ci        glGetProgramiv(newProgram, GL_LINK_STATUS, &success);
3435bd8deadSopenharmony_ci
3445bd8deadSopenharmony_ci        if (success)
3455bd8deadSopenharmony_ci        {
3465bd8deadSopenharmony_ci            GLint   binaryLength;
3475bd8deadSopenharmony_ci            void*   binary;
3485bd8deadSopenharmony_ci            FILE*   outfile;
3495bd8deadSopenharmony_ci
3505bd8deadSopenharmony_ci            //
3515bd8deadSopenharmony_ci            //  Retrieve the binary from the program object
3525bd8deadSopenharmony_ci            //
3535bd8deadSopenharmony_ci            glGetProgramiv(newProgram, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
3545bd8deadSopenharmony_ci            binary = (void*)malloc(binaryLength);
3555bd8deadSopenharmony_ci            glGetProgramBinaryOES(newProgram, binaryLength, NULL, binaryFormat, binary);
3565bd8deadSopenharmony_ci
3575bd8deadSopenharmony_ci            //
3585bd8deadSopenharmony_ci            //  Cache the program binary for future runs
3595bd8deadSopenharmony_ci            //
3605bd8deadSopenharmony_ci            outfile = fopen(myBinaryFileName, "wb");
3615bd8deadSopenharmony_ci            fwrite(binary, binaryLength, 1, outfile);
3625bd8deadSopenharmony_ci            fclose(outfile);
3635bd8deadSopenharmony_ci            free(binary);
3645bd8deadSopenharmony_ci        }
3655bd8deadSopenharmony_ci        else
3665bd8deadSopenharmony_ci        {
3675bd8deadSopenharmony_ci            //
3685bd8deadSopenharmony_ci            // Fallback to simpler source shaders?  Take my toys and go home?
3695bd8deadSopenharmony_ci            //
3705bd8deadSopenharmony_ci        }
3715bd8deadSopenharmony_ci
3725bd8deadSopenharmony_ci        //
3735bd8deadSopenharmony_ci        // Clean up
3745bd8deadSopenharmony_ci        //
3755bd8deadSopenharmony_ci        glDeleteShader(newVS);
3765bd8deadSopenharmony_ci        glDeleteShader(newFS);
3775bd8deadSopenharmony_ci        glDeleteProgram(newProgram);
3785bd8deadSopenharmony_ci    }
3795bd8deadSopenharmony_ci
3805bd8deadSopenharmony_ci    void loadProgramBinary(const char* myBinaryFileName, GLenum binaryFormat,
3815bd8deadSopenharmony_ci                           GLuint progObj)
3825bd8deadSopenharmony_ci    {
3835bd8deadSopenharmony_ci        GLint   binaryLength;
3845bd8deadSopenharmony_ci        void*   binary;
3855bd8deadSopenharmony_ci        GLint   success;
3865bd8deadSopenharmony_ci        FILE*   infile;
3875bd8deadSopenharmony_ci
3885bd8deadSopenharmony_ci        //
3895bd8deadSopenharmony_ci        //  Read the program binary
3905bd8deadSopenharmony_ci        //
3915bd8deadSopenharmony_ci        infile = fopen(myBinaryFileName, "rb");
3925bd8deadSopenharmony_ci        fseek(infile, 0, SEEK_END);
3935bd8deadSopenharmony_ci        binaryLength = (GLint)ftell(infile);
3945bd8deadSopenharmony_ci        binary = (void*)malloc(binaryLength);
3955bd8deadSopenharmony_ci        fseek(infile, 0, SEEK_SET);
3965bd8deadSopenharmony_ci        fread(binary, binaryLength, 1, infile);
3975bd8deadSopenharmony_ci        fclose(infile);
3985bd8deadSopenharmony_ci
3995bd8deadSopenharmony_ci        //
4005bd8deadSopenharmony_ci        //  Load the binary into the program object -- no need to link!
4015bd8deadSopenharmony_ci        //
4025bd8deadSopenharmony_ci        glProgramBinaryOES(progObj, binaryFormat, binary, binaryLength);
4035bd8deadSopenharmony_ci        free(binary);
4045bd8deadSopenharmony_ci
4055bd8deadSopenharmony_ci        glGetProgramiv(progObj, GL_LINK_STATUS, &success);
4065bd8deadSopenharmony_ci
4075bd8deadSopenharmony_ci        if (!success)
4085bd8deadSopenharmony_ci        {
4095bd8deadSopenharmony_ci            //
4105bd8deadSopenharmony_ci            // Something must have changed since the program binaries
4115bd8deadSopenharmony_ci            // were cached away.  Fallback to source shader loading path,
4125bd8deadSopenharmony_ci            // and then retrieve and cache new program binaries once again.
4135bd8deadSopenharmony_ci            //
4145bd8deadSopenharmony_ci        }
4155bd8deadSopenharmony_ci    }
4165bd8deadSopenharmony_ci
4175bd8deadSopenharmony_ciRevision History
4185bd8deadSopenharmony_ci
4195bd8deadSopenharmony_ci    #16    24/06/2020    Arthur Tombs    Fix typo: pass binaryLength by value
4205bd8deadSopenharmony_ci                                         instead of by pointer in example code
4215bd8deadSopenharmony_ci    #15    01/11/2019    Jon Leech       Add an error for ProgramBinary if there
4225bd8deadSopenharmony_ci                                         are no binary formats (Bug 16155).
4235bd8deadSopenharmony_ci    #14    10/08/2013    Jon Leech       Change GLvoid -> void (Bug 10412).
4245bd8deadSopenharmony_ci    #13    06/02/2008    Benj Lipchak    Fix typo: GLint -> int, update status.
4255bd8deadSopenharmony_ci    #12    05/07/2008    Benj Lipchak    Add Issue about BindAttribLocation.
4265bd8deadSopenharmony_ci    #11    04/03/2008    Benj Lipchak    Fix memory leaks in sample code.
4275bd8deadSopenharmony_ci    #10    03/27/2008    Benj Lipchak    Mark spec as ratified by the WG, add
4285bd8deadSopenharmony_ci                                         new issues, and update sample code.
4295bd8deadSopenharmony_ci    #09    03/13/2008    Benj Lipchak    Many minor updates!  Most notably,
4305bd8deadSopenharmony_ci                                         introduce PROGRAM_BINARY_FORMATS_OES
4315bd8deadSopenharmony_ci                                         and NUM_PROGRAM_BINARY_FORMATS_OES.
4325bd8deadSopenharmony_ci    #08    03/12/2008    Benj Lipchak    Rewrite as {Get}ProgramBinaryOES.  Add
4335bd8deadSopenharmony_ci                                         issues section.
4345bd8deadSopenharmony_ci    #07    02/27/2008    Benj Lipchak    When <bufSize> is too small, throw
4355bd8deadSopenharmony_ci                                         error and return 0 in <length>.  Limit
4365bd8deadSopenharmony_ci                                         the allowed reasons for subsequent
4375bd8deadSopenharmony_ci                                         binary rejection.  Rename to OES and
4385bd8deadSopenharmony_ci                                         GetShaderBinary.  Add the LinkProgram
4395bd8deadSopenharmony_ci                                         error condition.
4405bd8deadSopenharmony_ci    #06    01/10/2008    Benj Lipchak    Clarify that GetProgramInfoLog may be
4415bd8deadSopenharmony_ci                                         called after an implicit link, and
4425bd8deadSopenharmony_ci                                         clarify that the returned binary pair
4435bd8deadSopenharmony_ci                                         must be loaded with a single call to
4445bd8deadSopenharmony_ci                                         ShaderBinary or an error is thrown.
4455bd8deadSopenharmony_ci    #05    01/08/2008    Benj Lipchak    Clarify program object state after
4465bd8deadSopenharmony_ci                                         GetProgramBinaryEXT, fix example code.
4475bd8deadSopenharmony_ci    #04    01/02/2008    Benj Lipchak    Split GetProgramBinary into its own
4485bd8deadSopenharmony_ci                                         multi-vendor extension proposal.
4495bd8deadSopenharmony_ci    #03    11/26/2007    Benj Lipchak    Add sample usage and define tokens.
4505bd8deadSopenharmony_ci    #02    10/22/2007    Benj Lipchak    Add error conditions.
4515bd8deadSopenharmony_ci    #01    10/14/2007    Benj Lipchak    First draft.
452