Skip to content

Instantly share code, notes, and snippets.

@chris-hl
Created October 24, 2019 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chris-hl/591de2b34d3af0792bc6aff36d23d7c7 to your computer and use it in GitHub Desktop.
Save chris-hl/591de2b34d3af0792bc6aff36d23d7c7 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <unistd.h>
#include <err.h>
#include <sys/time.h>
#include <g2d.h>
#include <wayland-egl.h>
#define GL_GLEXT_PROTOTYPES 1
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#define RENDER_W 1920
#define RENDER_H 1080
static const char *vertShaderSrc =
"attribute vec4 g_vPosition;"
"attribute vec2 g_vTexCoord;"
"varying vec2 g_vVSTexCoord;"
"void main() {"
"gl_Position = g_vPosition;"
"g_vVSTexCoord = g_vTexCoord;"
"}";
static const char *fragShaderSrc =
"precision mediump float;"
"uniform sampler2D tImage;"
"varying vec2 g_vVSTexCoord;"
"void main() {"
"vec4 color = texture2D(tImage, g_vVSTexCoord);"
// do something simple: swap R, B channels
"gl_FragColor = vec4(color.b, color.g, color.r, color.a);"
"}";
static GLuint loadShader(GLint shaderType, const char* src)
{
GLuint shader;
GLint status = GL_FALSE;
shader = glCreateShader(shaderType);
if (!shader)
err(-1, "glCreateShader() failed");
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (!status)
err(-1, "Errors while compiling shader");
return shader;
}
static GLuint genTexture(const uint32_t w, const uint32_t h, GLint minmag_filter)
{
GLuint t;
glGenTextures(1, &t);
glBindTexture(GL_TEXTURE_2D, t);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minmag_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, minmag_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
return t;
}
static void setupFramebuffer(uint32_t w, uint32_t h, int useVIVMap)
{
GLuint frameBuffer;
GLuint renderT;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glGenTextures(1, &renderT);
glBindTexture(GL_TEXTURE_2D, renderT);
if (useVIVMap) {
struct g2d_buf *g2db;
void *vaddr;
uint32_t paddr;
g2db = g2d_alloc(4*w*h, 0);
vaddr = (uint8_t*)g2db->buf_vaddr;
paddr = g2db->buf_paddr;
glTexDirectVIVMap(GL_TEXTURE_2D, w, h, GL_RGBA, &vaddr, &paddr);
glTexDirectInvalidateVIV(GL_TEXTURE_2D);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderT, 0);
GLenum fbstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fbstatus != GL_FRAMEBUFFER_COMPLETE)
err(-1, "glCheckFramebufferStatus() failed with %d", fbstatus);
}
static uint64_t get_microseconds()
{
struct timeval time;
gettimeofday(&time, NULL);
return time.tv_sec * 1000000 + time.tv_usec;
}
int main(int argc, char **argv)
{
struct wl_display *wl_display;
EGLDisplay eglDisplay;
EGLint eglMajVer, eglMinVer;
EGLConfig eglConfig;
EGLSurface eglSurface;
EGLContext eglContext;
GLuint num_config;
GLuint gl_hProgram;
GLuint gl_hVertShader;
GLuint gl_hFragShader;
GLuint gl_hTextureImage;
GLuint gl_hUniformImageLoc;
/* full plane 'quad' */
float vertexPositions[] = { 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f, };
GLuint gl_hVertexLoc;
float vertexTexCoords[] = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, };
GLuint gl_hVertexTexLoc;
EGLint egl_attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
int useVIVMAP;
useVIVMAP = argc > 1;
wl_display = wl_display_connect(NULL);
eglDisplay = eglGetDisplay(wl_display);
if (eglDisplay == EGL_NO_DISPLAY)
err(-1, "eglGetDisplay failed");
eglInitialize(eglDisplay, &eglMajVer, &eglMinVer);
eglBindAPI(EGL_OPENGL_ES_API);
if (!eglChooseConfig(eglDisplay, egl_attribs, &eglConfig, 1, &num_config))
err(-1, "eglChooseConfig failed");
EGLint egl_context_attrs[] = {
EGL_CONTEXT_MAJOR_VERSION, 2,
EGL_NONE
};
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, egl_context_attrs);
if (!eglContext)
err(-1, "eglCreateContext failed");
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext);
setupFramebuffer(RENDER_W, RENDER_H, useVIVMAP);
glViewport(0, 0, RENDER_W, RENDER_H);
glCullFace(GL_BACK);
gl_hProgram = glCreateProgram();
gl_hVertShader = loadShader(GL_VERTEX_SHADER, vertShaderSrc);
gl_hFragShader = loadShader(GL_FRAGMENT_SHADER, fragShaderSrc);
glAttachShader(gl_hProgram, gl_hVertShader);
glAttachShader(gl_hProgram, gl_hFragShader);
gl_hVertexLoc = 0;
glBindAttribLocation(gl_hProgram, gl_hVertexLoc, "g_vPosition");
gl_hVertexTexLoc = 1;
glBindAttribLocation(gl_hProgram, gl_hVertexTexLoc, "g_vTexCoord");
glLinkProgram(gl_hProgram);
GLint linkstatus;
glGetProgramiv(gl_hProgram, GL_LINK_STATUS, &linkstatus);
if (!linkstatus)
err(-1, "Program link errors");
glUseProgram(gl_hProgram);
/* bind 'tImage' frag shader Sampler2D uniform to texture unit 1 */
gl_hUniformImageLoc = glGetUniformLocation(gl_hProgram, "tImage");
glActiveTexture(GL_TEXTURE1);
glUniform1i(gl_hUniformImageLoc, 1);
gl_hTextureImage = genTexture(RENDER_W, RENDER_H, GL_NEAREST);
/* bind vertices to vertex shader attributes */
glVertexAttribPointer(gl_hVertexLoc, 3, GL_FLOAT, 0, 0, vertexPositions);
glEnableVertexAttribArray(gl_hVertexLoc);
glVertexAttribPointer(gl_hVertexTexLoc, 2, GL_FLOAT, 0, 0, vertexTexCoords);
glEnableVertexAttribArray(gl_hVertexTexLoc);
uint64_t start = get_microseconds();
const uint32_t framecount = 60;
for (int frame = 0; frame < framecount; frame++) {
/* render something */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glFlush();
glFinish();
/* DO SOMETHING HERE WITH CONTENTS OF RENDER BUFFER */
};
uint64_t end = get_microseconds();
printf("frame useconds %u, fps %02.2f\n", (end-start)/framecount, (float)framecount / ((end-start) / 1000000.0));
glUseProgram(0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment