Subversion Repositories Kolibri OS

Rev

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 "main/mtypes.h"
  29. #include "main/extensions.h"
  30. #include "main/context.h"
  31. #include "main/texobj.h"
  32. #include "main/teximage.h"
  33. #include "main/texstate.h"
  34. #include "main/errors.h"
  35. #include "main/framebuffer.h"
  36. #include "main/fbobject.h"
  37. #include "main/renderbuffer.h"
  38. #include "main/version.h"
  39. #include "st_texture.h"
  40.  
  41. #include "st_context.h"
  42. #include "st_extensions.h"
  43. #include "st_format.h"
  44. #include "st_cb_fbo.h"
  45. #include "st_cb_flush.h"
  46. #include "st_manager.h"
  47.  
  48. #include "state_tracker/st_gl_api.h"
  49.  
  50. #include "pipe/p_context.h"
  51. #include "pipe/p_screen.h"
  52. #include "util/u_format.h"
  53. #include "util/u_pointer.h"
  54. #include "util/u_inlines.h"
  55. #include "util/u_atomic.h"
  56. #include "util/u_surface.h"
  57.  
  58. /**
  59.  * Cast wrapper to convert a struct gl_framebuffer to an st_framebuffer.
  60.  * Return NULL if the struct gl_framebuffer is a user-created framebuffer.
  61.  * We'll only return non-null for window system framebuffers.
  62.  * Note that this function may fail.
  63.  */
  64. static inline struct st_framebuffer *
  65. st_ws_framebuffer(struct gl_framebuffer *fb)
  66. {
  67.    /* FBO cannot be casted.  See st_new_framebuffer */
  68.    if (fb && _mesa_is_winsys_fbo(fb))
  69.       return (struct st_framebuffer *) fb;
  70.    return NULL;
  71. }
  72.  
  73. /**
  74.  * Map an attachment to a buffer index.
  75.  */
  76. static inline gl_buffer_index
  77. attachment_to_buffer_index(enum st_attachment_type statt)
  78. {
  79.    gl_buffer_index index;
  80.  
  81.    switch (statt) {
  82.    case ST_ATTACHMENT_FRONT_LEFT:
  83.       index = BUFFER_FRONT_LEFT;
  84.       break;
  85.    case ST_ATTACHMENT_BACK_LEFT:
  86.       index = BUFFER_BACK_LEFT;
  87.       break;
  88.    case ST_ATTACHMENT_FRONT_RIGHT:
  89.       index = BUFFER_FRONT_RIGHT;
  90.       break;
  91.    case ST_ATTACHMENT_BACK_RIGHT:
  92.       index = BUFFER_BACK_RIGHT;
  93.       break;
  94.    case ST_ATTACHMENT_DEPTH_STENCIL:
  95.       index = BUFFER_DEPTH;
  96.       break;
  97.    case ST_ATTACHMENT_ACCUM:
  98.       index = BUFFER_ACCUM;
  99.       break;
  100.    case ST_ATTACHMENT_SAMPLE:
  101.    default:
  102.       index = BUFFER_COUNT;
  103.       break;
  104.    }
  105.  
  106.    return index;
  107. }
  108.  
  109. /**
  110.  * Map a buffer index to an attachment.
  111.  */
  112. static inline enum st_attachment_type
  113. buffer_index_to_attachment(gl_buffer_index index)
  114. {
  115.    enum st_attachment_type statt;
  116.  
  117.    switch (index) {
  118.    case BUFFER_FRONT_LEFT:
  119.       statt = ST_ATTACHMENT_FRONT_LEFT;
  120.       break;
  121.    case BUFFER_BACK_LEFT:
  122.       statt = ST_ATTACHMENT_BACK_LEFT;
  123.       break;
  124.    case BUFFER_FRONT_RIGHT:
  125.       statt = ST_ATTACHMENT_FRONT_RIGHT;
  126.       break;
  127.    case BUFFER_BACK_RIGHT:
  128.       statt = ST_ATTACHMENT_BACK_RIGHT;
  129.       break;
  130.    case BUFFER_DEPTH:
  131.       statt = ST_ATTACHMENT_DEPTH_STENCIL;
  132.       break;
  133.    case BUFFER_ACCUM:
  134.       statt = ST_ATTACHMENT_ACCUM;
  135.       break;
  136.    default:
  137.       statt = ST_ATTACHMENT_INVALID;
  138.       break;
  139.    }
  140.  
  141.    return statt;
  142. }
  143.  
  144. /**
  145.  * Make sure a context picks up the latest cached state of the
  146.  * drawables it binds to.
  147.  */
  148. static void
  149. st_context_validate(struct st_context *st,
  150.                     struct st_framebuffer *stdraw,
  151.                     struct st_framebuffer *stread)
  152. {
  153.     if (stdraw && stdraw->stamp != st->draw_stamp) {
  154.        st->dirty.st |= ST_NEW_FRAMEBUFFER;
  155.        _mesa_resize_framebuffer(st->ctx, &stdraw->Base,
  156.                                 stdraw->Base.Width,
  157.                                 stdraw->Base.Height);
  158.        st->draw_stamp = stdraw->stamp;
  159.     }
  160.  
  161.     if (stread && stread->stamp != st->read_stamp) {
  162.        if (stread != stdraw) {
  163.           st->dirty.st |= ST_NEW_FRAMEBUFFER;
  164.           _mesa_resize_framebuffer(st->ctx, &stread->Base,
  165.                                    stread->Base.Width,
  166.                                    stread->Base.Height);
  167.        }
  168.        st->read_stamp = stread->stamp;
  169.     }
  170. }
  171.  
  172. /**
  173.  * Validate a framebuffer to make sure up-to-date pipe_textures are used.
  174.  * The context is only used for creating pipe surfaces and for calling
  175.  * _mesa_resize_framebuffer().
  176.  * (That should probably be rethought, since those surfaces become
  177.  * drawable state, not context state, and can be freed by another pipe
  178.  * context).
  179.  */
  180. static void
  181. st_framebuffer_validate(struct st_framebuffer *stfb,
  182.                         struct st_context *st)
  183. {
  184.    struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
  185.    uint width, height;
  186.    unsigned i;
  187.    boolean changed = FALSE;
  188.    int32_t new_stamp;
  189.  
  190.    /* Check for incomplete framebuffers (e.g. EGL_KHR_surfaceless_context) */
  191.    if (!stfb->iface)
  192.       return;
  193.  
  194.    new_stamp = p_atomic_read(&stfb->iface->stamp);
  195.    if (stfb->iface_stamp == new_stamp)
  196.       return;
  197.  
  198.    /* validate the fb */
  199.    do {
  200.       if (!stfb->iface->validate(&st->iface, stfb->iface, stfb->statts,
  201.                                  stfb->num_statts, textures))
  202.          return;
  203.  
  204.       stfb->iface_stamp = new_stamp;
  205.       new_stamp = p_atomic_read(&stfb->iface->stamp);
  206.    } while(stfb->iface_stamp != new_stamp);
  207.  
  208.    width = stfb->Base.Width;
  209.    height = stfb->Base.Height;
  210.  
  211.    for (i = 0; i < stfb->num_statts; i++) {
  212.       struct st_renderbuffer *strb;
  213.       struct pipe_surface *ps, surf_tmpl;
  214.       gl_buffer_index idx;
  215.  
  216.       if (!textures[i])
  217.          continue;
  218.  
  219.       idx = attachment_to_buffer_index(stfb->statts[i]);
  220.       if (idx >= BUFFER_COUNT) {
  221.          pipe_resource_reference(&textures[i], NULL);
  222.          continue;
  223.       }
  224.  
  225.       strb = st_renderbuffer(stfb->Base.Attachment[idx].Renderbuffer);
  226.       assert(strb);
  227.       if (strb->texture == textures[i]) {
  228.          pipe_resource_reference(&textures[i], NULL);
  229.          continue;
  230.       }
  231.  
  232.       u_surface_default_template(&surf_tmpl, textures[i]);
  233.       ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl);
  234.       if (ps) {
  235.          pipe_surface_reference(&strb->surface, ps);
  236.          pipe_resource_reference(&strb->texture, ps->texture);
  237.          /* ownership transfered */
  238.          pipe_surface_reference(&ps, NULL);
  239.  
  240.          changed = TRUE;
  241.  
  242.          strb->Base.Width = strb->surface->width;
  243.          strb->Base.Height = strb->surface->height;
  244.  
  245.          width = strb->Base.Width;
  246.          height = strb->Base.Height;
  247.       }
  248.  
  249.       pipe_resource_reference(&textures[i], NULL);
  250.    }
  251.  
  252.    if (changed) {
  253.       ++stfb->stamp;
  254.       _mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height);
  255.    }
  256. }
  257.  
  258. /**
  259.  * Update the attachments to validate by looping the existing renderbuffers.
  260.  */
  261. static void
  262. st_framebuffer_update_attachments(struct st_framebuffer *stfb)
  263. {
  264.    gl_buffer_index idx;
  265.  
  266.    stfb->num_statts = 0;
  267.    for (idx = 0; idx < BUFFER_COUNT; idx++) {
  268.       struct st_renderbuffer *strb;
  269.       enum st_attachment_type statt;
  270.  
  271.       strb = st_renderbuffer(stfb->Base.Attachment[idx].Renderbuffer);
  272.       if (!strb || strb->software)
  273.          continue;
  274.  
  275.       statt = buffer_index_to_attachment(idx);
  276.       if (statt != ST_ATTACHMENT_INVALID &&
  277.           st_visual_have_buffers(stfb->iface->visual, 1 << statt))
  278.          stfb->statts[stfb->num_statts++] = statt;
  279.    }
  280.    stfb->stamp++;
  281. }
  282.  
  283. /**
  284.  * Add a renderbuffer to the framebuffer.
  285.  */
  286. static boolean
  287. st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb,
  288.                                 gl_buffer_index idx)
  289. {
  290.    struct gl_renderbuffer *rb;
  291.    enum pipe_format format;
  292.    boolean sw;
  293.  
  294.    if (!stfb->iface)
  295.       return FALSE;
  296.  
  297.    /* do not distinguish depth/stencil buffers */
  298.    if (idx == BUFFER_STENCIL)
  299.       idx = BUFFER_DEPTH;
  300.  
  301.    switch (idx) {
  302.    case BUFFER_DEPTH:
  303.       format = stfb->iface->visual->depth_stencil_format;
  304.       sw = FALSE;
  305.       break;
  306.    case BUFFER_ACCUM:
  307.       format = stfb->iface->visual->accum_format;
  308.       sw = TRUE;
  309.       break;
  310.    default:
  311.       format = stfb->iface->visual->color_format;
  312.       if (stfb->Base.Visual.sRGBCapable)
  313.          format = util_format_srgb(format);
  314.       sw = FALSE;
  315.       break;
  316.    }
  317.  
  318.    if (format == PIPE_FORMAT_NONE)
  319.       return FALSE;
  320.  
  321.    rb = st_new_renderbuffer_fb(format, stfb->iface->visual->samples, sw);
  322.    if (!rb)
  323.       return FALSE;
  324.  
  325.    if (idx != BUFFER_DEPTH) {
  326.       _mesa_add_renderbuffer(&stfb->Base, idx, rb);
  327.    }
  328.    else {
  329.       if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0))
  330.          _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, rb);
  331.       if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1))
  332.          _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, rb);
  333.    }
  334.  
  335.    return TRUE;
  336. }
  337.  
  338. /**
  339.  * Intialize a struct gl_config from a visual.
  340.  */
  341. static void
  342. st_visual_to_context_mode(const struct st_visual *visual,
  343.                           struct gl_config *mode)
  344. {
  345.    memset(mode, 0, sizeof(*mode));
  346.  
  347.    if (st_visual_have_buffers(visual, ST_ATTACHMENT_BACK_LEFT_MASK))
  348.       mode->doubleBufferMode = GL_TRUE;
  349.    if (st_visual_have_buffers(visual,
  350.             ST_ATTACHMENT_FRONT_RIGHT_MASK | ST_ATTACHMENT_BACK_RIGHT_MASK))
  351.       mode->stereoMode = GL_TRUE;
  352.  
  353.    if (visual->color_format != PIPE_FORMAT_NONE) {
  354.       mode->rgbMode = GL_TRUE;
  355.  
  356.       mode->redBits =
  357.          util_format_get_component_bits(visual->color_format,
  358.                UTIL_FORMAT_COLORSPACE_RGB, 0);
  359.       mode->greenBits =
  360.          util_format_get_component_bits(visual->color_format,
  361.                UTIL_FORMAT_COLORSPACE_RGB, 1);
  362.       mode->blueBits =
  363.          util_format_get_component_bits(visual->color_format,
  364.                UTIL_FORMAT_COLORSPACE_RGB, 2);
  365.       mode->alphaBits =
  366.          util_format_get_component_bits(visual->color_format,
  367.                UTIL_FORMAT_COLORSPACE_RGB, 3);
  368.  
  369.       mode->rgbBits = mode->redBits +
  370.          mode->greenBits + mode->blueBits + mode->alphaBits;
  371.    }
  372.  
  373.    if (visual->depth_stencil_format != PIPE_FORMAT_NONE) {
  374.       mode->depthBits =
  375.          util_format_get_component_bits(visual->depth_stencil_format,
  376.                UTIL_FORMAT_COLORSPACE_ZS, 0);
  377.       mode->stencilBits =
  378.          util_format_get_component_bits(visual->depth_stencil_format,
  379.                UTIL_FORMAT_COLORSPACE_ZS, 1);
  380.  
  381.       mode->haveDepthBuffer = mode->depthBits > 0;
  382.       mode->haveStencilBuffer = mode->stencilBits > 0;
  383.    }
  384.  
  385.    if (visual->accum_format != PIPE_FORMAT_NONE) {
  386.       mode->haveAccumBuffer = GL_TRUE;
  387.  
  388.       mode->accumRedBits =
  389.          util_format_get_component_bits(visual->accum_format,
  390.                UTIL_FORMAT_COLORSPACE_RGB, 0);
  391.       mode->accumGreenBits =
  392.          util_format_get_component_bits(visual->accum_format,
  393.                UTIL_FORMAT_COLORSPACE_RGB, 1);
  394.       mode->accumBlueBits =
  395.          util_format_get_component_bits(visual->accum_format,
  396.                UTIL_FORMAT_COLORSPACE_RGB, 2);
  397.       mode->accumAlphaBits =
  398.          util_format_get_component_bits(visual->accum_format,
  399.                UTIL_FORMAT_COLORSPACE_RGB, 3);
  400.    }
  401.  
  402.    if (visual->samples > 1) {
  403.       mode->sampleBuffers = 1;
  404.       mode->samples = visual->samples;
  405.    }
  406. }
  407.  
  408. /**
  409.  * Create a framebuffer from a manager interface.
  410.  */
  411. static struct st_framebuffer *
  412. st_framebuffer_create(struct st_context *st,
  413.                       struct st_framebuffer_iface *stfbi)
  414. {
  415.    struct st_framebuffer *stfb;
  416.    struct gl_config mode;
  417.    gl_buffer_index idx;
  418.  
  419.    if (!stfbi)
  420.       return NULL;
  421.  
  422.    stfb = CALLOC_STRUCT(st_framebuffer);
  423.    if (!stfb)
  424.       return NULL;
  425.  
  426.    st_visual_to_context_mode(stfbi->visual, &mode);
  427.  
  428.    /*
  429.     * For desktop GL, sRGB framebuffer write is controlled by both the
  430.     * capability of the framebuffer and GL_FRAMEBUFFER_SRGB.  We should
  431.     * advertise the capability when the pipe driver (and core Mesa) supports
  432.     * it so that applications can enable sRGB write when they want to.
  433.     *
  434.     * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB.  When
  435.     * the attribute is GLX_TRUE, it tells the st manager to pick a color
  436.     * format such that util_format_srgb(visual->color_format) can be supported
  437.     * by the pipe driver.  We still need to advertise the capability here.
  438.     *
  439.     * For GLES, however, sRGB framebuffer write is controlled only by the
  440.     * capability of the framebuffer.  There is GL_EXT_sRGB_write_control to
  441.     * give applications the control back, but sRGB write is still enabled by
  442.     * default.  To avoid unexpected results, we should not advertise the
  443.     * capability.  This could change when we add support for
  444.     * EGL_KHR_gl_colorspace.
  445.     */
  446.    if (_mesa_is_desktop_gl(st->ctx)) {
  447.       struct pipe_screen *screen = st->pipe->screen;
  448.       const enum pipe_format srgb_format =
  449.          util_format_srgb(stfbi->visual->color_format);
  450.  
  451.       if (srgb_format != PIPE_FORMAT_NONE &&
  452.           st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE &&
  453.           screen->is_format_supported(screen, srgb_format,
  454.                                       PIPE_TEXTURE_2D, stfbi->visual->samples,
  455.                                       (PIPE_BIND_DISPLAY_TARGET |
  456.                                        PIPE_BIND_RENDER_TARGET)))
  457.          mode.sRGBCapable = GL_TRUE;
  458.    }
  459.  
  460.    _mesa_initialize_window_framebuffer(&stfb->Base, &mode);
  461.  
  462.    stfb->iface = stfbi;
  463.    stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1;
  464.  
  465.    /* add the color buffer */
  466.    idx = stfb->Base._ColorDrawBufferIndexes[0];
  467.    if (!st_framebuffer_add_renderbuffer(stfb, idx)) {
  468.       free(stfb);
  469.       return NULL;
  470.    }
  471.  
  472.    st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH);
  473.    st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM);
  474.  
  475.    stfb->stamp = 0;
  476.    st_framebuffer_update_attachments(stfb);
  477.  
  478.    return stfb;
  479. }
  480.  
  481. /**
  482.  * Reference a framebuffer.
  483.  */
  484. static void
  485. st_framebuffer_reference(struct st_framebuffer **ptr,
  486.                          struct st_framebuffer *stfb)
  487. {
  488.    struct gl_framebuffer *fb = &stfb->Base;
  489.    _mesa_reference_framebuffer((struct gl_framebuffer **) ptr, fb);
  490. }
  491.  
  492. static void
  493. st_context_flush(struct st_context_iface *stctxi, unsigned flags,
  494.                  struct pipe_fence_handle **fence)
  495. {
  496.    struct st_context *st = (struct st_context *) stctxi;
  497.    unsigned pipe_flags = 0;
  498.  
  499.    if (flags & ST_FLUSH_END_OF_FRAME) {
  500.       pipe_flags |= PIPE_FLUSH_END_OF_FRAME;
  501.    }
  502.  
  503.    st_flush(st, fence, pipe_flags);
  504.    if (flags & ST_FLUSH_FRONT)
  505.       st_manager_flush_frontbuffer(st);
  506. }
  507.  
  508. static boolean
  509. st_context_teximage(struct st_context_iface *stctxi,
  510.                     enum st_texture_type tex_type,
  511.                     int level, enum pipe_format pipe_format,
  512.                     struct pipe_resource *tex, boolean mipmap)
  513. {
  514.    struct st_context *st = (struct st_context *) stctxi;
  515.    struct gl_context *ctx = st->ctx;
  516.    struct gl_texture_object *texObj;
  517.    struct gl_texture_image *texImage;
  518.    struct st_texture_object *stObj;
  519.    struct st_texture_image *stImage;
  520.    GLenum internalFormat;
  521.    GLuint width, height, depth;
  522.    GLenum target;
  523.  
  524.    switch (tex_type) {
  525.    case ST_TEXTURE_1D:
  526.       target = GL_TEXTURE_1D;
  527.       break;
  528.    case ST_TEXTURE_2D:
  529.       target = GL_TEXTURE_2D;
  530.       break;
  531.    case ST_TEXTURE_3D:
  532.       target = GL_TEXTURE_3D;
  533.       break;
  534.    case ST_TEXTURE_RECT:
  535.       target = GL_TEXTURE_RECTANGLE_ARB;
  536.       break;
  537.    default:
  538.       return FALSE;
  539.    }
  540.  
  541.    texObj = _mesa_get_current_tex_object(ctx, target);
  542.  
  543.    _mesa_lock_texture(ctx, texObj);
  544.  
  545.    stObj = st_texture_object(texObj);
  546.    /* switch to surface based */
  547.    if (!stObj->surface_based) {
  548.       _mesa_clear_texture_object(ctx, texObj);
  549.       stObj->surface_based = GL_TRUE;
  550.    }
  551.  
  552.    texImage = _mesa_get_tex_image(ctx, texObj, target, level);
  553.    stImage = st_texture_image(texImage);
  554.    if (tex) {
  555.       mesa_format texFormat = st_pipe_format_to_mesa_format(pipe_format);
  556.  
  557.       if (util_format_has_alpha(tex->format))
  558.          internalFormat = GL_RGBA;
  559.       else
  560.          internalFormat = GL_RGB;
  561.  
  562.       _mesa_init_teximage_fields(ctx, texImage,
  563.                                  tex->width0, tex->height0, 1, 0,
  564.                                  internalFormat, texFormat);
  565.  
  566.       width = tex->width0;
  567.       height = tex->height0;
  568.       depth = tex->depth0;
  569.  
  570.       /* grow the image size until we hit level = 0 */
  571.       while (level > 0) {
  572.          if (width != 1)
  573.             width <<= 1;
  574.          if (height != 1)
  575.             height <<= 1;
  576.          if (depth != 1)
  577.             depth <<= 1;
  578.          level--;
  579.       }
  580.    }
  581.    else {
  582.       _mesa_clear_texture_image(ctx, texImage);
  583.       width = height = depth = 0;
  584.    }
  585.  
  586.    pipe_resource_reference(&stImage->pt, tex);
  587.    stObj->width0 = width;
  588.    stObj->height0 = height;
  589.    stObj->depth0 = depth;
  590.    stObj->surface_format = pipe_format;
  591.  
  592.    _mesa_dirty_texobj(ctx, texObj);
  593.    _mesa_unlock_texture(ctx, texObj);
  594.    
  595.    return TRUE;
  596. }
  597.  
  598. static void
  599. st_context_copy(struct st_context_iface *stctxi,
  600.                 struct st_context_iface *stsrci, unsigned mask)
  601. {
  602.    struct st_context *st = (struct st_context *) stctxi;
  603.    struct st_context *src = (struct st_context *) stsrci;
  604.  
  605.    _mesa_copy_context(src->ctx, st->ctx, mask);
  606. }
  607.  
  608. static boolean
  609. st_context_share(struct st_context_iface *stctxi,
  610.                  struct st_context_iface *stsrci)
  611. {
  612.    struct st_context *st = (struct st_context *) stctxi;
  613.    struct st_context *src = (struct st_context *) stsrci;
  614.  
  615.    return _mesa_share_state(st->ctx, src->ctx);
  616. }
  617.  
  618. static void
  619. st_context_destroy(struct st_context_iface *stctxi)
  620. {
  621.    struct st_context *st = (struct st_context *) stctxi;
  622.    st_destroy_context(st);
  623. }
  624.  
  625. static struct st_context_iface *
  626. st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
  627.                       const struct st_context_attribs *attribs,
  628.                       enum st_context_error *error,
  629.                       struct st_context_iface *shared_stctxi)
  630. {
  631.    struct st_context *shared_ctx = (struct st_context *) shared_stctxi;
  632.    struct st_context *st;
  633.    struct pipe_context *pipe;
  634.    struct gl_config mode;
  635.    gl_api api;
  636.  
  637.    if (!(stapi->profile_mask & (1 << attribs->profile)))
  638.       return NULL;
  639.  
  640.    switch (attribs->profile) {
  641.    case ST_PROFILE_DEFAULT:
  642.       api = API_OPENGL_COMPAT;
  643.       break;
  644.    case ST_PROFILE_OPENGL_ES1:
  645.       api = API_OPENGLES;
  646.       break;
  647.    case ST_PROFILE_OPENGL_ES2:
  648.       api = API_OPENGLES2;
  649.       break;
  650.    case ST_PROFILE_OPENGL_CORE:
  651.       api = API_OPENGL_CORE;
  652.       break;
  653.    default:
  654.       *error = ST_CONTEXT_ERROR_BAD_API;
  655.       return NULL;
  656.       break;
  657.    }
  658.  
  659.    pipe = smapi->screen->context_create(smapi->screen, NULL);
  660.    if (!pipe) {
  661.       *error = ST_CONTEXT_ERROR_NO_MEMORY;
  662.       return NULL;
  663.    }
  664.  
  665.    st_visual_to_context_mode(&attribs->visual, &mode);
  666.    st = st_create_context(api, pipe, &mode, shared_ctx, &attribs->options);
  667.    if (!st) {
  668.       *error = ST_CONTEXT_ERROR_NO_MEMORY;
  669.       pipe->destroy(pipe);
  670.       return NULL;
  671.    }
  672.  
  673.    if (attribs->flags & ST_CONTEXT_FLAG_DEBUG){
  674.       if (!_mesa_set_debug_state_int(st->ctx, GL_DEBUG_OUTPUT, GL_TRUE)) {
  675.          *error = ST_CONTEXT_ERROR_NO_MEMORY;
  676.          return NULL;
  677.       }
  678.       st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT;
  679.    }
  680.  
  681.    if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE)
  682.       st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
  683.    if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS)
  684.       st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
  685.    if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED)
  686.       st->ctx->Const.ResetStrategy = GL_LOSE_CONTEXT_ON_RESET_ARB;
  687.  
  688.    /* need to perform version check */
  689.    if (attribs->major > 1 || attribs->minor > 0) {
  690.       /* Is the actual version less than the requested version?
  691.        */
  692.       if (st->ctx->Version < attribs->major * 10U + attribs->minor) {
  693.          *error = ST_CONTEXT_ERROR_BAD_VERSION;
  694.          st_destroy_context(st);
  695.          return NULL;
  696.       }
  697.    }
  698.  
  699.    st->invalidate_on_gl_viewport =
  700.       smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE);
  701.  
  702.    st->iface.destroy = st_context_destroy;
  703.    st->iface.flush = st_context_flush;
  704.    st->iface.teximage = st_context_teximage;
  705.    st->iface.copy = st_context_copy;
  706.    st->iface.share = st_context_share;
  707.    st->iface.st_context_private = (void *) smapi;
  708.    st->iface.cso_context = st->cso_context;
  709.    st->iface.pipe = st->pipe;
  710.  
  711.    *error = ST_CONTEXT_SUCCESS;
  712.    return &st->iface;
  713. }
  714.  
  715. static struct st_context_iface *
  716. st_api_get_current(struct st_api *stapi)
  717. {
  718.    GET_CURRENT_CONTEXT(ctx);
  719.    struct st_context *st = (ctx) ? ctx->st : NULL;
  720.  
  721.    return (st) ? &st->iface : NULL;
  722. }
  723.  
  724. static struct st_framebuffer *
  725. st_framebuffer_reuse_or_create(struct st_context *st,
  726.                                struct gl_framebuffer *fb,
  727.                                struct st_framebuffer_iface *stfbi)
  728. {
  729.    struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL;
  730.  
  731.    /* dummy framebuffers cant be used as st_framebuffer */
  732.    if (cur && &cur->Base != _mesa_get_incomplete_framebuffer() &&
  733.        cur->iface == stfbi) {
  734.       /* reuse the current stfb */
  735.       st_framebuffer_reference(&stfb, cur);
  736.    }
  737.    else {
  738.       /* create a new one */
  739.       stfb = st_framebuffer_create(st, stfbi);
  740.    }
  741.  
  742.    return stfb;
  743. }
  744.  
  745. static boolean
  746. st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
  747.                     struct st_framebuffer_iface *stdrawi,
  748.                     struct st_framebuffer_iface *streadi)
  749. {
  750.    struct st_context *st = (struct st_context *) stctxi;
  751.    struct st_framebuffer *stdraw, *stread;
  752.    boolean ret;
  753.  
  754.    _glapi_check_multithread();
  755.  
  756.    if (st) {
  757.       /* reuse or create the draw fb */
  758.       stdraw = st_framebuffer_reuse_or_create(st,
  759.             st->ctx->WinSysDrawBuffer, stdrawi);
  760.       if (streadi != stdrawi) {
  761.          /* do the same for the read fb */
  762.          stread = st_framebuffer_reuse_or_create(st,
  763.                st->ctx->WinSysReadBuffer, streadi);
  764.       }
  765.       else {
  766.          stread = NULL;
  767.          /* reuse the draw fb for the read fb */
  768.          if (stdraw)
  769.             st_framebuffer_reference(&stread, stdraw);
  770.       }
  771.  
  772.       if (stdraw && stread) {
  773.          st_framebuffer_validate(stdraw, st);
  774.          if (stread != stdraw)
  775.             st_framebuffer_validate(stread, st);
  776.  
  777.          ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base);
  778.  
  779.          st->draw_stamp = stdraw->stamp - 1;
  780.          st->read_stamp = stread->stamp - 1;
  781.          st_context_validate(st, stdraw, stread);
  782.       }
  783.       else {
  784.          struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer();
  785.          ret = _mesa_make_current(st->ctx, incomplete, incomplete);
  786.       }
  787.  
  788.       st_framebuffer_reference(&stdraw, NULL);
  789.       st_framebuffer_reference(&stread, NULL);
  790.    }
  791.    else {
  792.       ret = _mesa_make_current(NULL, NULL, NULL);
  793.    }
  794.  
  795.    return ret;
  796. }
  797.  
  798. static st_proc_t
  799. st_api_get_proc_address(struct st_api *stapi, const char *procname)
  800. {
  801.    return (st_proc_t) _glapi_get_proc_address(procname);
  802. }
  803.  
  804. static void
  805. st_api_destroy(struct st_api *stapi)
  806. {
  807. }
  808.  
  809. /**
  810.  * Flush the front buffer if the current context renders to the front buffer.
  811.  */
  812. void
  813. st_manager_flush_frontbuffer(struct st_context *st)
  814. {
  815.    struct st_framebuffer *stfb = st_ws_framebuffer(st->ctx->DrawBuffer);
  816.    struct st_renderbuffer *strb = NULL;
  817.  
  818.    if (stfb)
  819.       strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
  820.    if (!strb)
  821.       return;
  822.  
  823.    /* never a dummy fb */
  824.    assert(&stfb->Base != _mesa_get_incomplete_framebuffer());
  825.    stfb->iface->flush_front(&st->iface, stfb->iface, ST_ATTACHMENT_FRONT_LEFT);
  826. }
  827.  
  828. /**
  829.  * Return the surface of an EGLImage.
  830.  * FIXME: I think this should operate on resources, not surfaces
  831.  */
  832. struct pipe_surface *
  833. st_manager_get_egl_image_surface(struct st_context *st, void *eglimg)
  834. {
  835.    struct st_manager *smapi =
  836.       (struct st_manager *) st->iface.st_context_private;
  837.    struct st_egl_image stimg;
  838.    struct pipe_surface *ps, surf_tmpl;
  839.  
  840.    if (!smapi || !smapi->get_egl_image)
  841.       return NULL;
  842.  
  843.    memset(&stimg, 0, sizeof(stimg));
  844.    if (!smapi->get_egl_image(smapi, eglimg, &stimg))
  845.       return NULL;
  846.  
  847.    u_surface_default_template(&surf_tmpl, stimg.texture);
  848.    surf_tmpl.u.tex.level = stimg.level;
  849.    surf_tmpl.u.tex.first_layer = stimg.layer;
  850.    surf_tmpl.u.tex.last_layer = stimg.layer;
  851.    ps = st->pipe->create_surface(st->pipe, stimg.texture, &surf_tmpl);
  852.    pipe_resource_reference(&stimg.texture, NULL);
  853.  
  854.    return ps;
  855. }
  856.  
  857. /**
  858.  * Re-validate the framebuffers.
  859.  */
  860. void
  861. st_manager_validate_framebuffers(struct st_context *st)
  862. {
  863.    struct st_framebuffer *stdraw = st_ws_framebuffer(st->ctx->DrawBuffer);
  864.    struct st_framebuffer *stread = st_ws_framebuffer(st->ctx->ReadBuffer);
  865.  
  866.    if (stdraw)
  867.       st_framebuffer_validate(stdraw, st);
  868.    if (stread && stread != stdraw)
  869.       st_framebuffer_validate(stread, st);
  870.  
  871.    st_context_validate(st, stdraw, stread);
  872. }
  873.  
  874. /**
  875.  * Add a color renderbuffer on demand.
  876.  */
  877. boolean
  878. st_manager_add_color_renderbuffer(struct st_context *st,
  879.                                   struct gl_framebuffer *fb,
  880.                                   gl_buffer_index idx)
  881. {
  882.    struct st_framebuffer *stfb = st_ws_framebuffer(fb);
  883.  
  884.    /* FBO */
  885.    if (!stfb)
  886.       return FALSE;
  887.  
  888.    if (stfb->Base.Attachment[idx].Renderbuffer)
  889.       return TRUE;
  890.  
  891.    switch (idx) {
  892.    case BUFFER_FRONT_LEFT:
  893.    case BUFFER_BACK_LEFT:
  894.    case BUFFER_FRONT_RIGHT:
  895.    case BUFFER_BACK_RIGHT:
  896.       break;
  897.    default:
  898.       return FALSE;
  899.       break;
  900.    }
  901.  
  902.    if (!st_framebuffer_add_renderbuffer(stfb, idx))
  903.       return FALSE;
  904.  
  905.    st_framebuffer_update_attachments(stfb);
  906.  
  907.    /*
  908.     * Force a call to the state tracker manager to validate the
  909.     * new renderbuffer. It might be that there is a window system
  910.     * renderbuffer available.
  911.     */
  912.    if(stfb->iface)
  913.       stfb->iface_stamp = p_atomic_read(&stfb->iface->stamp) - 1;
  914.  
  915.    st_invalidate_state(st->ctx, _NEW_BUFFERS);
  916.  
  917.    return TRUE;
  918. }
  919.  
  920. static unsigned get_version(struct pipe_screen *screen,
  921.                             struct st_config_options *options, gl_api api)
  922. {
  923.    struct gl_constants consts = {0};
  924.    struct gl_extensions extensions = {0};
  925.    GLuint version;
  926.  
  927.    if ((api == API_OPENGL_COMPAT || api == API_OPENGL_CORE) &&
  928.        _mesa_override_gl_version_contextless(&consts, &api, &version)) {
  929.       return version;
  930.    }
  931.  
  932.    _mesa_init_constants(&consts, api);
  933.    _mesa_init_extensions(&extensions);
  934.  
  935.    st_init_limits(screen, &consts, &extensions);
  936.    st_init_extensions(screen, &consts, &extensions, options, GL_TRUE);
  937.  
  938.    return _mesa_get_version(&extensions, &consts, api);
  939. }
  940.  
  941. static void
  942. st_api_query_versions(struct st_api *stapi, struct st_manager *sm,
  943.                       struct st_config_options *options,
  944.                       int *gl_core_version,
  945.                       int *gl_compat_version,
  946.                       int *gl_es1_version,
  947.                       int *gl_es2_version)
  948. {
  949.    *gl_core_version = get_version(sm->screen, options, API_OPENGL_CORE);
  950.    *gl_compat_version = get_version(sm->screen, options, API_OPENGL_COMPAT);
  951.    *gl_es1_version = get_version(sm->screen, options, API_OPENGLES);
  952.    *gl_es2_version = get_version(sm->screen, options, API_OPENGLES2);
  953. }
  954.  
  955. static const struct st_api st_gl_api = {
  956.    "Mesa " PACKAGE_VERSION,
  957.    ST_API_OPENGL,
  958.    ST_PROFILE_DEFAULT_MASK |
  959.    ST_PROFILE_OPENGL_CORE_MASK |
  960.    ST_PROFILE_OPENGL_ES1_MASK |
  961.    ST_PROFILE_OPENGL_ES2_MASK |
  962.    0,
  963.    ST_API_FEATURE_MS_VISUALS_MASK,
  964.    st_api_destroy,
  965.    st_api_query_versions,
  966.    st_api_get_proc_address,
  967.    st_api_create_context,
  968.    st_api_make_current,
  969.    st_api_get_current,
  970. };
  971.  
  972. struct st_api *
  973. st_gl_api_create(void)
  974. {
  975.    return (struct st_api *) &st_gl_api;
  976. }
  977.