123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- #include <gmodule.h>
- #ifdef __APPLE__
- #include <OpenCL/cl.h>
- #else
- #include <CL/cl.h>
- #endif
- #include <ufo/ufo-filter.h>
- // #include <ufo/ufo-element.h>
- #include <ufo/ufo-buffer.h>
- #include <ufo/ufo-resource-manager.h>
- #include "ufo-filter-scale.h"
- /**
- * SECTION:ufo-filter-scale
- * @Short_description: Scale image values
- * @Title: scale
- *
- * Scale input image values. The output
- * is a new image.
- * #UfoFilterScale: params.
- */
- struct _UfoFilterScalePrivate {
- float scale;
- cl_kernel kernel;
- };
- GType ufo_filter_scale_get_type(void) G_GNUC_CONST;
- /* Inherit from UFO_TYPE_FILTER */
- G_DEFINE_TYPE(UfoFilterScale, ufo_filter_scale, UFO_TYPE_FILTER);
- #define UFO_FILTER_SCALE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_FILTER_SCALE, UfoFilterScalePrivate))
- enum {
- PROP_0 =0,
- PROP_SCALE,
- N_PROPERTIES
- };
- static GParamSpec *scale_properties[N_PROPERTIES] = { NULL, };
- /*
- * virtual methods
- */
- static void ufo_filter_scale_initialize(UfoFilter *filter)
- {
- UfoFilterScale *self = UFO_FILTER_SCALE(filter);
- UfoResourceManager *manager = ufo_resource_manager();
- GError *error = NULL;
- self->priv->kernel = NULL;
- ufo_resource_manager_add_program(manager, "scale.cl", NULL, &error);
- if (error != NULL) {
- g_warning("%s", error->message);
- g_error_free(error);
- return;
- }
- self->priv->kernel = ufo_resource_manager_get_kernel(manager, "scale", &error);
- if (error != NULL) {
- g_warning("%s", error->message);
- g_error_free(error);
- }
- }
- static void ufo_filter_scale_process(UfoFilter *filter)
- {
- g_return_if_fail(UFO_IS_FILTER(filter));
- UfoFilterScale *self = UFO_FILTER_SCALE(filter);
- UfoChannel *input_channel = ufo_filter_get_input_channel(filter);
- UfoChannel *output_channel = ufo_filter_get_output_channel(filter);
- cl_command_queue command_queue = (cl_command_queue) ufo_filter_get_command_queue(filter);
- UfoBuffer *input = ufo_channel_get_input_buffer(input_channel);
- ufo_channel_allocate_output_buffers_like(output_channel, input);
-
- const gint32 num_elements = ufo_buffer_get_size(input) / sizeof(float);
- float scale = (float) self->priv->scale;
- while(input !=NULL)
- {
- float *in_data = ufo_buffer_get_host_array(input, command_queue);
- UfoBuffer *output = ufo_channel_get_output_buffer(output_channel);
-
- /* This avoids an unneccessary GPU-to-host transfer */
- ufo_buffer_invalidate_gpu_data(output);
- float *out_data = ufo_buffer_get_host_array(output, command_queue);
- for (int i = 0; i < num_elements; i++)
- out_data[i] = scale * in_data[i];
- ufo_channel_finalize_input_buffer(input_channel, input);
- ufo_channel_finalize_output_buffer(output_channel, output);
- input = ufo_channel_get_input_buffer(input_channel); // read next
- g_message("ufo-filter-scale: processing is completed");
- }
- /* UfoBuffer *oimage = NULL;
- gint32 width, height;
- UfoBuffer *buffer = (UfoBuffer *) g_async_queue_pop(input_queue);
- while (!ufo_buffer_is_finished(buffer)) {
- if (self->priv->kernel != NULL) {
- float scale
- = (float) self->priv->scale;
- size_t global_work_size[2];
- ufo_buffer_get_dimensions(buffer, &width, &height);
- global_work_size[0] = width;
- global_work_size[1] = height;
- cl_mem buffer_mem = (cl_mem) ufo_buffer_get_gpu_data(buffer, command_queue);
- cl_int err = CL_SUCCESS;
- err = clSetKernelArg(self->priv->kernel, 0, sizeof(float), &scale);
- err = clSetKernelArg(self->priv->kernel, 1, sizeof(cl_mem), (void *) &buffer_mem);
- err = clEnqueueNDRangeKernel(command_queue,
- self->priv->kernel,
- 2, NULL, global_work_size, NULL,
- 0, NULL, &event);
- ufo_filter_account_gpu_time(filter, (void **) &event);
- }
- g_async_queue_push(output_queue, buffer);
- buffer = (UfoBuffer *) g_async_queue_pop(input_queue);
- }
- // g_message("ufo-filter-scale: 0s/%fs", ufo_filter_get_gpu_time(filter));
- // g_async_queue_push(output_queue, buffer);
- */
- ufo_channel_finish(output_channel);
- }
- static void ufo_filter_scale_set_property(GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
- {
- UfoFilterScale *self = UFO_FILTER_SCALE(object);
- switch (property_id) {
- case PROP_SCALE:
- self->priv->scale = (float) g_value_get_double(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
- }
- static void ufo_filter_scale_get_property(GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
- {
- UfoFilterScale *self = UFO_FILTER_SCALE(object);
- switch (property_id) {
- case PROP_SCALE:
- g_value_set_double(value, (double) self->priv->scale);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
- }
- static void ufo_filter_scale_class_init(UfoFilterScaleClass *klass)
- {
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- UfoFilterClass *filter_class = UFO_FILTER_CLASS(klass);
- gobject_class->set_property = ufo_filter_scale_set_property;
- gobject_class->get_property = ufo_filter_scale_get_property;
- filter_class->initialize = ufo_filter_scale_initialize;
- filter_class->process = ufo_filter_scale_process;
- scale_properties[PROP_SCALE] =
- g_param_spec_double("scale",
- "Scale",
- "Scale for each pixel",
- -5.0, /* minimum */
- 10.0, /* maximum */
- 1.0, /* default */
- G_PARAM_READWRITE);
- g_object_class_install_property(gobject_class, PROP_SCALE, scale_properties[PROP_SCALE]);
- /* install private data */
- g_type_class_add_private(gobject_class, sizeof(UfoFilterScalePrivate));
- }
- static void ufo_filter_scale_init(UfoFilterScale *self)
- {
- UfoFilterScalePrivate *priv = self->priv = UFO_FILTER_SCALE_GET_PRIVATE(self);
- priv->scale = 1.0;
- priv->kernel = NULL;
-
- ufo_filter_register_input (UFO_FILTER(self), "image", 2);
- ufo_filter_register_output(UFO_FILTER(self), "image", 2);
- }
- G_MODULE_EXPORT *ufo_filter_plugin_new(void)
- {
- return g_object_new(UFO_TYPE_FILTER_SCALE, NULL);
- }
|