    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.BufferObjects
    -- Copyright   :  (c) Sven Panne 2002-2019
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -- This module corresponds to section 2.9 (Buffer Objects) of the OpenGL 2.1
    -- specs.
    --
    --------------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.BufferObjects (
       -- * Buffer Objects
       BufferObject,

       -- * Binding Buffer Objects
       BufferTarget(..), bindBuffer, arrayBufferBinding,
       vertexAttribArrayBufferBinding,

       -- * Handling Buffer Data
       BufferUsage(..), bufferData, TransferDirection(..), bufferSubData,

       -- * Mapping Buffer Objects
       BufferAccess(..), MappingFailure(..), withMappedBuffer,
       mapBuffer, unmapBuffer,
       bufferAccess, bufferMapped,

       MapBufferUsage(..), Offset, Length,
       mapBufferRange, flushMappedBufferRange,

       -- * Indexed Buffer manipulation
       BufferIndex,
       RangeStartIndex, RangeSize,
       BufferRange,
       IndexedBufferTarget(..),
       bindBufferBase, bindBufferRange,
       indexedBufferStart, indexedBufferSize
    ) where

    import Control.Monad.IO.Class
    import Data.Maybe ( fromMaybe )
    import Data.ObjectName
    import Data.StateVar
    import Foreign.Marshal.Array ( allocaArray, peekArray, withArrayLen )
    import Foreign.Marshal.Utils ( with )
    import Foreign.Ptr ( Ptr, nullPtr )
    import Graphics.Rendering.OpenGL.GL.DebugOutput
    import Graphics.Rendering.OpenGL.GL.Exception
    import Graphics.Rendering.OpenGL.GL.GLboolean
    import Graphics.Rendering.OpenGL.GL.PeekPoke
    import Graphics.Rendering.OpenGL.GL.QueryUtils
    import Graphics.Rendering.OpenGL.GL.VertexArrays
    import Graphics.Rendering.OpenGL.GLU.ErrorsInternal
    import Graphics.GL

    --------------------------------------------------------------------------------

    newtype BufferObject = BufferObject { BufferObject -> GLuint
    bufferID :: GLuint }
       deriving ( BufferObject -> BufferObject -> Bool
    (BufferObject -> BufferObject -> Bool)
    -> (BufferObject -> BufferObject -> Bool) -> Eq BufferObject
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: BufferObject -> BufferObject -> Bool
    == :: BufferObject -> BufferObject -> Bool
    $c/= :: BufferObject -> BufferObject -> Bool
    /= :: BufferObject -> BufferObject -> Bool
    Eq, Eq BufferObject
    Eq BufferObject =>
    (BufferObject -> BufferObject -> Ordering)
    -> (BufferObject -> BufferObject -> Bool)
    -> (BufferObject -> BufferObject -> Bool)
    -> (BufferObject -> BufferObject -> Bool)
    -> (BufferObject -> BufferObject -> Bool)
    -> (BufferObject -> BufferObject -> BufferObject)
    -> (BufferObject -> BufferObject -> BufferObject)
    -> Ord BufferObject
    BufferObject -> BufferObject -> Bool
    BufferObject -> BufferObject -> Ordering
    BufferObject -> BufferObject -> BufferObject
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: BufferObject -> BufferObject -> Ordering
    compare :: BufferObject -> BufferObject -> Ordering
    $c< :: BufferObject -> BufferObject -> Bool
    < :: BufferObject -> BufferObject -> Bool
    $c<= :: BufferObject -> BufferObject -> Bool
    <= :: BufferObject -> BufferObject -> Bool
    $c> :: BufferObject -> BufferObject -> Bool
    > :: BufferObject -> BufferObject -> Bool
    $c>= :: BufferObject -> BufferObject -> Bool
    >= :: BufferObject -> BufferObject -> Bool
    $cmax :: BufferObject -> BufferObject -> BufferObject
    max :: BufferObject -> BufferObject -> BufferObject
    $cmin :: BufferObject -> BufferObject -> BufferObject
    min :: BufferObject -> BufferObject -> BufferObject
    Ord, Int -> BufferObject -> ShowS
    [BufferObject] -> ShowS
    BufferObject -> String
    (Int -> BufferObject -> ShowS)
    -> (BufferObject -> String)
    -> ([BufferObject] -> ShowS)
    -> Show BufferObject
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> BufferObject -> ShowS
    showsPrec :: Int -> BufferObject -> ShowS
    $cshow :: BufferObject -> String
    show :: BufferObject -> String
    $cshowList :: [BufferObject] -> ShowS
    showList :: [BufferObject] -> ShowS
    Show )

    --------------------------------------------------------------------------------

    instance ObjectName BufferObject where
       isObjectName :: forall (m :: * -> *). MonadIO m => BufferObject -> m Bool
    isObjectName = IO Bool -> m Bool
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Bool -> m Bool)
    -> (BufferObject -> IO Bool) -> BufferObject -> m Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GLboolean -> Bool) -> IO GLboolean -> IO Bool
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap GLboolean -> Bool
    forall a. (Eq a, Num a) => a -> Bool
    unmarshalGLboolean (IO GLboolean -> IO Bool)
    -> (BufferObject -> IO GLboolean) -> BufferObject -> IO Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLuint -> IO GLboolean
    forall (m :: * -> *). MonadIO m => GLuint -> m GLboolean
    glIsBuffer (GLuint -> IO GLboolean)
    -> (BufferObject -> GLuint) -> BufferObject -> IO GLboolean
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferObject -> GLuint
    bufferID

       deleteObjectNames :: forall (m :: * -> *). MonadIO m => [BufferObject] -> m ()
    deleteObjectNames [BufferObject]
    bufferObjects =
          IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ())
    -> ((Int -> Ptr GLuint -> IO ()) -> IO ())
    -> (Int -> Ptr GLuint -> IO ())
    -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [GLuint] -> (Int -> Ptr GLuint -> IO ()) -> IO ()
    forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
    withArrayLen ((BufferObject -> GLuint) -> [BufferObject] -> [GLuint]
    forall a b. (a -> b) -> [a] -> [b]
    map BufferObject -> GLuint
    bufferID [BufferObject]
    bufferObjects) ((Int -> Ptr GLuint -> IO ()) -> m ())
    -> (Int -> Ptr GLuint -> IO ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $
             GLint -> Ptr GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLint -> Ptr GLuint -> m ()
    glDeleteBuffers (GLint -> Ptr GLuint -> IO ())
    -> (Int -> GLint) -> Int -> Ptr GLuint -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> GLint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    instance GeneratableObjectName BufferObject where
       genObjectNames :: forall (m :: * -> *). MonadIO m => Int -> m [BufferObject]
    genObjectNames Int
    n =
          IO [BufferObject] -> m [BufferObject]
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO [BufferObject] -> m [BufferObject])
    -> ((Ptr GLuint -> IO [BufferObject]) -> IO [BufferObject])
    -> (Ptr GLuint -> IO [BufferObject])
    -> m [BufferObject]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> (Ptr GLuint -> IO [BufferObject]) -> IO [BufferObject]
    forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
    allocaArray Int
    n ((Ptr GLuint -> IO [BufferObject]) -> m [BufferObject])
    -> (Ptr GLuint -> IO [BufferObject]) -> m [BufferObject]
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLuint
    buf -> do
            GLint -> Ptr GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLint -> Ptr GLuint -> m ()
    glGenBuffers (Int -> GLint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n) Ptr GLuint
    buf
            ([GLuint] -> [BufferObject]) -> IO [GLuint] -> IO [BufferObject]
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((GLuint -> BufferObject) -> [GLuint] -> [BufferObject]
    forall a b. (a -> b) -> [a] -> [b]
    map GLuint -> BufferObject
    BufferObject) (IO [GLuint] -> IO [BufferObject])
    -> IO [GLuint] -> IO [BufferObject]
    forall a b. (a -> b) -> a -> b
    $ Int -> Ptr GLuint -> IO [GLuint]
    forall a. Storable a => Int -> Ptr a -> IO [a]
    peekArray Int
    n Ptr GLuint
    buf

    instance CanBeLabeled BufferObject where
       objectLabel :: BufferObject -> StateVar (Maybe String)
    objectLabel = GLuint -> GLuint -> StateVar (Maybe String)
    objectNameLabel GLuint
    GL_BUFFER (GLuint -> StateVar (Maybe String))
    -> (BufferObject -> GLuint)
    -> BufferObject
    -> StateVar (Maybe String)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferObject -> GLuint
    bufferID

    --------------------------------------------------------------------------------

    data BufferTarget =
         ArrayBuffer
       | AtomicCounterBuffer
       | CopyReadBuffer
       | CopyWriteBuffer
       | DispatchIndirectBuffer
       | DrawIndirectBuffer
       | ElementArrayBuffer
       | PixelPackBuffer
       | PixelUnpackBuffer
       | QueryBuffer
       | ShaderStorageBuffer
       | TextureBuffer
       | TransformFeedbackBuffer
       | UniformBuffer
       deriving ( BufferTarget -> BufferTarget -> Bool
    (BufferTarget -> BufferTarget -> Bool)
    -> (BufferTarget -> BufferTarget -> Bool) -> Eq BufferTarget
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: BufferTarget -> BufferTarget -> Bool
    == :: BufferTarget -> BufferTarget -> Bool
    $c/= :: BufferTarget -> BufferTarget -> Bool
    /= :: BufferTarget -> BufferTarget -> Bool
    Eq, Eq BufferTarget
    Eq BufferTarget =>
    (BufferTarget -> BufferTarget -> Ordering)
    -> (BufferTarget -> BufferTarget -> Bool)
    -> (BufferTarget -> BufferTarget -> Bool)
    -> (BufferTarget -> BufferTarget -> Bool)
    -> (BufferTarget -> BufferTarget -> Bool)
    -> (BufferTarget -> BufferTarget -> BufferTarget)
    -> (BufferTarget -> BufferTarget -> BufferTarget)
    -> Ord BufferTarget
    BufferTarget -> BufferTarget -> Bool
    BufferTarget -> BufferTarget -> Ordering
    BufferTarget -> BufferTarget -> BufferTarget
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: BufferTarget -> BufferTarget -> Ordering
    compare :: BufferTarget -> BufferTarget -> Ordering
    $c< :: BufferTarget -> BufferTarget -> Bool
    < :: BufferTarget -> BufferTarget -> Bool
    $c<= :: BufferTarget -> BufferTarget -> Bool
    <= :: BufferTarget -> BufferTarget -> Bool
    $c> :: BufferTarget -> BufferTarget -> Bool
    > :: BufferTarget -> BufferTarget -> Bool
    $c>= :: BufferTarget -> BufferTarget -> Bool
    >= :: BufferTarget -> BufferTarget -> Bool
    $cmax :: BufferTarget -> BufferTarget -> BufferTarget
    max :: BufferTarget -> BufferTarget -> BufferTarget
    $cmin :: BufferTarget -> BufferTarget -> BufferTarget
    min :: BufferTarget -> BufferTarget -> BufferTarget
    Ord, Int -> BufferTarget -> ShowS
    [BufferTarget] -> ShowS
    BufferTarget -> String
    (Int -> BufferTarget -> ShowS)
    -> (BufferTarget -> String)
    -> ([BufferTarget] -> ShowS)
    -> Show BufferTarget
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> BufferTarget -> ShowS
    showsPrec :: Int -> BufferTarget -> ShowS
    $cshow :: BufferTarget -> String
    show :: BufferTarget -> String
    $cshowList :: [BufferTarget] -> ShowS
    showList :: [BufferTarget] -> ShowS
    Show )

    marshalBufferTarget :: BufferTarget -> GLenum
    marshalBufferTarget :: BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    x = case BufferTarget
    x of
       BufferTarget
    ArrayBuffer -> GLuint
    GL_ARRAY_BUFFER
       BufferTarget
    AtomicCounterBuffer -> GLuint
    GL_ATOMIC_COUNTER_BUFFER
       BufferTarget
    CopyReadBuffer -> GLuint
    GL_COPY_READ_BUFFER
       BufferTarget
    CopyWriteBuffer -> GLuint
    GL_COPY_WRITE_BUFFER
       BufferTarget
    DispatchIndirectBuffer -> GLuint
    GL_DISPATCH_INDIRECT_BUFFER
       BufferTarget
    DrawIndirectBuffer -> GLuint
    GL_DRAW_INDIRECT_BUFFER
       BufferTarget
    ElementArrayBuffer -> GLuint
    GL_ELEMENT_ARRAY_BUFFER
       BufferTarget
    PixelPackBuffer -> GLuint
    GL_PIXEL_PACK_BUFFER
       BufferTarget
    PixelUnpackBuffer -> GLuint
    GL_PIXEL_UNPACK_BUFFER
       BufferTarget
    QueryBuffer -> GLuint
    GL_QUERY_BUFFER
       BufferTarget
    ShaderStorageBuffer -> GLuint
    GL_SHADER_STORAGE_BUFFER
       BufferTarget
    TextureBuffer -> GLuint
    GL_TEXTURE_BUFFER
       BufferTarget
    TransformFeedbackBuffer -> GLuint
    GL_TRANSFORM_FEEDBACK_BUFFER
       BufferTarget
    UniformBuffer -> GLuint
    GL_UNIFORM_BUFFER

    bufferTargetToGetPName :: BufferTarget -> PName1I
    bufferTargetToGetPName :: BufferTarget -> PName1I
    bufferTargetToGetPName BufferTarget
    x = case BufferTarget
    x of
       BufferTarget
    ArrayBuffer -> PName1I
    GetArrayBufferBinding
       BufferTarget
    AtomicCounterBuffer -> PName1I
    GetAtomicCounterBufferBinding
       BufferTarget
    CopyReadBuffer -> PName1I
    GetCopyReadBufferBinding
       BufferTarget
    CopyWriteBuffer -> PName1I
    GetCopyWriteBufferBinding
       BufferTarget
    DispatchIndirectBuffer -> PName1I
    GetDispatchIndirectBufferBinding
       BufferTarget
    DrawIndirectBuffer -> PName1I
    GetDrawIndirectBufferBinding
       BufferTarget
    ElementArrayBuffer -> PName1I
    GetElementArrayBufferBinding
       BufferTarget
    PixelPackBuffer -> PName1I
    GetPixelPackBufferBinding
       BufferTarget
    PixelUnpackBuffer -> PName1I
    GetPixelUnpackBufferBinding
       BufferTarget
    QueryBuffer -> PName1I
    GetQueryBufferBinding
       BufferTarget
    ShaderStorageBuffer -> PName1I
    GetShaderStorageBufferBinding
       BufferTarget
    TextureBuffer -> PName1I
    GetTextureBindingBuffer
       BufferTarget
    TransformFeedbackBuffer -> PName1I
    GetTransformFeedbackBufferBinding
       BufferTarget
    UniformBuffer -> PName1I
    GetUniformBufferBinding

    --------------------------------------------------------------------------------

    data BufferUsage =
         StreamDraw
       | StreamRead
       | StreamCopy
       | StaticDraw
       | StaticRead
       | StaticCopy
       | DynamicDraw
       | DynamicRead
       | DynamicCopy
       deriving ( BufferUsage -> BufferUsage -> Bool
    (BufferUsage -> BufferUsage -> Bool)
    -> (BufferUsage -> BufferUsage -> Bool) -> Eq BufferUsage
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: BufferUsage -> BufferUsage -> Bool
    == :: BufferUsage -> BufferUsage -> Bool
    $c/= :: BufferUsage -> BufferUsage -> Bool
    /= :: BufferUsage -> BufferUsage -> Bool
    Eq, Eq BufferUsage
    Eq BufferUsage =>
    (BufferUsage -> BufferUsage -> Ordering)
    -> (BufferUsage -> BufferUsage -> Bool)
    -> (BufferUsage -> BufferUsage -> Bool)
    -> (BufferUsage -> BufferUsage -> Bool)
    -> (BufferUsage -> BufferUsage -> Bool)
    -> (BufferUsage -> BufferUsage -> BufferUsage)
    -> (BufferUsage -> BufferUsage -> BufferUsage)
    -> Ord BufferUsage
    BufferUsage -> BufferUsage -> Bool
    BufferUsage -> BufferUsage -> Ordering
    BufferUsage -> BufferUsage -> BufferUsage
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: BufferUsage -> BufferUsage -> Ordering
    compare :: BufferUsage -> BufferUsage -> Ordering
    $c< :: BufferUsage -> BufferUsage -> Bool
    < :: BufferUsage -> BufferUsage -> Bool
    $c<= :: BufferUsage -> BufferUsage -> Bool
    <= :: BufferUsage -> BufferUsage -> Bool
    $c> :: BufferUsage -> BufferUsage -> Bool
    > :: BufferUsage -> BufferUsage -> Bool
    $c>= :: BufferUsage -> BufferUsage -> Bool
    >= :: BufferUsage -> BufferUsage -> Bool
    $cmax :: BufferUsage -> BufferUsage -> BufferUsage
    max :: BufferUsage -> BufferUsage -> BufferUsage
    $cmin :: BufferUsage -> BufferUsage -> BufferUsage
    min :: BufferUsage -> BufferUsage -> BufferUsage
    Ord, Int -> BufferUsage -> ShowS
    [BufferUsage] -> ShowS
    BufferUsage -> String
    (Int -> BufferUsage -> ShowS)
    -> (BufferUsage -> String)
    -> ([BufferUsage] -> ShowS)
    -> Show BufferUsage
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> BufferUsage -> ShowS
    showsPrec :: Int -> BufferUsage -> ShowS
    $cshow :: BufferUsage -> String
    show :: BufferUsage -> String
    $cshowList :: [BufferUsage] -> ShowS
    showList :: [BufferUsage] -> ShowS
    Show )

    marshalBufferUsage :: BufferUsage -> GLenum
    marshalBufferUsage :: BufferUsage -> GLuint
    marshalBufferUsage BufferUsage
    x = case BufferUsage
    x of
       BufferUsage
    StreamDraw -> GLuint
    GL_STREAM_DRAW
       BufferUsage
    StreamRead -> GLuint
    GL_STREAM_READ
       BufferUsage
    StreamCopy -> GLuint
    GL_STREAM_COPY
       BufferUsage
    StaticDraw -> GLuint
    GL_STATIC_DRAW
       BufferUsage
    StaticRead -> GLuint
    GL_STATIC_READ
       BufferUsage
    StaticCopy -> GLuint
    GL_STATIC_COPY
       BufferUsage
    DynamicDraw -> GLuint
    GL_DYNAMIC_DRAW
       BufferUsage
    DynamicRead -> GLuint
    GL_DYNAMIC_READ
       BufferUsage
    DynamicCopy -> GLuint
    GL_DYNAMIC_COPY

    unmarshalBufferUsage :: GLenum -> BufferUsage
    unmarshalBufferUsage :: GLuint -> BufferUsage
    unmarshalBufferUsage GLuint
    x
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_STREAM_DRAW = BufferUsage
    StreamDraw
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_STREAM_READ = BufferUsage
    StreamRead
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_STREAM_COPY = BufferUsage
    StreamCopy
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_STATIC_DRAW = BufferUsage
    StaticDraw
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_STATIC_READ = BufferUsage
    StaticRead
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_STATIC_COPY = BufferUsage
    StaticCopy
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_DYNAMIC_DRAW = BufferUsage
    DynamicDraw
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_DYNAMIC_READ = BufferUsage
    DynamicRead
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_DYNAMIC_COPY = BufferUsage
    DynamicCopy
       | Bool
    otherwise = String -> BufferUsage
    forall a. HasCallStack => String -> a
    error (String
    "unmarshalBufferUsage: illegal value " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ GLuint -> String
    forall a. Show a => a -> String
    show GLuint
    x)

    --------------------------------------------------------------------------------

    data BufferAccess =
         ReadOnly
       | WriteOnly
       | ReadWrite
       deriving ( BufferAccess -> BufferAccess -> Bool
    (BufferAccess -> BufferAccess -> Bool)
    -> (BufferAccess -> BufferAccess -> Bool) -> Eq BufferAccess
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: BufferAccess -> BufferAccess -> Bool
    == :: BufferAccess -> BufferAccess -> Bool
    $c/= :: BufferAccess -> BufferAccess -> Bool
    /= :: BufferAccess -> BufferAccess -> Bool
    Eq, Eq BufferAccess
    Eq BufferAccess =>
    (BufferAccess -> BufferAccess -> Ordering)
    -> (BufferAccess -> BufferAccess -> Bool)
    -> (BufferAccess -> BufferAccess -> Bool)
    -> (BufferAccess -> BufferAccess -> Bool)
    -> (BufferAccess -> BufferAccess -> Bool)
    -> (BufferAccess -> BufferAccess -> BufferAccess)
    -> (BufferAccess -> BufferAccess -> BufferAccess)
    -> Ord BufferAccess
    BufferAccess -> BufferAccess -> Bool
    BufferAccess -> BufferAccess -> Ordering
    BufferAccess -> BufferAccess -> BufferAccess
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: BufferAccess -> BufferAccess -> Ordering
    compare :: BufferAccess -> BufferAccess -> Ordering
    $c< :: BufferAccess -> BufferAccess -> Bool
    < :: BufferAccess -> BufferAccess -> Bool
    $c<= :: BufferAccess -> BufferAccess -> Bool
    <= :: BufferAccess -> BufferAccess -> Bool
    $c> :: BufferAccess -> BufferAccess -> Bool
    > :: BufferAccess -> BufferAccess -> Bool
    $c>= :: BufferAccess -> BufferAccess -> Bool
    >= :: BufferAccess -> BufferAccess -> Bool
    $cmax :: BufferAccess -> BufferAccess -> BufferAccess
    max :: BufferAccess -> BufferAccess -> BufferAccess
    $cmin :: BufferAccess -> BufferAccess -> BufferAccess
    min :: BufferAccess -> BufferAccess -> BufferAccess
    Ord, Int -> BufferAccess -> ShowS
    [BufferAccess] -> ShowS
    BufferAccess -> String
    (Int -> BufferAccess -> ShowS)
    -> (BufferAccess -> String)
    -> ([BufferAccess] -> ShowS)
    -> Show BufferAccess
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> BufferAccess -> ShowS
    showsPrec :: Int -> BufferAccess -> ShowS
    $cshow :: BufferAccess -> String
    show :: BufferAccess -> String
    $cshowList :: [BufferAccess] -> ShowS
    showList :: [BufferAccess] -> ShowS
    Show )

    marshalBufferAccess :: BufferAccess -> GLenum
    marshalBufferAccess :: BufferAccess -> GLuint
    marshalBufferAccess BufferAccess
    x = case BufferAccess
    x of
       BufferAccess
    ReadOnly -> GLuint
    GL_READ_ONLY
       BufferAccess
    WriteOnly -> GLuint
    GL_WRITE_ONLY
       BufferAccess
    ReadWrite -> GLuint
    GL_READ_WRITE

    unmarshalBufferAccess :: GLenum -> BufferAccess
    unmarshalBufferAccess :: GLuint -> BufferAccess
    unmarshalBufferAccess GLuint
    x
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_READ_ONLY = BufferAccess
    ReadOnly
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_WRITE_ONLY = BufferAccess
    WriteOnly
       | GLuint
    x GLuint -> GLuint -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLuint
    GL_READ_WRITE = BufferAccess
    ReadWrite
       | Bool
    otherwise = String -> BufferAccess
    forall a. HasCallStack => String -> a
    error (String
    "unmarshalBufferAccess: illegal value " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ GLuint -> String
    forall a. Show a => a -> String
    show GLuint
    x)

    --------------------------------------------------------------------------------

    bindBuffer :: BufferTarget -> StateVar (Maybe BufferObject)
    bindBuffer :: BufferTarget -> StateVar (Maybe BufferObject)
    bindBuffer BufferTarget
    t = IO (Maybe BufferObject)
    -> (Maybe BufferObject -> IO ()) -> StateVar (Maybe BufferObject)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (BufferTarget -> IO (Maybe BufferObject)
    getBindBuffer BufferTarget
    t) (BufferTarget -> Maybe BufferObject -> IO ()
    setBindBuffer BufferTarget
    t)

    getBindBuffer :: BufferTarget -> IO (Maybe BufferObject)
    getBindBuffer :: BufferTarget -> IO (Maybe BufferObject)
    getBindBuffer = (BufferTarget -> PName1I)
    -> BufferTarget -> IO (Maybe BufferObject)
    forall a. (a -> PName1I) -> a -> IO (Maybe BufferObject)
    bufferQuery BufferTarget -> PName1I
    bufferTargetToGetPName

    bufferQuery :: (a -> PName1I) -> a -> IO (Maybe BufferObject)
    bufferQuery :: forall a. (a -> PName1I) -> a -> IO (Maybe BufferObject)
    bufferQuery a -> PName1I
    func a
    t = do
       buf <- (GLint -> BufferObject) -> PName1I -> IO BufferObject
    forall p a. GetPName1I p => (GLint -> a) -> p -> IO a
    forall a. (GLint -> a) -> PName1I -> IO a
    getInteger1 (GLuint -> BufferObject
    BufferObject (GLuint -> BufferObject)
    -> (GLint -> GLuint) -> GLint -> BufferObject
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral) (a -> PName1I
    func a
    t)
       return $ if buf == noBufferObject then Nothing else Just buf

    noBufferObject :: BufferObject
    noBufferObject :: BufferObject
    noBufferObject = GLuint -> BufferObject
    BufferObject GLuint
    0

    setBindBuffer :: BufferTarget -> Maybe BufferObject -> IO ()
    setBindBuffer :: BufferTarget -> Maybe BufferObject -> IO ()
    setBindBuffer BufferTarget
    t =
       GLuint -> GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> GLuint -> m ()
    glBindBuffer (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t) (GLuint -> IO ())
    -> (Maybe BufferObject -> GLuint) -> Maybe BufferObject -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferObject -> GLuint
    bufferID (BufferObject -> GLuint)
    -> (Maybe BufferObject -> BufferObject)
    -> Maybe BufferObject
    -> GLuint
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferObject -> Maybe BufferObject -> BufferObject
    forall a. a -> Maybe a -> a
    fromMaybe BufferObject
    noBufferObject

    clientArrayTypeToGetPName :: ClientArrayType -> PName1I
    clientArrayTypeToGetPName :: ClientArrayType -> PName1I
    clientArrayTypeToGetPName ClientArrayType
    x = case ClientArrayType
    x of
       ClientArrayType
    VertexArray -> PName1I
    GetVertexArrayBufferBinding
       ClientArrayType
    NormalArray -> PName1I
    GetNormalArrayBufferBinding
       ClientArrayType
    ColorArray -> PName1I
    GetColorArrayBufferBinding
       ClientArrayType
    IndexArray -> PName1I
    GetIndexArrayBufferBinding
       ClientArrayType
    TextureCoordArray -> PName1I
    GetTextureCoordArrayBufferBinding
       ClientArrayType
    EdgeFlagArray -> PName1I
    GetEdgeFlagArrayBufferBinding
       ClientArrayType
    FogCoordArray -> PName1I
    GetFogCoordArrayBufferBinding
       ClientArrayType
    SecondaryColorArray -> PName1I
    GetSecondaryColorArrayBufferBinding
       ClientArrayType
    MatrixIndexArray -> String -> PName1I
    forall a. HasCallStack => String -> a
    error String
    "clientArrayTypeToGetPName: impossible"

    arrayBufferBinding :: ClientArrayType -> GettableStateVar (Maybe BufferObject)
    arrayBufferBinding :: ClientArrayType -> IO (Maybe BufferObject)
    arrayBufferBinding ClientArrayType
    t =
       IO (Maybe BufferObject) -> IO (Maybe BufferObject)
    forall a. IO a -> IO a
    makeGettableStateVar (IO (Maybe BufferObject) -> IO (Maybe BufferObject))
    -> IO (Maybe BufferObject) -> IO (Maybe BufferObject)
    forall a b. (a -> b) -> a -> b
    $ case ClientArrayType
    t of
          ClientArrayType
    MatrixIndexArray -> do IO ()
    recordInvalidEnum ; Maybe BufferObject -> IO (Maybe BufferObject)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe BufferObject
    forall a. Maybe a
    Nothing
          ClientArrayType
    _ -> (ClientArrayType -> PName1I)
    -> ClientArrayType -> IO (Maybe BufferObject)
    forall a. (a -> PName1I) -> a -> IO (Maybe BufferObject)
    bufferQuery ClientArrayType -> PName1I
    clientArrayTypeToGetPName ClientArrayType
    t

    vertexAttribArrayBufferBinding :: AttribLocation -> GettableStateVar (Maybe BufferObject)
    vertexAttribArrayBufferBinding :: AttribLocation -> IO (Maybe BufferObject)
    vertexAttribArrayBufferBinding AttribLocation
    location =
       IO (Maybe BufferObject) -> IO (Maybe BufferObject)
    forall a. IO a -> IO a
    makeGettableStateVar (IO (Maybe BufferObject) -> IO (Maybe BufferObject))
    -> IO (Maybe BufferObject) -> IO (Maybe BufferObject)
    forall a b. (a -> b) -> a -> b
    $ do
          buf <- (GLint -> BufferObject)
    -> AttribLocation -> GetVertexAttribPName -> IO BufferObject
    forall b.
    (GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribInteger1 (GLuint -> BufferObject
    BufferObject (GLuint -> BufferObject)
    -> (GLint -> GLuint) -> GLint -> BufferObject
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral) AttribLocation
    location GetVertexAttribPName
    GetVertexAttribArrayBufferBinding
          return $ if buf == noBufferObject then Nothing else Just buf

    --------------------------------------------------------------------------------

    bufferData :: BufferTarget -> StateVar (GLsizeiptr, Ptr a, BufferUsage)
    bufferData :: forall a.
    BufferTarget -> StateVar (RangeStartIndex, Ptr a, BufferUsage)
    bufferData BufferTarget
    t = IO (RangeStartIndex, Ptr a, BufferUsage)
    -> ((RangeStartIndex, Ptr a, BufferUsage) -> IO ())
    -> StateVar (RangeStartIndex, Ptr a, BufferUsage)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (BufferTarget -> IO (RangeStartIndex, Ptr a, BufferUsage)
    forall a. BufferTarget -> IO (RangeStartIndex, Ptr a, BufferUsage)
    getBufferData BufferTarget
    t) (BufferTarget -> (RangeStartIndex, Ptr a, BufferUsage) -> IO ()
    forall a.
    BufferTarget -> (RangeStartIndex, Ptr a, BufferUsage) -> IO ()
    setBufferData BufferTarget
    t)

    getBufferData :: BufferTarget -> IO (GLsizeiptr, Ptr a, BufferUsage)
    getBufferData :: forall a. BufferTarget -> IO (RangeStartIndex, Ptr a, BufferUsage)
    getBufferData BufferTarget
    t = do
       s <- BufferTarget
    -> (GLuint -> RangeStartIndex)
    -> GetBufferPName
    -> GettableStateVar RangeStartIndex
    forall a. BufferTarget -> (GLuint -> a) -> GetBufferPName -> IO a
    getBufferParameter BufferTarget
    t GLuint -> RangeStartIndex
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GetBufferPName
    GetBufferSize
       p <- getBufferPointer t
       u <- getBufferParameter t unmarshalBufferUsage GetBufferUsage
       return (s, p, u)

    setBufferData :: BufferTarget -> (GLsizeiptr, Ptr a, BufferUsage) -> IO ()
    setBufferData :: forall a.
    BufferTarget -> (RangeStartIndex, Ptr a, BufferUsage) -> IO ()
    setBufferData BufferTarget
    t (RangeStartIndex
    s, Ptr a
    p, BufferUsage
    u) =
       GLuint -> RangeStartIndex -> Ptr a -> GLuint -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> RangeStartIndex -> Ptr a -> GLuint -> m ()
    glBufferData (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t) RangeStartIndex
    s Ptr a
    p (BufferUsage -> GLuint
    marshalBufferUsage BufferUsage
    u)

    --------------------------------------------------------------------------------

    data TransferDirection =
         ReadFromBuffer
       | WriteToBuffer
       deriving ( TransferDirection -> TransferDirection -> Bool
    (TransferDirection -> TransferDirection -> Bool)
    -> (TransferDirection -> TransferDirection -> Bool)
    -> Eq TransferDirection
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TransferDirection -> TransferDirection -> Bool
    == :: TransferDirection -> TransferDirection -> Bool
    $c/= :: TransferDirection -> TransferDirection -> Bool
    /= :: TransferDirection -> TransferDirection -> Bool
    Eq, Eq TransferDirection
    Eq TransferDirection =>
    (TransferDirection -> TransferDirection -> Ordering)
    -> (TransferDirection -> TransferDirection -> Bool)
    -> (TransferDirection -> TransferDirection -> Bool)
    -> (TransferDirection -> TransferDirection -> Bool)
    -> (TransferDirection -> TransferDirection -> Bool)
    -> (TransferDirection -> TransferDirection -> TransferDirection)
    -> (TransferDirection -> TransferDirection -> TransferDirection)
    -> Ord TransferDirection
    TransferDirection -> TransferDirection -> Bool
    TransferDirection -> TransferDirection -> Ordering
    TransferDirection -> TransferDirection -> TransferDirection
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: TransferDirection -> TransferDirection -> Ordering
    compare :: TransferDirection -> TransferDirection -> Ordering
    $c< :: TransferDirection -> TransferDirection -> Bool
    < :: TransferDirection -> TransferDirection -> Bool
    $c<= :: TransferDirection -> TransferDirection -> Bool
    <= :: TransferDirection -> TransferDirection -> Bool
    $c> :: TransferDirection -> TransferDirection -> Bool
    > :: TransferDirection -> TransferDirection -> Bool
    $c>= :: TransferDirection -> TransferDirection -> Bool
    >= :: TransferDirection -> TransferDirection -> Bool
    $cmax :: TransferDirection -> TransferDirection -> TransferDirection
    max :: TransferDirection -> TransferDirection -> TransferDirection
    $cmin :: TransferDirection -> TransferDirection -> TransferDirection
    min :: TransferDirection -> TransferDirection -> TransferDirection
    Ord, Int -> TransferDirection -> ShowS
    [TransferDirection] -> ShowS
    TransferDirection -> String
    (Int -> TransferDirection -> ShowS)
    -> (TransferDirection -> String)
    -> ([TransferDirection] -> ShowS)
    -> Show TransferDirection
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> TransferDirection -> ShowS
    showsPrec :: Int -> TransferDirection -> ShowS
    $cshow :: TransferDirection -> String
    show :: TransferDirection -> String
    $cshowList :: [TransferDirection] -> ShowS
    showList :: [TransferDirection] -> ShowS
    Show )

    bufferSubData ::
       BufferTarget -> TransferDirection -> GLintptr -> GLsizeiptr -> Ptr a -> IO ()
    bufferSubData :: forall a.
    BufferTarget
    -> TransferDirection
    -> RangeStartIndex
    -> RangeStartIndex
    -> Ptr a
    -> IO ()
    bufferSubData BufferTarget
    t TransferDirection
    WriteToBuffer = GLuint -> RangeStartIndex -> RangeStartIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> RangeStartIndex -> RangeStartIndex -> Ptr a -> m ()
    glBufferSubData (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t)
    bufferSubData BufferTarget
    t TransferDirection
    ReadFromBuffer = GLuint -> RangeStartIndex -> RangeStartIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> RangeStartIndex -> RangeStartIndex -> Ptr a -> m ()
    glGetBufferSubData (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t)

    --------------------------------------------------------------------------------

    data GetBufferPName =
         GetBufferSize
       | GetBufferUsage
       | GetBufferAccess
       | GetBufferMapped

    marshalGetBufferPName :: GetBufferPName -> GLenum
    marshalGetBufferPName :: GetBufferPName -> GLuint
    marshalGetBufferPName GetBufferPName
    x = case GetBufferPName
    x of
       GetBufferPName
    GetBufferSize -> GLuint
    GL_BUFFER_SIZE
       GetBufferPName
    GetBufferUsage -> GLuint
    GL_BUFFER_USAGE
       GetBufferPName
    GetBufferAccess -> GLuint
    GL_BUFFER_ACCESS
       GetBufferPName
    GetBufferMapped -> GLuint
    GL_BUFFER_MAPPED

    getBufferParameter :: BufferTarget -> (GLenum -> a) -> GetBufferPName -> IO a
    getBufferParameter :: forall a. BufferTarget -> (GLuint -> a) -> GetBufferPName -> IO a
    getBufferParameter BufferTarget
    t GLuint -> a
    f GetBufferPName
    p = GLint -> (Ptr GLint -> IO a) -> IO a
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with GLint
    0 ((Ptr GLint -> IO a) -> IO a) -> (Ptr GLint -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    buf -> do
       GLuint -> GLuint -> Ptr GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> GLuint -> Ptr GLint -> m ()
    glGetBufferParameteriv (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t)
                              (GetBufferPName -> GLuint
    marshalGetBufferPName GetBufferPName
    p) Ptr GLint
    buf
       (GLint -> a) -> Ptr GLint -> IO a
    forall a b. Storable a => (a -> b) -> Ptr a -> IO b
    peek1 (GLuint -> a
    f (GLuint -> a) -> (GLint -> GLuint) -> GLint -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral) Ptr GLint
    buf

    --------------------------------------------------------------------------------

    getBufferPointer :: BufferTarget -> IO (Ptr a)
    getBufferPointer :: forall a. BufferTarget -> IO (Ptr a)
    getBufferPointer BufferTarget
    t = Ptr a -> (Ptr (Ptr a) -> IO (Ptr a)) -> IO (Ptr a)
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with Ptr a
    forall a. Ptr a
    nullPtr ((Ptr (Ptr a) -> IO (Ptr a)) -> IO (Ptr a))
    -> (Ptr (Ptr a) -> IO (Ptr a)) -> IO (Ptr a)
    forall a b. (a -> b) -> a -> b
    $ \Ptr (Ptr a)
    buf -> do
       GLuint -> GLuint -> Ptr (Ptr a) -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> GLuint -> Ptr (Ptr a) -> m ()
    glGetBufferPointerv (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t) GLuint
    GL_BUFFER_MAP_POINTER Ptr (Ptr a)
    buf
       (Ptr a -> Ptr a) -> Ptr (Ptr a) -> IO (Ptr a)
    forall a b. Storable a => (a -> b) -> Ptr a -> IO b
    peek1 Ptr a -> Ptr a
    forall a. a -> a
    id Ptr (Ptr a)
    buf

    --------------------------------------------------------------------------------

    data MappingFailure =
         MappingFailed
       | UnmappingFailed
       deriving ( MappingFailure -> MappingFailure -> Bool
    (MappingFailure -> MappingFailure -> Bool)
    -> (MappingFailure -> MappingFailure -> Bool) -> Eq MappingFailure
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: MappingFailure -> MappingFailure -> Bool
    == :: MappingFailure -> MappingFailure -> Bool
    $c/= :: MappingFailure -> MappingFailure -> Bool
    /= :: MappingFailure -> MappingFailure -> Bool
    Eq, Eq MappingFailure
    Eq MappingFailure =>
    (MappingFailure -> MappingFailure -> Ordering)
    -> (MappingFailure -> MappingFailure -> Bool)
    -> (MappingFailure -> MappingFailure -> Bool)
    -> (MappingFailure -> MappingFailure -> Bool)
    -> (MappingFailure -> MappingFailure -> Bool)
    -> (MappingFailure -> MappingFailure -> MappingFailure)
    -> (MappingFailure -> MappingFailure -> MappingFailure)
    -> Ord MappingFailure
    MappingFailure -> MappingFailure -> Bool
    MappingFailure -> MappingFailure -> Ordering
    MappingFailure -> MappingFailure -> MappingFailure
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: MappingFailure -> MappingFailure -> Ordering
    compare :: MappingFailure -> MappingFailure -> Ordering
    $c< :: MappingFailure -> MappingFailure -> Bool
    < :: MappingFailure -> MappingFailure -> Bool
    $c<= :: MappingFailure -> MappingFailure -> Bool
    <= :: MappingFailure -> MappingFailure -> Bool
    $c> :: MappingFailure -> MappingFailure -> Bool
    > :: MappingFailure -> MappingFailure -> Bool
    $c>= :: MappingFailure -> MappingFailure -> Bool
    >= :: MappingFailure -> MappingFailure -> Bool
    $cmax :: MappingFailure -> MappingFailure -> MappingFailure
    max :: MappingFailure -> MappingFailure -> MappingFailure
    $cmin :: MappingFailure -> MappingFailure -> MappingFailure
    min :: MappingFailure -> MappingFailure -> MappingFailure
    Ord, Int -> MappingFailure -> ShowS
    [MappingFailure] -> ShowS
    MappingFailure -> String
    (Int -> MappingFailure -> ShowS)
    -> (MappingFailure -> String)
    -> ([MappingFailure] -> ShowS)
    -> Show MappingFailure
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> MappingFailure -> ShowS
    showsPrec :: Int -> MappingFailure -> ShowS
    $cshow :: MappingFailure -> String
    show :: MappingFailure -> String
    $cshowList :: [MappingFailure] -> ShowS
    showList :: [MappingFailure] -> ShowS
    Show )

    -- | Convenience function for an exception-safe combination of 'mapBuffer' and
    -- 'unmapBuffer'.
    withMappedBuffer :: BufferTarget -> BufferAccess -> (Ptr a -> IO b) -> (MappingFailure -> IO b) -> IO b
    withMappedBuffer :: forall a b.
    BufferTarget
    -> BufferAccess
    -> (Ptr a -> IO b)
    -> (MappingFailure -> IO b)
    -> IO b
    withMappedBuffer BufferTarget
    t BufferAccess
    a Ptr a -> IO b
    action MappingFailure -> IO b
    err = do
       maybeBuf <- BufferTarget -> BufferAccess -> IO (Maybe (Ptr a))
    forall a. BufferTarget -> BufferAccess -> IO (Maybe (Ptr a))
    mapBuffer BufferTarget
    t BufferAccess
    a
       case maybeBuf  of
          Maybe (Ptr a)
    Nothing -> MappingFailure -> IO b
    err MappingFailure
    MappingFailed
          Just Ptr a
    buf -> do (ret, ok) <- Ptr a -> IO b
    action Ptr a
    buf IO b -> IO Bool -> IO (b, Bool)
    forall a b. IO a -> IO b -> IO (a, b)
    `finallyRet` BufferTarget -> IO Bool
    unmapBuffer BufferTarget
    t
                         if ok
                            then return ret
                            else err UnmappingFailed

    mapBuffer :: BufferTarget -> BufferAccess -> IO (Maybe (Ptr a))
    mapBuffer :: forall a. BufferTarget -> BufferAccess -> IO (Maybe (Ptr a))
    mapBuffer BufferTarget
    t = (Ptr a -> Maybe (Ptr a)) -> IO (Ptr a) -> IO (Maybe (Ptr a))
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Maybe (Ptr a) -> (Ptr a -> Maybe (Ptr a)) -> Ptr a -> Maybe (Ptr a)
    forall b a. b -> (Ptr a -> b) -> Ptr a -> b
    maybeNullPtr Maybe (Ptr a)
    forall a. Maybe a
    Nothing Ptr a -> Maybe (Ptr a)
    forall a. a -> Maybe a
    Just) (IO (Ptr a) -> IO (Maybe (Ptr a)))
    -> (BufferAccess -> IO (Ptr a))
    -> BufferAccess
    -> IO (Maybe (Ptr a))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferTarget -> BufferAccess -> IO (Ptr a)
    forall a. BufferTarget -> BufferAccess -> IO (Ptr a)
    mapBuffer_ BufferTarget
    t

    mapBuffer_ :: BufferTarget -> BufferAccess -> IO (Ptr a)
    mapBuffer_ :: forall a. BufferTarget -> BufferAccess -> IO (Ptr a)
    mapBuffer_ BufferTarget
    t = GLuint -> GLuint -> IO (Ptr a)
    forall (m :: * -> *) a. MonadIO m => GLuint -> GLuint -> m (Ptr a)
    glMapBuffer (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t) (GLuint -> IO (Ptr a))
    -> (BufferAccess -> GLuint) -> BufferAccess -> IO (Ptr a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferAccess -> GLuint
    marshalBufferAccess

    unmapBuffer :: BufferTarget -> IO Bool
    unmapBuffer :: BufferTarget -> IO Bool
    unmapBuffer = (GLboolean -> Bool) -> IO GLboolean -> IO Bool
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap GLboolean -> Bool
    forall a. (Eq a, Num a) => a -> Bool
    unmarshalGLboolean (IO GLboolean -> IO Bool)
    -> (BufferTarget -> IO GLboolean) -> BufferTarget -> IO Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLuint -> IO GLboolean
    forall (m :: * -> *). MonadIO m => GLuint -> m GLboolean
    glUnmapBuffer (GLuint -> IO GLboolean)
    -> (BufferTarget -> GLuint) -> BufferTarget -> IO GLboolean
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferTarget -> GLuint
    marshalBufferTarget

    bufferAccess :: BufferTarget -> GettableStateVar BufferAccess
    bufferAccess :: BufferTarget -> GettableStateVar BufferAccess
    bufferAccess BufferTarget
    t = GettableStateVar BufferAccess -> GettableStateVar BufferAccess
    forall a. IO a -> IO a
    makeGettableStateVar (GettableStateVar BufferAccess -> GettableStateVar BufferAccess)
    -> GettableStateVar BufferAccess -> GettableStateVar BufferAccess
    forall a b. (a -> b) -> a -> b
    $
       BufferTarget
    -> (GLuint -> BufferAccess)
    -> GetBufferPName
    -> GettableStateVar BufferAccess
    forall a. BufferTarget -> (GLuint -> a) -> GetBufferPName -> IO a
    getBufferParameter BufferTarget
    t GLuint -> BufferAccess
    unmarshalBufferAccess GetBufferPName
    GetBufferAccess

    bufferMapped :: BufferTarget -> GettableStateVar Bool
    bufferMapped :: BufferTarget -> IO Bool
    bufferMapped BufferTarget
    t = IO Bool -> IO Bool
    forall a. IO a -> IO a
    makeGettableStateVar (IO Bool -> IO Bool) -> IO Bool -> IO Bool
    forall a b. (a -> b) -> a -> b
    $
       BufferTarget -> (GLuint -> Bool) -> GetBufferPName -> IO Bool
    forall a. BufferTarget -> (GLuint -> a) -> GetBufferPName -> IO a
    getBufferParameter BufferTarget
    t GLuint -> Bool
    forall a. (Eq a, Num a) => a -> Bool
    unmarshalGLboolean GetBufferPName
    GetBufferMapped

    --------------------------------------------------------------------------------

    data MapBufferUsage =
         Read
       | Write
       | InvalidateRange
       | InvalidateBuffer
       | FlushExplicit
       | Unsychronized
       deriving ( MapBufferUsage -> MapBufferUsage -> Bool
    (MapBufferUsage -> MapBufferUsage -> Bool)
    -> (MapBufferUsage -> MapBufferUsage -> Bool) -> Eq MapBufferUsage
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: MapBufferUsage -> MapBufferUsage -> Bool
    == :: MapBufferUsage -> MapBufferUsage -> Bool
    $c/= :: MapBufferUsage -> MapBufferUsage -> Bool
    /= :: MapBufferUsage -> MapBufferUsage -> Bool
    Eq, Eq MapBufferUsage
    Eq MapBufferUsage =>
    (MapBufferUsage -> MapBufferUsage -> Ordering)
    -> (MapBufferUsage -> MapBufferUsage -> Bool)
    -> (MapBufferUsage -> MapBufferUsage -> Bool)
    -> (MapBufferUsage -> MapBufferUsage -> Bool)
    -> (MapBufferUsage -> MapBufferUsage -> Bool)
    -> (MapBufferUsage -> MapBufferUsage -> MapBufferUsage)
    -> (MapBufferUsage -> MapBufferUsage -> MapBufferUsage)
    -> Ord MapBufferUsage
    MapBufferUsage -> MapBufferUsage -> Bool
    MapBufferUsage -> MapBufferUsage -> Ordering
    MapBufferUsage -> MapBufferUsage -> MapBufferUsage
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: MapBufferUsage -> MapBufferUsage -> Ordering
    compare :: MapBufferUsage -> MapBufferUsage -> Ordering
    $c< :: MapBufferUsage -> MapBufferUsage -> Bool
    < :: MapBufferUsage -> MapBufferUsage -> Bool
    $c<= :: MapBufferUsage -> MapBufferUsage -> Bool
    <= :: MapBufferUsage -> MapBufferUsage -> Bool
    $c> :: MapBufferUsage -> MapBufferUsage -> Bool
    > :: MapBufferUsage -> MapBufferUsage -> Bool
    $c>= :: MapBufferUsage -> MapBufferUsage -> Bool
    >= :: MapBufferUsage -> MapBufferUsage -> Bool
    $cmax :: MapBufferUsage -> MapBufferUsage -> MapBufferUsage
    max :: MapBufferUsage -> MapBufferUsage -> MapBufferUsage
    $cmin :: MapBufferUsage -> MapBufferUsage -> MapBufferUsage
    min :: MapBufferUsage -> MapBufferUsage -> MapBufferUsage
    Ord, Int -> MapBufferUsage -> ShowS
    [MapBufferUsage] -> ShowS
    MapBufferUsage -> String
    (Int -> MapBufferUsage -> ShowS)
    -> (MapBufferUsage -> String)
    -> ([MapBufferUsage] -> ShowS)
    -> Show MapBufferUsage
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> MapBufferUsage -> ShowS
    showsPrec :: Int -> MapBufferUsage -> ShowS
    $cshow :: MapBufferUsage -> String
    show :: MapBufferUsage -> String
    $cshowList :: [MapBufferUsage] -> ShowS
    showList :: [MapBufferUsage] -> ShowS
    Show )

    type Offset = GLintptr
    type Length = GLsizeiptr

    marshalMapBufferUsage :: MapBufferUsage -> GLbitfield
    marshalMapBufferUsage :: MapBufferUsage -> GLuint
    marshalMapBufferUsage MapBufferUsage
    x = case MapBufferUsage
    x of
        MapBufferUsage
    Read -> GLuint
    GL_MAP_READ_BIT
        MapBufferUsage
    Write -> GLuint
    GL_MAP_WRITE_BIT
        MapBufferUsage
    InvalidateRange -> GLuint
    GL_MAP_INVALIDATE_RANGE_BIT
        MapBufferUsage
    InvalidateBuffer -> GLuint
    GL_MAP_INVALIDATE_BUFFER_BIT
        MapBufferUsage
    FlushExplicit -> GLuint
    GL_MAP_FLUSH_EXPLICIT_BIT
        MapBufferUsage
    Unsychronized -> GLuint
    GL_MAP_FLUSH_EXPLICIT_BIT

    --------------------------------------------------------------------------------

    mapBufferRange_ ::
       BufferTarget -> Offset -> Length -> [MapBufferUsage] -> IO (Ptr a)
    mapBufferRange_ :: forall a.
    BufferTarget
    -> RangeStartIndex
    -> RangeStartIndex
    -> [MapBufferUsage]
    -> IO (Ptr a)
    mapBufferRange_ BufferTarget
    t RangeStartIndex
    o RangeStartIndex
    l [MapBufferUsage]
    b = GLuint
    -> RangeStartIndex -> RangeStartIndex -> GLuint -> IO (Ptr a)
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> RangeStartIndex -> RangeStartIndex -> GLuint -> m (Ptr a)
    glMapBufferRange (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t) RangeStartIndex
    o RangeStartIndex
    l
       ([GLuint] -> GLuint
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ((MapBufferUsage -> GLuint) -> [MapBufferUsage] -> [GLuint]
    forall a b. (a -> b) -> [a] -> [b]
    map MapBufferUsage -> GLuint
    marshalMapBufferUsage [MapBufferUsage]
    b))

    mapBufferRange ::
       BufferTarget -> Offset -> Length -> [MapBufferUsage] -> IO (Maybe (Ptr a))
    mapBufferRange :: forall a.
    BufferTarget
    -> RangeStartIndex
    -> RangeStartIndex
    -> [MapBufferUsage]
    -> IO (Maybe (Ptr a))
    mapBufferRange BufferTarget
    t RangeStartIndex
    o RangeStartIndex
    l [MapBufferUsage]
    b =
       (Ptr a -> Maybe (Ptr a)) -> IO (Ptr a) -> IO (Maybe (Ptr a))
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Maybe (Ptr a) -> (Ptr a -> Maybe (Ptr a)) -> Ptr a -> Maybe (Ptr a)
    forall b a. b -> (Ptr a -> b) -> Ptr a -> b
    maybeNullPtr Maybe (Ptr a)
    forall a. Maybe a
    Nothing Ptr a -> Maybe (Ptr a)
    forall a. a -> Maybe a
    Just) (IO (Ptr a) -> IO (Maybe (Ptr a)))
    -> IO (Ptr a) -> IO (Maybe (Ptr a))
    forall a b. (a -> b) -> a -> b
    $ BufferTarget
    -> RangeStartIndex
    -> RangeStartIndex
    -> [MapBufferUsage]
    -> IO (Ptr a)
    forall a.
    BufferTarget
    -> RangeStartIndex
    -> RangeStartIndex
    -> [MapBufferUsage]
    -> IO (Ptr a)
    mapBufferRange_ BufferTarget
    t RangeStartIndex
    o RangeStartIndex
    l [MapBufferUsage]
    b

    flushMappedBufferRange :: BufferTarget -> Offset -> Length -> IO ()
    flushMappedBufferRange :: BufferTarget -> RangeStartIndex -> RangeStartIndex -> IO ()
    flushMappedBufferRange BufferTarget
    t = GLuint -> RangeStartIndex -> RangeStartIndex -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> RangeStartIndex -> RangeStartIndex -> m ()
    glFlushMappedBufferRange (BufferTarget -> GLuint
    marshalBufferTarget BufferTarget
    t)

    --------------------------------------------------------------------------------

    type BufferIndex = GLuint

    type RangeStartIndex = GLintptr
    type RangeSize = GLsizeiptr
    type BufferRange = (BufferObject, RangeStartIndex, RangeSize)

    data IndexedBufferTarget =
         IndexedAtomicCounterBuffer
       | IndexedShaderStorageBuffer
       | IndexedTransformFeedbackBuffer
       | IndexedUniformBuffer
       deriving ( IndexedBufferTarget -> IndexedBufferTarget -> Bool
    (IndexedBufferTarget -> IndexedBufferTarget -> Bool)
    -> (IndexedBufferTarget -> IndexedBufferTarget -> Bool)
    -> Eq IndexedBufferTarget
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    == :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    $c/= :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    /= :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    Eq, Eq IndexedBufferTarget
    Eq IndexedBufferTarget =>
    (IndexedBufferTarget -> IndexedBufferTarget -> Ordering)
    -> (IndexedBufferTarget -> IndexedBufferTarget -> Bool)
    -> (IndexedBufferTarget -> IndexedBufferTarget -> Bool)
    -> (IndexedBufferTarget -> IndexedBufferTarget -> Bool)
    -> (IndexedBufferTarget -> IndexedBufferTarget -> Bool)
    -> (IndexedBufferTarget
        -> IndexedBufferTarget -> IndexedBufferTarget)
    -> (IndexedBufferTarget
        -> IndexedBufferTarget -> IndexedBufferTarget)
    -> Ord IndexedBufferTarget
    IndexedBufferTarget -> IndexedBufferTarget -> Bool
    IndexedBufferTarget -> IndexedBufferTarget -> Ordering
    IndexedBufferTarget -> IndexedBufferTarget -> IndexedBufferTarget
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: IndexedBufferTarget -> IndexedBufferTarget -> Ordering
    compare :: IndexedBufferTarget -> IndexedBufferTarget -> Ordering
    $c< :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    < :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    $c<= :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    <= :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    $c> :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    > :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    $c>= :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    >= :: IndexedBufferTarget -> IndexedBufferTarget -> Bool
    $cmax :: IndexedBufferTarget -> IndexedBufferTarget -> IndexedBufferTarget
    max :: IndexedBufferTarget -> IndexedBufferTarget -> IndexedBufferTarget
    $cmin :: IndexedBufferTarget -> IndexedBufferTarget -> IndexedBufferTarget
    min :: IndexedBufferTarget -> IndexedBufferTarget -> IndexedBufferTarget
    Ord, Int -> IndexedBufferTarget -> ShowS
    [IndexedBufferTarget] -> ShowS
    IndexedBufferTarget -> String
    (Int -> IndexedBufferTarget -> ShowS)
    -> (IndexedBufferTarget -> String)
    -> ([IndexedBufferTarget] -> ShowS)
    -> Show IndexedBufferTarget
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> IndexedBufferTarget -> ShowS
    showsPrec :: Int -> IndexedBufferTarget -> ShowS
    $cshow :: IndexedBufferTarget -> String
    show :: IndexedBufferTarget -> String
    $cshowList :: [IndexedBufferTarget] -> ShowS
    showList :: [IndexedBufferTarget] -> ShowS
    Show )

    marshalIndexedBufferTarget :: IndexedBufferTarget -> IPName1I
    marshalIndexedBufferTarget :: IndexedBufferTarget -> IPName1I
    marshalIndexedBufferTarget IndexedBufferTarget
    x = case IndexedBufferTarget
    x of
       IndexedBufferTarget
    IndexedAtomicCounterBuffer -> IPName1I
    GetAtomicCounterBuffer
       IndexedBufferTarget
    IndexedShaderStorageBuffer -> IPName1I
    GetShaderStorageBuffer
       IndexedBufferTarget
    IndexedTransformFeedbackBuffer -> IPName1I
    GetTransformFeedbackBuffer
       IndexedBufferTarget
    IndexedUniformBuffer -> IPName1I
    GetUniformBuffer

    bindBufferBase :: IndexedBufferTarget -> BufferIndex -> StateVar (Maybe BufferObject)
    bindBufferBase :: IndexedBufferTarget -> GLuint -> StateVar (Maybe BufferObject)
    bindBufferBase IndexedBufferTarget
    t GLuint
    i = IO (Maybe BufferObject)
    -> (Maybe BufferObject -> IO ()) -> StateVar (Maybe BufferObject)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (IndexedBufferTarget -> GLuint -> IO (Maybe BufferObject)
    getIndexedBufferBinding IndexedBufferTarget
    t GLuint
    i) (IndexedBufferTarget -> GLuint -> Maybe BufferObject -> IO ()
    setIndexedBufferBase IndexedBufferTarget
    t GLuint
    i)

    getIndexedBufferBinding :: IndexedBufferTarget -> BufferIndex -> IO (Maybe BufferObject)
    getIndexedBufferBinding :: IndexedBufferTarget -> GLuint -> IO (Maybe BufferObject)
    getIndexedBufferBinding IndexedBufferTarget
    t GLuint
    i = do
       buf <- (GLint -> BufferObject) -> IPName1I -> GLuint -> IO BufferObject
    forall p a. GetIPName1I p => (GLint -> a) -> p -> GLuint -> IO a
    forall a. (GLint -> a) -> IPName1I -> GLuint -> IO a
    getInteger1i (GLuint -> BufferObject
    BufferObject (GLuint -> BufferObject)
    -> (GLint -> GLuint) -> GLint -> BufferObject
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral) (IndexedBufferTarget -> IPName1I
    marshalIndexedBufferTarget IndexedBufferTarget
    t) GLuint
    i
       return $ if buf == noBufferObject then Nothing else Just buf

    setIndexedBufferBase :: IndexedBufferTarget -> BufferIndex -> Maybe BufferObject -> IO ()
    setIndexedBufferBase :: IndexedBufferTarget -> GLuint -> Maybe BufferObject -> IO ()
    setIndexedBufferBase IndexedBufferTarget
    t GLuint
    i Maybe BufferObject
    buf =
       case IPName1I -> Maybe GLuint
    forall p. GetPName p => p -> Maybe GLuint
    marshalGetPName (IPName1I -> Maybe GLuint)
    -> (IndexedBufferTarget -> IPName1I)
    -> IndexedBufferTarget
    -> Maybe GLuint
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IndexedBufferTarget -> IPName1I
    marshalIndexedBufferTarget (IndexedBufferTarget -> Maybe GLuint)
    -> IndexedBufferTarget -> Maybe GLuint
    forall a b. (a -> b) -> a -> b
    $ IndexedBufferTarget
    t of
          Maybe GLuint
    Nothing -> IO ()
    recordInvalidEnum
          Just GLuint
    t' -> GLuint -> GLuint -> GLuint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> GLuint -> GLuint -> m ()
    glBindBufferBase GLuint
    t' GLuint
    i (GLuint -> IO ())
    -> (Maybe BufferObject -> GLuint) -> Maybe BufferObject -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferObject -> GLuint
    bufferID (BufferObject -> GLuint)
    -> (Maybe BufferObject -> BufferObject)
    -> Maybe BufferObject
    -> GLuint
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferObject -> Maybe BufferObject -> BufferObject
    forall a. a -> Maybe a -> a
    fromMaybe BufferObject
    noBufferObject (Maybe BufferObject -> IO ()) -> Maybe BufferObject -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Maybe BufferObject
    buf

    bindBufferRange :: IndexedBufferTarget -> BufferIndex -> StateVar (Maybe BufferRange)
    bindBufferRange :: IndexedBufferTarget -> GLuint -> StateVar (Maybe BufferRange)
    bindBufferRange IndexedBufferTarget
    t GLuint
    i = IO (Maybe BufferRange)
    -> (Maybe BufferRange -> IO ()) -> StateVar (Maybe BufferRange)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (IndexedBufferTarget -> GLuint -> IO (Maybe BufferRange)
    getIndexedBufferRange IndexedBufferTarget
    t GLuint
    i) (IndexedBufferTarget -> GLuint -> Maybe BufferRange -> IO ()
    setIndexedBufferRange IndexedBufferTarget
    t GLuint
    i)

    getIndexedBufferRange :: IndexedBufferTarget -> BufferIndex -> IO (Maybe BufferRange)
    getIndexedBufferRange :: IndexedBufferTarget -> GLuint -> IO (Maybe BufferRange)
    getIndexedBufferRange IndexedBufferTarget
    t GLuint
    i = do
      buf <- (GLint -> BufferObject) -> IPName1I -> GLuint -> IO BufferObject
    forall p a. GetIPName1I p => (GLint -> a) -> p -> GLuint -> IO a
    forall a. (GLint -> a) -> IPName1I -> GLuint -> IO a
    getInteger1i (GLuint -> BufferObject
    BufferObject (GLuint -> BufferObject)
    -> (GLint -> GLuint) -> GLint -> BufferObject
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral) (IndexedBufferTarget -> IPName1I
    marshalIndexedBufferTarget IndexedBufferTarget
    t) GLuint
    i
      if buf == noBufferObject
         then return Nothing
         else do start <- get $ indexedBufferStart t i
                 size <- get $ indexedBufferSize t i
                 return $ Just (buf, start, size)

    setIndexedBufferRange :: IndexedBufferTarget -> BufferIndex -> Maybe BufferRange -> IO ()
    setIndexedBufferRange :: IndexedBufferTarget -> GLuint -> Maybe BufferRange -> IO ()
    setIndexedBufferRange IndexedBufferTarget
    t GLuint
    i Maybe BufferRange
    br =
       case IPName1I -> Maybe GLuint
    forall p. GetPName p => p -> Maybe GLuint
    marshalGetPName (IPName1I -> Maybe GLuint)
    -> (IndexedBufferTarget -> IPName1I)
    -> IndexedBufferTarget
    -> Maybe GLuint
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IndexedBufferTarget -> IPName1I
    marshalIndexedBufferTarget (IndexedBufferTarget -> Maybe GLuint)
    -> IndexedBufferTarget -> Maybe GLuint
    forall a b. (a -> b) -> a -> b
    $ IndexedBufferTarget
    t of
          Maybe GLuint
    Nothing -> IO ()
    recordInvalidEnum
          Just GLuint
    t' -> GLuint
    -> GLuint -> GLuint -> RangeStartIndex -> RangeStartIndex -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint
    -> GLuint -> GLuint -> RangeStartIndex -> RangeStartIndex -> m ()
    glBindBufferRange GLuint
    t' GLuint
    i (BufferObject -> GLuint
    bufferID BufferObject
    buf) RangeStartIndex
    start RangeStartIndex
    range
       where (BufferObject
    buf, RangeStartIndex
    start, RangeStartIndex
    range) = BufferRange -> Maybe BufferRange -> BufferRange
    forall a. a -> Maybe a -> a
    fromMaybe (BufferObject
    noBufferObject, RangeStartIndex
    0, RangeStartIndex
    0) Maybe BufferRange
    br

    getIndexed :: Num a => IPName1I -> BufferIndex -> GettableStateVar a
    getIndexed :: forall a. Num a => IPName1I -> GLuint -> GettableStateVar a
    getIndexed IPName1I
    e GLuint
    i = IO a -> IO a
    forall a. IO a -> IO a
    makeGettableStateVar (IO a -> IO a) -> IO a -> IO a
    forall a b. (a -> b) -> a -> b
    $ (GLint64 -> a) -> IPName1I -> GLuint -> IO a
    forall p a. GetIPName1I p => (GLint64 -> a) -> p -> GLuint -> IO a
    forall a. (GLint64 -> a) -> IPName1I -> GLuint -> IO a
    getInteger641i GLint64 -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral IPName1I
    e GLuint
    i

    marshalIndexedBufferStart :: IndexedBufferTarget -> IPName1I
    marshalIndexedBufferStart :: IndexedBufferTarget -> IPName1I
    marshalIndexedBufferStart IndexedBufferTarget
    x = case IndexedBufferTarget
    x of
       IndexedBufferTarget
    IndexedAtomicCounterBuffer -> IPName1I
    GetAtomicCounterBufferStart
       IndexedBufferTarget
    IndexedShaderStorageBuffer -> IPName1I
    GetShaderStorageBufferStart
       IndexedBufferTarget
    IndexedTransformFeedbackBuffer -> IPName1I
    GetTransformFeedbackBufferStart
       IndexedBufferTarget
    IndexedUniformBuffer -> IPName1I
    GetUniformBufferStart

    indexedBufferStart :: IndexedBufferTarget -> BufferIndex -> GettableStateVar RangeStartIndex
    indexedBufferStart :: IndexedBufferTarget -> GLuint -> GettableStateVar RangeStartIndex
    indexedBufferStart = IPName1I -> GLuint -> GettableStateVar RangeStartIndex
    forall a. Num a => IPName1I -> GLuint -> GettableStateVar a
    getIndexed (IPName1I -> GLuint -> GettableStateVar RangeStartIndex)
    -> (IndexedBufferTarget -> IPName1I)
    -> IndexedBufferTarget
    -> GLuint
    -> GettableStateVar RangeStartIndex
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IndexedBufferTarget -> IPName1I
    marshalIndexedBufferStart

    marshalIndexedBufferSize :: IndexedBufferTarget -> IPName1I
    marshalIndexedBufferSize :: IndexedBufferTarget -> IPName1I
    marshalIndexedBufferSize IndexedBufferTarget
    x = case IndexedBufferTarget
    x of
       IndexedBufferTarget
    IndexedAtomicCounterBuffer -> IPName1I
    GetAtomicCounterBufferSize
       IndexedBufferTarget
    IndexedShaderStorageBuffer -> IPName1I
    GetShaderStorageBufferSize
       IndexedBufferTarget
    IndexedTransformFeedbackBuffer -> IPName1I
    GetTransformFeedbackBufferSize
       IndexedBufferTarget
    IndexedUniformBuffer -> IPName1I
    GetUniformBufferSize

    indexedBufferSize :: IndexedBufferTarget -> BufferIndex -> GettableStateVar RangeSize
    indexedBufferSize :: IndexedBufferTarget -> GLuint -> GettableStateVar RangeStartIndex
    indexedBufferSize = IPName1I -> GLuint -> GettableStateVar RangeStartIndex
    forall a. Num a => IPName1I -> GLuint -> GettableStateVar a
    getIndexed (IPName1I -> GLuint -> GettableStateVar RangeStartIndex)
    -> (IndexedBufferTarget -> IPName1I)
    -> IndexedBufferTarget
    -> GLuint
    -> GettableStateVar RangeStartIndex
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IndexedBufferTarget -> IPName1I
    marshalIndexedBufferSize