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
  17.  * OR 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
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER 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_inlines.h"
  30. #include "util/u_atomic.h"
  31. #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
  32.  
  33. #include "stw_st.h"
  34. #include "stw_device.h"
  35. #include "stw_framebuffer.h"
  36. #include "stw_pixelformat.h"
  37.  
  38. struct stw_st_framebuffer {
  39.    struct st_framebuffer_iface base;
  40.  
  41.    struct stw_framebuffer *fb;
  42.    struct st_visual stvis;
  43.  
  44.    struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
  45.    unsigned texture_width, texture_height;
  46.    unsigned texture_mask;
  47. };
  48.  
  49. static INLINE struct stw_st_framebuffer *
  50. stw_st_framebuffer(struct st_framebuffer_iface *stfb)
  51. {
  52.    return (struct stw_st_framebuffer *) stfb;
  53. }
  54.  
  55. /**
  56.  * Remove outdated textures and create the requested ones.
  57.  */
  58. static void
  59. stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
  60.                                    unsigned width, unsigned height,
  61.                                    unsigned mask)
  62. {
  63.    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  64.    struct pipe_resource templ;
  65.    unsigned i;
  66.  
  67.    /* remove outdated textures */
  68.    if (stwfb->texture_width != width || stwfb->texture_height != height) {
  69.       for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
  70.          pipe_resource_reference(&stwfb->textures[i], NULL);
  71.    }
  72.  
  73.    memset(&templ, 0, sizeof(templ));
  74.    templ.target = PIPE_TEXTURE_2D;
  75.    templ.width0 = width;
  76.    templ.height0 = height;
  77.    templ.depth0 = 1;
  78.    templ.array_size = 1;
  79.    templ.last_level = 0;
  80.  
  81.    for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
  82.       enum pipe_format format;
  83.       unsigned bind;
  84.  
  85.       /* the texture already exists or not requested */
  86.       if (stwfb->textures[i] || !(mask & (1 << i))) {
  87.          /* remember the texture */
  88.          if (stwfb->textures[i])
  89.             mask |= (1 << i);
  90.          continue;
  91.       }
  92.  
  93.       switch (i) {
  94.       case ST_ATTACHMENT_FRONT_LEFT:
  95.       case ST_ATTACHMENT_BACK_LEFT:
  96.          format = stwfb->stvis.color_format;
  97.          bind = PIPE_BIND_DISPLAY_TARGET |
  98.                 PIPE_BIND_RENDER_TARGET;
  99.          break;
  100.       case ST_ATTACHMENT_DEPTH_STENCIL:
  101.          format = stwfb->stvis.depth_stencil_format;
  102.          bind = PIPE_BIND_DEPTH_STENCIL;
  103.          break;
  104.       default:
  105.          format = PIPE_FORMAT_NONE;
  106.          break;
  107.       }
  108.  
  109.       if (format != PIPE_FORMAT_NONE) {
  110.          templ.format = format;
  111.          templ.bind = bind;
  112.  
  113.          stwfb->textures[i] =
  114.             stw_dev->screen->resource_create(stw_dev->screen, &templ);
  115.       }
  116.    }
  117.  
  118.    stwfb->texture_width = width;
  119.    stwfb->texture_height = height;
  120.    stwfb->texture_mask = mask;
  121. }
  122.  
  123. static boolean
  124. stw_st_framebuffer_validate(struct st_context_iface *stctx,
  125.                             struct st_framebuffer_iface *stfb,
  126.                             const enum st_attachment_type *statts,
  127.                             unsigned count,
  128.                             struct pipe_resource **out)
  129. {
  130.    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  131.    unsigned statt_mask, i;
  132.  
  133.    statt_mask = 0x0;
  134.    for (i = 0; i < count; i++)
  135.       statt_mask |= 1 << statts[i];
  136.  
  137.    pipe_mutex_lock(stwfb->fb->mutex);
  138.  
  139.    if (stwfb->fb->must_resize || (statt_mask & ~stwfb->texture_mask)) {
  140.       stw_st_framebuffer_validate_locked(&stwfb->base,
  141.             stwfb->fb->width, stwfb->fb->height, statt_mask);
  142.       stwfb->fb->must_resize = FALSE;
  143.    }
  144.  
  145.    for (i = 0; i < count; i++) {
  146.       out[i] = NULL;
  147.       pipe_resource_reference(&out[i], stwfb->textures[statts[i]]);
  148.    }
  149.  
  150.    stw_framebuffer_release(stwfb->fb);
  151.  
  152.    return TRUE;
  153. }
  154.  
  155. /**
  156.  * Present an attachment of the framebuffer.
  157.  */
  158. static boolean
  159. stw_st_framebuffer_present_locked(HDC hdc,
  160.                                   struct st_framebuffer_iface *stfb,
  161.                                   enum st_attachment_type statt)
  162. {
  163.    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  164.    struct pipe_resource *resource;
  165.  
  166.    resource = stwfb->textures[statt];
  167.    if (resource) {
  168.       stw_framebuffer_present_locked(hdc, stwfb->fb, resource);
  169.    }
  170.  
  171.    return TRUE;
  172. }
  173.  
  174. static boolean
  175. stw_st_framebuffer_flush_front(struct st_context_iface *stctx,
  176.                                struct st_framebuffer_iface *stfb,
  177.                                enum st_attachment_type statt)
  178. {
  179.    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  180.    boolean ret;
  181.    HDC hDC;
  182.  
  183.    pipe_mutex_lock(stwfb->fb->mutex);
  184.  
  185.    /* We must not cache HDCs anywhere, as they can be invalidated by the
  186.     * application, or screen resolution changes. */
  187.  
  188.    hDC = GetDC(stwfb->fb->hWnd);
  189.  
  190.    ret = stw_st_framebuffer_present_locked(hDC, &stwfb->base, statt);
  191.  
  192.    ReleaseDC(stwfb->fb->hWnd, hDC);
  193.  
  194.    return ret;
  195. }
  196.  
  197. /**
  198.  * Create a framebuffer interface.
  199.  */
  200. struct st_framebuffer_iface *
  201. stw_st_create_framebuffer(struct stw_framebuffer *fb)
  202. {
  203.    struct stw_st_framebuffer *stwfb;
  204.  
  205.    stwfb = CALLOC_STRUCT(stw_st_framebuffer);
  206.    if (!stwfb)
  207.       return NULL;
  208.  
  209.    stwfb->fb = fb;
  210.    stwfb->stvis = fb->pfi->stvis;
  211.  
  212.    stwfb->base.visual = &stwfb->stvis;
  213.    p_atomic_set(&stwfb->base.stamp, 1);
  214.    stwfb->base.flush_front = stw_st_framebuffer_flush_front;
  215.    stwfb->base.validate = stw_st_framebuffer_validate;
  216.  
  217.    return &stwfb->base;
  218. }
  219.  
  220. /**
  221.  * Destroy a framebuffer interface.
  222.  */
  223. void
  224. stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb)
  225. {
  226.    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  227.    int i;
  228.  
  229.    for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
  230.       pipe_resource_reference(&stwfb->textures[i], NULL);
  231.  
  232.    FREE(stwfb);
  233. }
  234.  
  235. /**
  236.  * Swap the buffers of the given framebuffer.
  237.  */
  238. boolean
  239. stw_st_swap_framebuffer_locked(HDC hdc, struct st_framebuffer_iface *stfb)
  240. {
  241.    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  242.    unsigned front = ST_ATTACHMENT_FRONT_LEFT, back = ST_ATTACHMENT_BACK_LEFT;
  243.    struct pipe_resource *ptex;
  244.    unsigned mask;
  245.  
  246.    /* swap the textures */
  247.    ptex = stwfb->textures[front];
  248.    stwfb->textures[front] = stwfb->textures[back];
  249.    stwfb->textures[back] = ptex;
  250.  
  251.    /* convert to mask */
  252.    front = 1 << front;
  253.    back = 1 << back;
  254.  
  255.    /* swap the bits in mask */
  256.    mask = stwfb->texture_mask & ~(front | back);
  257.    if (stwfb->texture_mask & front)
  258.       mask |= back;
  259.    if (stwfb->texture_mask & back)
  260.       mask |= front;
  261.    stwfb->texture_mask = mask;
  262.  
  263.    front = ST_ATTACHMENT_FRONT_LEFT;
  264.    return stw_st_framebuffer_present_locked(hdc, &stwfb->base, front);
  265. }
  266.  
  267.  
  268. /**
  269.  * Return the pipe_resource that correspond to given buffer.
  270.  */
  271. struct pipe_resource *
  272. stw_get_framebuffer_resource(struct st_framebuffer_iface *stfb,
  273.                              enum st_attachment_type att)
  274. {
  275.    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  276.    return stwfb->textures[att];
  277. }
  278.  
  279.  
  280. /**
  281.  * Create an st_api of the state tracker.
  282.  */
  283. struct st_api *
  284. stw_st_create_api(void)
  285. {
  286.    return st_gl_api_create();
  287. }
  288.