Subversion Repositories Kolibri OS

Rev

Rev 4517 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/time.h>
  5.  
  6. #include "render.h"
  7. #include <i915_drm.h>
  8. #include <kos32sys.h>
  9.  
  10.  
  11. static int drm_ioctl(int fd, unsigned long request, void *arg)
  12. {
  13.     ioctl_t  io;
  14.  
  15.     io.handle   = fd;
  16.     io.io_code  = request;
  17.     io.input    = arg;
  18.     io.inp_size = 64;
  19.     io.output   = NULL;
  20.     io.out_size = 0;
  21.  
  22.     return call_service(&io);
  23. }
  24.  
  25. static EGLImageKHR px_create_image(EGLDisplay display, EGLContext context,
  26.                          int width, int height, int stride, int name)
  27. {
  28.         EGLImageKHR image;
  29.         EGLint attribs[] = {
  30.                 EGL_WIDTH, 0,
  31.                 EGL_HEIGHT, 0,
  32.                 EGL_DRM_BUFFER_STRIDE_MESA, 0,
  33.                 EGL_DRM_BUFFER_FORMAT_MESA,
  34.                 EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
  35.                 EGL_DRM_BUFFER_USE_MESA,
  36.                 EGL_DRM_BUFFER_USE_SHARE_MESA |
  37.                     EGL_DRM_BUFFER_USE_SCANOUT_MESA,
  38.                 EGL_NONE
  39.         };
  40.         attribs[1] = width;
  41.         attribs[3] = height;
  42.         attribs[5] = stride/4;
  43.  
  44.     printf("%s w:%d :%d pitch:%d handle %d\n", __FUNCTION__,
  45.            width, height, stride, name);
  46.  
  47.         image = eglCreateImageKHR(display, context, EGL_DRM_BUFFER_MESA,
  48.                                                  (void *) (uintptr_t)name, attribs);
  49.  
  50.         return image;
  51. }
  52.  
  53. static GLint create_shader(GLenum type, const char *source)
  54. {
  55.         GLint ok;
  56.     GLint shader;
  57.  
  58.     shader = glCreateShader(type);
  59.     if(shader == 0)
  60.         goto err;
  61.  
  62.     glShaderSource(shader, 1, (const GLchar **) &source, NULL);
  63.     glCompileShader(shader);
  64.     glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
  65.         if (!ok) {
  66.                 GLchar *info;
  67.                 GLint size;
  68.  
  69.         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
  70.                 info = malloc(size);
  71.  
  72.         glGetShaderInfoLog(shader, size, NULL, info);
  73.                 printf("Failed to compile %s: %s\n",
  74.                 type == GL_FRAGMENT_SHADER ? "FS" : "VS",info);
  75.                 printf("Program source:\n%s", source);
  76.                 printf("GLSL compile failure\n");
  77.         free(info);
  78.         glDeleteProgram(shader);
  79.         shader = 0;
  80.         }
  81. err:
  82.     return shader;
  83. }
  84.  
  85.  
  86. struct render* create_render(EGLDisplay dpy, EGLSurface surface, int dx, int dy)
  87. {
  88.     const char *vs_src =
  89.             "attribute vec4 v_position;\n"
  90.             "attribute vec4 v_texcoord0;\n"
  91.             "varying vec2 source_texture;\n"
  92.             "void main()\n"
  93.             "{\n"
  94.             "   gl_Position = v_position;\n"
  95.             "   source_texture = v_texcoord0.xy;\n"
  96.             "}\n";
  97.  
  98.         const char *fs_src =
  99. //          "precision mediump float;\n"
  100.             "varying vec2 source_texture;\n"
  101.             "uniform sampler2D sampler;\n"
  102.             "void main()\n"
  103.             "{\n"
  104.             "   vec3 cg = texture2D(sampler, source_texture).rgb;\n"
  105.             "   gl_FragColor = vec4(cg.r,cg.g,cg.b,1.0);\n"
  106.             "}\n";
  107.     EGLint config_attribs[14];
  108.     EGLConfig config;
  109.     EGLint num_configs;
  110.  
  111.     EGLContext context;
  112.  
  113.     struct drm_i915_fb_info fb;
  114.     GLint  vs_shader, fs_shader;
  115.     GLenum status;
  116.     GLint ret;
  117.     int fd;
  118.     struct render *render;
  119.  
  120.  
  121.     fd = get_service("DISPLAY");
  122.  
  123.     memset(&fb, 0, sizeof(fb));
  124.     ret = drm_ioctl(fd, SRV_FBINFO, &fb);
  125.     if( ret != 0 )
  126.     {   printf("failed to get framebuffer info\n");
  127.         goto err;
  128.     };
  129.  
  130.     render = (struct render*)malloc(sizeof(struct render));
  131.     if(render == NULL)
  132.         goto err;
  133.  
  134.     render->fd  = fd;
  135.     render->dpy = dpy;
  136.     render->dx  = dx;
  137.     render->dy  = dy;
  138.  
  139.     if(!eglQuerySurface(dpy, surface, EGL_WIDTH, &render->width))
  140.         goto err1;
  141.  
  142.     if(!eglQuerySurface(dpy, surface, EGL_HEIGHT, &render->height))
  143.         goto err1;
  144.  
  145.     render->scr_width  = fb.width;
  146.     render->scr_height = fb.height;
  147.  
  148.     render->front = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_FRONT);
  149.     if(render->front == EGL_NO_IMAGE_KHR)
  150.         goto err1;
  151.  
  152.     render->back  = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_BACK);
  153.     if( render->back == EGL_NO_IMAGE_KHR)
  154.         goto err2;
  155.  
  156.  
  157.     context = eglGetCurrentContext();
  158.  
  159.     config_attribs[0] = EGL_RED_SIZE;
  160.     config_attribs[1] = 1;
  161.     config_attribs[2] = EGL_GREEN_SIZE;
  162.     config_attribs[3] = 1;
  163.     config_attribs[4] = EGL_BLUE_SIZE;
  164.     config_attribs[5] = 1;
  165.     config_attribs[6] = EGL_DEPTH_SIZE;
  166.     config_attribs[7] = 1;
  167.  
  168.     config_attribs[8] = EGL_SURFACE_TYPE;
  169.     config_attribs[9] = EGL_WINDOW_BIT;
  170.  
  171.     config_attribs[10] = EGL_RENDERABLE_TYPE;
  172.     config_attribs[11] = EGL_OPENGL_BIT;
  173.     config_attribs[12] = EGL_NONE;
  174.  
  175.     if (!eglChooseConfig(dpy,config_attribs, &config, 1, &num_configs) || !num_configs)
  176.     {
  177.         printf("failed to choose a config");
  178.         goto err3;
  179.     }
  180.  
  181.     render->context = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL);
  182.     if (!context)
  183.     {
  184.         printf("failed to create context");
  185.         goto err3;
  186.     };
  187.  
  188.     if (!eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context))
  189.     {
  190.         printf("failed to make window current");
  191.         goto err4;
  192.     };
  193.  
  194.  
  195.     glGenTextures(2, render->tx_buffers);
  196.     if(glGetError() != GL_NO_ERROR)
  197.        goto err5;
  198.  
  199.     glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_FRONT]);
  200.     if(glGetError() != GL_NO_ERROR)
  201.        goto err6;
  202.  
  203.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
  204.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
  205.     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->front);
  206.     if(glGetError() != GL_NO_ERROR)
  207.        goto err6;
  208.  
  209.     glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_BACK]);
  210.     if(glGetError() != GL_NO_ERROR)
  211.        goto err6;
  212.  
  213.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
  214.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
  215.     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->back);
  216.     if(glGetError() != GL_NO_ERROR)
  217.        goto err6;
  218.  
  219.     glBindTexture(GL_TEXTURE_2D, 0);
  220.  
  221.     render->back_buffer = EGL_DRM_BUFFER_BACK;
  222.  
  223.  
  224.     render->screen = px_create_image(dpy,context,fb.width,fb.height,
  225.                                      fb.pitch,fb.name);
  226.     if(render->screen == EGL_NO_IMAGE_KHR)
  227.         goto err6;
  228.  
  229.     glGenTextures(1, &render->tx_screen);
  230.     if(glGetError() != GL_NO_ERROR)
  231.        goto err6;
  232.  
  233.     glBindTexture(GL_TEXTURE_2D, render->tx_screen);
  234.     if(glGetError() != GL_NO_ERROR)
  235.        goto err7;
  236.  
  237.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
  238.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
  239.     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->screen);
  240.     if(glGetError() != GL_NO_ERROR)
  241.        goto err7;
  242.  
  243.     glBindTexture(GL_TEXTURE_2D, 0);
  244.  
  245.     glGenFramebuffers(1, &render->framebuffer);
  246.     if(glGetError() != GL_NO_ERROR)
  247.        goto err8;
  248.  
  249.     glBindFramebuffer(GL_FRAMEBUFFER, render->framebuffer);
  250.     if(glGetError() != GL_NO_ERROR)
  251.        goto err9;
  252.  
  253.     glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
  254.                            GL_TEXTURE_2D, render->tx_screen,0);
  255.  
  256.     status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  257.     if (status != GL_FRAMEBUFFER_COMPLETE)
  258.     {
  259.         const char *str;
  260.         switch (status)
  261.         {
  262.             case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
  263.                  str = "incomplete attachment";
  264.                  break;
  265.             case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
  266.                 str = "incomplete/missing attachment";
  267.                 break;
  268.             case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
  269.                 str = "incomplete draw buffer";
  270.                 break;
  271.             case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
  272.                 str = "incomplete read buffer";
  273.                 break;
  274.             case GL_FRAMEBUFFER_UNSUPPORTED:
  275.                 str = "unsupported";
  276.                 break;
  277.             case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
  278.                 str = "incomplete multiple";
  279.                 break;
  280.             default:
  281.                 str = "unknown error";
  282.                 break;
  283.         }
  284.         printf("destination is framebuffer incomplete: %s [%#x]\n", str, status);
  285.         goto err9;
  286.     }
  287.  
  288.     glViewport(0, 0, render->scr_width, render->scr_height);
  289.     glMatrixMode(GL_PROJECTION);
  290.         glLoadIdentity();
  291.         glMatrixMode(GL_MODELVIEW);
  292.         glLoadIdentity();
  293.  
  294.     render->blit_prog = glCreateProgram();
  295.     if(render->blit_prog == 0)
  296.         goto err9;
  297.  
  298.     vs_shader = create_shader(GL_VERTEX_SHADER,vs_src);
  299.     if(vs_shader == 0)
  300.         goto err10;
  301.  
  302.     fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_src);
  303.     if(fs_shader == 0)
  304.         goto err11;
  305.  
  306.     glAttachShader(render->blit_prog, vs_shader);
  307.     glAttachShader(render->blit_prog, fs_shader);
  308.     glBindAttribLocation(render->blit_prog, 0, "v_position");
  309.     glBindAttribLocation(render->blit_prog, 1, "v_texcoord0");
  310.  
  311.     glLinkProgram(render->blit_prog);
  312.     glGetProgramiv(render->blit_prog, GL_LINK_STATUS, &ret);
  313.     if (!ret)
  314.     {
  315.         GLchar *info;
  316.         GLint size;
  317.  
  318.         glGetProgramiv(render->blit_prog, GL_INFO_LOG_LENGTH, &size);
  319.         info = malloc(size);
  320.  
  321.         glGetProgramInfoLog(render->blit_prog, size, NULL, info);
  322.         printf("Failed to link: %s\n", info);
  323.         printf("GLSL link failure\n");
  324.         free(info);
  325.     }
  326.  
  327.     render->sampler = glGetUniformLocation(render->blit_prog,"sampler");
  328.  
  329.     eglMakeCurrent(dpy, surface, surface, context);
  330.  
  331.     return render;
  332.  
  333. err11:
  334.     glDeleteShader(vs_shader);
  335. err10:
  336.     glDeleteProgram(render->blit_prog);
  337. err9:
  338.     glDeleteFramebuffers(1, &render->framebuffer);
  339. err8:
  340.     eglDestroyImageKHR(dpy, render->screen);
  341. err7:
  342.     glDeleteTextures(1, &render->tx_screen);
  343. err6:
  344.     glDeleteTextures(2, render->tx_buffers);
  345. err5:
  346.     eglMakeCurrent(dpy, surface, surface, context);
  347. err4:
  348.     eglDestroyContext(dpy, render->context);
  349. err3:
  350.     eglDestroyImageKHR(dpy, render->back);
  351. err2:
  352.     eglDestroyImageKHR(dpy, render->front);
  353. err1:
  354.     free(render);
  355. err:
  356.     return NULL;
  357. };
  358.  
  359.  
  360.  
  361.