extern static CVReturn CVOpenGLESTextureCacheCreateTextureFromImage(
     /* CFAllocatorRef __nullable */ IntPtr allocator,
     /* CVOpenGLESTextureCacheRef */ IntPtr textureCache,
     /* CVImageBufferRef __nonnull */ IntPtr sourceImage,
     /* CFDictionaryRef __nullable */ IntPtr textureAttr,
     /* GLenum */ int target,
     /* GLint */ OpenTK.Graphics.ES20.All internalFormat,
     /* GLsizei */ int width,
     /* GLsizei */ int height,
     /* GLenum */ OpenTK.Graphics.ES20.All format,
     /* GLenum */ OpenTK.Graphics.ES20.DataType type,
     /* size_t */ IntPtr planeIndex,
     /* CVOpenGLESTextureRef __nullable * __nonnull */ out IntPtr textureOut);
        public CVOpenGLESTexture TextureFromImage(CVImageBuffer imageBuffer, bool isTexture2d, OpenTK.Graphics.ES20.All internalFormat, int width, int height, OpenTK.Graphics.ES20.All pixelFormat, OpenTK.Graphics.ES20.DataType pixelType, int planeIndex, out CVReturn errorCode)
        {
            if (imageBuffer == null)
            {
                throw new ArgumentNullException("imageBuffer");
            }

            int    target = isTexture2d ? 0x0DE1 /* GL_TEXTURE_2D */ : 0x8D41 /* GL_RENDERBUFFER */;
            IntPtr texture;

            errorCode = CVOpenGLESTextureCacheCreateTextureFromImage(
                IntPtr.Zero,
                handle,                 /* textureCache dict, one day we might add it */
                imageBuffer.Handle,
                IntPtr.Zero,
                target,
                internalFormat, width, height, pixelFormat,
                pixelType, (IntPtr)planeIndex, out texture);
            if (errorCode != 0)
            {
                return(null);
            }
            return(new CVOpenGLESTexture(texture));
        }