Use software renderer for EGL, just use it for uploading the texture
Jeffrey Pfau jeffrey@endrift.com
Sun, 21 Jul 2013 05:15:02 -0700
2 files changed,
95 insertions(+),
20 deletions(-)
M
CMakeLists.txt
→
CMakeLists.txt
@@ -18,7 +18,7 @@ include_directories(${CMAKE_SOURCE_DIR}/src/sdl)
if(BUILD_RASPI AND BUILD_EGL) set(MAIN_SRC ${CMAKE_SOURCE_DIR}/src/egl-main.c) - set(OPENGL_LIBRARY "-lEGL -lGLESv2 -lvcos -lvchiq_arm -lvchostif -lbcm_host") + set(OPENGL_LIBRARY "-lEGL -lGLESv2 -lbcm_host") set(OPENGL_INCLUDE_DIR "") add_definitions(-DBUILD_RASPI) elseif(BUILD_BBB OR BUILD_RASPI)
M
src/egl-main.c
→
src/egl-main.c
@@ -1,7 +1,7 @@
#include "debugger.h" #include "gba-thread.h" #include "gba.h" -#include "renderers/video-glsl.h" +#include "renderers/video-software.h" #include "sdl-events.h" #include <SDL.h>@@ -10,18 +10,51 @@ #include <EGL/egl.h>
#include <bcm_host.h> -#include <fcntl.h> #include <errno.h> +#include <fcntl.h> +#include <malloc.h> #include <signal.h> #include <sys/time.h> #include <unistd.h> struct GBAVideoEGLRenderer { - struct GBAVideoGLSLRenderer d; + struct GBAVideoSoftwareRenderer d; EGLDisplay display; EGLSurface surface; EGLContext context; + EGL_DISPMANX_WINDOW_T window; + GLuint tex; + GLuint fragmentShader; + GLuint vertexShader; + GLuint program; + GLuint bufferObject; + GLuint texLocation; + GLuint positionLocation; +}; + +static const char* _vertexShader = + "attribute vec4 position;\n" + "varying vec2 texCoord;\n" + + "void main() {\n" + " gl_Position = position;\n" + " texCoord = (position.st + vec2(1.0, -1.0)) * vec2(0.46875, -0.3125);\n" + "}"; + +static const char* _fragmentShader = + "varying vec2 texCoord;\n" + "uniform sampler2D tex;\n" + + "void main() {\n" + " gl_FragColor = texture2D(tex, texCoord);\n" + "}"; + +static const GLfloat _vertices[] = { + -1.f, -1.f, + -1.f, 1.f, + 1.f, 1.f, + 1.f, -1.f, }; static int _GBAEGLInit(struct GBAVideoEGLRenderer* renderer);@@ -44,7 +77,7 @@
if (!_GBAEGLInit(&renderer)) { return 1; } - GBAVideoGLSLRendererCreate(&renderer.d); + GBAVideoSoftwareRendererCreate(&renderer.d); context.fd = fd; context.renderer = &renderer.d.d;@@ -85,7 +118,6 @@ EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };@@ -102,48 +134,91 @@ EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE }; + int dispWidth = 240, dispHeight = 160, adjWidth; renderer->context = eglCreateContext(renderer->display, config, EGL_NO_CONTEXT, contextAttributes); + graphics_get_display_size(0, &dispWidth, &dispHeight); + adjWidth = dispHeight / 2 * 3; DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0); DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); VC_RECT_T destRect = { - .x = 0, + .x = (dispWidth - adjWidth) / 2, .y = 0, - .width = 240, - .height = 160 + .width = adjWidth, + .height = dispHeight }; VC_RECT_T srcRect = { .x = 0, .y = 0, - .width = 240, - .height = 160 + .width = 240 << 16, + .height = 160 << 16 }; - DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(update, display, 0, &destRect, 0, &srcRect, DISPMANX_PROTECTION_NONE, 0, 0, DISPMANX_NO_ROTATE); + DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(update, display, 0, &destRect, 0, &srcRect, DISPMANX_PROTECTION_NONE, 0, 0, 0); vc_dispmanx_update_submit_sync(update); - EGL_DISPMANX_WINDOW_T window = { - .element = element, - .width = 240, - .height = 160 - }; + renderer->window.element = element; + renderer->window.width = dispWidth; + renderer->window.height = dispHeight; - renderer->surface = eglCreateWindowSurface(renderer->display, config, &window, 0); - return EGL_TRUE == eglMakeCurrent(renderer->display, renderer->surface, renderer->surface, renderer->context); + renderer->surface = eglCreateWindowSurface(renderer->display, config, &renderer->window, 0); + if (EGL_FALSE == eglMakeCurrent(renderer->display, renderer->surface, renderer->surface, renderer->context)) { + return 0; + } + + renderer->d.outputBuffer = memalign(16, 256 * 256 * 4); + renderer->d.outputBufferStride = 256; + glGenTextures(1, &renderer->tex); + glBindTexture(GL_TEXTURE_2D, renderer->tex); + 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); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + renderer->fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + renderer->vertexShader = glCreateShader(GL_VERTEX_SHADER); + renderer->program = glCreateProgram(); + + glShaderSource(renderer->fragmentShader, 1, (const GLchar**) &_fragmentShader, 0); + glShaderSource(renderer->vertexShader, 1, (const GLchar**) &_vertexShader, 0); + glAttachShader(renderer->program, renderer->vertexShader); + glAttachShader(renderer->program, renderer->fragmentShader); + char log[1024]; + glCompileShader(renderer->fragmentShader); + glCompileShader(renderer->vertexShader); + glGetShaderInfoLog(renderer->fragmentShader, 1024, 0, log); + glGetShaderInfoLog(renderer->vertexShader, 1024, 0, log); + glLinkProgram(renderer->program); + glGetProgramInfoLog(renderer->program, 1024, 0, log); + printf("%s\n", log); + renderer->texLocation = glGetUniformLocation(renderer->program, "tex"); + renderer->positionLocation = glGetAttribLocation(renderer->program, "position"); + glClearColor(1.f, 0.f, 0.f, 1.f); + return 1; } static void _GBAEGLRunloop(struct GBAThread* context, struct GBAVideoEGLRenderer* renderer) { SDL_Event event; while (context->started && context->debugger->state != DEBUGGER_EXITING) { - GBAVideoGLSLRendererProcessEvents(&renderer->d); pthread_mutex_lock(&renderer->d.mutex); if (renderer->d.d.framesPending) { renderer->d.d.framesPending = 0; pthread_mutex_unlock(&renderer->d.mutex); + glViewport(0, 0, 240, 160); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(renderer->program); + glUniform1i(renderer->texLocation, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, renderer->tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, renderer->d.outputBuffer); + glVertexAttribPointer(renderer->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(renderer->positionLocation); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glUseProgram(0); eglSwapBuffers(renderer->display, renderer->surface); while (SDL_PollEvent(&event)) {