aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/evas/filters/evas_filter_private.h
blob: 544d76717ccdb3843e8eb50c7c6debe7eaa7b771 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifndef EVAS_FILTER_PRIVATE_H
#define EVAS_FILTER_PRIVATE_H

#include "evas_filter.h"
#include "evas_private.h"

// This is a potential optimization.
#define DIV_USING_BITSHIFT 1

#ifdef LITTLE_ENDIAN
#define ALPHA 3
#define RGB0 0
#define RGB3 3
#define RED 2
#define GREEN 1
#define BLUE 0
#else
#define ALPHA 0
#define RGB0 1
#define RGB3 4
#define RED 0
#define GREEN 1
#define BLUE 2
#endif

// RGBA = (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
#define ALPHA_OF(a) ((a) >> 24)
#define RED_OF(a)   (((a) >> 16) & 0xff)
#define GREEN_OF(a) (((a) >> 8) & 0xff)
#define BLUE_OF(a)  ((a) & 0xff)

// Helpers
#define ENFN ctx->evas->engine.func
#define ENDT ctx->evas->engine.data.output

#define BUFFERS_LOCK() do { if (cmd->input) cmd->input->locked = 1; if (cmd->output) cmd->output->locked = 1; if (cmd->mask) cmd->mask->locked = 1; } while (0)
#define BUFFERS_UNLOCK() do { if (cmd->input) cmd->input->locked = 0; if (cmd->output) cmd->output->locked = 0; if (cmd->mask) cmd->mask->locked = 0; } while (0)

typedef enum _Evas_Filter_Interpolation_Mode Evas_Filter_Interpolation_Mode;

struct _Evas_Filter_Context
{
   Evas_Public_Data *evas;
   Eina_Inlist *commands;
   Eina_List *buffers; // Evas_Filter_Buffer *
   int last_buffer_id;
   int last_command_id;

   // Variables changing at each run
   int w, h; // Dimensions of the input/output buffers
   int padl, padt, padr, padb; // Padding in the current input/output buffers

   struct
   {
      /** Post-processing callback. The context can be safely destroyed here. */
      Evas_Filter_Cb cb;
      void *data;
   } post_run;

   struct
   {
      int bufid;
      void *context;
      int x, y;
   } target;

   Eina_Bool async : 1;
   Eina_Bool gl_engine : 1;
   Eina_Bool running : 1;
};

struct _Evas_Filter_Command
{
   EINA_INLIST;

   int id;
   Evas_Filter_Mode mode;
   Evas_Filter_Context *ctx;

   Evas_Filter_Buffer *input;
   Evas_Filter_Buffer *mask;
   Evas_Filter_Buffer *output;

   union
   {
      struct
      {
         int dx, dy;
         Evas_Filter_Blur_Type type;
      } blur;

      struct
      {
         DATA8 *data; // Pointer to 256 char array
         Evas_Filter_Channel channel;
      } curve;

      struct
      {
         // mask contains the map data
         Evas_Filter_Displacement_Flags flags;
         int intensity; // Max displacement in pixels
      } displacement;

      struct
      {
         float xyangle; // in degrees: 0-360 (modulo)
         float zangle;  // degrees: 0-90 (defaults to 0)
         float specular_factor; // range TBD: 0-...
         float elevation;
         DATA32 dark;
         DATA32 color;
         DATA32 white;
         Eina_Bool compensate : 1; // Compensate for darkening
         //Eina_Bool specular : 1; // Use specular light as well (needs specular_factor > 0)
      } bump;

      struct
      {
         Evas_Filter_Transform_Flags flags;
      } transform;
   };

   struct {
      int render_op;
      int R, G, B, A;
      int ox, oy;
      union {
         struct {
            int x, y, w, h;
         };
         struct {
            int l, r, t, b;
         };
      } clip;
      Evas_Filter_Fill_Mode fillmode;
      Eina_Bool clip_use : 1;
      Eina_Bool clip_mode_lrtb : 1;
      Eina_Bool need_temp_buffer : 1;
   } draw;
};

struct _Evas_Filter_Buffer
{
   EINA_REFCOUNT;

   int id;
   Evas_Filter_Context *ctx;

   Evas_Object *source;
   Eina_Stringshare *source_name;
   void *backing;
   void *glimage;
   int w, h;

   Evas_Object *proxy;

   Eina_Bool alpha_only : 1;  // 1 channel (A) instead of 4 (RGBA)
   Eina_Bool allocated : 1;   // allocated on demand, belongs to this context
   Eina_Bool transient : 1;   // temporary buffer (automatic allocation)
   Eina_Bool locked : 1;      // internal flag
   Eina_Bool stolen : 1;      // stolen by the client
   Eina_Bool delete_me : 1;   // request delete asap (after released by client)
};

enum _Evas_Filter_Interpolation_Mode
{
   EVAS_FILTER_INTERPOLATION_MODE_NONE,
   EVAS_FILTER_INTERPOLATION_MODE_LINEAR
};

void                     evas_filter_context_clear(Evas_Filter_Context *ctx);
void                     evas_filter_context_source_set(Evas_Filter_Context *ctx, Evas_Object *eo_proxy, Evas_Object *eo_source, int bufid, Eina_Stringshare *name);

/* FIXME: CPU filters entry points. Move these to the Evas Engine itself. */
Evas_Filter_Apply_Func   evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func   evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func   evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func   evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func   evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func   evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func   evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func   evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd);

/* Utility functions */
void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols);
Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h);
Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid);
Eina_Bool           _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, int w, int h, Eina_Bool alpha_only);
Evas_Filter_Buffer *_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, Eina_Bool alpha_only);
#define             evas_filter_buffer_alloc_new(ctx, w, h, a) _filter_buffer_data_new(ctx, NULL, w, h, a)
Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only);
Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, DATA8* points /* pairs x + y */, int point_count, Evas_Filter_Interpolation_Mode mode);
Evas_Filter_Command *_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid);

#endif // EVAS_FILTER_PRIVATE_H