From f53662a0f46b3ada1aebde93de576fd2009b69e8 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Tue, 21 Jan 2014 14:25:30 +0000 Subject: [PATCH] sdk: GL blitter git-svn-id: svn://kolibrios.org@4502 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../sdk/sources/libdrm/include/drm/i915_drm.h | 82 ++-- contrib/sdk/sources/render/Makefile | 42 ++ contrib/sdk/sources/render/blit.c | 95 +++++ contrib/sdk/sources/render/render.c | 360 ++++++++++++++++++ contrib/sdk/sources/render/render.h | 39 ++ contrib/sdk/sources/render/swap.c | 100 +++++ 6 files changed, 677 insertions(+), 41 deletions(-) create mode 100644 contrib/sdk/sources/render/Makefile create mode 100644 contrib/sdk/sources/render/blit.c create mode 100644 contrib/sdk/sources/render/render.c create mode 100644 contrib/sdk/sources/render/render.h create mode 100644 contrib/sdk/sources/render/swap.c diff --git a/contrib/sdk/sources/libdrm/include/drm/i915_drm.h b/contrib/sdk/sources/libdrm/include/drm/i915_drm.h index 584d9c2aae..3c710f9ae2 100644 --- a/contrib/sdk/sources/libdrm/include/drm/i915_drm.h +++ b/contrib/sdk/sources/libdrm/include/drm/i915_drm.h @@ -141,58 +141,58 @@ typedef struct _drm_i915_sarea { /* Flags for perf_boxes */ -#define I915_BOX_RING_EMPTY 0x1 -#define I915_BOX_FLIP 0x2 -#define I915_BOX_WAIT 0x4 -#define I915_BOX_TEXTURE_LOAD 0x8 -#define I915_BOX_LOST_CONTEXT 0x10 +#define I915_BOX_RING_EMPTY 0x1 +#define I915_BOX_FLIP 0x2 +#define I915_BOX_WAIT 0x4 +#define I915_BOX_TEXTURE_LOAD 0x8 +#define I915_BOX_LOST_CONTEXT 0x10 /* I915 specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ -#define DRM_I915_INIT 0x00 -#define DRM_I915_FLUSH 0x01 -#define DRM_I915_FLIP 0x02 -#define DRM_I915_BATCHBUFFER 0x03 -#define DRM_I915_IRQ_EMIT 0x04 -#define DRM_I915_IRQ_WAIT 0x05 -#define DRM_I915_GETPARAM 0x06 -#define DRM_I915_SETPARAM 0x07 -#define DRM_I915_ALLOC 0x08 -#define DRM_I915_FREE 0x09 -#define DRM_I915_INIT_HEAP 0x0a -#define DRM_I915_CMDBUFFER 0x0b -#define DRM_I915_DESTROY_HEAP 0x0c +#define DRM_I915_INIT 0x00 +#define DRM_I915_FLUSH 0x01 +#define DRM_I915_FLIP 0x02 +#define DRM_I915_BATCHBUFFER 0x03 +#define DRM_I915_IRQ_EMIT 0x04 +#define DRM_I915_IRQ_WAIT 0x05 +#define DRM_I915_GETPARAM 0x06 +#define DRM_I915_SETPARAM 0x07 +#define DRM_I915_ALLOC 0x08 +#define DRM_I915_FREE 0x09 +#define DRM_I915_INIT_HEAP 0x0a +#define DRM_I915_CMDBUFFER 0x0b +#define DRM_I915_DESTROY_HEAP 0x0c #define DRM_I915_SET_VBLANK_PIPE 0x0d #define DRM_I915_GET_VBLANK_PIPE 0x0e -#define DRM_I915_VBLANK_SWAP 0x0f -#define DRM_I915_HWS_ADDR 0x11 -#define DRM_I915_GEM_INIT 0x13 -#define DRM_I915_GEM_EXECBUFFER 0x14 -#define DRM_I915_GEM_PIN 0x15 -#define DRM_I915_GEM_UNPIN 0x16 -#define DRM_I915_GEM_BUSY 0x17 -#define DRM_I915_GEM_THROTTLE 0x18 -#define DRM_I915_GEM_ENTERVT 0x19 -#define DRM_I915_GEM_LEAVEVT 0x1a -#define DRM_I915_GEM_CREATE 0x1b -#define DRM_I915_GEM_PREAD 0x1c -#define DRM_I915_GEM_PWRITE 0x1d -#define DRM_I915_GEM_MMAP 0x1e -#define DRM_I915_GEM_SET_DOMAIN 0x1f -#define DRM_I915_GEM_SW_FINISH 0x20 -#define DRM_I915_GEM_SET_TILING 0x21 -#define DRM_I915_GEM_GET_TILING 0x22 -#define DRM_I915_GEM_GET_APERTURE 0x23 -#define DRM_I915_GEM_MMAP_GTT 0x24 +#define DRM_I915_VBLANK_SWAP 0x0f +#define DRM_I915_HWS_ADDR 0x11 +#define DRM_I915_GEM_INIT 0x13 +#define DRM_I915_GEM_EXECBUFFER 0x14 +#define DRM_I915_GEM_PIN 0x15 +#define DRM_I915_GEM_UNPIN 0x16 +#define DRM_I915_GEM_BUSY 0x17 +#define DRM_I915_GEM_THROTTLE 0x18 +#define DRM_I915_GEM_ENTERVT 0x19 +#define DRM_I915_GEM_LEAVEVT 0x1a +#define DRM_I915_GEM_CREATE 0x1b +#define DRM_I915_GEM_PREAD 0x1c +#define DRM_I915_GEM_PWRITE 0x1d +#define DRM_I915_GEM_MMAP 0x1e +#define DRM_I915_GEM_SET_DOMAIN 0x1f +#define DRM_I915_GEM_SW_FINISH 0x20 +#define DRM_I915_GEM_SET_TILING 0x21 +#define DRM_I915_GEM_GET_TILING 0x22 +#define DRM_I915_GEM_GET_APERTURE 0x23 +#define DRM_I915_GEM_MMAP_GTT 0x24 #define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 -#define DRM_I915_GEM_MADVISE 0x26 +#define DRM_I915_GEM_MADVISE 0x26 #define DRM_I915_OVERLAY_PUT_IMAGE 0x27 -#define DRM_I915_OVERLAY_ATTRS 0x28 +#define DRM_I915_OVERLAY_ATTRS 0x28 #define DRM_I915_GEM_EXECBUFFER2 0x29 #define DRM_I915_GET_SPRITE_COLORKEY 0x2a #define DRM_I915_SET_SPRITE_COLORKEY 0x2b -#define DRM_I915_GEM_WAIT 0x2c +#define DRM_I915_GEM_WAIT 0x2c #define DRM_I915_GEM_CONTEXT_CREATE 0x2d #define DRM_I915_GEM_CONTEXT_DESTROY 0x2e #define DRM_I915_GEM_SET_CACHEING 0x2f diff --git a/contrib/sdk/sources/render/Makefile b/contrib/sdk/sources/render/Makefile new file mode 100644 index 0000000000..c1f502ffd5 --- /dev/null +++ b/contrib/sdk/sources/render/Makefile @@ -0,0 +1,42 @@ + +LIBRARY= librender + +CC=gcc +CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fomit-frame-pointer + +AR= ar + +INCLUDES= -I. -I../newlib/include -I../Mesa/include -I../libdrm/include/drm + +LIBPATH:= -L../../lib + + +DEFINES= -D__unix__ -DMESA_EGL_NO_X11_HEADERS + + +SOURCES = render.c \ + blit.c \ + swap.c + + +OBJECTS = $(patsubst %.c, %.o, $(SOURCES)) + + +# targets + + +all:$(LIBRARY).a + +$(LIBRARY).a: $(OBJECTS) Makefile + ar cvrs $(LIBRARY).a $(OBJECTS) + mv -f $(LIBRARY).a ../../lib + +%.o : %.c Makefile + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $< + +clean: + -rm -f *.o + + + + diff --git a/contrib/sdk/sources/render/blit.c b/contrib/sdk/sources/render/blit.c new file mode 100644 index 0000000000..a38f15d9a4 --- /dev/null +++ b/contrib/sdk/sources/render/blit.c @@ -0,0 +1,95 @@ +#include +#include +#include + +#include "render.h" +#include + +void render_blit(struct render *render, enum px_buffer buffer) +{ + char proc_info[1024]; + + EGLContext context; + EGLSurface draw, read; + int winx, winy; + + float dst_xscale, dst_yscale; + float *vertices = render->vertices; + float *texcoords = render->texcoords; + int r, b; + + if(render == NULL) + return; + + get_proc_info(proc_info); + + winx = *(uint32_t*)(proc_info+34); + winy = *(uint32_t*)(proc_info+38); + + context = eglGetCurrentContext(); + draw = eglGetCurrentSurface(EGL_DRAW); + read = eglGetCurrentSurface(EGL_READ); + + if (!eglMakeCurrent(render->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context)) + { + printf("failed to make window current"); + goto err1; + }; + + glUseProgram(render->blit_prog); + glUniform1i(render->sampler, 0); + + glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),render->vertices); + glEnableVertexAttribArray(0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, render->tx_buffers[buffer]); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),render->texcoords); + glEnableVertexAttribArray(1); + + dst_xscale = 1.0/render->scr_width; + dst_yscale = 1.0/render->scr_height; + + r = winx + render->dx + render->width ; + b = winy + render->dy + render->height; + + float t0, t1, t2, t5; + + vertices[0] = t0 = 2*(winx+render->dx)*dst_xscale - 1.0; + vertices[1 * 2] = t2 = 2*r*dst_xscale - 1.0; + + vertices[2 * 2] = t2; + vertices[3 * 2] = t0; + + vertices[1] = t1 = 2*(winy+render->dy)*dst_yscale - 1.0; + vertices[2*2+1] = t5 = 2*b*dst_yscale - 1.0; + vertices[1*2+1] = t1; + vertices[3*2+1] = t5; + + texcoords[0] = 0.0; + texcoords[1] = 0.0; + texcoords[1*2] = 1.0; + texcoords[1*2+1]= 0.0; + texcoords[2*2] = 1.0; + texcoords[2*2+1]= 1.0; + texcoords[3*2] = 0.0; + texcoords[3*2+1]= 1.0; + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisable(GL_TEXTURE_2D); + glUseProgram(0); + +err1: + eglMakeCurrent(render->dpy, draw, read, context); +} + diff --git a/contrib/sdk/sources/render/render.c b/contrib/sdk/sources/render/render.c new file mode 100644 index 0000000000..cb4ae12ce8 --- /dev/null +++ b/contrib/sdk/sources/render/render.c @@ -0,0 +1,360 @@ +#include +#include +#include +#include + +#include "render.h" +#include +#include + + +static int drm_ioctl(int fd, unsigned long request, void *arg) +{ + ioctl_t io; + + io.handle = fd; + io.io_code = request; + io.input = arg; + io.inp_size = 64; + io.output = NULL; + io.out_size = 0; + + return call_service(&io); +} + +static EGLImageKHR px_create_image(EGLDisplay display, EGLContext context, + int width, int height, int stride, int name) +{ + EGLImageKHR image; + EGLint attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_STRIDE_MESA, 0, + EGL_DRM_BUFFER_FORMAT_MESA, + EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, + EGL_DRM_BUFFER_USE_SHARE_MESA | + EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + attribs[1] = width; + attribs[3] = height; + attribs[5] = stride/4; + + printf("%s w:%d :%d pitch:%d handle %d\n", __FUNCTION__, + width, height, stride, name); + + image = eglCreateImageKHR(display, context, EGL_DRM_BUFFER_MESA, + (void *) (uintptr_t)name, attribs); + + return image; +} + +static GLint create_shader(GLenum type, const char *source) +{ + GLint ok; + GLint shader; + + shader = glCreateShader(type); + if(shader == 0) + goto err; + + glShaderSource(shader, 1, (const GLchar **) &source, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); + if (!ok) { + GLchar *info; + GLint size; + + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); + + glGetShaderInfoLog(shader, size, NULL, info); + printf("Failed to compile %s: %s\n", + type == GL_FRAGMENT_SHADER ? "FS" : "VS",info); + printf("Program source:\n%s", source); + printf("GLSL compile failure\n"); + free(info); + glDeleteProgram(shader); + shader = 0; + } +err: + return shader; +} + + +struct render* create_render(EGLDisplay dpy, EGLSurface surface, int dx, int dy) +{ + const char *vs_src = + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord0;\n" + "varying vec2 source_texture;\n" + "void main()\n" + "{\n" + " gl_Position = v_position;\n" + " source_texture = v_texcoord0.xy;\n" + "}\n"; + + const char *fs_src = +// "precision mediump float;\n" + "varying vec2 source_texture;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " vec3 cg = texture2D(sampler, source_texture).rgb;\n" + " gl_FragColor = vec4(cg.r,cg.g,cg.b,1.0);\n" + "}\n"; + EGLint config_attribs[14]; + EGLConfig config; + EGLint num_configs; + + EGLContext context; + + struct drm_i915_fb_info fb; + GLint vs_shader, fs_shader; + GLenum status; + GLint ret; + int fd; + struct render *render; + + + fd = get_service("DISPLAY"); + + memset(&fb, 0, sizeof(fb)); + ret = drm_ioctl(fd, SRV_FBINFO, &fb); + if( ret != 0 ) + { printf("failed to get framebuffer info\n"); + goto err; + }; + + render = (struct render*)malloc(sizeof(struct render)); + if(render == NULL) + goto err; + + render->fd = fd; + render->dpy = dpy; + render->dx = dx; + render->dy = dy; + + if(!eglQuerySurface(dpy, surface, EGL_WIDTH, &render->width)) + goto err1; + + if(!eglQuerySurface(dpy, surface, EGL_HEIGHT, &render->height)) + goto err1; + + render->scr_width = fb.width; + render->scr_height = fb.height; + + render->front = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_FRONT); + if(render->front == EGL_NO_IMAGE_KHR) + goto err1; + + render->back = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_BACK); + if( render->back == EGL_NO_IMAGE_KHR) + goto err2; + + + context = eglGetCurrentContext(); + + config_attribs[0] = EGL_RED_SIZE; + config_attribs[1] = 1; + config_attribs[2] = EGL_GREEN_SIZE; + config_attribs[3] = 1; + config_attribs[4] = EGL_BLUE_SIZE; + config_attribs[5] = 1; + config_attribs[6] = EGL_DEPTH_SIZE; + config_attribs[7] = 1; + + config_attribs[8] = EGL_SURFACE_TYPE; + config_attribs[9] = EGL_WINDOW_BIT; + + config_attribs[10] = EGL_RENDERABLE_TYPE; + config_attribs[11] = EGL_OPENGL_BIT; + config_attribs[12] = EGL_NONE; + + if (!eglChooseConfig(dpy,config_attribs, &config, 1, &num_configs) || !num_configs) + { + printf("failed to choose a config"); + goto err3; + } + + render->context = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL); + if (!context) + { + printf("failed to create context"); + goto err3; + }; + + if (!eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context)) + { + printf("failed to make window current"); + goto err4; + }; + + + glGenTextures(2, render->tx_buffers); + if(glGetError() != GL_NO_ERROR) + goto err5; + + glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_FRONT]); + if(glGetError() != GL_NO_ERROR) + goto err6; + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->front); + if(glGetError() != GL_NO_ERROR) + goto err6; + + glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_BACK]); + if(glGetError() != GL_NO_ERROR) + goto err6; + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->back); + if(glGetError() != GL_NO_ERROR) + goto err6; + + glBindTexture(GL_TEXTURE_2D, 0); + + render->back_buffer = EGL_DRM_BUFFER_BACK; + + + render->screen = px_create_image(dpy,context,fb.width,fb.height, + fb.pitch,fb.name); + if(render->screen == EGL_NO_IMAGE_KHR) + goto err6; + + glGenTextures(1, &render->tx_screen); + if(glGetError() != GL_NO_ERROR) + goto err6; + + glBindTexture(GL_TEXTURE_2D, render->tx_screen); + if(glGetError() != GL_NO_ERROR) + goto err7; + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->screen); + if(glGetError() != GL_NO_ERROR) + goto err7; + + glBindTexture(GL_TEXTURE_2D, 0); + + glGenFramebuffers(1, &render->framebuffer); + if(glGetError() != GL_NO_ERROR) + goto err8; + + glBindFramebuffer(GL_FRAMEBUFFER, render->framebuffer); + if(glGetError() != GL_NO_ERROR) + goto err9; + + glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, render->tx_screen,0); + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + { + const char *str; + switch (status) + { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + str = "incomplete attachment"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + str = "incomplete/missing attachment"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + str = "incomplete draw buffer"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + str = "incomplete read buffer"; + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + str = "unsupported"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + str = "incomplete multiple"; + break; + default: + str = "unknown error"; + break; + } + printf("destination is framebuffer incomplete: %s [%#x]\n", str, status); + goto err9; + } + + glViewport(0, 0, render->scr_width, render->scr_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + render->blit_prog = glCreateProgram(); + if(render->blit_prog == 0) + goto err9; + + vs_shader = create_shader(GL_VERTEX_SHADER,vs_src); + if(vs_shader == 0) + goto err10; + + fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_src); + if(fs_shader == 0) + goto err11; + + glAttachShader(render->blit_prog, vs_shader); + glAttachShader(render->blit_prog, fs_shader); + glBindAttribLocation(render->blit_prog, 0, "v_position"); + glBindAttribLocation(render->blit_prog, 1, "v_texcoord0"); + + glLinkProgram(render->blit_prog); + glGetProgramiv(render->blit_prog, GL_LINK_STATUS, &ret); + if (!ret) + { + GLchar *info; + GLint size; + + glGetProgramiv(render->blit_prog, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); + + glGetProgramInfoLog(render->blit_prog, size, NULL, info); + printf("Failed to link: %s\n", info); + printf("GLSL link failure\n"); + free(info); + } + + render->sampler = glGetUniformLocation(render->blit_prog,"sampler"); + + eglMakeCurrent(dpy, surface, surface, context); + + return render; + +err11: + glDeleteShader(vs_shader); +err10: + glDeleteProgram(render->blit_prog); +err9: + glDeleteFramebuffers(1, &render->framebuffer); +err8: + eglDestroyImageKHR(dpy, render->screen); +err7: + glDeleteTextures(1, &render->tx_screen); +err6: + glDeleteTextures(2, render->tx_buffers); +err5: + eglMakeCurrent(dpy, surface, surface, context); +err4: + eglDestroyContext(dpy, render->context); +err3: + eglDestroyImageKHR(dpy, render->back); +err2: + eglDestroyImageKHR(dpy, render->front); +err1: + free(render); +err: + return NULL; +}; + + + diff --git a/contrib/sdk/sources/render/render.h b/contrib/sdk/sources/render/render.h new file mode 100644 index 0000000000..de611c27fa --- /dev/null +++ b/contrib/sdk/sources/render/render.h @@ -0,0 +1,39 @@ +#ifndef __GL_RENDER_H__ +#define __GL_RENDER_H__ + +#define EGL_EGLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES + +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "GL/gl.h" + +enum px_buffer +{ + PX_FRONT = 0, + PX_BACK = 1 +}; + +struct render +{ + int fd; + EGLDisplay dpy; + EGLContext context; + EGLint dx, dy; + EGLint width, height; + EGLint scr_width, scr_height; + GLuint framebuffer; + EGLImageKHR front, back, screen; + GLuint tx_buffers[2]; + GLuint tx_screen; + int back_buffer; + GLuint blit_prog; + GLint sampler; + float vertices[8], texcoords[8]; +}; + +struct render* create_render(EGLDisplay dpy, EGLSurface surface, int dx, int dy); +void render_blit(struct render *render, enum px_buffer buffer); +void render_swap_and_blit(struct render *render); + +#endif /* __GL_RENDER_H__ */ diff --git a/contrib/sdk/sources/render/swap.c b/contrib/sdk/sources/render/swap.c new file mode 100644 index 0000000000..1c466cc5ea --- /dev/null +++ b/contrib/sdk/sources/render/swap.c @@ -0,0 +1,100 @@ +#include +#include +#include + +#include "render.h" +#include + +void render_swap_and_blit(struct render *render) +{ + char proc_info[1024]; + + EGLContext context; + EGLSurface draw, read; + int winx, winy; + + float dst_xscale, dst_yscale; + float *vertices = render->vertices; + float *texcoords = render->texcoords; + int r, b; + + if(render == NULL) + return; + + get_proc_info(proc_info); + + winx = *(uint32_t*)(proc_info+34); + winy = *(uint32_t*)(proc_info+38); + + context = eglGetCurrentContext(); + draw = eglGetCurrentSurface(EGL_DRAW); + read = eglGetCurrentSurface(EGL_READ); + + eglSwapBuffers(render->dpy,draw); + + if (!eglMakeCurrent(render->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context)) + { + printf("failed to make window current"); + goto err1; + }; + + glUseProgram(render->blit_prog); + glUniform1i(render->sampler, 0); + + glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),render->vertices); + glEnableVertexAttribArray(0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, render->tx_buffers[render->back_buffer]); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),render->texcoords); + glEnableVertexAttribArray(1); + + dst_xscale = 1.0/render->scr_width; + dst_yscale = 1.0/render->scr_height; + + r = winx + render->dx + render->width; + b = winy + render->dy + render->height; + + float t0, t1, t2, t5; + + vertices[0] = t0 = 2*(winx+render->dx)*dst_xscale - 1.0; + vertices[1 * 2] = t2 = 2*r*dst_xscale - 1.0; + + vertices[2 * 2] = t2; + vertices[3 * 2] = t0; + + vertices[1] = t1 = 2*(winy+render->dy)*dst_yscale - 1.0; + vertices[2*2+1] = t5 = 2*b*dst_yscale - 1.0; + vertices[1*2+1] = t1; + vertices[3*2+1] = t5; + + texcoords[0] = 0.0; + texcoords[1] = 0.0; + texcoords[1*2] = 1.0; + texcoords[1*2+1]= 0.0; + texcoords[2*2] = 1.0; + texcoords[2*2+1]= 1.0; + texcoords[3*2] = 0.0; + texcoords[3*2+1]= 1.0; + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisable(GL_TEXTURE_2D); + glUseProgram(0); + + render->back_buffer++; + render->back_buffer&=1; + +err1: + eglMakeCurrent(render->dpy, draw, read, context); +} +