ufo-filter-scale.host 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include <gmodule.h>
  2. #ifdef __APPLE__
  3. #include <OpenCL/cl.h>
  4. #else
  5. #include <CL/cl.h>
  6. #endif
  7. #include <ufo/ufo-filter.h>
  8. // #include <ufo/ufo-element.h>
  9. #include <ufo/ufo-buffer.h>
  10. #include <ufo/ufo-resource-manager.h>
  11. #include "ufo-filter-scale.h"
  12. /**
  13. * SECTION:ufo-filter-scale
  14. * @Short_description: Scale image values
  15. * @Title: scale
  16. *
  17. * Scale input image values. The output
  18. * is a new image.
  19. * #UfoFilterScale: params.
  20. */
  21. struct _UfoFilterScalePrivate {
  22. float scale;
  23. cl_kernel kernel;
  24. };
  25. GType ufo_filter_scale_get_type(void) G_GNUC_CONST;
  26. /* Inherit from UFO_TYPE_FILTER */
  27. G_DEFINE_TYPE(UfoFilterScale, ufo_filter_scale, UFO_TYPE_FILTER);
  28. #define UFO_FILTER_SCALE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_SCALE, UfoFilterScalePrivate))
  29. enum {
  30. PROP_0 =0,
  31. PROP_SCALE,
  32. N_PROPERTIES
  33. };
  34. static GParamSpec *scale_properties[N_PROPERTIES] = { NULL, };
  35. /*
  36. * virtual methods
  37. */
  38. static void ufo_filter_scale_initialize(UfoFilter *filter)
  39. {
  40. UfoFilterScale *self = UFO_FILTER_SCALE(filter);
  41. UfoResourceManager *manager = ufo_resource_manager();
  42. GError *error = NULL;
  43. self->priv->kernel = NULL;
  44. ufo_resource_manager_add_program(manager, "scale.cl", NULL, &error);
  45. if (error != NULL) {
  46. g_warning("%s", error->message);
  47. g_error_free(error);
  48. return;
  49. }
  50. self->priv->kernel = ufo_resource_manager_get_kernel(manager, "scale", &error);
  51. if (error != NULL) {
  52. g_warning("%s", error->message);
  53. g_error_free(error);
  54. }
  55. }
  56. static void ufo_filter_scale_process(UfoFilter *filter)
  57. {
  58. g_return_if_fail(UFO_IS_FILTER(filter));
  59. UfoFilterScale *self = UFO_FILTER_SCALE(filter);
  60. UfoChannel *input_channel = ufo_filter_get_input_channel(filter);
  61. UfoChannel *output_channel = ufo_filter_get_output_channel(filter);
  62. cl_command_queue command_queue = (cl_command_queue) ufo_filter_get_command_queue(filter);
  63. UfoBuffer *input = ufo_channel_get_input_buffer(input_channel);
  64. ufo_channel_allocate_output_buffers_like(output_channel, input);
  65. const gint32 num_elements = ufo_buffer_get_size(input) / sizeof(float);
  66. float scale = (float) self->priv->scale;
  67. while(input !=NULL)
  68. {
  69. float *in_data = ufo_buffer_get_host_array(input, command_queue);
  70. UfoBuffer *output = ufo_channel_get_output_buffer(output_channel);
  71. /* This avoids an unneccessary GPU-to-host transfer */
  72. ufo_buffer_invalidate_gpu_data(output);
  73. float *out_data = ufo_buffer_get_host_array(output, command_queue);
  74. for (int i = 0; i < num_elements; i++)
  75. out_data[i] = scale * in_data[i];
  76. ufo_channel_finalize_input_buffer(input_channel, input);
  77. ufo_channel_finalize_output_buffer(output_channel, output);
  78. input = ufo_channel_get_input_buffer(input_channel); // read next
  79. g_message("ufo-filter-scale: processing is completed");
  80. }
  81. /* UfoBuffer *oimage = NULL;
  82. gint32 width, height;
  83. UfoBuffer *buffer = (UfoBuffer *) g_async_queue_pop(input_queue);
  84. while (!ufo_buffer_is_finished(buffer)) {
  85. if (self->priv->kernel != NULL) {
  86. float scale
  87. = (float) self->priv->scale;
  88. size_t global_work_size[2];
  89. ufo_buffer_get_dimensions(buffer, &width, &height);
  90. global_work_size[0] = width;
  91. global_work_size[1] = height;
  92. cl_mem buffer_mem = (cl_mem) ufo_buffer_get_gpu_data(buffer, command_queue);
  93. cl_int err = CL_SUCCESS;
  94. err = clSetKernelArg(self->priv->kernel, 0, sizeof(float), &scale);
  95. err = clSetKernelArg(self->priv->kernel, 1, sizeof(cl_mem), (void *) &buffer_mem);
  96. err = clEnqueueNDRangeKernel(command_queue,
  97. self->priv->kernel,
  98. 2, NULL, global_work_size, NULL,
  99. 0, NULL, &event);
  100. ufo_filter_account_gpu_time(filter, (void **) &event);
  101. }
  102. g_async_queue_push(output_queue, buffer);
  103. buffer = (UfoBuffer *) g_async_queue_pop(input_queue);
  104. }
  105. // g_message("ufo-filter-scale: 0s/%fs", ufo_filter_get_gpu_time(filter));
  106. // g_async_queue_push(output_queue, buffer);
  107. */
  108. ufo_channel_finish(output_channel);
  109. }
  110. static void ufo_filter_scale_set_property(GObject *object,
  111. guint property_id,
  112. const GValue *value,
  113. GParamSpec *pspec)
  114. {
  115. UfoFilterScale *self = UFO_FILTER_SCALE(object);
  116. switch (property_id) {
  117. case PROP_SCALE:
  118. self->priv->scale = (float) g_value_get_double(value);
  119. break;
  120. default:
  121. G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
  122. break;
  123. }
  124. }
  125. static void ufo_filter_scale_get_property(GObject *object,
  126. guint property_id,
  127. GValue *value,
  128. GParamSpec *pspec)
  129. {
  130. UfoFilterScale *self = UFO_FILTER_SCALE(object);
  131. switch (property_id) {
  132. case PROP_SCALE:
  133. g_value_set_double(value, (double) self->priv->scale);
  134. break;
  135. default:
  136. G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
  137. break;
  138. }
  139. }
  140. static void ufo_filter_scale_class_init(UfoFilterScaleClass *klass)
  141. {
  142. GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
  143. UfoFilterClass *filter_class = UFO_FILTER_CLASS(klass);
  144. gobject_class->set_property = ufo_filter_scale_set_property;
  145. gobject_class->get_property = ufo_filter_scale_get_property;
  146. filter_class->initialize = ufo_filter_scale_initialize;
  147. filter_class->process = ufo_filter_scale_process;
  148. scale_properties[PROP_SCALE] =
  149. g_param_spec_double("scale",
  150. "Scale",
  151. "Scale for each pixel",
  152. -5.0, /* minimum */
  153. 10.0, /* maximum */
  154. 1.0, /* default */
  155. G_PARAM_READWRITE);
  156. g_object_class_install_property(gobject_class, PROP_SCALE, scale_properties[PROP_SCALE]);
  157. /* install private data */
  158. g_type_class_add_private(gobject_class, sizeof(UfoFilterScalePrivate));
  159. }
  160. static void ufo_filter_scale_init(UfoFilterScale *self)
  161. {
  162. UfoFilterScalePrivate *priv = self->priv = UFO_FILTER_SCALE_GET_PRIVATE(self);
  163. priv->scale = 1.0;
  164. priv->kernel = NULL;
  165. ufo_filter_register_input (UFO_FILTER(self), "image", 2);
  166. ufo_filter_register_output(UFO_FILTER(self), "image", 2);
  167. }
  168. G_MODULE_EXPORT *ufo_filter_plugin_new(void)
  169. {
  170. return g_object_new(UFO_TYPE_FILTER_SCALE, NULL);
  171. }