Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2012-2014, Haiku, Inc. All Rights Reserved.
  3.  * Distributed under the terms of the MIT License.
  4.  *
  5.  * Authors:
  6.  *      Artur Wyszynski, harakash@gmail.com
  7.  *      Alexander von Gluck IV, kallisti5@unixzen.com
  8.  */
  9.  
  10. #include "hgl_context.h"
  11.  
  12. #include <stdio.h>
  13.  
  14. #include "pipe/p_format.h"
  15. #include "util/u_atomic.h"
  16. #include "util/u_format.h"
  17. #include "util/u_memory.h"
  18. #include "util/u_inlines.h"
  19. #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
  20.  
  21. #include "GLView.h"
  22.  
  23.  
  24. #ifdef DEBUG
  25. #   define TRACE(x...) printf("hgl:state_tracker: " x)
  26. #   define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
  27. #else
  28. #   define TRACE(x...)
  29. #   define CALLED()
  30. #endif
  31. #define ERROR(x...) printf("hgl:state_tracker: " x)
  32.  
  33.  
  34. // Perform a safe void to hgl_context cast
  35. static INLINE struct hgl_context*
  36. hgl_st_context(struct st_context_iface *stctxi)
  37. {
  38.         struct hgl_context* context;
  39.         assert(stctxi);
  40.         context = (struct hgl_context*)stctxi->st_manager_private;
  41.         assert(context);
  42.         return context;
  43. }
  44.  
  45.  
  46. // Perform a safe void to hgl_buffer cast
  47. static INLINE struct hgl_buffer*
  48. hgl_st_framebuffer(struct st_framebuffer_iface *stfbi)
  49. {
  50.         struct hgl_buffer* buffer;
  51.         assert(stfbi);
  52.         buffer = (struct hgl_buffer*)stfbi->st_manager_private;
  53.         assert(buffer);
  54.         return buffer;
  55. }
  56.  
  57.  
  58. static boolean
  59. hgl_st_framebuffer_flush_front(struct st_context_iface *stctxi,
  60.         struct st_framebuffer_iface* stfbi, enum st_attachment_type statt)
  61. {
  62.         CALLED();
  63.  
  64.         //struct hgl_context* context = hgl_st_context(stctxi);
  65.         //struct hgl_buffer* buffer = hgl_st_context(stfbi);
  66.  
  67.         #if 0
  68.         struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
  69.         pipe_mutex_lock(stwfb->fb->mutex);
  70.  
  71.         struct pipe_resource* resource = textures[statt];
  72.         if (resource)
  73.                 stw_framebuffer_present_locked(...);
  74.         #endif
  75.  
  76.         return TRUE;
  77. }
  78.  
  79.  
  80. static boolean
  81. hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
  82.         unsigned width, unsigned height, unsigned mask)
  83. {
  84.         struct hgl_buffer* buffer;
  85.         enum st_attachment_type i;
  86.         struct pipe_resource templat;
  87.  
  88.         CALLED();
  89.  
  90.         buffer = hgl_st_framebuffer(stfbi);
  91.  
  92.         if (buffer->width != width || buffer->height != height) {
  93.                 for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
  94.                         pipe_resource_reference(&buffer->textures[i], NULL);
  95.         }
  96.  
  97.         memset(&templat, 0, sizeof(templat));
  98.         templat.target = buffer->target;
  99.         templat.width0 = width;
  100.         templat.height0 = height;
  101.         templat.depth0 = 1;
  102.         templat.array_size = 1;
  103.         templat.last_level = 0;
  104.  
  105.         for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
  106.                 enum pipe_format format;
  107.                 unsigned bind;
  108.  
  109.                 switch (i) {
  110.                         case ST_ATTACHMENT_FRONT_LEFT:
  111.                         case ST_ATTACHMENT_BACK_LEFT:
  112.                         case ST_ATTACHMENT_FRONT_RIGHT:
  113.                         case ST_ATTACHMENT_BACK_RIGHT:
  114.                                 format = buffer->visual->color_format;
  115.                                 bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
  116.                                 break;
  117.                         case ST_ATTACHMENT_DEPTH_STENCIL:
  118.                                 format = buffer->visual->depth_stencil_format;
  119.                                 bind = PIPE_BIND_DEPTH_STENCIL;
  120.                                 break;
  121.                         default:
  122.                                 format = PIPE_FORMAT_NONE;
  123.                                 bind = 0;
  124.                                 break;
  125.                 }
  126.  
  127.                 if (format != PIPE_FORMAT_NONE) {
  128.                         templat.format = format;
  129.                         templat.bind = bind;
  130.                         buffer->textures[i] = buffer->screen->resource_create(buffer->screen,
  131.                                 &templat);
  132.                         if (!buffer->textures[i])
  133.                                 return FALSE;
  134.                 }
  135.         }
  136.  
  137.         buffer->width = width;
  138.         buffer->height = height;
  139.         buffer->mask = mask;
  140.  
  141.         return TRUE;
  142. }
  143.  
  144.  
  145. /**
  146.  * Called by the st manager to validate the framebuffer (allocate
  147.  * its resources).
  148.  */
  149. static boolean
  150. hgl_st_framebuffer_validate(struct st_context_iface *stctxi,
  151.         struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts,
  152.         unsigned count, struct pipe_resource **out)
  153. {
  154.         struct hgl_context* context;
  155.         struct hgl_buffer* buffer;
  156.         unsigned stAttachmentMask, newMask;
  157.         unsigned i;
  158.         boolean resized;
  159.  
  160.         CALLED();
  161.  
  162.         context = hgl_st_context(stctxi);
  163.         buffer = hgl_st_framebuffer(stfbi);
  164.  
  165.         //int32 width = 0;
  166.         //int32 height = 0;
  167.         //get_bitmap_size(context->bitmap, &width, &height);
  168.  
  169.         // Build mask of current attachments
  170.         stAttachmentMask = 0;
  171.         for (i = 0; i < count; i++)
  172.                 stAttachmentMask |= 1 << statts[i];
  173.  
  174.         newMask = stAttachmentMask & ~buffer->mask;
  175.  
  176.         resized = (buffer->width != context->width)
  177.                 || (buffer->height != context->height);
  178.  
  179.         if (resized || newMask) {
  180.                 boolean ret;
  181.                 TRACE("%s: resize event. old:  %d x %d; new: %d x %d\n", __func__,
  182.                         buffer->width, buffer->height, context->width, context->height);
  183.  
  184.                 ret = hgl_st_framebuffer_validate_textures(stfbi,
  185.                         context->width, context->height, stAttachmentMask);
  186.                
  187.                 if (!ret)
  188.                         return ret;
  189.  
  190.                 // TODO: Simply update attachments
  191.                 //if (!resized) {
  192.  
  193.                 //}
  194.         }
  195.  
  196.         for (i = 0; i < count; i++) {
  197.                 out[i] = NULL;
  198.                 pipe_resource_reference(&out[i], buffer->textures[statts[i]]);
  199.         }
  200.  
  201.         return TRUE;
  202. }
  203.  
  204.  
  205. static int
  206. hgl_st_manager_get_param(struct st_manager *smapi, enum st_manager_param param)
  207. {
  208.         CALLED();
  209.  
  210.         switch (param) {
  211.                 case ST_MANAGER_BROKEN_INVALIDATE:
  212.                         return 1;
  213.         }
  214.  
  215.         return 0;
  216. }
  217.  
  218.  
  219. /**
  220.  * Create new framebuffer
  221.  */
  222. struct hgl_buffer *
  223. hgl_create_st_framebuffer(struct hgl_context* context)
  224. {
  225.         struct hgl_buffer *buffer;
  226.         CALLED();
  227.  
  228.         // Our requires before creating a framebuffer
  229.         assert(context);
  230.         assert(context->screen);
  231.         assert(context->stVisual);
  232.  
  233.         buffer = CALLOC_STRUCT(hgl_buffer);
  234.         assert(buffer);
  235.  
  236.         // calloc and configure our st_framebuffer interface
  237.         buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface);
  238.         assert(buffer->stfbi);
  239.  
  240.         // Prepare our buffer
  241.         buffer->visual = context->stVisual;
  242.         buffer->screen = context->screen;
  243.  
  244.         if (context->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES))
  245.                 buffer->target = PIPE_TEXTURE_2D;
  246.         else
  247.                 buffer->target = PIPE_TEXTURE_RECT;
  248.  
  249.         // Prepare our state_tracker interface
  250.         buffer->stfbi->flush_front = hgl_st_framebuffer_flush_front;
  251.         buffer->stfbi->validate = hgl_st_framebuffer_validate;
  252.         buffer->stfbi->visual = context->stVisual;
  253.  
  254.         p_atomic_set(&buffer->stfbi->stamp, 1);
  255.         buffer->stfbi->st_manager_private = (void*)buffer;
  256.  
  257.         return buffer;
  258. }
  259.  
  260.  
  261. struct st_api*
  262. hgl_create_st_api()
  263. {
  264.         CALLED();
  265.         return st_gl_api_create();
  266. }
  267.  
  268.  
  269. struct st_manager *
  270. hgl_create_st_manager(struct hgl_context* context)
  271. {
  272.         struct st_manager* manager;
  273.  
  274.         CALLED();
  275.  
  276.         // Required things
  277.         assert(context);
  278.         assert(context->screen);
  279.  
  280.         manager = CALLOC_STRUCT(st_manager);
  281.         assert(manager);
  282.  
  283.         //manager->display = dpy;
  284.         manager->screen = context->screen;
  285.         manager->get_param = hgl_st_manager_get_param;
  286.  
  287.         return manager;
  288. }
  289.  
  290.  
  291. void
  292. hgl_destroy_st_manager(struct st_manager *manager)
  293. {
  294.         CALLED();
  295.  
  296.         FREE(manager);
  297. }
  298.  
  299.  
  300. struct st_visual*
  301. hgl_create_st_visual(ulong options)
  302. {
  303.         struct st_visual* visual;
  304.  
  305.         CALLED();
  306.  
  307.         visual = CALLOC_STRUCT(st_visual);
  308.         assert(visual);
  309.  
  310.         // Determine color format
  311.         if ((options & BGL_INDEX) != 0) {
  312.                 // Index color
  313.                 visual->color_format = PIPE_FORMAT_B5G6R5_UNORM;
  314.                 // TODO: Indexed color depth buffer?
  315.                 visual->depth_stencil_format = PIPE_FORMAT_NONE;
  316.         } else {
  317.                 // RGB color
  318.                 visual->color_format = (options & BGL_ALPHA)
  319.                         ? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM;
  320.                 // TODO: Determine additional stencil formats
  321.                 visual->depth_stencil_format = (options & BGL_DEPTH)
  322.                         ? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE;
  323.     }
  324.  
  325.         visual->accum_format = (options & BGL_ACCUM)
  326.                 ? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
  327.  
  328.         visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
  329.         visual->render_buffer = ST_ATTACHMENT_FRONT_LEFT;
  330.  
  331.         if ((options & BGL_DOUBLE) != 0) {
  332.                 visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
  333.                 visual->render_buffer = ST_ATTACHMENT_BACK_LEFT;
  334.         }
  335.  
  336.         #if 0
  337.         if ((options & BGL_STEREO) != 0) {
  338.                 visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
  339.                 if ((options & BGL_DOUBLE) != 0)
  340.                         visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
  341.     }
  342.         #endif
  343.  
  344.         if ((options & BGL_DEPTH) || (options & BGL_STENCIL))
  345.                 visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
  346.  
  347.         TRACE("%s: Visual color format: %s\n", __func__,
  348.                 util_format_name(visual->color_format));
  349.  
  350.         return visual;
  351. }
  352.  
  353.  
  354. void
  355. hgl_destroy_st_visual(struct st_visual* visual)
  356. {
  357.         CALLED();
  358.  
  359.         FREE(visual);
  360. }
  361.