gl: compatibility with cgo pointer rules proposal

The current cgo proposal (golang/go#12416) is at:

https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md

Maybe relevant to golang/go#12718

Change-Id: I5a399eec703ba3a793ab64d979bb73b083f23df9
Reviewed-on: https://go-review.googlesource.com/15100
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/gl/gl.go b/gl/gl.go
index 45f0103..a0da12c 100644
--- a/gl/gl.go
+++ b/gl/gl.go
@@ -146,14 +146,18 @@
 }
 
 func (ctx *context) BufferData(target Enum, src []byte, usage Enum) {
+	parg := unsafe.Pointer(nil)
+	if len(src) > 0 {
+		parg = unsafe.Pointer(&src[0])
+	}
 	ctx.enqueue(call{
 		args: C.struct_fnargs{
 			fn: C.glfnBufferData,
 			a0: target.c(),
 			a1: C.uintptr_t(len(src)),
-			a2: (C.uintptr_t)(uintptr(unsafe.Pointer(&src[0]))),
-			a3: usage.c(),
+			a2: usage.c(),
 		},
+		parg:     parg,
 		blocking: true,
 	})
 }
@@ -177,8 +181,8 @@
 			a0: target.c(),
 			a1: C.uintptr_t(offset),
 			a2: C.uintptr_t(len(data)),
-			a3: (C.uintptr_t)(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -264,8 +268,8 @@
 			a4: C.uintptr_t(height),
 			a5: C.uintptr_t(border),
 			a6: C.uintptr_t(len(data)),
-			a7: C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -282,8 +286,8 @@
 			a5: C.uintptr_t(height),
 			a6: format.c(),
 			a7: C.uintptr_t(len(data)),
-			a8: C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -704,8 +708,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnGetFloatv,
 			a0: pname.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -717,8 +721,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnGetIntegerv,
 			a0: pname.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&buf[0]))),
 		},
+		parg:     unsafe.Pointer(&buf[0]),
 		blocking: true,
 	})
 
@@ -893,8 +897,8 @@
 			fn: C.glfnGetTexParameterfv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -905,7 +909,6 @@
 			fn: C.glfnGetTexParameteriv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
 		blocking: true,
 	})
@@ -917,8 +920,8 @@
 			fn: C.glfnGetUniformfv,
 			a0: p.c(),
 			a1: src.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -929,8 +932,8 @@
 			fn: C.glfnGetUniformiv,
 			a0: p.c(),
 			a1: src.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -940,8 +943,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnGetUniformLocation,
 			a0: p.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(C.CString(name)))),
 		},
+		parg:     unsafe.Pointer(C.CString(name)),
 		blocking: true,
 	}))}
 }
@@ -958,8 +961,8 @@
 			fn: C.glfnGetVertexAttribfv,
 			a0: src.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -976,8 +979,8 @@
 			fn: C.glfnGetVertexAttribiv,
 			a0: src.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -1111,8 +1114,8 @@
 			a3: C.uintptr_t(height),
 			a4: format.c(),
 			a5: ty.c(),
-			a6: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -1246,9 +1249,9 @@
 	// It is common to pass TexImage2D a nil data, indicating that a
 	// bound GL buffer is being used as the source. In that case, it
 	// is not necessary to block.
-	blocking, a7 := false, C.uintptr_t(0)
+	parg := unsafe.Pointer(nil)
 	if len(data) > 0 {
-		blocking, a7 = true, C.uintptr_t(uintptr(unsafe.Pointer(&data[0])))
+		parg = unsafe.Pointer(&data[0])
 	}
 
 	ctx.enqueue(call{
@@ -1262,9 +1265,9 @@
 			a4: C.uintptr_t(height),
 			a5: format.c(),
 			a6: ty.c(),
-			a7: a7,
 		},
-		blocking: blocking,
+		parg:     parg,
+		blocking: parg != nil,
 	})
 }
 
@@ -1281,8 +1284,8 @@
 			a5: C.uintptr_t(height),
 			a6: format.c(),
 			a7: ty.c(),
-			a8: C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -1304,8 +1307,8 @@
 			fn: C.glfnTexParameterfv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&params[0]))),
 		},
+		parg:     unsafe.Pointer(&params[0]),
 		blocking: true,
 	})
 }
@@ -1327,8 +1330,8 @@
 			fn: C.glfnTexParameteriv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&params[0]))),
 		},
+		parg:     unsafe.Pointer(&params[0]),
 		blocking: true,
 	})
 }
@@ -1349,8 +1352,8 @@
 			fn: C.glfnUniform1fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src)),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1371,8 +1374,8 @@
 			fn: C.glfnUniform1iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src)),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1394,8 +1397,8 @@
 			fn: C.glfnUniform2fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 2),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1417,8 +1420,8 @@
 			fn: C.glfnUniform2iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 2),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1441,8 +1444,8 @@
 			fn: C.glfnUniform3fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 3),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1465,8 +1468,8 @@
 			fn: C.glfnUniform3iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 3),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1490,8 +1493,8 @@
 			fn: C.glfnUniform4fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 4),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1515,8 +1518,8 @@
 			fn: C.glfnUniform4iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 4),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1528,8 +1531,8 @@
 			// OpenGL ES 2 does not support transpose.
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 4),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1540,8 +1543,8 @@
 			fn: C.glfnUniformMatrix3fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 9),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1552,8 +1555,8 @@
 			fn: C.glfnUniformMatrix4fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 16),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1591,8 +1594,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib1fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1613,8 +1616,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib2fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1636,8 +1639,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib3fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -1660,8 +1663,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib4fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
diff --git a/gl/gldebug.go b/gl/gldebug.go
index a0d152e..380e2bb 100644
--- a/gl/gldebug.go
+++ b/gl/gldebug.go
@@ -806,14 +806,18 @@
 		errstr := ctx.errDrain()
 		log.Printf("gl.BufferData(%v, len(%d), %v) %v", target, len(src), usage, errstr)
 	}()
+	parg := unsafe.Pointer(nil)
+	if len(src) > 0 {
+		parg = unsafe.Pointer(&src[0])
+	}
 	ctx.enqueue(call{
 		args: C.struct_fnargs{
 			fn: C.glfnBufferData,
 			a0: target.c(),
 			a1: C.uintptr_t(len(src)),
-			a2: (C.uintptr_t)(uintptr(unsafe.Pointer(&src[0]))),
-			a3: usage.c(),
+			a2: usage.c(),
 		},
+		parg:     parg,
 		blocking: true,
 	})
 }
@@ -845,8 +849,8 @@
 			a0: target.c(),
 			a1: C.uintptr_t(offset),
 			a2: C.uintptr_t(len(data)),
-			a3: (C.uintptr_t)(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -964,8 +968,8 @@
 			a4: C.uintptr_t(height),
 			a5: C.uintptr_t(border),
 			a6: C.uintptr_t(len(data)),
-			a7: C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -986,8 +990,8 @@
 			a5: C.uintptr_t(height),
 			a6: format.c(),
 			a7: C.uintptr_t(len(data)),
-			a8: C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -1549,8 +1553,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnGetFloatv,
 			a0: pname.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -1565,8 +1569,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnGetIntegerv,
 			a0: pname.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&buf[0]))),
 		},
+		parg:     unsafe.Pointer(&buf[0]),
 		blocking: true,
 	})
 	for i, v := range buf {
@@ -1780,8 +1784,8 @@
 			fn: C.glfnGetTexParameterfv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -1796,7 +1800,6 @@
 			fn: C.glfnGetTexParameteriv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
 		blocking: true,
 	})
@@ -1812,8 +1815,8 @@
 			fn: C.glfnGetUniformfv,
 			a0: p.c(),
 			a1: src.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -1828,8 +1831,8 @@
 			fn: C.glfnGetUniformiv,
 			a0: p.c(),
 			a1: src.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -1844,8 +1847,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnGetUniformLocation,
 			a0: p.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(C.CString(name)))),
 		},
+		parg:     unsafe.Pointer(C.CString(name)),
 		blocking: true,
 	}))}
 }
@@ -1870,8 +1873,8 @@
 			fn: C.glfnGetVertexAttribfv,
 			a0: src.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -1896,8 +1899,8 @@
 			fn: C.glfnGetVertexAttribiv,
 			a0: src.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -2083,8 +2086,8 @@
 			a3: C.uintptr_t(height),
 			a4: format.c(),
 			a5: ty.c(),
-			a6: C.uintptr_t(uintptr(unsafe.Pointer(&dst[0]))),
 		},
+		parg:     unsafe.Pointer(&dst[0]),
 		blocking: true,
 	})
 }
@@ -2259,9 +2262,9 @@
 		errstr := ctx.errDrain()
 		log.Printf("gl.TexImage2D(%v, %v, %v, %v, %v, %v, len(%d)) %v", target, level, width, height, format, ty, len(data), errstr)
 	}()
-	blocking, a7 := false, C.uintptr_t(0)
+	parg := unsafe.Pointer(nil)
 	if len(data) > 0 {
-		blocking, a7 = true, C.uintptr_t(uintptr(unsafe.Pointer(&data[0])))
+		parg = unsafe.Pointer(&data[0])
 	}
 	ctx.enqueue(call{
 		args: C.struct_fnargs{
@@ -2274,9 +2277,9 @@
 			a4: C.uintptr_t(height),
 			a5: format.c(),
 			a6: ty.c(),
-			a7: a7,
 		},
-		blocking: blocking,
+		parg:     parg,
+		blocking: parg != nil,
 	})
 }
 
@@ -2297,8 +2300,8 @@
 			a5: C.uintptr_t(height),
 			a6: format.c(),
 			a7: ty.c(),
-			a8: C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))),
 		},
+		parg:     unsafe.Pointer(&data[0]),
 		blocking: true,
 	})
 }
@@ -2328,8 +2331,8 @@
 			fn: C.glfnTexParameterfv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&params[0]))),
 		},
+		parg:     unsafe.Pointer(&params[0]),
 		blocking: true,
 	})
 }
@@ -2359,8 +2362,8 @@
 			fn: C.glfnTexParameteriv,
 			a0: target.c(),
 			a1: pname.c(),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&params[0]))),
 		},
+		parg:     unsafe.Pointer(&params[0]),
 		blocking: true,
 	})
 }
@@ -2389,8 +2392,8 @@
 			fn: C.glfnUniform1fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src)),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2419,8 +2422,8 @@
 			fn: C.glfnUniform1iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src)),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2450,8 +2453,8 @@
 			fn: C.glfnUniform2fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 2),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2481,8 +2484,8 @@
 			fn: C.glfnUniform2iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 2),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2513,8 +2516,8 @@
 			fn: C.glfnUniform3fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 3),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2545,8 +2548,8 @@
 			fn: C.glfnUniform3iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 3),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2578,8 +2581,8 @@
 			fn: C.glfnUniform4fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 4),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2611,8 +2614,8 @@
 			fn: C.glfnUniform4iv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 4),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2628,8 +2631,8 @@
 
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 4),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2644,8 +2647,8 @@
 			fn: C.glfnUniformMatrix3fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 9),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2660,8 +2663,8 @@
 			fn: C.glfnUniformMatrix4fv,
 			a0: dst.c(),
 			a1: C.uintptr_t(len(src) / 16),
-			a2: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2715,8 +2718,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib1fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2745,8 +2748,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib2fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2776,8 +2779,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib3fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
@@ -2808,8 +2811,8 @@
 		args: C.struct_fnargs{
 			fn: C.glfnVertexAttrib4fv,
 			a0: dst.c(),
-			a1: C.uintptr_t(uintptr(unsafe.Pointer(&src[0]))),
 		},
+		parg:     unsafe.Pointer(&src[0]),
 		blocking: true,
 	})
 }
diff --git a/gl/work.c b/gl/work.c
index bcc1b4c..f400784 100644
--- a/gl/work.c
+++ b/gl/work.c
@@ -8,7 +8,7 @@
 #include "_cgo_export.h"
 #include "work.h"
 
-uintptr_t processFn(struct fnargs* args) {
+uintptr_t processFn(struct fnargs* args, char* parg) {
 	uintptr_t ret = 0;
 	switch (args->fn) {
 	case glfnUNDEFINED:
@@ -52,10 +52,10 @@
 		glBlendFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3);
 		break;
 	case glfnBufferData:
-		glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2, (GLenum)args->a3);
+		glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg, (GLenum)args->a2);
 		break;
 	case glfnBufferSubData:
-		glBufferSubData((GLenum)args->a0, (GLint)args->a1, (GLsizeiptr)args->a2, (GLvoid*)args->a3);
+		glBufferSubData((GLenum)args->a0, (GLint)args->a1, (GLsizeiptr)args->a2, (GLvoid*)parg);
 		break;
 	case glfnCheckFramebufferStatus:
 		ret = glCheckFramebufferStatus((GLenum)args->a0);
@@ -79,10 +79,10 @@
 		glCompileShader((GLint)args->a0);
 		break;
 	case glfnCompressedTexImage2D:
-		glCompressedTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLsizeiptr)args->a6, (GLvoid*)args->a7);
+		glCompressedTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLsizeiptr)args->a6, (GLvoid*)parg);
 		break;
 	case glfnCompressedTexSubImage2D:
-		glCompressedTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLenum)args->a6, (GLsizeiptr)args->a7, (GLvoid*)args->a8);
+		glCompressedTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLenum)args->a6, (GLsizeiptr)args->a7, (GLvoid*)parg);
 		break;
 	case glfnCopyTexImage2D:
 		glCopyTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7);
@@ -211,10 +211,10 @@
 		glGetBufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret);
 		break;
 	case glfnGetFloatv:
-		glGetFloatv((GLenum)args->a0, (GLfloat*)args->a1);
+		glGetFloatv((GLenum)args->a0, (GLfloat*)parg);
 		break;
 	case glfnGetIntegerv:
-		glGetIntegerv((GLenum)args->a0, (GLint*)args->a1);
+		glGetIntegerv((GLenum)args->a0, (GLint*)parg);
 		break;
 	case glfnGetError:
 		ret = glGetError();
@@ -247,26 +247,26 @@
 		ret = (uintptr_t)glGetString((GLenum)args->a0);
 		break;
 	case glfnGetTexParameterfv:
-		glGetTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)args->a2);
+		glGetTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg);
 		break;
 	case glfnGetTexParameteriv:
-		glGetTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)args->a2);
+		glGetTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg);
 		break;
 	case glfnGetUniformfv:
-		glGetUniformfv((GLuint)args->a0, (GLint)args->a1, (GLfloat*)args->a2);
+		glGetUniformfv((GLuint)args->a0, (GLint)args->a1, (GLfloat*)parg);
 		break;
 	case glfnGetUniformiv:
-		glGetUniformiv((GLuint)args->a0, (GLint)args->a1, (GLint*)args->a2);
+		glGetUniformiv((GLuint)args->a0, (GLint)args->a1, (GLint*)parg);
 		break;
 	case glfnGetUniformLocation:
-		ret = glGetUniformLocation((GLint)args->a0, (GLchar*)args->a1);
+		ret = glGetUniformLocation((GLint)args->a0, (GLchar*)parg);
 		free((void*)args->a1);
 		break;
 	case glfnGetVertexAttribfv:
-		glGetVertexAttribfv((GLuint)args->a0, (GLenum)args->a1, (GLfloat*)args->a2);
+		glGetVertexAttribfv((GLuint)args->a0, (GLenum)args->a1, (GLfloat*)parg);
 		break;
 	case glfnGetVertexAttribiv:
-		glGetVertexAttribiv((GLuint)args->a0, (GLenum)args->a1, (GLint*)args->a2);
+		glGetVertexAttribiv((GLuint)args->a0, (GLenum)args->a1, (GLint*)parg);
 		break;
 	case glfnHint:
 		glHint((GLenum)args->a0, (GLenum)args->a1);
@@ -305,7 +305,7 @@
 		glPolygonOffset(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1);
 		break;
 	case glfnReadPixels:
-		glReadPixels((GLint)args->a0, (GLint)args->a1, (GLsizei)args->a2, (GLsizei)args->a3, (GLenum)args->a4, (GLenum)args->a5, (void*)args->a6);
+		glReadPixels((GLint)args->a0, (GLint)args->a1, (GLsizei)args->a2, (GLsizei)args->a3, (GLenum)args->a4, (GLenum)args->a5, (void*)parg);
 		break;
 	case glfnReleaseShaderCompiler:
 		glReleaseShaderCompiler();
@@ -356,7 +356,7 @@
 			0, // border
 			(GLenum)args->a5,
 			(GLenum)args->a6,
-			(const GLvoid*)args->a7);
+			(const GLvoid*)parg);
 		break;
 	case glfnTexSubImage2D:
 		glTexSubImage2D(
@@ -368,76 +368,76 @@
 			(GLsizei)args->a5,
 			(GLenum)args->a6,
 			(GLenum)args->a7,
-			(const GLvoid*)args->a8);
+			(const GLvoid*)parg);
 		break;
 	case glfnTexParameterf:
 		glTexParameterf((GLenum)args->a0, (GLenum)args->a1, *(GLfloat*)&args->a2);
 		break;
 	case glfnTexParameterfv:
-		glTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)args->a2);
+		glTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg);
 		break;
 	case glfnTexParameteri:
 		glTexParameteri((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2);
 		break;
 	case glfnTexParameteriv:
-		glTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)args->a2);
+		glTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg);
 		break;
 	case glfnUniform1f:
 		glUniform1f((GLint)args->a0, *(GLfloat*)&args->a1);
 		break;
 	case glfnUniform1fv:
-		glUniform1fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform1fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniform1i:
 		glUniform1i((GLint)args->a0, (GLint)args->a1);
 		break;
 	case glfnUniform1iv:
-		glUniform1iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform1iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniform2f:
 		glUniform2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2);
 		break;
 	case glfnUniform2fv:
-		glUniform2fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform2fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniform2i:
 		glUniform2i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2);
 		break;
 	case glfnUniform2iv:
-		glUniform2iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform2iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniform3f:
 		glUniform3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
 		break;
 	case glfnUniform3fv:
-		glUniform3fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform3fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniform3i:
 		glUniform3i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3);
 		break;
 	case glfnUniform3iv:
-		glUniform3iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform3iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniform4f:
 		glUniform4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4);
 		break;
 	case glfnUniform4fv:
-		glUniform4fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform4fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniform4i:
 		glUniform4i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4);
 		break;
 	case glfnUniform4iv:
-		glUniform4iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)args->a2);
+		glUniform4iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
 		break;
 	case glfnUniformMatrix2fv:
-		glUniformMatrix2fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)args->a2);
+		glUniformMatrix2fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
 		break;
 	case glfnUniformMatrix3fv:
-		glUniformMatrix3fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)args->a2);
+		glUniformMatrix3fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
 		break;
 	case glfnUniformMatrix4fv:
-		glUniformMatrix4fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)args->a2);
+		glUniformMatrix4fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
 		break;
 	case glfnUseProgram:
 		glUseProgram((GLint)args->a0);
@@ -449,25 +449,25 @@
 		glVertexAttrib1f((GLint)args->a0, *(GLfloat*)&args->a1);
 		break;
 	case glfnVertexAttrib1fv:
-		glVertexAttrib1fv((GLint)args->a0, (GLfloat*)args->a1);
+		glVertexAttrib1fv((GLint)args->a0, (GLfloat*)parg);
 		break;
 	case glfnVertexAttrib2f:
 		glVertexAttrib2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2);
 		break;
 	case glfnVertexAttrib2fv:
-		glVertexAttrib2fv((GLint)args->a0, (GLfloat*)args->a1);
+		glVertexAttrib2fv((GLint)args->a0, (GLfloat*)parg);
 		break;
 	case glfnVertexAttrib3f:
 		glVertexAttrib3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
 		break;
 	case glfnVertexAttrib3fv:
-		glVertexAttrib3fv((GLint)args->a0, (GLfloat*)args->a1);
+		glVertexAttrib3fv((GLint)args->a0, (GLfloat*)parg);
 		break;
 	case glfnVertexAttrib4f:
 		glVertexAttrib4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4);
 		break;
 	case glfnVertexAttrib4fv:
-		glVertexAttrib4fv((GLint)args->a0, (GLfloat*)args->a1);
+		glVertexAttrib4fv((GLint)args->a0, (GLfloat*)parg);
 		break;
 	case glfnVertexAttribPointer:
 		glVertexAttribPointer((GLuint)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLboolean)args->a3, (GLsizei)args->a4, (const GLvoid*)args->a5);
diff --git a/gl/work.go b/gl/work.go
index 3c4b34a..eda47ce 100644
--- a/gl/work.go
+++ b/gl/work.go
@@ -20,17 +20,25 @@
 #include <stdint.h>
 #include "work.h"
 
-// TODO: return uintptr_t instead of taking ret.
-void process(struct fnargs* cargs, int count, uintptr_t* ret) {
-	int i;
-	for (i = 0; i < count; i++) {
-		*ret = processFn(&cargs[i]);
+uintptr_t process(struct fnargs* cargs, char* parg0, char* parg1, char* parg2, int count) {
+	uintptr_t ret;
+
+	ret = processFn(&cargs[0], parg0);
+	if (count > 1) {
+		ret = processFn(&cargs[1], parg1);
 	}
+	if (count > 2) {
+		ret = processFn(&cargs[2], parg2);
+	}
+
+	return ret;
 }
 */
 import "C"
 
-const workbufLen = 10
+import "unsafe"
+
+const workbufLen = 3
 
 type context struct {
 	cptr uintptr
@@ -52,7 +60,7 @@
 	retvalue chan C.uintptr_t
 
 	cargs [workbufLen]C.struct_fnargs
-	ret   C.uintptr_t
+	parg  [workbufLen]*C.char
 }
 
 func (ctx *context) WorkAvailable() <-chan struct{} { return ctx.workAvailable }
@@ -71,6 +79,7 @@
 
 type call struct {
 	args     C.struct_fnargs
+	parg     unsafe.Pointer
 	blocking bool
 }
 
@@ -89,7 +98,7 @@
 }
 
 func (ctx *context) DoWork() {
-	queue := make([]call, 0, len(ctx.work))
+	queue := make([]call, 0, len(ctx.work)) // len(ctx.work) == workbufLen
 	for {
 		// Wait until at least one piece of work is ready.
 		// Accumulate work until a piece is marked as blocking.
@@ -114,13 +123,14 @@
 		// Process the queued GL functions.
 		for i, q := range queue {
 			ctx.cargs[i] = q.args
+			ctx.parg[i] = (*C.char)(q.parg)
 		}
-		C.process(&ctx.cargs[0], C.int(len(queue)), &ctx.ret)
+		ret := C.process(&ctx.cargs[0], ctx.parg[0], ctx.parg[1], ctx.parg[2], C.int(len(queue)))
 
 		// Cleanup and signal.
 		queue = queue[:0]
 		if blocking {
-			ctx.retvalue <- ctx.ret
+			ctx.retvalue <- ret
 		}
 	}
 }
diff --git a/gl/work.h b/gl/work.h
index bfd3a6e..59eba7b 100644
--- a/gl/work.h
+++ b/gl/work.h
@@ -171,9 +171,8 @@
 	uintptr_t a5;
 	uintptr_t a6;
 	uintptr_t a7;
-	uintptr_t a8;
 };
 
 extern uintptr_t ret;
 
-extern uintptr_t processFn(struct fnargs* args);
+extern uintptr_t processFn(struct fnargs* args, char* parg);