github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/mobile/gl/gl.go (about)

     1  // Copyright 2014 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build linux darwin windows
     6  // +build !gldebug
     7  
     8  package gl
     9  
    10  // TODO(crawshaw): should functions on specific types become methods? E.g.
    11  //                 func (t Texture) Bind(target Enum)
    12  //                 this seems natural in Go, but moves us slightly
    13  //                 further away from the underlying OpenGL spec.
    14  
    15  import (
    16  	"math"
    17  	"unsafe"
    18  )
    19  
    20  func (ctx *context) ActiveTexture(texture Enum) {
    21  	ctx.enqueue(call{
    22  		args: fnargs{
    23  			fn: glfnActiveTexture,
    24  			a0: texture.c(),
    25  		},
    26  	})
    27  }
    28  
    29  func (ctx *context) AttachShader(p Program, s Shader) {
    30  	ctx.enqueue(call{
    31  		args: fnargs{
    32  			fn: glfnAttachShader,
    33  			a0: p.c(),
    34  			a1: s.c(),
    35  		},
    36  	})
    37  }
    38  
    39  func (ctx *context) BindAttribLocation(p Program, a Attrib, name string) {
    40  	s, free := ctx.cString(name)
    41  	defer free()
    42  	ctx.enqueue(call{
    43  		args: fnargs{
    44  			fn: glfnBindAttribLocation,
    45  			a0: p.c(),
    46  			a1: a.c(),
    47  			a2: s,
    48  		},
    49  		blocking: true,
    50  	})
    51  }
    52  
    53  func (ctx *context) BindBuffer(target Enum, b Buffer) {
    54  	ctx.enqueue(call{
    55  		args: fnargs{
    56  			fn: glfnBindBuffer,
    57  			a0: target.c(),
    58  			a1: b.c(),
    59  		},
    60  	})
    61  }
    62  
    63  func (ctx *context) BindFramebuffer(target Enum, fb Framebuffer) {
    64  	ctx.enqueue(call{
    65  		args: fnargs{
    66  			fn: glfnBindFramebuffer,
    67  			a0: target.c(),
    68  			a1: fb.c(),
    69  		},
    70  	})
    71  }
    72  
    73  func (ctx *context) BindRenderbuffer(target Enum, rb Renderbuffer) {
    74  	ctx.enqueue(call{
    75  		args: fnargs{
    76  			fn: glfnBindRenderbuffer,
    77  			a0: target.c(),
    78  			a1: rb.c(),
    79  		},
    80  	})
    81  }
    82  
    83  func (ctx *context) BindTexture(target Enum, t Texture) {
    84  	ctx.enqueue(call{
    85  		args: fnargs{
    86  			fn: glfnBindTexture,
    87  			a0: target.c(),
    88  			a1: t.c(),
    89  		},
    90  	})
    91  }
    92  
    93  func (ctx *context) BlendColor(red, green, blue, alpha float32) {
    94  	ctx.enqueue(call{
    95  		args: fnargs{
    96  			fn: glfnBlendColor,
    97  			a0: uintptr(math.Float32bits(red)),
    98  			a1: uintptr(math.Float32bits(green)),
    99  			a2: uintptr(math.Float32bits(blue)),
   100  			a3: uintptr(math.Float32bits(alpha)),
   101  		},
   102  	})
   103  }
   104  
   105  func (ctx *context) BlendEquation(mode Enum) {
   106  	ctx.enqueue(call{
   107  		args: fnargs{
   108  			fn: glfnBlendEquation,
   109  			a0: mode.c(),
   110  		},
   111  	})
   112  }
   113  
   114  func (ctx *context) BlendEquationSeparate(modeRGB, modeAlpha Enum) {
   115  	ctx.enqueue(call{
   116  		args: fnargs{
   117  			fn: glfnBlendEquationSeparate,
   118  			a0: modeRGB.c(),
   119  			a1: modeAlpha.c(),
   120  		},
   121  	})
   122  }
   123  
   124  func (ctx *context) BlendFunc(sfactor, dfactor Enum) {
   125  	ctx.enqueue(call{
   126  		args: fnargs{
   127  			fn: glfnBlendFunc,
   128  			a0: sfactor.c(),
   129  			a1: dfactor.c(),
   130  		},
   131  	})
   132  }
   133  
   134  func (ctx *context) BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) {
   135  	ctx.enqueue(call{
   136  		args: fnargs{
   137  			fn: glfnBlendFuncSeparate,
   138  			a0: sfactorRGB.c(),
   139  			a1: dfactorRGB.c(),
   140  			a2: sfactorAlpha.c(),
   141  			a3: dfactorAlpha.c(),
   142  		},
   143  	})
   144  }
   145  
   146  func (ctx *context) BufferData(target Enum, src []byte, usage Enum) {
   147  	parg := unsafe.Pointer(nil)
   148  	if len(src) > 0 {
   149  		parg = unsafe.Pointer(&src[0])
   150  	}
   151  	ctx.enqueue(call{
   152  		args: fnargs{
   153  			fn: glfnBufferData,
   154  			a0: target.c(),
   155  			a1: uintptr(len(src)),
   156  			a2: usage.c(),
   157  		},
   158  		parg:     parg,
   159  		blocking: true,
   160  	})
   161  }
   162  
   163  func (ctx *context) BufferInit(target Enum, size int, usage Enum) {
   164  	ctx.enqueue(call{
   165  		args: fnargs{
   166  			fn: glfnBufferData,
   167  			a0: target.c(),
   168  			a1: uintptr(size),
   169  			a2: 0,
   170  			a3: usage.c(),
   171  		},
   172  	})
   173  }
   174  
   175  func (ctx *context) BufferSubData(target Enum, offset int, data []byte) {
   176  	ctx.enqueue(call{
   177  		args: fnargs{
   178  			fn: glfnBufferSubData,
   179  			a0: target.c(),
   180  			a1: uintptr(offset),
   181  			a2: uintptr(len(data)),
   182  		},
   183  		parg:     unsafe.Pointer(&data[0]),
   184  		blocking: true,
   185  	})
   186  }
   187  
   188  func (ctx *context) CheckFramebufferStatus(target Enum) Enum {
   189  	return Enum(ctx.enqueue(call{
   190  		args: fnargs{
   191  			fn: glfnCheckFramebufferStatus,
   192  			a0: target.c(),
   193  		},
   194  		blocking: true,
   195  	}))
   196  }
   197  
   198  func (ctx *context) Clear(mask Enum) {
   199  	ctx.enqueue(call{
   200  		args: fnargs{
   201  			fn: glfnClear,
   202  			a0: uintptr(mask),
   203  		},
   204  	})
   205  }
   206  
   207  func (ctx *context) ClearColor(red, green, blue, alpha float32) {
   208  	ctx.enqueue(call{
   209  		args: fnargs{
   210  			fn: glfnClearColor,
   211  			a0: uintptr(math.Float32bits(red)),
   212  			a1: uintptr(math.Float32bits(green)),
   213  			a2: uintptr(math.Float32bits(blue)),
   214  			a3: uintptr(math.Float32bits(alpha)),
   215  		},
   216  	})
   217  }
   218  
   219  func (ctx *context) ClearDepthf(d float32) {
   220  	ctx.enqueue(call{
   221  		args: fnargs{
   222  			fn: glfnClearDepthf,
   223  			a0: uintptr(math.Float32bits(d)),
   224  		},
   225  	})
   226  }
   227  
   228  func (ctx *context) ClearStencil(s int) {
   229  	ctx.enqueue(call{
   230  		args: fnargs{
   231  			fn: glfnClearStencil,
   232  			a0: uintptr(s),
   233  		},
   234  	})
   235  }
   236  
   237  func (ctx *context) ColorMask(red, green, blue, alpha bool) {
   238  	ctx.enqueue(call{
   239  		args: fnargs{
   240  			fn: glfnColorMask,
   241  			a0: glBoolean(red),
   242  			a1: glBoolean(green),
   243  			a2: glBoolean(blue),
   244  			a3: glBoolean(alpha),
   245  		},
   246  	})
   247  }
   248  
   249  func (ctx *context) CompileShader(s Shader) {
   250  	ctx.enqueue(call{
   251  		args: fnargs{
   252  			fn: glfnCompileShader,
   253  			a0: s.c(),
   254  		},
   255  	})
   256  }
   257  
   258  func (ctx *context) CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) {
   259  	ctx.enqueue(call{
   260  		args: fnargs{
   261  			fn: glfnCompressedTexImage2D,
   262  			a0: target.c(),
   263  			a1: uintptr(level),
   264  			a2: internalformat.c(),
   265  			a3: uintptr(width),
   266  			a4: uintptr(height),
   267  			a5: uintptr(border),
   268  			a6: uintptr(len(data)),
   269  		},
   270  		parg:     unsafe.Pointer(&data[0]),
   271  		blocking: true,
   272  	})
   273  }
   274  
   275  func (ctx *context) CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) {
   276  	ctx.enqueue(call{
   277  		args: fnargs{
   278  			fn: glfnCompressedTexSubImage2D,
   279  			a0: target.c(),
   280  			a1: uintptr(level),
   281  			a2: uintptr(xoffset),
   282  			a3: uintptr(yoffset),
   283  			a4: uintptr(width),
   284  			a5: uintptr(height),
   285  			a6: format.c(),
   286  			a7: uintptr(len(data)),
   287  		},
   288  		parg:     unsafe.Pointer(&data[0]),
   289  		blocking: true,
   290  	})
   291  }
   292  
   293  func (ctx *context) CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) {
   294  	ctx.enqueue(call{
   295  		args: fnargs{
   296  			fn: glfnCopyTexImage2D,
   297  			a0: target.c(),
   298  			a1: uintptr(level),
   299  			a2: internalformat.c(),
   300  			a3: uintptr(x),
   301  			a4: uintptr(y),
   302  			a5: uintptr(width),
   303  			a6: uintptr(height),
   304  			a7: uintptr(border),
   305  		},
   306  	})
   307  }
   308  
   309  func (ctx *context) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) {
   310  	ctx.enqueue(call{
   311  		args: fnargs{
   312  			fn: glfnCopyTexSubImage2D,
   313  			a0: target.c(),
   314  			a1: uintptr(level),
   315  			a2: uintptr(xoffset),
   316  			a3: uintptr(yoffset),
   317  			a4: uintptr(x),
   318  			a5: uintptr(y),
   319  			a6: uintptr(width),
   320  			a7: uintptr(height),
   321  		},
   322  	})
   323  }
   324  
   325  func (ctx *context) CreateBuffer() Buffer {
   326  	return Buffer{Value: uint32(ctx.enqueue(call{
   327  		args: fnargs{
   328  			fn: glfnGenBuffer,
   329  		},
   330  		blocking: true,
   331  	}))}
   332  }
   333  
   334  func (ctx *context) CreateFramebuffer() Framebuffer {
   335  	return Framebuffer{Value: uint32(ctx.enqueue(call{
   336  		args: fnargs{
   337  			fn: glfnGenFramebuffer,
   338  		},
   339  		blocking: true,
   340  	}))}
   341  }
   342  
   343  func (ctx *context) CreateProgram() Program {
   344  	return Program{
   345  		Init: true,
   346  		Value: uint32(ctx.enqueue(call{
   347  			args: fnargs{
   348  				fn: glfnCreateProgram,
   349  			},
   350  			blocking: true,
   351  		},
   352  		))}
   353  }
   354  
   355  func (ctx *context) CreateRenderbuffer() Renderbuffer {
   356  	return Renderbuffer{Value: uint32(ctx.enqueue(call{
   357  		args: fnargs{
   358  			fn: glfnGenRenderbuffer,
   359  		},
   360  		blocking: true,
   361  	}))}
   362  }
   363  
   364  func (ctx *context) CreateShader(ty Enum) Shader {
   365  	return Shader{Value: uint32(ctx.enqueue(call{
   366  		args: fnargs{
   367  			fn: glfnCreateShader,
   368  			a0: uintptr(ty),
   369  		},
   370  		blocking: true,
   371  	}))}
   372  }
   373  
   374  func (ctx *context) CreateTexture() Texture {
   375  	return Texture{Value: uint32(ctx.enqueue(call{
   376  		args: fnargs{
   377  			fn: glfnGenTexture,
   378  		},
   379  		blocking: true,
   380  	}))}
   381  }
   382  
   383  func (ctx *context) CullFace(mode Enum) {
   384  	ctx.enqueue(call{
   385  		args: fnargs{
   386  			fn: glfnCullFace,
   387  			a0: mode.c(),
   388  		},
   389  	})
   390  }
   391  
   392  func (ctx *context) DeleteBuffer(v Buffer) {
   393  	ctx.enqueue(call{
   394  		args: fnargs{
   395  			fn: glfnDeleteBuffer,
   396  			a0: uintptr(v.Value),
   397  		},
   398  	})
   399  }
   400  
   401  func (ctx *context) DeleteFramebuffer(v Framebuffer) {
   402  	ctx.enqueue(call{
   403  		args: fnargs{
   404  			fn: glfnDeleteFramebuffer,
   405  			a0: uintptr(v.Value),
   406  		},
   407  	})
   408  }
   409  
   410  func (ctx *context) DeleteProgram(p Program) {
   411  	ctx.enqueue(call{
   412  		args: fnargs{
   413  			fn: glfnDeleteProgram,
   414  			a0: p.c(),
   415  		},
   416  	})
   417  }
   418  
   419  func (ctx *context) DeleteRenderbuffer(v Renderbuffer) {
   420  	ctx.enqueue(call{
   421  		args: fnargs{
   422  			fn: glfnDeleteRenderbuffer,
   423  			a0: v.c(),
   424  		},
   425  	})
   426  }
   427  
   428  func (ctx *context) DeleteShader(s Shader) {
   429  	ctx.enqueue(call{
   430  		args: fnargs{
   431  			fn: glfnDeleteShader,
   432  			a0: s.c(),
   433  		},
   434  	})
   435  }
   436  
   437  func (ctx *context) DeleteTexture(v Texture) {
   438  	ctx.enqueue(call{
   439  		args: fnargs{
   440  			fn: glfnDeleteTexture,
   441  			a0: v.c(),
   442  		},
   443  	})
   444  }
   445  
   446  func (ctx *context) DepthFunc(fn Enum) {
   447  	ctx.enqueue(call{
   448  		args: fnargs{
   449  			fn: glfnDepthFunc,
   450  			a0: fn.c(),
   451  		},
   452  	})
   453  }
   454  
   455  func (ctx *context) DepthMask(flag bool) {
   456  	ctx.enqueue(call{
   457  		args: fnargs{
   458  			fn: glfnDepthMask,
   459  			a0: glBoolean(flag),
   460  		},
   461  	})
   462  }
   463  
   464  func (ctx *context) DepthRangef(n, f float32) {
   465  	ctx.enqueue(call{
   466  		args: fnargs{
   467  			fn: glfnDepthRangef,
   468  			a0: uintptr(math.Float32bits(n)),
   469  			a1: uintptr(math.Float32bits(f)),
   470  		},
   471  	})
   472  }
   473  
   474  func (ctx *context) DetachShader(p Program, s Shader) {
   475  	ctx.enqueue(call{
   476  		args: fnargs{
   477  			fn: glfnDetachShader,
   478  			a0: p.c(),
   479  			a1: s.c(),
   480  		},
   481  	})
   482  }
   483  
   484  func (ctx *context) Disable(cap Enum) {
   485  	ctx.enqueue(call{
   486  		args: fnargs{
   487  			fn: glfnDisable,
   488  			a0: cap.c(),
   489  		},
   490  	})
   491  }
   492  
   493  func (ctx *context) DisableVertexAttribArray(a Attrib) {
   494  	ctx.enqueue(call{
   495  		args: fnargs{
   496  			fn: glfnDisableVertexAttribArray,
   497  			a0: a.c(),
   498  		},
   499  	})
   500  }
   501  
   502  func (ctx *context) DrawArrays(mode Enum, first, count int) {
   503  	ctx.enqueue(call{
   504  		args: fnargs{
   505  			fn: glfnDrawArrays,
   506  			a0: mode.c(),
   507  			a1: uintptr(first),
   508  			a2: uintptr(count),
   509  		},
   510  	})
   511  }
   512  
   513  func (ctx *context) DrawElements(mode Enum, count int, ty Enum, offset int) {
   514  	ctx.enqueue(call{
   515  		args: fnargs{
   516  			fn: glfnDrawElements,
   517  			a0: mode.c(),
   518  			a1: uintptr(count),
   519  			a2: ty.c(),
   520  			a3: uintptr(offset),
   521  		},
   522  	})
   523  }
   524  
   525  func (ctx *context) Enable(cap Enum) {
   526  	ctx.enqueue(call{
   527  		args: fnargs{
   528  			fn: glfnEnable,
   529  			a0: cap.c(),
   530  		},
   531  	})
   532  }
   533  
   534  func (ctx *context) EnableVertexAttribArray(a Attrib) {
   535  	ctx.enqueue(call{
   536  		args: fnargs{
   537  			fn: glfnEnableVertexAttribArray,
   538  			a0: a.c(),
   539  		},
   540  	})
   541  }
   542  
   543  func (ctx *context) Finish() {
   544  	ctx.enqueue(call{
   545  		args: fnargs{
   546  			fn: glfnFinish,
   547  		},
   548  		blocking: true,
   549  	})
   550  }
   551  
   552  func (ctx *context) Flush() {
   553  	ctx.enqueue(call{
   554  		args: fnargs{
   555  			fn: glfnFlush,
   556  		},
   557  		blocking: true,
   558  	})
   559  }
   560  
   561  func (ctx *context) FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) {
   562  	ctx.enqueue(call{
   563  		args: fnargs{
   564  			fn: glfnFramebufferRenderbuffer,
   565  			a0: target.c(),
   566  			a1: attachment.c(),
   567  			a2: rbTarget.c(),
   568  			a3: rb.c(),
   569  		},
   570  	})
   571  }
   572  
   573  func (ctx *context) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {
   574  	ctx.enqueue(call{
   575  		args: fnargs{
   576  			fn: glfnFramebufferTexture2D,
   577  			a0: target.c(),
   578  			a1: attachment.c(),
   579  			a2: texTarget.c(),
   580  			a3: t.c(),
   581  			a4: uintptr(level),
   582  		},
   583  	})
   584  }
   585  
   586  func (ctx *context) FrontFace(mode Enum) {
   587  	ctx.enqueue(call{
   588  		args: fnargs{
   589  			fn: glfnFrontFace,
   590  			a0: mode.c(),
   591  		},
   592  	})
   593  }
   594  
   595  func (ctx *context) GenerateMipmap(target Enum) {
   596  	ctx.enqueue(call{
   597  		args: fnargs{
   598  			fn: glfnGenerateMipmap,
   599  			a0: target.c(),
   600  		},
   601  	})
   602  }
   603  
   604  func (ctx *context) GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) {
   605  	bufSize := ctx.GetProgrami(p, ACTIVE_ATTRIBUTE_MAX_LENGTH)
   606  	buf := make([]byte, bufSize)
   607  	var cType int
   608  
   609  	cSize := ctx.enqueue(call{
   610  		args: fnargs{
   611  			fn: glfnGetActiveAttrib,
   612  			a0: p.c(),
   613  			a1: uintptr(index),
   614  			a2: uintptr(bufSize),
   615  			a3: uintptr(unsafe.Pointer(&cType)), // TODO(crawshaw): not safe for a moving collector
   616  		},
   617  		parg:     unsafe.Pointer(&buf[0]),
   618  		blocking: true,
   619  	})
   620  
   621  	return goString(buf), int(cSize), Enum(cType)
   622  }
   623  
   624  func (ctx *context) GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) {
   625  	bufSize := ctx.GetProgrami(p, ACTIVE_UNIFORM_MAX_LENGTH)
   626  	buf := make([]byte, bufSize+8) // extra space for cType
   627  	var cType int
   628  
   629  	cSize := ctx.enqueue(call{
   630  		args: fnargs{
   631  			fn: glfnGetActiveUniform,
   632  			a0: p.c(),
   633  			a1: uintptr(index),
   634  			a2: uintptr(bufSize),
   635  			a3: uintptr(unsafe.Pointer(&cType)), // TODO(crawshaw): not safe for a moving collector
   636  		},
   637  		parg:     unsafe.Pointer(&buf[0]),
   638  		blocking: true,
   639  	})
   640  
   641  	return goString(buf), int(cSize), Enum(cType)
   642  }
   643  
   644  func (ctx *context) GetAttachedShaders(p Program) []Shader {
   645  	shadersLen := ctx.GetProgrami(p, ATTACHED_SHADERS)
   646  	if shadersLen == 0 {
   647  		return nil
   648  	}
   649  	buf := make([]uint32, shadersLen)
   650  
   651  	n := int(ctx.enqueue(call{
   652  		args: fnargs{
   653  			fn: glfnGetAttachedShaders,
   654  			a0: p.c(),
   655  			a1: uintptr(shadersLen),
   656  		},
   657  		parg:     unsafe.Pointer(&buf[0]),
   658  		blocking: true,
   659  	}))
   660  
   661  	buf = buf[:int(n)]
   662  	shaders := make([]Shader, len(buf))
   663  	for i, s := range buf {
   664  		shaders[i] = Shader{Value: uint32(s)}
   665  	}
   666  	return shaders
   667  }
   668  
   669  func (ctx *context) GetAttribLocation(p Program, name string) Attrib {
   670  	s, free := ctx.cString(name)
   671  	defer free()
   672  	return Attrib{Value: uint(ctx.enqueue(call{
   673  		args: fnargs{
   674  			fn: glfnGetAttribLocation,
   675  			a0: p.c(),
   676  			a1: s,
   677  		},
   678  		blocking: true,
   679  	}))}
   680  }
   681  
   682  func (ctx *context) GetBooleanv(dst []bool, pname Enum) {
   683  	buf := make([]int32, len(dst))
   684  
   685  	ctx.enqueue(call{
   686  		args: fnargs{
   687  			fn: glfnGetBooleanv,
   688  			a0: pname.c(),
   689  		},
   690  		parg:     unsafe.Pointer(&buf[0]),
   691  		blocking: true,
   692  	})
   693  
   694  	for i, v := range buf {
   695  		dst[i] = v != 0
   696  	}
   697  }
   698  
   699  func (ctx *context) GetFloatv(dst []float32, pname Enum) {
   700  	ctx.enqueue(call{
   701  		args: fnargs{
   702  			fn: glfnGetFloatv,
   703  			a0: pname.c(),
   704  		},
   705  		parg:     unsafe.Pointer(&dst[0]),
   706  		blocking: true,
   707  	})
   708  }
   709  
   710  func (ctx *context) GetIntegerv(dst []int32, pname Enum) {
   711  	ctx.enqueue(call{
   712  		args: fnargs{
   713  			fn: glfnGetIntegerv,
   714  			a0: pname.c(),
   715  		},
   716  		parg:     unsafe.Pointer(&dst[0]),
   717  		blocking: true,
   718  	})
   719  }
   720  
   721  func (ctx *context) GetInteger(pname Enum) int {
   722  	var v [1]int32
   723  	ctx.GetIntegerv(v[:], pname)
   724  	return int(v[0])
   725  }
   726  
   727  func (ctx *context) GetBufferParameteri(target, value Enum) int {
   728  	return int(ctx.enqueue(call{
   729  		args: fnargs{
   730  			fn: glfnGetBufferParameteri,
   731  			a0: target.c(),
   732  			a1: value.c(),
   733  		},
   734  		blocking: true,
   735  	}))
   736  }
   737  
   738  func (ctx *context) GetError() Enum {
   739  	return Enum(ctx.enqueue(call{
   740  		args: fnargs{
   741  			fn: glfnGetError,
   742  		},
   743  		blocking: true,
   744  	}))
   745  }
   746  
   747  func (ctx *context) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
   748  	return int(ctx.enqueue(call{
   749  		args: fnargs{
   750  			fn: glfnGetFramebufferAttachmentParameteriv,
   751  			a0: target.c(),
   752  			a1: attachment.c(),
   753  			a2: pname.c(),
   754  		},
   755  		blocking: true,
   756  	}))
   757  }
   758  
   759  func (ctx *context) GetProgrami(p Program, pname Enum) int {
   760  	return int(ctx.enqueue(call{
   761  		args: fnargs{
   762  			fn: glfnGetProgramiv,
   763  			a0: p.c(),
   764  			a1: pname.c(),
   765  		},
   766  		blocking: true,
   767  	}))
   768  }
   769  
   770  func (ctx *context) GetProgramInfoLog(p Program) string {
   771  	infoLen := ctx.GetProgrami(p, INFO_LOG_LENGTH)
   772  	if infoLen == 0 {
   773  		return ""
   774  	}
   775  	buf := make([]byte, infoLen)
   776  
   777  	ctx.enqueue(call{
   778  		args: fnargs{
   779  			fn: glfnGetProgramInfoLog,
   780  			a0: p.c(),
   781  			a1: uintptr(infoLen),
   782  		},
   783  		parg:     unsafe.Pointer(&buf[0]),
   784  		blocking: true,
   785  	})
   786  
   787  	return goString(buf)
   788  }
   789  
   790  func (ctx *context) GetRenderbufferParameteri(target, pname Enum) int {
   791  	return int(ctx.enqueue(call{
   792  		args: fnargs{
   793  			fn: glfnGetRenderbufferParameteriv,
   794  			a0: target.c(),
   795  			a1: pname.c(),
   796  		},
   797  		blocking: true,
   798  	}))
   799  }
   800  
   801  func (ctx *context) GetShaderi(s Shader, pname Enum) int {
   802  	return int(ctx.enqueue(call{
   803  		args: fnargs{
   804  			fn: glfnGetShaderiv,
   805  			a0: s.c(),
   806  			a1: pname.c(),
   807  		},
   808  		blocking: true,
   809  	}))
   810  }
   811  
   812  func (ctx *context) GetShaderInfoLog(s Shader) string {
   813  	infoLen := ctx.GetShaderi(s, INFO_LOG_LENGTH)
   814  	if infoLen == 0 {
   815  		return ""
   816  	}
   817  	buf := make([]byte, infoLen)
   818  
   819  	ctx.enqueue(call{
   820  		args: fnargs{
   821  			fn: glfnGetShaderInfoLog,
   822  			a0: s.c(),
   823  			a1: uintptr(infoLen),
   824  		},
   825  		parg:     unsafe.Pointer(&buf[0]),
   826  		blocking: true,
   827  	})
   828  
   829  	return goString(buf)
   830  }
   831  
   832  func (ctx *context) GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHigh, precision int) {
   833  	var rangeAndPrec [3]int32
   834  
   835  	ctx.enqueue(call{
   836  		args: fnargs{
   837  			fn: glfnGetShaderPrecisionFormat,
   838  			a0: shadertype.c(),
   839  			a1: precisiontype.c(),
   840  		},
   841  		parg:     unsafe.Pointer(&rangeAndPrec[0]),
   842  		blocking: true,
   843  	})
   844  
   845  	return int(rangeAndPrec[0]), int(rangeAndPrec[1]), int(rangeAndPrec[2])
   846  }
   847  
   848  func (ctx *context) GetShaderSource(s Shader) string {
   849  	sourceLen := ctx.GetShaderi(s, SHADER_SOURCE_LENGTH)
   850  	if sourceLen == 0 {
   851  		return ""
   852  	}
   853  	buf := make([]byte, sourceLen)
   854  
   855  	ctx.enqueue(call{
   856  		args: fnargs{
   857  			fn: glfnGetShaderSource,
   858  			a0: s.c(),
   859  			a1: uintptr(sourceLen),
   860  		},
   861  		parg:     unsafe.Pointer(&buf[0]),
   862  		blocking: true,
   863  	})
   864  
   865  	return goString(buf)
   866  }
   867  
   868  func (ctx *context) GetString(pname Enum) string {
   869  	ret := ctx.enqueue(call{
   870  		args: fnargs{
   871  			fn: glfnGetString,
   872  			a0: pname.c(),
   873  		},
   874  		blocking: true,
   875  	})
   876  	retp := unsafe.Pointer(ret)
   877  	buf := (*[1 << 24]byte)(retp)[:]
   878  	return goString(buf)
   879  }
   880  
   881  func (ctx *context) GetTexParameterfv(dst []float32, target, pname Enum) {
   882  	ctx.enqueue(call{
   883  		args: fnargs{
   884  			fn: glfnGetTexParameterfv,
   885  			a0: target.c(),
   886  			a1: pname.c(),
   887  		},
   888  		parg:     unsafe.Pointer(&dst[0]),
   889  		blocking: true,
   890  	})
   891  }
   892  
   893  func (ctx *context) GetTexParameteriv(dst []int32, target, pname Enum) {
   894  	ctx.enqueue(call{
   895  		args: fnargs{
   896  			fn: glfnGetTexParameteriv,
   897  			a0: target.c(),
   898  			a1: pname.c(),
   899  		},
   900  		blocking: true,
   901  	})
   902  }
   903  
   904  func (ctx *context) GetUniformfv(dst []float32, src Uniform, p Program) {
   905  	ctx.enqueue(call{
   906  		args: fnargs{
   907  			fn: glfnGetUniformfv,
   908  			a0: p.c(),
   909  			a1: src.c(),
   910  		},
   911  		parg:     unsafe.Pointer(&dst[0]),
   912  		blocking: true,
   913  	})
   914  }
   915  
   916  func (ctx *context) GetUniformiv(dst []int32, src Uniform, p Program) {
   917  	ctx.enqueue(call{
   918  		args: fnargs{
   919  			fn: glfnGetUniformiv,
   920  			a0: p.c(),
   921  			a1: src.c(),
   922  		},
   923  		parg:     unsafe.Pointer(&dst[0]),
   924  		blocking: true,
   925  	})
   926  }
   927  
   928  func (ctx *context) GetUniformLocation(p Program, name string) Uniform {
   929  	s, free := ctx.cString(name)
   930  	defer free()
   931  	return Uniform{Value: int32(ctx.enqueue(call{
   932  		args: fnargs{
   933  			fn: glfnGetUniformLocation,
   934  			a0: p.c(),
   935  			a1: s,
   936  		},
   937  		blocking: true,
   938  	}))}
   939  }
   940  
   941  func (ctx *context) GetVertexAttribf(src Attrib, pname Enum) float32 {
   942  	var params [1]float32
   943  	ctx.GetVertexAttribfv(params[:], src, pname)
   944  	return params[0]
   945  }
   946  
   947  func (ctx *context) GetVertexAttribfv(dst []float32, src Attrib, pname Enum) {
   948  	ctx.enqueue(call{
   949  		args: fnargs{
   950  			fn: glfnGetVertexAttribfv,
   951  			a0: src.c(),
   952  			a1: pname.c(),
   953  		},
   954  		parg:     unsafe.Pointer(&dst[0]),
   955  		blocking: true,
   956  	})
   957  }
   958  
   959  func (ctx *context) GetVertexAttribi(src Attrib, pname Enum) int32 {
   960  	var params [1]int32
   961  	ctx.GetVertexAttribiv(params[:], src, pname)
   962  	return params[0]
   963  }
   964  
   965  func (ctx *context) GetVertexAttribiv(dst []int32, src Attrib, pname Enum) {
   966  	ctx.enqueue(call{
   967  		args: fnargs{
   968  			fn: glfnGetVertexAttribiv,
   969  			a0: src.c(),
   970  			a1: pname.c(),
   971  		},
   972  		parg:     unsafe.Pointer(&dst[0]),
   973  		blocking: true,
   974  	})
   975  }
   976  
   977  func (ctx *context) Hint(target, mode Enum) {
   978  	ctx.enqueue(call{
   979  		args: fnargs{
   980  			fn: glfnHint,
   981  			a0: target.c(),
   982  			a1: mode.c(),
   983  		},
   984  	})
   985  }
   986  
   987  func (ctx *context) IsBuffer(b Buffer) bool {
   988  	return 0 != ctx.enqueue(call{
   989  		args: fnargs{
   990  			fn: glfnIsBuffer,
   991  			a0: b.c(),
   992  		},
   993  		blocking: true,
   994  	})
   995  }
   996  
   997  func (ctx *context) IsEnabled(cap Enum) bool {
   998  	return 0 != ctx.enqueue(call{
   999  		args: fnargs{
  1000  			fn: glfnIsEnabled,
  1001  			a0: cap.c(),
  1002  		},
  1003  		blocking: true,
  1004  	})
  1005  }
  1006  
  1007  func (ctx *context) IsFramebuffer(fb Framebuffer) bool {
  1008  	return 0 != ctx.enqueue(call{
  1009  		args: fnargs{
  1010  			fn: glfnIsFramebuffer,
  1011  			a0: fb.c(),
  1012  		},
  1013  		blocking: true,
  1014  	})
  1015  }
  1016  
  1017  func (ctx *context) IsProgram(p Program) bool {
  1018  	return 0 != ctx.enqueue(call{
  1019  		args: fnargs{
  1020  			fn: glfnIsProgram,
  1021  			a0: p.c(),
  1022  		},
  1023  		blocking: true,
  1024  	})
  1025  }
  1026  
  1027  func (ctx *context) IsRenderbuffer(rb Renderbuffer) bool {
  1028  	return 0 != ctx.enqueue(call{
  1029  		args: fnargs{
  1030  			fn: glfnIsRenderbuffer,
  1031  			a0: rb.c(),
  1032  		},
  1033  		blocking: true,
  1034  	})
  1035  }
  1036  
  1037  func (ctx *context) IsShader(s Shader) bool {
  1038  	return 0 != ctx.enqueue(call{
  1039  		args: fnargs{
  1040  			fn: glfnIsShader,
  1041  			a0: s.c(),
  1042  		},
  1043  		blocking: true,
  1044  	})
  1045  }
  1046  
  1047  func (ctx *context) IsTexture(t Texture) bool {
  1048  	return 0 != ctx.enqueue(call{
  1049  		args: fnargs{
  1050  			fn: glfnIsTexture,
  1051  			a0: t.c(),
  1052  		},
  1053  		blocking: true,
  1054  	})
  1055  }
  1056  
  1057  func (ctx *context) LineWidth(width float32) {
  1058  	ctx.enqueue(call{
  1059  		args: fnargs{
  1060  			fn: glfnLineWidth,
  1061  			a0: uintptr(math.Float32bits(width)),
  1062  		},
  1063  	})
  1064  }
  1065  
  1066  func (ctx *context) LinkProgram(p Program) {
  1067  	ctx.enqueue(call{
  1068  		args: fnargs{
  1069  			fn: glfnLinkProgram,
  1070  			a0: p.c(),
  1071  		},
  1072  	})
  1073  }
  1074  
  1075  func (ctx *context) PixelStorei(pname Enum, param int32) {
  1076  	ctx.enqueue(call{
  1077  		args: fnargs{
  1078  			fn: glfnPixelStorei,
  1079  			a0: pname.c(),
  1080  			a1: uintptr(param),
  1081  		},
  1082  	})
  1083  }
  1084  
  1085  func (ctx *context) PolygonOffset(factor, units float32) {
  1086  	ctx.enqueue(call{
  1087  		args: fnargs{
  1088  			fn: glfnPolygonOffset,
  1089  			a0: uintptr(math.Float32bits(factor)),
  1090  			a1: uintptr(math.Float32bits(units)),
  1091  		},
  1092  	})
  1093  }
  1094  
  1095  func (ctx *context) ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) {
  1096  	ctx.enqueue(call{
  1097  		args: fnargs{
  1098  			fn: glfnReadPixels,
  1099  			// TODO(crawshaw): support PIXEL_PACK_BUFFER in GLES3, uses offset.
  1100  			a0: uintptr(x),
  1101  			a1: uintptr(y),
  1102  			a2: uintptr(width),
  1103  			a3: uintptr(height),
  1104  			a4: format.c(),
  1105  			a5: ty.c(),
  1106  		},
  1107  		parg:     unsafe.Pointer(&dst[0]),
  1108  		blocking: true,
  1109  	})
  1110  }
  1111  
  1112  func (ctx *context) ReleaseShaderCompiler() {
  1113  	ctx.enqueue(call{
  1114  		args: fnargs{
  1115  			fn: glfnReleaseShaderCompiler,
  1116  		},
  1117  	})
  1118  }
  1119  
  1120  func (ctx *context) RenderbufferStorage(target, internalFormat Enum, width, height int) {
  1121  	ctx.enqueue(call{
  1122  		args: fnargs{
  1123  			fn: glfnRenderbufferStorage,
  1124  			a0: target.c(),
  1125  			a1: internalFormat.c(),
  1126  			a2: uintptr(width),
  1127  			a3: uintptr(height),
  1128  		},
  1129  	})
  1130  }
  1131  
  1132  func (ctx *context) SampleCoverage(value float32, invert bool) {
  1133  	ctx.enqueue(call{
  1134  		args: fnargs{
  1135  			fn: glfnSampleCoverage,
  1136  			a0: uintptr(math.Float32bits(value)),
  1137  			a1: glBoolean(invert),
  1138  		},
  1139  	})
  1140  }
  1141  
  1142  func (ctx *context) Scissor(x, y, width, height int32) {
  1143  	ctx.enqueue(call{
  1144  		args: fnargs{
  1145  			fn: glfnScissor,
  1146  			a0: uintptr(x),
  1147  			a1: uintptr(y),
  1148  			a2: uintptr(width),
  1149  			a3: uintptr(height),
  1150  		},
  1151  	})
  1152  }
  1153  
  1154  func (ctx *context) ShaderSource(s Shader, src string) {
  1155  	strp, free := ctx.cStringPtr(src)
  1156  	defer free()
  1157  	ctx.enqueue(call{
  1158  		args: fnargs{
  1159  			fn: glfnShaderSource,
  1160  			a0: s.c(),
  1161  			a1: 1,
  1162  			a2: strp,
  1163  		},
  1164  		blocking: true,
  1165  	})
  1166  }
  1167  
  1168  func (ctx *context) StencilFunc(fn Enum, ref int, mask uint32) {
  1169  	ctx.enqueue(call{
  1170  		args: fnargs{
  1171  			fn: glfnStencilFunc,
  1172  			a0: fn.c(),
  1173  			a1: uintptr(ref),
  1174  			a2: uintptr(mask),
  1175  		},
  1176  	})
  1177  }
  1178  
  1179  func (ctx *context) StencilFuncSeparate(face, fn Enum, ref int, mask uint32) {
  1180  	ctx.enqueue(call{
  1181  		args: fnargs{
  1182  			fn: glfnStencilFuncSeparate,
  1183  			a0: face.c(),
  1184  			a1: fn.c(),
  1185  			a2: uintptr(ref),
  1186  			a3: uintptr(mask),
  1187  		},
  1188  	})
  1189  }
  1190  
  1191  func (ctx *context) StencilMask(mask uint32) {
  1192  	ctx.enqueue(call{
  1193  		args: fnargs{
  1194  			fn: glfnStencilMask,
  1195  			a0: uintptr(mask),
  1196  		},
  1197  	})
  1198  }
  1199  
  1200  func (ctx *context) StencilMaskSeparate(face Enum, mask uint32) {
  1201  	ctx.enqueue(call{
  1202  		args: fnargs{
  1203  			fn: glfnStencilMaskSeparate,
  1204  			a0: face.c(),
  1205  			a1: uintptr(mask),
  1206  		},
  1207  	})
  1208  }
  1209  
  1210  func (ctx *context) StencilOp(fail, zfail, zpass Enum) {
  1211  	ctx.enqueue(call{
  1212  		args: fnargs{
  1213  			fn: glfnStencilOp,
  1214  			a0: fail.c(),
  1215  			a1: zfail.c(),
  1216  			a2: zpass.c(),
  1217  		},
  1218  	})
  1219  }
  1220  
  1221  func (ctx *context) StencilOpSeparate(face, sfail, dpfail, dppass Enum) {
  1222  	ctx.enqueue(call{
  1223  		args: fnargs{
  1224  			fn: glfnStencilOpSeparate,
  1225  			a0: face.c(),
  1226  			a1: sfail.c(),
  1227  			a2: dpfail.c(),
  1228  			a3: dppass.c(),
  1229  		},
  1230  	})
  1231  }
  1232  
  1233  func (ctx *context) TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data []byte) {
  1234  	// It is common to pass TexImage2D a nil data, indicating that a
  1235  	// bound GL buffer is being used as the source. In that case, it
  1236  	// is not necessary to block.
  1237  	parg := unsafe.Pointer(nil)
  1238  	if len(data) > 0 {
  1239  		parg = unsafe.Pointer(&data[0])
  1240  	}
  1241  
  1242  	ctx.enqueue(call{
  1243  		args: fnargs{
  1244  			fn: glfnTexImage2D,
  1245  			// TODO(crawshaw): GLES3 offset for PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER.
  1246  			a0: target.c(),
  1247  			a1: uintptr(level),
  1248  			a2: uintptr(format),
  1249  			a3: uintptr(width),
  1250  			a4: uintptr(height),
  1251  			a5: format.c(),
  1252  			a6: ty.c(),
  1253  		},
  1254  		parg:     parg,
  1255  		blocking: parg != nil,
  1256  	})
  1257  }
  1258  
  1259  func (ctx *context) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) {
  1260  	ctx.enqueue(call{
  1261  		args: fnargs{
  1262  			fn: glfnTexSubImage2D,
  1263  			// TODO(crawshaw): GLES3 offset for PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER.
  1264  			a0: target.c(),
  1265  			a1: uintptr(level),
  1266  			a2: uintptr(x),
  1267  			a3: uintptr(y),
  1268  			a4: uintptr(width),
  1269  			a5: uintptr(height),
  1270  			a6: format.c(),
  1271  			a7: ty.c(),
  1272  		},
  1273  		parg:     unsafe.Pointer(&data[0]),
  1274  		blocking: true,
  1275  	})
  1276  }
  1277  
  1278  func (ctx *context) TexParameterf(target, pname Enum, param float32) {
  1279  	ctx.enqueue(call{
  1280  		args: fnargs{
  1281  			fn: glfnTexParameterf,
  1282  			a0: target.c(),
  1283  			a1: pname.c(),
  1284  			a2: uintptr(math.Float32bits(param)),
  1285  		},
  1286  	})
  1287  }
  1288  
  1289  func (ctx *context) TexParameterfv(target, pname Enum, params []float32) {
  1290  	ctx.enqueue(call{
  1291  		args: fnargs{
  1292  			fn: glfnTexParameterfv,
  1293  			a0: target.c(),
  1294  			a1: pname.c(),
  1295  		},
  1296  		parg:     unsafe.Pointer(&params[0]),
  1297  		blocking: true,
  1298  	})
  1299  }
  1300  
  1301  func (ctx *context) TexParameteri(target, pname Enum, param int) {
  1302  	ctx.enqueue(call{
  1303  		args: fnargs{
  1304  			fn: glfnTexParameteri,
  1305  			a0: target.c(),
  1306  			a1: pname.c(),
  1307  			a2: uintptr(param),
  1308  		},
  1309  	})
  1310  }
  1311  
  1312  func (ctx *context) TexParameteriv(target, pname Enum, params []int32) {
  1313  	ctx.enqueue(call{
  1314  		args: fnargs{
  1315  			fn: glfnTexParameteriv,
  1316  			a0: target.c(),
  1317  			a1: pname.c(),
  1318  		},
  1319  		parg:     unsafe.Pointer(&params[0]),
  1320  		blocking: true,
  1321  	})
  1322  }
  1323  
  1324  func (ctx *context) Uniform1f(dst Uniform, v float32) {
  1325  	ctx.enqueue(call{
  1326  		args: fnargs{
  1327  			fn: glfnUniform1f,
  1328  			a0: dst.c(),
  1329  			a1: uintptr(math.Float32bits(v)),
  1330  		},
  1331  	})
  1332  }
  1333  
  1334  func (ctx *context) Uniform1fv(dst Uniform, src []float32) {
  1335  	ctx.enqueue(call{
  1336  		args: fnargs{
  1337  			fn: glfnUniform1fv,
  1338  			a0: dst.c(),
  1339  			a1: uintptr(len(src)),
  1340  		},
  1341  		parg:     unsafe.Pointer(&src[0]),
  1342  		blocking: true,
  1343  	})
  1344  }
  1345  
  1346  func (ctx *context) Uniform1i(dst Uniform, v int) {
  1347  	ctx.enqueue(call{
  1348  		args: fnargs{
  1349  			fn: glfnUniform1i,
  1350  			a0: dst.c(),
  1351  			a1: uintptr(v),
  1352  		},
  1353  	})
  1354  }
  1355  
  1356  func (ctx *context) Uniform1iv(dst Uniform, src []int32) {
  1357  	ctx.enqueue(call{
  1358  		args: fnargs{
  1359  			fn: glfnUniform1iv,
  1360  			a0: dst.c(),
  1361  			a1: uintptr(len(src)),
  1362  		},
  1363  		parg:     unsafe.Pointer(&src[0]),
  1364  		blocking: true,
  1365  	})
  1366  }
  1367  
  1368  func (ctx *context) Uniform2f(dst Uniform, v0, v1 float32) {
  1369  	ctx.enqueue(call{
  1370  		args: fnargs{
  1371  			fn: glfnUniform2f,
  1372  			a0: dst.c(),
  1373  			a1: uintptr(math.Float32bits(v0)),
  1374  			a2: uintptr(math.Float32bits(v1)),
  1375  		},
  1376  	})
  1377  }
  1378  
  1379  func (ctx *context) Uniform2fv(dst Uniform, src []float32) {
  1380  	ctx.enqueue(call{
  1381  		args: fnargs{
  1382  			fn: glfnUniform2fv,
  1383  			a0: dst.c(),
  1384  			a1: uintptr(len(src) / 2),
  1385  		},
  1386  		parg:     unsafe.Pointer(&src[0]),
  1387  		blocking: true,
  1388  	})
  1389  }
  1390  
  1391  func (ctx *context) Uniform2i(dst Uniform, v0, v1 int) {
  1392  	ctx.enqueue(call{
  1393  		args: fnargs{
  1394  			fn: glfnUniform2i,
  1395  			a0: dst.c(),
  1396  			a1: uintptr(v0),
  1397  			a2: uintptr(v1),
  1398  		},
  1399  	})
  1400  }
  1401  
  1402  func (ctx *context) Uniform2iv(dst Uniform, src []int32) {
  1403  	ctx.enqueue(call{
  1404  		args: fnargs{
  1405  			fn: glfnUniform2iv,
  1406  			a0: dst.c(),
  1407  			a1: uintptr(len(src) / 2),
  1408  		},
  1409  		parg:     unsafe.Pointer(&src[0]),
  1410  		blocking: true,
  1411  	})
  1412  }
  1413  
  1414  func (ctx *context) Uniform3f(dst Uniform, v0, v1, v2 float32) {
  1415  	ctx.enqueue(call{
  1416  		args: fnargs{
  1417  			fn: glfnUniform3f,
  1418  			a0: dst.c(),
  1419  			a1: uintptr(math.Float32bits(v0)),
  1420  			a2: uintptr(math.Float32bits(v1)),
  1421  			a3: uintptr(math.Float32bits(v2)),
  1422  		},
  1423  	})
  1424  }
  1425  
  1426  func (ctx *context) Uniform3fv(dst Uniform, src []float32) {
  1427  	ctx.enqueue(call{
  1428  		args: fnargs{
  1429  			fn: glfnUniform3fv,
  1430  			a0: dst.c(),
  1431  			a1: uintptr(len(src) / 3),
  1432  		},
  1433  		parg:     unsafe.Pointer(&src[0]),
  1434  		blocking: true,
  1435  	})
  1436  }
  1437  
  1438  func (ctx *context) Uniform3i(dst Uniform, v0, v1, v2 int32) {
  1439  	ctx.enqueue(call{
  1440  		args: fnargs{
  1441  			fn: glfnUniform3i,
  1442  			a0: dst.c(),
  1443  			a1: uintptr(v0),
  1444  			a2: uintptr(v1),
  1445  			a3: uintptr(v2),
  1446  		},
  1447  	})
  1448  }
  1449  
  1450  func (ctx *context) Uniform3iv(dst Uniform, src []int32) {
  1451  	ctx.enqueue(call{
  1452  		args: fnargs{
  1453  			fn: glfnUniform3iv,
  1454  			a0: dst.c(),
  1455  			a1: uintptr(len(src) / 3),
  1456  		},
  1457  		parg:     unsafe.Pointer(&src[0]),
  1458  		blocking: true,
  1459  	})
  1460  }
  1461  
  1462  func (ctx *context) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {
  1463  	ctx.enqueue(call{
  1464  		args: fnargs{
  1465  			fn: glfnUniform4f,
  1466  			a0: dst.c(),
  1467  			a1: uintptr(math.Float32bits(v0)),
  1468  			a2: uintptr(math.Float32bits(v1)),
  1469  			a3: uintptr(math.Float32bits(v2)),
  1470  			a4: uintptr(math.Float32bits(v3)),
  1471  		},
  1472  	})
  1473  }
  1474  
  1475  func (ctx *context) Uniform4fv(dst Uniform, src []float32) {
  1476  	ctx.enqueue(call{
  1477  		args: fnargs{
  1478  			fn: glfnUniform4fv,
  1479  			a0: dst.c(),
  1480  			a1: uintptr(len(src) / 4),
  1481  		},
  1482  		parg:     unsafe.Pointer(&src[0]),
  1483  		blocking: true,
  1484  	})
  1485  }
  1486  
  1487  func (ctx *context) Uniform4i(dst Uniform, v0, v1, v2, v3 int32) {
  1488  	ctx.enqueue(call{
  1489  		args: fnargs{
  1490  			fn: glfnUniform4i,
  1491  			a0: dst.c(),
  1492  			a1: uintptr(v0),
  1493  			a2: uintptr(v1),
  1494  			a3: uintptr(v2),
  1495  			a4: uintptr(v3),
  1496  		},
  1497  	})
  1498  }
  1499  
  1500  func (ctx *context) Uniform4iv(dst Uniform, src []int32) {
  1501  	ctx.enqueue(call{
  1502  		args: fnargs{
  1503  			fn: glfnUniform4iv,
  1504  			a0: dst.c(),
  1505  			a1: uintptr(len(src) / 4),
  1506  		},
  1507  		parg:     unsafe.Pointer(&src[0]),
  1508  		blocking: true,
  1509  	})
  1510  }
  1511  
  1512  func (ctx *context) UniformMatrix2fv(dst Uniform, src []float32) {
  1513  	ctx.enqueue(call{
  1514  		args: fnargs{
  1515  			fn: glfnUniformMatrix2fv,
  1516  			// OpenGL ES 2 does not support transpose.
  1517  			a0: dst.c(),
  1518  			a1: uintptr(len(src) / 4),
  1519  		},
  1520  		parg:     unsafe.Pointer(&src[0]),
  1521  		blocking: true,
  1522  	})
  1523  }
  1524  
  1525  func (ctx *context) UniformMatrix3fv(dst Uniform, src []float32) {
  1526  	ctx.enqueue(call{
  1527  		args: fnargs{
  1528  			fn: glfnUniformMatrix3fv,
  1529  			a0: dst.c(),
  1530  			a1: uintptr(len(src) / 9),
  1531  		},
  1532  		parg:     unsafe.Pointer(&src[0]),
  1533  		blocking: true,
  1534  	})
  1535  }
  1536  
  1537  func (ctx *context) UniformMatrix4fv(dst Uniform, src []float32) {
  1538  	ctx.enqueue(call{
  1539  		args: fnargs{
  1540  			fn: glfnUniformMatrix4fv,
  1541  			a0: dst.c(),
  1542  			a1: uintptr(len(src) / 16),
  1543  		},
  1544  		parg:     unsafe.Pointer(&src[0]),
  1545  		blocking: true,
  1546  	})
  1547  }
  1548  
  1549  func (ctx *context) UseProgram(p Program) {
  1550  	ctx.enqueue(call{
  1551  		args: fnargs{
  1552  			fn: glfnUseProgram,
  1553  			a0: p.c(),
  1554  		},
  1555  	})
  1556  }
  1557  
  1558  func (ctx *context) ValidateProgram(p Program) {
  1559  	ctx.enqueue(call{
  1560  		args: fnargs{
  1561  			fn: glfnValidateProgram,
  1562  			a0: p.c(),
  1563  		},
  1564  	})
  1565  }
  1566  
  1567  func (ctx *context) VertexAttrib1f(dst Attrib, x float32) {
  1568  	ctx.enqueue(call{
  1569  		args: fnargs{
  1570  			fn: glfnVertexAttrib1f,
  1571  			a0: dst.c(),
  1572  			a1: uintptr(math.Float32bits(x)),
  1573  		},
  1574  	})
  1575  }
  1576  
  1577  func (ctx *context) VertexAttrib1fv(dst Attrib, src []float32) {
  1578  	ctx.enqueue(call{
  1579  		args: fnargs{
  1580  			fn: glfnVertexAttrib1fv,
  1581  			a0: dst.c(),
  1582  		},
  1583  		parg:     unsafe.Pointer(&src[0]),
  1584  		blocking: true,
  1585  	})
  1586  }
  1587  
  1588  func (ctx *context) VertexAttrib2f(dst Attrib, x, y float32) {
  1589  	ctx.enqueue(call{
  1590  		args: fnargs{
  1591  			fn: glfnVertexAttrib2f,
  1592  			a0: dst.c(),
  1593  			a1: uintptr(math.Float32bits(x)),
  1594  			a2: uintptr(math.Float32bits(y)),
  1595  		},
  1596  	})
  1597  }
  1598  
  1599  func (ctx *context) VertexAttrib2fv(dst Attrib, src []float32) {
  1600  	ctx.enqueue(call{
  1601  		args: fnargs{
  1602  			fn: glfnVertexAttrib2fv,
  1603  			a0: dst.c(),
  1604  		},
  1605  		parg:     unsafe.Pointer(&src[0]),
  1606  		blocking: true,
  1607  	})
  1608  }
  1609  
  1610  func (ctx *context) VertexAttrib3f(dst Attrib, x, y, z float32) {
  1611  	ctx.enqueue(call{
  1612  		args: fnargs{
  1613  			fn: glfnVertexAttrib3f,
  1614  			a0: dst.c(),
  1615  			a1: uintptr(math.Float32bits(x)),
  1616  			a2: uintptr(math.Float32bits(y)),
  1617  			a3: uintptr(math.Float32bits(z)),
  1618  		},
  1619  	})
  1620  }
  1621  
  1622  func (ctx *context) VertexAttrib3fv(dst Attrib, src []float32) {
  1623  	ctx.enqueue(call{
  1624  		args: fnargs{
  1625  			fn: glfnVertexAttrib3fv,
  1626  			a0: dst.c(),
  1627  		},
  1628  		parg:     unsafe.Pointer(&src[0]),
  1629  		blocking: true,
  1630  	})
  1631  }
  1632  
  1633  func (ctx *context) VertexAttrib4f(dst Attrib, x, y, z, w float32) {
  1634  	ctx.enqueue(call{
  1635  		args: fnargs{
  1636  			fn: glfnVertexAttrib4f,
  1637  			a0: dst.c(),
  1638  			a1: uintptr(math.Float32bits(x)),
  1639  			a2: uintptr(math.Float32bits(y)),
  1640  			a3: uintptr(math.Float32bits(z)),
  1641  			a4: uintptr(math.Float32bits(w)),
  1642  		},
  1643  	})
  1644  }
  1645  
  1646  func (ctx *context) VertexAttrib4fv(dst Attrib, src []float32) {
  1647  	ctx.enqueue(call{
  1648  		args: fnargs{
  1649  			fn: glfnVertexAttrib4fv,
  1650  			a0: dst.c(),
  1651  		},
  1652  		parg:     unsafe.Pointer(&src[0]),
  1653  		blocking: true,
  1654  	})
  1655  }
  1656  
  1657  func (ctx *context) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {
  1658  	ctx.enqueue(call{
  1659  		args: fnargs{
  1660  			fn: glfnVertexAttribPointer,
  1661  			a0: dst.c(),
  1662  			a1: uintptr(size),
  1663  			a2: ty.c(),
  1664  			a3: glBoolean(normalized),
  1665  			a4: uintptr(stride),
  1666  			a5: uintptr(offset),
  1667  		},
  1668  	})
  1669  }
  1670  
  1671  func (ctx *context) Viewport(x, y, width, height int) {
  1672  	ctx.enqueue(call{
  1673  		args: fnargs{
  1674  			fn: glfnViewport,
  1675  			a0: uintptr(x),
  1676  			a1: uintptr(y),
  1677  			a2: uintptr(width),
  1678  			a3: uintptr(height),
  1679  		},
  1680  	})
  1681  }