Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2010 LunarG Inc.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Chia-I Wu <olv@lunarg.com>
  26.  */
  27.  
  28. #include "util/u_memory.h"
  29. #include "util/u_string.h"
  30. #include "util/u_inlines.h"
  31. #include "util/u_pointer.h"
  32. #include "util/u_dl.h"
  33. #include "egldriver.h"
  34. #include "eglimage.h"
  35. #include "eglmutex.h"
  36.  
  37. #include "egl_g3d.h"
  38. #include "egl_g3d_st.h"
  39.  
  40. struct egl_g3d_st_manager {
  41.    struct st_manager base;
  42.    _EGLDisplay *display;
  43. };
  44.  
  45. static INLINE struct egl_g3d_st_manager *
  46. egl_g3d_st_manager(struct st_manager *smapi)
  47. {
  48.    return (struct egl_g3d_st_manager *) smapi;
  49. }
  50.  
  51. static boolean
  52. egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
  53.                                  void *egl_image,
  54.                                  struct st_egl_image *out)
  55. {
  56.    struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
  57.    EGLImageKHR handle = (EGLImageKHR) egl_image;
  58.    _EGLImage *img;
  59.    struct egl_g3d_image *gimg;
  60.  
  61.    /* this is called from state trackers */
  62.    _eglLockMutex(&gsmapi->display->Mutex);
  63.  
  64.    img = _eglLookupImage(handle, gsmapi->display);
  65.    if (!img) {
  66.       _eglUnlockMutex(&gsmapi->display->Mutex);
  67.       return FALSE;
  68.    }
  69.  
  70.    gimg = egl_g3d_image(img);
  71.  
  72.    out->texture = NULL;
  73.    pipe_resource_reference(&out->texture, gimg->texture);
  74.    out->level = gimg->level;
  75.    out->layer = gimg->layer;
  76.  
  77.    _eglUnlockMutex(&gsmapi->display->Mutex);
  78.  
  79.    return TRUE;
  80. }
  81.  
  82. static int
  83. egl_g3d_st_manager_get_param(struct st_manager *smapi,
  84.                              enum st_manager_param param)
  85. {
  86.    return 0;
  87. }
  88.  
  89. struct st_manager *
  90. egl_g3d_create_st_manager(_EGLDisplay *dpy)
  91. {
  92.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  93.    struct egl_g3d_st_manager *gsmapi;
  94.  
  95.    gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
  96.    if (gsmapi) {
  97.       gsmapi->display = dpy;
  98.  
  99.       gsmapi->base.screen = gdpy->native->screen;
  100.       gsmapi->base.get_egl_image = egl_g3d_st_manager_get_egl_image;
  101.       gsmapi->base.get_param = egl_g3d_st_manager_get_param;
  102.    }
  103.  
  104.    return &gsmapi->base;;
  105. }
  106.  
  107. void
  108. egl_g3d_destroy_st_manager(struct st_manager *smapi)
  109. {
  110.    struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
  111.    FREE(gsmapi);
  112. }
  113.  
  114. static boolean
  115. egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_context_iface *stctx,
  116.                                            struct st_framebuffer_iface *stfbi,
  117.                                            enum st_attachment_type statt)
  118. {
  119.    return TRUE;
  120. }
  121.  
  122. static void
  123. pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf)
  124. {
  125.    /* TODO */
  126. }
  127.  
  128. static void
  129. pbuffer_allocate_pbuffer_texture(struct egl_g3d_surface *gsurf)
  130. {
  131.    struct egl_g3d_display *gdpy =
  132.       egl_g3d_display(gsurf->base.Resource.Display);
  133.    struct pipe_screen *screen = gdpy->native->screen;
  134.    struct pipe_resource templ, *ptex;
  135.  
  136.    memset(&templ, 0, sizeof(templ));
  137.    templ.target = PIPE_TEXTURE_2D;
  138.    templ.last_level = 0;
  139.    templ.width0 = gsurf->base.Width;
  140.    templ.height0 = gsurf->base.Height;
  141.    templ.depth0 = 1;
  142.    templ.array_size = 1;
  143.    templ.format = gsurf->stvis.color_format;
  144.    /* for rendering and binding to texture */
  145.    templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
  146.  
  147.    ptex = screen->resource_create(screen, &templ);
  148.    gsurf->render_texture = ptex;
  149. }
  150.  
  151. static boolean
  152. egl_g3d_st_framebuffer_validate_pbuffer(struct st_context_iface *stctx,
  153.                                         struct st_framebuffer_iface *stfbi,
  154.                                         const enum st_attachment_type *statts,
  155.                                         unsigned count,
  156.                                         struct pipe_resource **out)
  157. {
  158.    _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
  159.    struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
  160.    unsigned i;
  161.  
  162.    for (i = 0; i < count; i++) {
  163.       out[i] = NULL;
  164.  
  165.       if (gsurf->stvis.render_buffer != statts[i])
  166.          continue;
  167.  
  168.       if (!gsurf->render_texture) {
  169.          switch (gsurf->client_buffer_type) {
  170.          case EGL_NONE:
  171.             pbuffer_allocate_pbuffer_texture(gsurf);
  172.             break;
  173.          case EGL_OPENVG_IMAGE:
  174.             pbuffer_reference_openvg_image(gsurf);
  175.             break;
  176.          default:
  177.             break;
  178.          }
  179.  
  180.          if (!gsurf->render_texture)
  181.             return FALSE;
  182.       }
  183.  
  184.       pipe_resource_reference(&out[i], gsurf->render_texture);
  185.    }
  186.  
  187.    return TRUE;
  188. }
  189.  
  190. static boolean
  191. egl_g3d_st_framebuffer_flush_front(struct st_context_iface *stctx,
  192.                                    struct st_framebuffer_iface *stfbi,
  193.                                    enum st_attachment_type statt)
  194. {
  195.    _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
  196.    struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
  197.    struct native_present_control ctrl;
  198.  
  199.    memset(&ctrl, 0, sizeof(ctrl));
  200.    ctrl.natt = NATIVE_ATTACHMENT_FRONT_LEFT;
  201.  
  202.    return gsurf->native->present(gsurf->native, &ctrl);
  203. }
  204.  
  205. static boolean
  206. egl_g3d_st_framebuffer_validate(struct st_context_iface *stctx,
  207.                                 struct st_framebuffer_iface *stfbi,
  208.                                 const enum st_attachment_type *statts,
  209.                                 unsigned count,
  210.                                 struct pipe_resource **out)
  211. {
  212.    _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
  213.    struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
  214.    struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
  215.    uint attachment_mask = 0;
  216.    unsigned i;
  217.  
  218.    for (i = 0; i < count; i++) {
  219.       int natt;
  220.  
  221.       switch (statts[i]) {
  222.       case ST_ATTACHMENT_FRONT_LEFT:
  223.          natt = NATIVE_ATTACHMENT_FRONT_LEFT;
  224.          break;
  225.       case ST_ATTACHMENT_BACK_LEFT:
  226.          natt = NATIVE_ATTACHMENT_BACK_LEFT;
  227.          break;
  228.       case ST_ATTACHMENT_FRONT_RIGHT:
  229.          natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
  230.          break;
  231.       case ST_ATTACHMENT_BACK_RIGHT:
  232.          natt = NATIVE_ATTACHMENT_BACK_RIGHT;
  233.          break;
  234.       default:
  235.          natt = -1;
  236.          break;
  237.       }
  238.  
  239.       if (natt >= 0)
  240.          attachment_mask |= 1 << natt;
  241.    }
  242.  
  243.    if (!gsurf->native->validate(gsurf->native, attachment_mask,
  244.          &gsurf->sequence_number, textures, &gsurf->base.Width,
  245.          &gsurf->base.Height))
  246.       return FALSE;
  247.  
  248.    for (i = 0; i < count; i++) {
  249.       struct pipe_resource *tex;
  250.       int natt;
  251.  
  252.       switch (statts[i]) {
  253.       case ST_ATTACHMENT_FRONT_LEFT:
  254.          natt = NATIVE_ATTACHMENT_FRONT_LEFT;
  255.          break;
  256.       case ST_ATTACHMENT_BACK_LEFT:
  257.          natt = NATIVE_ATTACHMENT_BACK_LEFT;
  258.          break;
  259.       case ST_ATTACHMENT_FRONT_RIGHT:
  260.          natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
  261.          break;
  262.       case ST_ATTACHMENT_BACK_RIGHT:
  263.          natt = NATIVE_ATTACHMENT_BACK_RIGHT;
  264.          break;
  265.       default:
  266.          natt = -1;
  267.          break;
  268.       }
  269.  
  270.       if (natt >= 0) {
  271.          tex = textures[natt];
  272.  
  273.          if (statts[i] == stfbi->visual->render_buffer)
  274.             pipe_resource_reference(&gsurf->render_texture, tex);
  275.  
  276.          if (attachment_mask & (1 << natt)) {
  277.             /* transfer the ownership to the caller */
  278.             out[i] = tex;
  279.             attachment_mask &= ~(1 << natt);
  280.          }
  281.          else {
  282.             /* the attachment is listed more than once */
  283.             pipe_resource_reference(&out[i], tex);
  284.          }
  285.       }
  286.    }
  287.  
  288.    return TRUE;
  289. }
  290.  
  291. struct st_framebuffer_iface *
  292. egl_g3d_create_st_framebuffer(_EGLSurface *surf)
  293. {
  294.    struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
  295.    struct st_framebuffer_iface *stfbi;
  296.  
  297.    stfbi = CALLOC_STRUCT(st_framebuffer_iface);
  298.    if (!stfbi)
  299.       return NULL;
  300.  
  301.    stfbi->visual = &gsurf->stvis;
  302.    p_atomic_set(&stfbi->stamp, 1);
  303.  
  304.    if (gsurf->base.Type != EGL_PBUFFER_BIT) {
  305.       stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
  306.       stfbi->validate = egl_g3d_st_framebuffer_validate;
  307.    }
  308.    else {
  309.       stfbi->flush_front = egl_g3d_st_framebuffer_flush_front_pbuffer;
  310.       stfbi->validate = egl_g3d_st_framebuffer_validate_pbuffer;
  311.    }
  312.    stfbi->st_manager_private = (void *) &gsurf->base;
  313.  
  314.    return stfbi;
  315. }
  316.  
  317. void
  318. egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
  319. {
  320.    FREE(stfbi);
  321. }
  322.