move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / direct3d / evas_outbuf.c
1 #include "evas_engine.h"
2
3
4 void
5 evas_direct3d_outbuf_init(void)
6 {
7 }
8
9 void
10 evas_direct3d_outbuf_free(Outbuf *buf)
11 {
12    free(buf);
13 }
14
15 Outbuf *
16 evas_direct3d_outbuf_setup_d3d(int                width,
17                                int                height,
18                                int                rotation,
19                                Outbuf_Depth       depth,
20                                HWND               window,
21                                LPDIRECT3D9        object,
22                                LPDIRECT3DDEVICE9  device,
23                                LPD3DXSPRITE       sprite,
24                                LPDIRECT3DTEXTURE9 texture,
25                                int                w_depth)
26 {
27    Outbuf *buf;
28
29    buf = (Outbuf *)calloc(1, sizeof(Outbuf));
30    if (!buf)
31       return NULL;
32
33    buf->width = width;
34    buf->height = height;
35    buf->depth = depth;
36    buf->rot = rotation;
37
38    buf->priv.d3d.window = window;
39    buf->priv.d3d.object = object;
40    buf->priv.d3d.device = device;
41    buf->priv.d3d.sprite = sprite;
42    buf->priv.d3d.texture = texture;
43    buf->priv.d3d.depth = w_depth;
44
45    {
46       Gfx_Func_Convert        conv_func;
47       Direct3D_Output_Buffer *d3dob;
48
49       d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth, 1, 1, NULL);
50
51       conv_func = NULL;
52       if (d3dob)
53         {
54            if (evas_direct3d_masks_get(buf))
55              {
56                 if ((rotation == 0) || (rotation == 180))
57                   conv_func = evas_common_convert_func_get(0,
58                                                            width,
59                                                            height,
60                                                            evas_direct3d_output_buffer_depth (d3dob),
61                                                            buf->priv.mask.r,
62                                                            buf->priv.mask.g,
63                                                            buf->priv.mask.b,
64                                                            PAL_MODE_NONE,
65                                                            rotation);
66                 else if ((rotation == 90) || (rotation == 270))
67                   conv_func = evas_common_convert_func_get(0,
68                                                            height,
69                                                            width,
70                                                            evas_direct3d_output_buffer_depth (d3dob),
71                                                            buf->priv.mask.r,
72                                                            buf->priv.mask.g,
73                                                            buf->priv.mask.b,
74                                                            PAL_MODE_NONE,
75                                                            rotation);
76              }
77            evas_direct3d_output_buffer_free(d3dob);
78            if (!conv_func)
79              {
80                printf(".[ Evas Error ].\n"
81                       " {\n"
82                       "  At depth         %i:\n"
83                       "  RGB format mask: %08x, %08x, %08x\n"
84                       "  Not supported by and compiled in converters!\n"
85                       " }\n",
86                       buf->priv.d3d.depth,
87                       buf->priv.mask.r,
88                       buf->priv.mask.g,
89                       buf->priv.mask.b);
90              }
91         }
92    }
93
94    return buf;
95 }
96
97 RGBA_Image *
98 evas_direct3d_outbuf_new_region_for_update(Outbuf *buf,
99                                            int x,
100                                            int y,
101                                            int width,
102                                            int height,
103                                            int *cx,
104                                            int *cy,
105                                            int *cw,
106                                            int *ch)
107 {
108    RGBA_Image             *im;
109    Direct3D_Output_Buffer *d3dob = NULL;
110    int                     bpl = 0;
111
112    *cx = 0;
113    *cy = 0;
114    *cw = width;
115    *ch = height;
116
117    if ((buf->rot == 0) &&
118        (buf->priv.mask.r == 0xff0000) &&
119        (buf->priv.mask.g == 0x00ff00) &&
120        (buf->priv.mask.b == 0x0000ff))
121      {
122         im = evas_cache_image_empty(evas_common_image_cache_get());
123         im->image->w = width;
124         im->image->h = height;
125         im->image->data = NULL;
126         im->image->no_free = 1;
127         d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth,
128                                                 width,
129                                                 height,
130                                                 NULL);
131         im->extended_info = d3dob;
132         im->image->data = (DATA32 *)evas_direct3d_output_buffer_data(d3dob, &bpl);
133      }
134    else
135      {
136         im = (RGBA_Image*) evas_cache_image_empty(evas_common_image_cache_get());
137         evas_cache_image_surface_alloc(&im->cache_entry, width, height);
138         im->extended_info = d3dob;
139         if ((buf->rot == 0) || (buf->rot == 180))
140           d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth,
141                                                   width,
142                                                   height,
143                                                   NULL);
144         else if ((buf->rot == 90) || (buf->rot == 270))
145           d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth,
146                                                   width,
147                                                   height,
148                                                   NULL);
149         im->extended_info = d3dob;
150      }
151
152    buf->priv.pending_writes = evas_list_append(buf->priv.pending_writes, im);
153
154    return im;
155 }
156
157 void
158 evas_direct3d_outbuf_free_region_for_update(Outbuf     *buf,
159                                             RGBA_Image *update)
160 {
161    /* no need to do anything - they are cleaned up on flush */
162 }
163
164 void
165 evas_direct3d_outbuf_flush(Outbuf *buf)
166 {
167    Evas_List *l;
168    void      *d3d_data;
169    int        d3d_width;
170    int        d3d_height;
171    int        d3d_pitch;
172
173    /* lock the texture */
174    if (!(d3d_data = evas_direct3d_lock(buf,
175                                        &d3d_width, &d3d_height, &d3d_pitch)))
176      goto free_images;
177
178    /* copy safely the images that need to be drawn onto the back surface */
179    for (l = buf->priv.pending_writes; l; l = l->next)
180      {
181         RGBA_Image             *im;
182         Direct3D_Output_Buffer *d3dob;
183
184         im = l->data;
185         d3dob = im->extended_info;
186         /* paste now */
187         evas_direct3d_output_buffer_paste(d3dob,
188                                           d3d_data,
189                                           d3d_width,
190                                           d3d_height,
191                                           d3d_pitch,
192                                           d3dob->x,
193                                           d3dob->y);
194      }
195
196    /* unlock the texture */
197    evas_direct3d_unlock(buf);
198
199  free_images:
200    while (buf->priv.pending_writes)
201      {
202         RGBA_Image             *im;
203         Direct3D_Output_Buffer *d3dob;
204
205         im = buf->priv.pending_writes->data;
206         buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes,
207                                                          buf->priv.pending_writes);
208         d3dob = im->extended_info;
209         evas_cache_image_drop(im);
210         if (d3dob) evas_direct3d_output_buffer_free(d3dob);
211      }
212    evas_common_cpu_end_opt();
213 }
214
215 void
216 evas_direct3d_outbuf_push_updated_region(Outbuf     *buf,
217                                          RGBA_Image *update,
218                                          int         x,
219                                          int         y,
220                                          int         width,
221                                          int         height)
222 {
223    Gfx_Func_Convert        conv_func;
224    Direct3D_Output_Buffer *d3dob;
225    DATA32                 *src_data;
226    void                   *data;
227    int                     bpl = 0;
228
229    conv_func = NULL;
230    d3dob = update->extended_info;
231
232    if ((buf->rot == 0) || (buf->rot == 180))
233      conv_func = evas_common_convert_func_get(NULL,
234                                               width,
235                                               height,
236                                               evas_direct3d_output_buffer_depth(d3dob),
237                                               buf->priv.mask.r,
238                                               buf->priv.mask.g,
239                                               buf->priv.mask.b,
240                                               PAL_MODE_NONE,
241                                               buf->rot);
242    else if ((buf->rot == 90) || (buf->rot == 270))
243      conv_func = evas_common_convert_func_get(NULL,
244                                               height,
245                                               width,
246                                               evas_direct3d_output_buffer_depth(d3dob),
247                                               buf->priv.mask.r,
248                                               buf->priv.mask.g,
249                                               buf->priv.mask.b,
250                                               PAL_MODE_NONE,
251                                               buf->rot);
252
253    if (!conv_func) return;
254
255    data = evas_direct3d_output_buffer_data(d3dob, &bpl);
256    src_data = update->image->data;
257    if (buf->rot == 0)
258      {
259         d3dob->x = x;
260         d3dob->y = y;
261      }
262    else if (buf->rot == 90)
263      {
264         d3dob->x = y;
265         d3dob->y = buf->width - x - width;
266      }
267    else if (buf->rot == 180)
268      {
269         d3dob->x = buf->width - x - width;
270         d3dob->y = buf->height - y - height;
271      }
272    else if (buf->rot == 270)
273      {
274         d3dob->x = buf->height - y - height;
275         d3dob->y = x;
276      }
277    if ((buf->rot == 0) || (buf->rot == 180))
278      {
279         d3dob->width = width;
280         d3dob->height = height;
281      }
282    else if ((buf->rot == 90) || (buf->rot == 270))
283      {
284         d3dob->width = height;
285         d3dob->height = width;
286      }
287
288    if (data != src_data)
289      conv_func(src_data, data,
290                0,
291                bpl /
292                ((evas_direct3d_output_buffer_depth(d3dob))) - d3dob->width,
293                d3dob->width, d3dob->height, x, y, NULL);
294 }
295
296 void
297 evas_direct3d_outbuf_reconfigure(Outbuf      *buf,
298                                  int          width,
299                                  int          height,
300                                  int          rotation,
301                                  Outbuf_Depth depth)
302 {
303    if ((width == buf->width) && (height == buf->height) &&
304        (rotation == buf->rot) && (depth == buf->depth))
305      return;
306    buf->width = width;
307    buf->height = height;
308    buf->rot = rotation;
309 }
310
311 int
312 evas_direct3d_outbuf_width_get(Outbuf *buf)
313 {
314    return buf->width;
315 }
316
317 int
318 evas_direct3d_outbuf_height_get(Outbuf *buf)
319 {
320    return buf->height;
321 }
322
323 Outbuf_Depth
324 evas_direct3d_outbuf_depth_get(Outbuf *buf)
325 {
326    return buf->depth;
327 }
328
329 int
330 evas_direct3d_outbuf_rot_get(Outbuf *buf)
331 {
332    return buf->rot;
333 }