Subversion Repositories Kolibri OS

Rev

Rev 5602 | Rev 6137 | 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 <drm/i915_drm.h>
  5. #include <kos32sys.h>
  6. #include "pixlib3.h"
  7. #include "pixdriver.h"
  8. #include "pxgl.h"
  9.  
  10. #define WIN_STATE_MINIMIZED  0x02
  11. #define WIN_STATE_ROLLED     0x04
  12.  
  13. static int drm_ioctl(int fd, unsigned long request, void *arg)
  14. {
  15.     ioctl_t  io;
  16.  
  17.     io.handle   = fd;
  18.     io.io_code  = request;
  19.     io.input    = arg;
  20.     io.inp_size = 64;
  21.     io.output   = NULL;
  22.     io.out_size = 0;
  23.  
  24.     return call_service(&io);
  25. }
  26.  
  27. static EGLImageKHR px_create_image(struct render *px,void *name,GLuint tex, EGLint *attribs)
  28. {
  29.     EGLImageKHR image;
  30.  
  31.     image = eglCreateImageKHR(px->dpy, px->context,
  32.                               EGL_DRM_BUFFER_MESA, name, attribs);
  33.     if(image == NULL)
  34.         goto err_0;
  35.  
  36.     glBindTexture(GL_TEXTURE_2D, tex);
  37.     if(glGetError() != GL_NO_ERROR)
  38.        goto err_1;
  39.  
  40.     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
  41.     if(glGetError() != GL_NO_ERROR)
  42.        goto err_1;
  43.  
  44.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  45.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  46.  
  47.     return image;
  48.  
  49. err_1:
  50.     eglDestroyImageKHR(px->dpy, image);
  51. err_0:
  52.     return NULL;
  53. };
  54.  
  55. static int update_fb(struct render *px, int name, int pitch)
  56. {
  57.     GLenum      status;
  58.     EGLImageKHR screen;
  59.  
  60.     EGLint attribs[] = {
  61.         EGL_WIDTH, px->scr_width,
  62.         EGL_HEIGHT, px->scr_height,
  63.         EGL_DRM_BUFFER_STRIDE_MESA, pitch/4,
  64.         EGL_DRM_BUFFER_FORMAT_MESA,
  65.         EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
  66.         EGL_DRM_BUFFER_USE_MESA,
  67.         EGL_DRM_BUFFER_USE_SHARE_MESA |
  68.         EGL_DRM_BUFFER_USE_SCANOUT_MESA,
  69.         EGL_NONE
  70.     };
  71.     char *errmsg;
  72.  
  73.     px->screen = px_create_image(px,(void*)name, px->texture[TEX_SCREEN], attribs);
  74.     errmsg = "failed to create new screen image\n";
  75.     if(px->screen == EGL_NO_IMAGE_KHR)
  76.         goto err_0;
  77.  
  78.     px->screen = screen;
  79.  
  80.     glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
  81.                        GL_TEXTURE_2D, px->texture[TEX_SCREEN],0);
  82.  
  83.     status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  84.     if (status != GL_FRAMEBUFFER_COMPLETE)
  85.     {
  86.         const char *str;
  87.         switch (status)
  88.         {
  89.             case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
  90.                 str = "incomplete attachment";
  91.                 break;
  92.             case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
  93.                 str = "incomplete/missing attachment";
  94.                 break;
  95.             case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
  96.                 str = "incomplete draw buffer";
  97.                 break;
  98.             case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
  99.                 str = "incomplete read buffer";
  100.                 break;
  101.             case GL_FRAMEBUFFER_UNSUPPORTED:
  102.                 str = "unsupported";
  103.                 break;
  104.             case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
  105.                 str = "incomplete multiple";
  106.                 break;
  107.             default:
  108.                 str = "unknown error";
  109.                 break;
  110.         }
  111.         DBG("destination framebuffer incomplete: %s [%#x]\n", str, status);
  112.  
  113.         return -1;
  114.     };
  115.  
  116.     DBG("framebuffer changed successfull\n");
  117.  
  118.     glViewport(0, 0, px->scr_width, px->scr_height);
  119.  
  120.     return 0;
  121.  
  122. err_0:
  123.     DBG("%s %s\n", __FUNCTION__, errmsg);
  124.  
  125.     return -1;
  126. };
  127.  
  128. static GLint create_shader(GLenum type, const char *source)
  129. {
  130.     GLint ok;
  131.     GLint shader;
  132.  
  133.     shader = glCreateShader(type);
  134.     if(shader == 0)
  135.         goto err;
  136.  
  137.     glShaderSource(shader, 1, (const GLchar **) &source, NULL);
  138.     glCompileShader(shader);
  139.     glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
  140.     if (!ok) {
  141.         GLchar *info;
  142.         GLint size;
  143.  
  144.         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
  145.         info = malloc(size);
  146.  
  147.         glGetShaderInfoLog(shader, size, NULL, info);
  148.         DBG("Failed to compile %s: %s\n",
  149.                 type == GL_FRAGMENT_SHADER ? "FS" : "VS",info);
  150.         DBG("Program source:\n%s", source);
  151.         DBG("GLSL compile failure\n");
  152.         free(info);
  153.         glDeleteShader(shader);
  154.         shader = 0;
  155.     };
  156.  
  157.     DBG("create shader %d\n", shader);
  158. err:
  159.     return shader;
  160. }
  161.  
  162.  
  163. static void *px_create_obj(struct render *px, size_t size,
  164.                            GLuint *handle, GLuint *name)
  165. {
  166.     struct drm_i915_gem_create create;
  167.     struct drm_i915_gem_mmap mmap_arg;
  168.     struct drm_gem_close close;
  169.     struct drm_gem_flink flink;
  170.  
  171.     create.size   = size;
  172.     create.handle = 0;
  173.  
  174.     if(drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_CREATE, &create))
  175.         goto err_0;
  176.  
  177.     *handle      = create.handle;
  178.     flink.handle = create.handle;
  179.     if (drm_ioctl(px->fd, DRM_IOCTL_GEM_FLINK, &flink))
  180.         goto err_1;
  181.  
  182.     *name = flink.name;
  183.  
  184.     mmap_arg.handle = *handle;
  185.     mmap_arg.offset = 0;
  186.     mmap_arg.size   = size;
  187.     if (drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg))
  188.     {
  189.         DBG("%s: failed to mmap bitmap handle=%d, %d bytes, into CPU domain\n",
  190.                __FUNCTION__, *handle, size);
  191.         goto err_1;
  192.     };
  193.  
  194.     return (void*)(uintptr_t)mmap_arg.addr_ptr;
  195.  
  196. err_1:
  197.     close.handle = *handle;
  198.     drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
  199. err_0:
  200.     return NULL;
  201. };
  202.  
  203. static int px_create_bitmap(struct render *px, struct bitmap *bitmap,
  204.                             size_t size, EGLint format)
  205. {
  206.     struct drm_gem_close close;
  207.     EGLint attribs[] = {
  208.         EGL_WIDTH, bitmap->width,
  209.         EGL_HEIGHT, bitmap->height,
  210.         EGL_DRM_BUFFER_STRIDE_MESA, 0,
  211.         EGL_DRM_BUFFER_FORMAT_MESA,
  212.         format,
  213.         EGL_DRM_BUFFER_USE_MESA,
  214.         EGL_DRM_BUFFER_USE_SHARE_MESA,
  215.         EGL_NONE
  216.     };
  217.  
  218.     bitmap->buffer = px_create_obj(px, size, &bitmap->handle, &bitmap->name);
  219.     if(bitmap->buffer == NULL)
  220.         goto err_0;
  221.  
  222.     switch(format)
  223.     {
  224.         case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
  225.             attribs[5] = bitmap->pitch/4;
  226.             break;
  227.         case EGL_DRM_BUFFER_FORMAT_R8_MESA:
  228.             attribs[5] = bitmap->pitch;
  229.             break;
  230.         default:
  231.             DBG("%s invalid format %x\n",
  232.                     __FUNCTION__, format);
  233.             goto err_1;
  234.     }
  235.  
  236.     bitmap->image = px_create_image(px,(void*)bitmap->name,
  237.                                     bitmap->tex, attribs);
  238.     if(bitmap->image == NULL)
  239.         goto err_1;
  240.  
  241.     DBG("create bitmap:%p %dx%d pitch:%d\n"
  242.            "KHRimage:%p gl_tex:%d handle:%d name:%d\n"
  243.            "mapped at %x\n",
  244.             bitmap, bitmap->width, bitmap->height, bitmap->pitch,
  245.             bitmap->image, bitmap->tex, bitmap->handle, bitmap->name,
  246.             bitmap->buffer);
  247.  
  248.     return 0;
  249.  
  250. err_1:
  251.     user_free(bitmap->buffer);
  252.     close.handle = bitmap->handle;
  253.     drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
  254. err_0:
  255.     return -1;
  256. }
  257.  
  258.  
  259. static int create_mask(struct render *px)
  260. {
  261.     struct drm_i915_mask_update update;
  262.     int    pitch;
  263.  
  264.     pitch = (px->width+15) & ~15;
  265.  
  266.     px->mask.width  = px->width;
  267.     px->mask.height = px->height;
  268.     px->mask.pitch  = pitch;
  269.     px->mask.tex    = px->texture[TEX_MASK];
  270.     px->mask_size   = pitch * px->height;
  271.  
  272.     if(px_create_bitmap(px, &px->mask, px->mask_size,
  273.                          EGL_DRM_BUFFER_FORMAT_R8_MESA) == 0)
  274.     {
  275.         update.handle = px->mask.handle;
  276.         update.dx     = px->dx;
  277.         update.dy     = px->dy;
  278.         update.width  = px->width;
  279.         update.height = px->height;
  280.         update.bo_pitch = (px->width+15) & ~15;
  281.         update.bo_map = (int)px->mask.buffer;
  282.         update.forced = 1;
  283.         drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
  284.         return 0;
  285.     };
  286.     return -1;
  287. };
  288.  
  289.  
  290. static int update_mask(struct render *px)
  291. {
  292.     struct drm_gem_close close;
  293.     EGLint attribs[] = {
  294.         EGL_WIDTH, 0,
  295.         EGL_HEIGHT, 0,
  296.         EGL_DRM_BUFFER_STRIDE_MESA, 0,
  297.         EGL_DRM_BUFFER_FORMAT_MESA,
  298.         EGL_DRM_BUFFER_FORMAT_R8_MESA,
  299.         EGL_DRM_BUFFER_USE_MESA,
  300.         EGL_DRM_BUFFER_USE_SHARE_MESA,
  301.         EGL_NONE
  302.     };
  303.     unsigned int size, pitch;
  304.  
  305.     eglDestroyImageKHR(px->dpy, px->mask.image);
  306.  
  307.     pitch = (px->width+15) & ~15;
  308.     size = pitch*px->height;
  309.  
  310.     if(size > px->mask_size)
  311.     {
  312.         user_free(px->mask.buffer);
  313.         close.handle = px->mask.handle;
  314.         drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
  315.  
  316.         px->mask_size = size;
  317.  
  318.         px->mask.buffer = px_create_obj(px, px->mask_size,
  319.                                       &px->mask.handle, &px->mask.name);
  320.         if(px->mask.buffer == 0)
  321.             goto err_0;
  322.     };
  323.  
  324.     attribs[1] = px->width;
  325.     attribs[3] = px->height;
  326.     attribs[5] = pitch;
  327.  
  328.     px->mask.image = px_create_image(px,(void*)px->mask.name,
  329.                                      px->mask.tex, attribs);
  330.     if(px->mask.image == NULL)
  331.         goto err_1;
  332.  
  333.     DBG("create mask w:%d h:%d pitch:%d\n"
  334.         "KHRimage:%p gl_tex:%d handle:%d name:%d\n"
  335.         "mapped at %x\n",
  336.          px->width, px->height,
  337.          pitch, px->mask.image, px->texture[TEX_MASK],
  338.          px->mask.handle, px->mask.name, px->mask.buffer);
  339.  
  340.     return 0;
  341.  
  342. err_1:
  343.     user_free(px->mask.buffer);
  344.     close.handle = px->mask.handle;
  345.     drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
  346. err_0:
  347.     return -1;
  348. };
  349.  
  350. static struct render* create_render(EGLDisplay dpy, EGLContext context, int dx, int dy, int w, int h)
  351. {
  352.     const char *vs_src =
  353.         "attribute vec4 v_position;\n"
  354.         "attribute vec4 v_texcoord0;\n"
  355.         "varying vec2 source_texture;\n"
  356.         "void main()\n"
  357.         "{\n"
  358.         "   gl_Position = v_position;\n"
  359.         "   source_texture = v_texcoord0.xy;\n"
  360.         "}\n";
  361.  
  362.     const char *fs_i965 =
  363.         "varying vec2 source_texture;\n"
  364.         "uniform sampler2D sampler_src;\n"
  365.         "uniform sampler2D sampler_mask;\n"
  366.         "void main()\n"
  367.         "{\n"
  368.         "   float ca = texture2D(sampler_mask, source_texture).r;\n"
  369.         "   gl_FragColor = vec4(texture2D(sampler_src, source_texture).rgb, ca);\n"
  370.         "}\n";
  371.  
  372.     struct drm_i915_fb_info fb;
  373.     struct render *px;
  374.     GLint  vs_shader, fs_shader;
  375.     int    ret;
  376.  
  377.     px = (struct render*)malloc(sizeof(struct render));
  378.     if(px == NULL)
  379.         goto err_0;
  380.  
  381.     px->fd  = get_service("DISPLAY");
  382.  
  383.     __builtin_memset(&fb, 0, sizeof(fb));
  384.     if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
  385.     {   DBG("failed to get framebuffer info\n");
  386.         goto err_1;
  387.     };
  388.  
  389.     px->dpy     = dpy;
  390.     px->context = context;
  391.     px->dx      = dx;
  392.     px->dy      = dy;
  393.     px->width   = w;
  394.     px->height  = h;
  395.     px->scr_width  = fb.width;
  396.     px->scr_height = fb.height;
  397.  
  398.     glGenTextures(2, px->texture);
  399.     if(glGetError() != GL_NO_ERROR)
  400.        goto err_1;
  401.  
  402.     glGenFramebuffers(1, &px->framebuffer);
  403.     if(glGetError() != GL_NO_ERROR)
  404.        goto err_2;
  405.  
  406.     glBindFramebuffer(GL_FRAMEBUFFER, px->framebuffer);
  407.     if(glGetError() != GL_NO_ERROR)
  408.        goto err_3;
  409.  
  410.     if(update_fb(px, fb.name, fb.pitch))
  411.        goto err_4;
  412.  
  413.     glMatrixMode(GL_PROJECTION);
  414.     glLoadIdentity();
  415.     glMatrixMode(GL_MODELVIEW);
  416.     glLoadIdentity();
  417.  
  418.     if(create_mask(px))
  419.         goto err_4;
  420.  
  421.     px->blit_prog = glCreateProgram();
  422.     if(px->blit_prog == 0)
  423.         goto err_4;
  424.  
  425.     vs_shader = create_shader(GL_VERTEX_SHADER, vs_src);
  426.     if(vs_shader == 0)
  427.         goto err_4;
  428.  
  429.     fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_i965);
  430.     if(fs_shader == 0)
  431.         goto err_4;
  432.  
  433.     glAttachShader(px->blit_prog, vs_shader);
  434.     glAttachShader(px->blit_prog, fs_shader);
  435.     glBindAttribLocation(px->blit_prog, 0, "v_position");
  436.     glBindAttribLocation(px->blit_prog, 1, "v_texcoord0");
  437.  
  438.     glLinkProgram(px->blit_prog);
  439.     glGetProgramiv(px->blit_prog, GL_LINK_STATUS, &ret);
  440.     if (!ret)
  441.     {
  442.         GLchar *info;
  443.         GLint size;
  444.  
  445.         glGetProgramiv(px->blit_prog, GL_INFO_LOG_LENGTH, &size);
  446.         info = malloc(size);
  447.  
  448.         glGetProgramInfoLog(px->blit_prog, size, NULL, info);
  449.         DBG("Failed to link: %s\n", info);
  450.         DBG("GLSL link failure\n");
  451.         free(info);
  452.         goto err_4;
  453.     }
  454.  
  455.     px->sampler = glGetUniformLocation(px->blit_prog,"sampler_src");
  456.     px->sm_mask = glGetUniformLocation(px->blit_prog,"sampler_mask");
  457.  
  458.     glUseProgram(px->blit_prog);
  459.     glUniform1i(px->sampler, 0);
  460.     glUniform1i(px->sm_mask, 1);
  461.  
  462.     glEnableClientState(GL_VERTEX_ARRAY);
  463.  
  464.     glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->vertices);
  465.     glEnableVertexAttribArray(0);
  466.  
  467.     glVertexAttribPointer(1, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->tc_src);
  468.     glEnableVertexAttribArray(1);
  469.  
  470.     glEnable(GL_BLEND);
  471.     glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  472.  
  473.     px->tc_src[0]    = 0.0;
  474.     px->tc_src[1]    = 0.0;
  475.     px->tc_src[1*2]  = 1.0;
  476.     px->tc_src[1*2+1]= 0.0;
  477.     px->tc_src[2*2]  = 1.0;
  478.     px->tc_src[2*2+1]= 1.0;
  479.     px->tc_src[3*2]  = 0.0;
  480.     px->tc_src[3*2+1]= 1.0;
  481.  
  482.     DBG("create render framebuffer:%p %dx%d pitch:%d name %d\n",
  483.         px->screen,fb.width, fb.height, fb.pitch, fb.name);
  484.  
  485.     return px;
  486.  
  487. err_4:
  488.     glBindFramebuffer(GL_FRAMEBUFFER, 0);
  489. err_3:
  490.     glDeleteFramebuffers(1, &px->framebuffer);
  491. err_2:
  492.     glDeleteTextures(2, px->texture);
  493. err_1:
  494.     free(px);
  495. err_0:
  496.     return NULL;
  497. };
  498.  
  499. static struct render *px;
  500.  
  501. static bitmap_t *hw_create_bitmap(uint32_t width, uint32_t height)
  502. {
  503.     struct bitmap *bitmap;
  504.  
  505.     bitmap = malloc(sizeof(struct bitmap));
  506.     if(bitmap == NULL)
  507.         return NULL;
  508.  
  509.     glGenTextures(1, &bitmap->tex);
  510.     if(glGetError() != GL_NO_ERROR)
  511.        goto err_0;
  512.  
  513.     bitmap->width   = width;
  514.     bitmap->height  = height;
  515.     bitmap->pitch   = (width*4 + 15) & ~15;
  516.  
  517.     if(px_create_bitmap(px, bitmap, bitmap->pitch * bitmap->height,
  518.                          EGL_DRM_BUFFER_FORMAT_ARGB32_MESA) == 0)
  519.     {
  520.         return bitmap;
  521.     };
  522.  
  523.     glDeleteTextures(1, &bitmap->tex);
  524. err_0:
  525.     free(bitmap);
  526.     return NULL;
  527. };
  528.  
  529. static planar_t* hw_create_planar(EGLint name, EGLint format, uint32_t width, uint32_t height,
  530.                             uint32_t offset0, uint32_t pitch0,
  531.                             uint32_t offset1, uint32_t pitch1,
  532.                             uint32_t offset2, uint32_t pitch2)
  533. {
  534.     struct drm_gem_close close;
  535.     planar_t *planar;
  536.     EGLImageKHR img;
  537.     int num_planes;
  538.     int i;
  539.  
  540.     EGLint attribs[] = {
  541.         EGL_WIDTH, width,
  542.         EGL_HEIGHT,height,
  543.         EGL_DRM_BUFFER_FORMAT_MESA, format,
  544.         EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset0,
  545.         EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch0,
  546.         EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset1,
  547.         EGL_DMA_BUF_PLANE1_PITCH_EXT, pitch1,
  548.         EGL_DMA_BUF_PLANE2_OFFSET_EXT, offset2,
  549.         EGL_DMA_BUF_PLANE2_PITCH_EXT, pitch2,
  550.         EGL_NONE, EGL_NONE
  551.     };
  552.  
  553.     switch (format)
  554.     {
  555.         case EGL_TEXTURE_Y_UV_WL:
  556.             num_planes = 2;
  557.             break;
  558.         case EGL_TEXTURE_Y_U_V_WL:
  559.             num_planes = 3;
  560.             break;
  561.         case EGL_TEXTURE_Y_XUXV_WL:
  562.             num_planes = 2;
  563.             break;
  564.         default:
  565.             num_planes = 0;
  566.     }
  567.  
  568.     if(num_planes == 0)
  569.         return NULL;
  570.  
  571.     planar = calloc(1, sizeof(struct planar));
  572.     if(planar == NULL)
  573.         return NULL;
  574.  
  575.     img = eglCreatePlanarImage(px->dpy, px->context, (EGLClientBuffer)name, attribs);
  576.     if(img == NULL)
  577.         goto err_0;
  578.  
  579.     planar->width  = width;
  580.     planar->height = height;
  581.     planar->name   = name;
  582.     planar->planar_image = img;
  583.  
  584.     planar->offset[0] = offset0;
  585.     planar->offset[1] = offset1;
  586.     planar->offset[2] = offset2;
  587.  
  588.     planar->pitch[0] = pitch0;
  589.     planar->pitch[1] = pitch1;
  590.     planar->pitch[2] = pitch2;
  591.  
  592.     glGenTextures(num_planes, &planar->tex[0]);
  593.  
  594.     for(i = 0; i < num_planes; i++)
  595.     {
  596.         EGLint attr[3];
  597.         attr[0] = EGL_WAYLAND_PLANE_WL;
  598.         attr[1] = i;
  599.         attr[2] = EGL_NONE;
  600.  
  601.         planar->image[i] = eglCreateImageKHR(px->dpy, px->context,
  602.                            EGL_WAYLAND_BUFFER_WL,(EGLClientBuffer)name, attr);
  603.  
  604.         glBindTexture(GL_TEXTURE_2D, planar->tex[i]);
  605.  
  606.         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, planar->image[i]);
  607.  
  608.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  609.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  610.     };
  611.  
  612.     return planar;
  613.  
  614. err_0:
  615.     free(planar);
  616.  
  617.     return NULL;
  618. }
  619.  
  620.  
  621. static int hw_destroy_bitmap(bitmap_t * bitmap)
  622. {
  623.     struct drm_gem_close close;
  624.  
  625.     glDeleteTextures(1, &bitmap->tex);
  626.     eglDestroyImageKHR(px->dpy, bitmap->image);
  627.     user_free(bitmap->buffer);
  628.     close.handle = bitmap->handle;
  629.     drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
  630.     free(bitmap);
  631. };
  632.  
  633. static void *hw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch)
  634. {
  635.     *pitch = bitmap->pitch;
  636.  
  637.     return bitmap->buffer;
  638. };
  639.  
  640. static int hw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height)
  641. {
  642.     return 0;
  643. }
  644.  
  645. char proc_info[1024];
  646.  
  647. static int hw_blit(bitmap_t *bitmap, int dst_x, int dst_y,
  648.                    uint32_t w, uint32_t h, int src_x, int src_y)
  649. {
  650.     struct drm_i915_mask_update update;
  651.     struct drm_i915_fb_info fb;
  652.  
  653.     uint32_t winx, winy, winw, winh;
  654.     uint8_t  state;
  655.     float xscale, yscale;
  656.     int r, b;
  657.     float *vertices  = px->vertices;
  658.  
  659.     get_proc_info(proc_info);
  660.  
  661.     state  = *(uint8_t*)(proc_info+70);
  662.     if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
  663.         return;
  664.  
  665.     winx = *(uint32_t*)(proc_info+34);
  666.     winy = *(uint32_t*)(proc_info+38);
  667.     winw = *(uint32_t*)(proc_info+42)+1;
  668.     winh = *(uint32_t*)(proc_info+46)+1;
  669.  
  670.     __builtin_memset(&fb, 0, sizeof(fb));
  671.     if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
  672.     {
  673.         DBG("failed to get framebuffer info\n");
  674.         return;
  675.     };
  676.  
  677.     if( fb.width  != px->scr_width ||
  678.         fb.height != px->scr_height )
  679.     {
  680.         px->scr_width  = fb.width;
  681.         px->scr_height = fb.height;
  682.  
  683.         eglDestroyImageKHR(px->dpy, px->screen);
  684.  
  685.         if(update_fb(px, fb.name, fb.pitch))
  686.             return;
  687.     };
  688.  
  689.     update.handle = px->mask.handle;
  690.     update.dx     = px->dx;
  691.     update.dy     = px->dy;
  692.     update.width  = px->width;
  693.     update.height = px->height;
  694.     update.bo_pitch = (px->width+15) & ~15;
  695.     update.bo_map = (int)px->mask.buffer;
  696.  
  697.     if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
  698.     {
  699.         return;
  700.     }
  701.  
  702.     xscale = 1.0/px->scr_width;
  703.     yscale = 1.0/px->scr_height;
  704.  
  705.     r = winx + px->dx + px->width;
  706.     b = winy + px->dy + px->height;
  707.  
  708.     float t0, t1, t2, t5;
  709.  
  710. //    render->tc_src[1*2]  = 1.0;
  711. //    render->tc_src[2*2]  = 1.0;
  712. //    render->tc_src[2*2+1]= 1.0;
  713. //    render->tc_src[3*2+1]= 1.0;
  714.  
  715.     vertices[0]     = t0 = 2*(winx+px->dx)*xscale - 1.0;
  716.     vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
  717.  
  718.     vertices[2 * 2] = t2;
  719.     vertices[3 * 2] = t0;
  720.  
  721.     vertices[1]     = t1 = 2*(winy+px->dy)*yscale - 1.0;
  722.     vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
  723.     vertices[1*2+1] = t1;
  724.     vertices[3*2+1] = t5;
  725.  
  726.     glActiveTexture(GL_TEXTURE0);
  727.     glBindTexture(GL_TEXTURE_2D, bitmap->tex);
  728.  
  729.     glActiveTexture(GL_TEXTURE1);
  730.     glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
  731.  
  732.     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  733.  
  734.     glFlush();
  735.  
  736.     return;
  737. };
  738.  
  739. static int hw_create_client(int x, int y, uint32_t width, uint32_t height)
  740. {
  741.     px = create_render(eglGetCurrentDisplay(), eglGetCurrentContext(), x, y, width, height);
  742.  
  743.     return !px;
  744. };
  745.  
  746. static int hw_resize_client(int x, int y, uint32_t width, uint32_t height)
  747. {
  748.     if( x != px->dx ||
  749.         y != px->dy ||
  750.         width != px->width ||
  751.         height != px->height )
  752.     {
  753.         struct drm_i915_mask_update update;
  754.  
  755.         px->dx     = x;
  756.         px->dy     = y;
  757.         px->width  = width;
  758.         px->height = height;
  759.         update_mask(px);
  760.  
  761.         update.handle = px->mask.handle;
  762.         update.dx     = px->dx;
  763.         update.dy     = px->dy;
  764.         update.width  = px->width;
  765.         update.height = px->height;
  766.         update.bo_pitch = (px->width+15) & ~15;
  767.         update.bo_map = (int)px->mask.buffer;
  768.         update.forced = 1;
  769.  
  770.         drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
  771.     };
  772.  
  773.     return 0;
  774. };
  775.  
  776. static void hw_fini(void)
  777. {
  778.     struct drm_gem_close close;
  779.  
  780.     DBG("%s\n", __FUNCTION__);
  781.  
  782.     eglDestroyImageKHR(px->dpy, px->mask.image);
  783.     user_free(px->mask.buffer);
  784.     close.handle = px->mask.handle;
  785.     drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
  786.  
  787.     glBindFramebuffer(GL_FRAMEBUFFER, 0);
  788.     glDeleteFramebuffers(1, &px->framebuffer);
  789.     eglDestroyImageKHR(px->dpy, px->screen);
  790.     glDeleteTextures(2, px->texture);
  791.     egl_destroy(px->dpy, px->context);
  792.     free(px);
  793. };
  794.  
  795. static struct pix_driver gl_driver =
  796. {
  797.     HW_TEX_BLIT,
  798.     hw_create_bitmap,
  799.     hw_destroy_bitmap,
  800.     hw_lock_bitmap,
  801.     hw_resize_bitmap,
  802.     hw_blit,
  803.     hw_create_client,
  804.     hw_resize_client,
  805.     hw_fini,
  806.     hw_create_planar
  807. };
  808.  
  809. struct pix_driver *DrvInit(uint32_t service)
  810. {
  811.     EGLDisplay     dpy;
  812.     EGLConfig      config;
  813.     EGLContext     context;
  814.     int            ret;
  815.  
  816.     ret = egl_initialize(&dpy, &config, &context);
  817.     if( ret )
  818.         return NULL;
  819.  
  820.     return &gl_driver;
  821.  
  822. err_0:
  823.     egl_destroy(dpy, context);
  824.     return NULL;
  825. }
  826.  
  827.  
  828.