gl: support for GL ES 3.0
This CL covers the basic structure for supporting ES 3.0 where the platform provides it, and includes one ES 3.0 function as a proof-of-concept. The rest of the functions and constant values will follow in later CLs. ES 3.0 is available everywhere except Android older than version 4.3, approximately half of Android devices today: https://developer.android.com/about/dashboards/index.html#OpenGL Change-Id: Ief7714131227c447a0c603dadad0bd5285999bb3 Reviewed-on: https://go-review.googlesource.com/23821 Reviewed-by: Nigel Tao <nigeltao@golang.org>
This commit is contained in:
parent
d6153aa12b
commit
b8e0f58304
10
gl/doc.go
10
gl/doc.go
@ -3,7 +3,15 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package gl implements Go bindings for OpenGL ES 2.
|
||||
Package gl implements Go bindings for OpenGL ES 2.0 and ES 3.0.
|
||||
|
||||
The GL functions are defined on a Context object that is responsible for
|
||||
tracking a GL context. Typically a windowing system package (such as
|
||||
golang.org/x/exp/shiny/screen) will call NewContext and provide
|
||||
a gl.Context for a user application.
|
||||
|
||||
If the gl package is compiled on a platform capable of supporting ES 3.0,
|
||||
the gl.Context object also implements gl.Context3.
|
||||
|
||||
The bindings are deliberately minimal, staying as close the C API as
|
||||
possible. The semantics of each function maps onto functions
|
||||
|
3
gl/fn.go
3
gl/fn.go
@ -23,6 +23,8 @@ type fnargs struct {
|
||||
a5 uintptr
|
||||
a6 uintptr
|
||||
a7 uintptr
|
||||
a8 uintptr
|
||||
a9 uintptr
|
||||
}
|
||||
|
||||
type glfn int
|
||||
@ -41,6 +43,7 @@ const (
|
||||
glfnBlendEquationSeparate
|
||||
glfnBlendFunc
|
||||
glfnBlendFuncSeparate
|
||||
glfnBlitFramebuffer
|
||||
glfnBufferData
|
||||
glfnBufferSubData
|
||||
glfnCheckFramebufferStatus
|
||||
|
@ -103,6 +103,13 @@ func main() {
|
||||
if fn.Recv == nil || fn.Recv.List[0].Names[0].Name != "ctx" {
|
||||
continue
|
||||
}
|
||||
tname := "<unknown>"
|
||||
t := fn.Recv.List[0].Type
|
||||
if star, ok := t.(*ast.StarExpr); ok {
|
||||
tname = "*" + star.X.(*ast.Ident).Name
|
||||
} else if t, ok := t.(*ast.Ident); ok {
|
||||
tname = t.Name
|
||||
}
|
||||
|
||||
var (
|
||||
params []string
|
||||
@ -112,7 +119,7 @@ func main() {
|
||||
)
|
||||
|
||||
// Print function signature.
|
||||
fmt.Fprintf(buf, "func (ctx *context) %s(", fn.Name.Name)
|
||||
fmt.Fprintf(buf, "func (ctx %s) %s(", tname, fn.Name.Name)
|
||||
for i, p := range fn.Type.Params.List {
|
||||
if i > 0 {
|
||||
fmt.Fprint(buf, ", ")
|
||||
|
18
gl/gl.go
18
gl/gl.go
@ -1679,3 +1679,21 @@ func (ctx *context) Viewport(x, y, width, height int) {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (ctx context3) BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1 int, mask uint, filter Enum) {
|
||||
ctx.enqueue(call{
|
||||
args: fnargs{
|
||||
fn: glfnBlitFramebuffer,
|
||||
a0: uintptr(srcX0),
|
||||
a1: uintptr(srcY0),
|
||||
a2: uintptr(srcX1),
|
||||
a3: uintptr(srcY1),
|
||||
a4: uintptr(dstX0),
|
||||
a5: uintptr(dstY0),
|
||||
a6: uintptr(dstX1),
|
||||
a7: uintptr(dstY1),
|
||||
a8: uintptr(mask),
|
||||
a9: filter.c(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -2858,3 +2858,25 @@ func (ctx *context) Viewport(x, y, width, height int) {
|
||||
},
|
||||
blocking: true})
|
||||
}
|
||||
|
||||
func (ctx context3) BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1 int, mask uint, filter Enum) {
|
||||
defer func() {
|
||||
errstr := ctx.errDrain()
|
||||
log.Printf("gl.BlitFramebuffer(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v) %v", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, errstr)
|
||||
}()
|
||||
ctx.enqueueDebug(call{
|
||||
args: fnargs{
|
||||
fn: glfnBlitFramebuffer,
|
||||
a0: uintptr(srcX0),
|
||||
a1: uintptr(srcY0),
|
||||
a2: uintptr(srcX1),
|
||||
a3: uintptr(srcY1),
|
||||
a4: uintptr(dstX0),
|
||||
a5: uintptr(dstY0),
|
||||
a6: uintptr(dstX1),
|
||||
a7: uintptr(dstY1),
|
||||
a8: uintptr(mask),
|
||||
a9: filter.c(),
|
||||
},
|
||||
blocking: true})
|
||||
}
|
||||
|
@ -4,7 +4,15 @@
|
||||
|
||||
package gl
|
||||
|
||||
// Context is an OpenGL context.
|
||||
// Context is an OpenGL ES context.
|
||||
//
|
||||
// A Context has a method for every GL function supported by ES 2 or later.
|
||||
// In a program compiled with ES 3 support, a Context is also a Context3.
|
||||
// For example, a program can:
|
||||
//
|
||||
// func f(glctx gl.Context) {
|
||||
// glctx.(gl.Context3).BlitFramebuffer(...)
|
||||
// }
|
||||
//
|
||||
// Calls are not safe for concurrent use. However calls can be made from
|
||||
// any goroutine, the gl package removes the notion of thread-local
|
||||
@ -816,6 +824,19 @@ type Context interface {
|
||||
Viewport(x, y, width, height int)
|
||||
}
|
||||
|
||||
// Context3 is an OpenGL ES 3 context.
|
||||
//
|
||||
// When the gl package is compiled with GL ES 3 support, the produced
|
||||
// Context object also implements the Context3 interface.
|
||||
type Context3 interface {
|
||||
Context
|
||||
|
||||
// BlitFramebuffer copies a block of pixels between framebuffers.
|
||||
//
|
||||
// https://www.khronos.org/opengles/sdk/docs/man3/html/glBlitFramebuffer.xhtml
|
||||
BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1 int, mask uint, filter Enum)
|
||||
}
|
||||
|
||||
// Worker is used by display driver code to execute OpenGL calls.
|
||||
//
|
||||
// Typically display driver code creates a gl.Context for an application,
|
||||
|
12
gl/work.c
12
gl/work.c
@ -8,6 +8,15 @@
|
||||
#include "_cgo_export.h"
|
||||
#include "work.h"
|
||||
|
||||
#if defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0
|
||||
#else
|
||||
#include <stdio.h>
|
||||
void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
|
||||
printf("GLES3 function is missing\n");
|
||||
exit(2);
|
||||
}
|
||||
#endif
|
||||
|
||||
uintptr_t processFn(struct fnargs* args, char* parg) {
|
||||
uintptr_t ret = 0;
|
||||
switch (args->fn) {
|
||||
@ -50,6 +59,9 @@ uintptr_t processFn(struct fnargs* args, char* parg) {
|
||||
case glfnBlendFuncSeparate:
|
||||
glBlendFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3);
|
||||
break;
|
||||
case glfnBlitFramebuffer:
|
||||
glBlitFramebuffer((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7, (GLbitfield)args->a8, (GLenum)args->a9);
|
||||
break;
|
||||
case glfnBufferData:
|
||||
glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg, (GLenum)args->a2);
|
||||
break;
|
||||
|
16
gl/work.go
16
gl/work.go
@ -12,6 +12,7 @@ package gl
|
||||
#cgo darwin,arm64 LDFLAGS: -framework OpenGLES
|
||||
#cgo linux LDFLAGS: -lGLESv2
|
||||
|
||||
#cgo android CFLAGS: -Dos_android
|
||||
#cgo darwin,amd64 CFLAGS: -Dos_osx
|
||||
#cgo darwin,arm CFLAGS: -Dos_ios
|
||||
#cgo darwin,arm64 CFLAGS: -Dos_ios
|
||||
@ -66,6 +67,10 @@ type context struct {
|
||||
|
||||
func (ctx *context) WorkAvailable() <-chan struct{} { return ctx.workAvailable }
|
||||
|
||||
type context3 struct {
|
||||
*context
|
||||
}
|
||||
|
||||
// NewContext creates a cgo OpenGL context.
|
||||
//
|
||||
// See the Worker interface for more details on how it is used.
|
||||
@ -75,7 +80,16 @@ func NewContext() (Context, Worker) {
|
||||
work: make(chan call, workbufLen),
|
||||
retvalue: make(chan C.uintptr_t),
|
||||
}
|
||||
return glctx, glctx
|
||||
if C.GLES_VERSION == "GL_ES_2_0" {
|
||||
return glctx, glctx
|
||||
}
|
||||
return context3{glctx}, glctx
|
||||
}
|
||||
|
||||
// Version returns a GL ES version string, either "GL_ES_2_0" or "GL_ES_3_0".
|
||||
// Future versions of the gl package may return "GL_ES_3_1".
|
||||
func Version() string {
|
||||
return C.GLES_VERSION
|
||||
}
|
||||
|
||||
func (ctx *context) enqueue(c call) uintptr {
|
||||
|
21
gl/work.h
21
gl/work.h
@ -2,16 +2,30 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifdef os_linux
|
||||
#include <GLES2/gl2.h> // install on Ubuntu with: sudo apt-get install libegl1-mesa-dev libgles2-mesa-dev libx11-dev
|
||||
#ifdef os_android
|
||||
// TODO(crawshaw): We could include <android/api-level.h> and
|
||||
// condition on __ANDROID_API__ to get GLES3 headers. However
|
||||
// we also need to add -lGLESv3 to LDFLAGS, which we cannot do
|
||||
// from inside an ifdef.
|
||||
#include <GLES2/gl2.h>
|
||||
#elif os_linux
|
||||
#include <GLES3/gl3.h> // install on Ubuntu with: sudo apt-get install libegl1-mesa-dev libgles2-mesa-dev libx11-dev
|
||||
#endif
|
||||
|
||||
#ifdef os_ios
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#endif
|
||||
|
||||
#ifdef os_osx
|
||||
#include <OpenGL/gl3.h>
|
||||
#endif
|
||||
|
||||
#if defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0
|
||||
#define GLES_VERSION "GL_ES_3_0"
|
||||
#else
|
||||
#define GLES_VERSION "GL_ES_2_0"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -31,6 +45,7 @@ typedef enum {
|
||||
glfnBlendEquationSeparate,
|
||||
glfnBlendFunc,
|
||||
glfnBlendFuncSeparate,
|
||||
glfnBlitFramebuffer,
|
||||
glfnBufferData,
|
||||
glfnBufferSubData,
|
||||
glfnCheckFramebufferStatus,
|
||||
@ -173,6 +188,8 @@ struct fnargs {
|
||||
uintptr_t a5;
|
||||
uintptr_t a6;
|
||||
uintptr_t a7;
|
||||
uintptr_t a8;
|
||||
uintptr_t a9;
|
||||
};
|
||||
|
||||
extern uintptr_t processFn(struct fnargs* args, char* parg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user