• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright (C) 2009-2010 Samsung Electronics
3     Copyright (C) 2009-2010 ProFUSION embedded systems
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14 
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20 
21 #include "config.h"
22 #include "ewk_view.h"
23 
24 #include "ewk_logging.h"
25 
26 #include <Evas.h>
27 #include <eina_safety_checks.h>
28 #include <ewk_tiled_backing_store.h>
29 
30 static Ewk_View_Smart_Class _parent_sc = EWK_VIEW_SMART_CLASS_INIT_NULL;
31 
_ewk_view_tiled_render_cb(void * data,Ewk_Tile * t,const Eina_Rectangle * area)32 static Eina_Bool _ewk_view_tiled_render_cb(void *data, Ewk_Tile *t, const Eina_Rectangle *area)
33 {
34     Ewk_View_Private_Data *priv = (Ewk_View_Private_Data*)data;
35     Eina_Rectangle r = {area->x + t->x, area->y + t->y, area->w, area->h};
36 
37     return ewk_view_paint_contents(priv, t->cairo, &r);
38 }
39 
_ewk_view_tiled_updates_process_pre(void * data,Evas_Object * o)40 static void *_ewk_view_tiled_updates_process_pre(void *data, Evas_Object *o)
41 {
42     Ewk_View_Private_Data *priv = (Ewk_View_Private_Data*)data;
43     ewk_view_layout_if_needed_recursive(priv);
44     return 0;
45 }
46 
_ewk_view_tiled_smart_backing_store_add(Ewk_View_Smart_Data * sd)47 static Evas_Object *_ewk_view_tiled_smart_backing_store_add(Ewk_View_Smart_Data *sd)
48 {
49     Evas_Object *bs = ewk_tiled_backing_store_add(sd->base.evas);
50     ewk_tiled_backing_store_render_cb_set
51         (bs, _ewk_view_tiled_render_cb, sd->_priv);
52     ewk_tiled_backing_store_updates_process_pre_set
53         (bs, _ewk_view_tiled_updates_process_pre, sd->_priv);
54     return bs;
55 }
56 
57 static void
_ewk_view_tiled_contents_size_changed_cb(void * data,Evas_Object * o,void * event_info)58 _ewk_view_tiled_contents_size_changed_cb(void *data, Evas_Object *o, void *event_info)
59 {
60     Evas_Coord *size = (Evas_Coord*)event_info;
61     Ewk_View_Smart_Data *sd = (Ewk_View_Smart_Data*)data;
62 
63     ewk_tiled_backing_store_contents_resize
64         (sd->backing_store, size[0], size[1]);
65 }
66 
_ewk_view_tiled_smart_add(Evas_Object * o)67 static void _ewk_view_tiled_smart_add(Evas_Object *o)
68 {
69     Ewk_View_Smart_Data *sd;
70 
71     _parent_sc.sc.add(o);
72 
73     sd = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o);
74     evas_object_smart_callback_add(
75         sd->main_frame, "contents,size,changed",
76         _ewk_view_tiled_contents_size_changed_cb, sd);
77     ewk_frame_paint_full_set(sd->main_frame, EINA_TRUE);
78 }
79 
_ewk_view_tiled_smart_scrolls_process(Ewk_View_Smart_Data * sd)80 static Eina_Bool _ewk_view_tiled_smart_scrolls_process(Ewk_View_Smart_Data *sd)
81 {
82     const Ewk_Scroll_Request *sr;
83     const Ewk_Scroll_Request *sr_end;
84     size_t count;
85     Evas_Coord vw, vh;
86 
87     ewk_frame_contents_size_get(sd->main_frame, &vw, &vh);
88 
89     sr = ewk_view_scroll_requests_get(sd->_priv, &count);
90     sr_end = sr + count;
91     for (; sr < sr_end; sr++) {
92         if (sr->main_scroll)
93             ewk_tiled_backing_store_scroll_full_offset_add
94                 (sd->backing_store, sr->dx, sr->dy);
95         else {
96             Evas_Coord sx, sy, sw, sh;
97 
98             sx = sr->x;
99             sy = sr->y;
100             sw = sr->w;
101             sh = sr->h;
102 
103             if (abs(sr->dx) >= sw || abs(sr->dy) >= sh) {
104                 /* doubt webkit would be so     stupid... */
105                 DBG("full page scroll %+03d,%+03d. convert to repaint %d,%d + %dx%d",
106                     sr->dx, sr->dy, sx, sy, sw, sh);
107                 ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh);
108                 continue;
109             }
110 
111             if (sx + sw > vw)
112                 sw = vw - sx;
113             if (sy + sh > vh)
114                 sh = vh - sy;
115 
116             if (sw < 0)
117                 sw = 0;
118             if (sh < 0)
119                 sh = 0;
120 
121             if (!sw || !sh)
122                 continue;
123 
124             sx -= abs(sr->dx);
125             sy -= abs(sr->dy);
126             sw += abs(sr->dx);
127             sh += abs(sr->dy);
128             ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh);
129             INF("using repaint for inner frame scolling!");
130         }
131     }
132 
133     return EINA_TRUE;
134 }
135 
_ewk_view_tiled_smart_repaints_process(Ewk_View_Smart_Data * sd)136 static Eina_Bool _ewk_view_tiled_smart_repaints_process(Ewk_View_Smart_Data *sd)
137 {
138     const Eina_Rectangle *pr, *pr_end;
139     size_t count;
140     int sx, sy;
141 
142     ewk_frame_scroll_pos_get(sd->main_frame, &sx, &sy);
143 
144     pr = ewk_view_repaints_get(sd->_priv, &count);
145     pr_end = pr + count;
146     for (; pr < pr_end; pr++) {
147         Eina_Rectangle r;
148         r.x = pr->x + sx;
149         r.y = pr->y + sy;
150         r.w = pr->w;
151         r.h = pr->h;
152         ewk_tiled_backing_store_update(sd->backing_store, &r);
153     }
154     ewk_tiled_backing_store_updates_process(sd->backing_store);
155 
156     return EINA_TRUE;
157 }
158 
_ewk_view_tiled_smart_contents_resize(Ewk_View_Smart_Data * sd,int w,int h)159 static Eina_Bool _ewk_view_tiled_smart_contents_resize(Ewk_View_Smart_Data *sd, int w, int h)
160 {
161     ewk_tiled_backing_store_contents_resize(sd->backing_store, w, h);
162     return EINA_TRUE;
163 }
164 
_ewk_view_tiled_smart_zoom_set(Ewk_View_Smart_Data * sd,float zoom,Evas_Coord cx,Evas_Coord cy)165 static Eina_Bool _ewk_view_tiled_smart_zoom_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy)
166 {
167     Evas_Coord x, y, w, h;
168     Eina_Bool r;
169     r = ewk_tiled_backing_store_zoom_set(sd->backing_store,
170                                          &zoom, cx, cy, &x, &y);
171     if (!r)
172         return r;
173     ewk_tiled_backing_store_disabled_update_set(sd->backing_store, EINA_TRUE);
174     r = _parent_sc.zoom_set(sd, zoom, cx, cy);
175     ewk_frame_scroll_set(sd->main_frame, -x, -y);
176     ewk_frame_scroll_size_get(sd->main_frame, &w, &h);
177     ewk_tiled_backing_store_fix_offsets(sd->backing_store, w, h);
178     ewk_view_scrolls_process(sd);
179     evas_object_smart_calculate(sd->backing_store);
180     evas_object_smart_calculate(sd->self);
181     ewk_tiled_backing_store_disabled_update_set(sd->backing_store, EINA_FALSE);
182     return r;
183 }
184 
_ewk_view_tiled_smart_zoom_weak_set(Ewk_View_Smart_Data * sd,float zoom,Evas_Coord cx,Evas_Coord cy)185 static Eina_Bool _ewk_view_tiled_smart_zoom_weak_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy)
186 {
187     return ewk_tiled_backing_store_zoom_weak_set(sd->backing_store, zoom, cx, cy);
188 }
189 
_ewk_view_tiled_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data * sd,Eina_Bool smooth_scale)190 static void _ewk_view_tiled_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data *sd, Eina_Bool smooth_scale)
191 {
192     ewk_tiled_backing_store_zoom_weak_smooth_scale_set(sd->backing_store, smooth_scale);
193 }
194 
_ewk_view_tiled_smart_flush(Ewk_View_Smart_Data * sd)195 static void _ewk_view_tiled_smart_flush(Ewk_View_Smart_Data *sd)
196 {
197     ewk_tiled_backing_store_flush(sd->backing_store);
198     _parent_sc.flush(sd);
199 }
200 
_ewk_view_tiled_smart_pre_render_region(Ewk_View_Smart_Data * sd,Evas_Coord x,Evas_Coord y,Evas_Coord w,Evas_Coord h,float zoom)201 static Eina_Bool _ewk_view_tiled_smart_pre_render_region(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom)
202 {
203     return ewk_tiled_backing_store_pre_render_region
204         (sd->backing_store, x, y, w, h, zoom);
205 }
206 
_ewk_view_tiled_smart_pre_render_relative_radius(Ewk_View_Smart_Data * sd,unsigned int n,float zoom)207 static Eina_Bool _ewk_view_tiled_smart_pre_render_relative_radius(Ewk_View_Smart_Data *sd, unsigned int n, float zoom)
208 {
209     return ewk_tiled_backing_store_pre_render_relative_radius
210         (sd->backing_store, n, zoom);
211 }
212 
_ewk_view_tiled_smart_pre_render_cancel(Ewk_View_Smart_Data * sd)213 static void _ewk_view_tiled_smart_pre_render_cancel(Ewk_View_Smart_Data *sd)
214 {
215     ewk_tiled_backing_store_pre_render_cancel(sd->backing_store);
216 }
217 
_ewk_view_tiled_smart_disable_render(Ewk_View_Smart_Data * sd)218 static Eina_Bool _ewk_view_tiled_smart_disable_render(Ewk_View_Smart_Data *sd)
219 {
220     return ewk_tiled_backing_store_disable_render(sd->backing_store);
221 }
222 
_ewk_view_tiled_smart_enable_render(Ewk_View_Smart_Data * sd)223 static Eina_Bool _ewk_view_tiled_smart_enable_render(Ewk_View_Smart_Data *sd)
224 {
225     return ewk_tiled_backing_store_enable_render(sd->backing_store);
226 }
227 
228 /**
229  * Sets the smart class api using tiled backing store, enabling view
230  * to be inherited.
231  *
232  * @param api class definition to be set, all members with the
233  *        exception of Evas_Smart_Class->data may be overridden. Must
234  *        @b not be @c NULL.
235  *
236  * @note Evas_Smart_Class->data is used to implement type checking and
237  *       is not supposed to be changed/overridden. If you need extra
238  *       data for your smart class to work, just extend
239  *       Ewk_View_Smart_Class instead.
240  *
241  * @return @c EINA_TRUE on success, @c EINA_FALSE on failure (probably
242  *         version mismatch).
243  *
244  * @see ewk_view_base_smart_set()
245  */
ewk_view_tiled_smart_set(Ewk_View_Smart_Class * api)246 Eina_Bool ewk_view_tiled_smart_set(Ewk_View_Smart_Class *api)
247 {
248     if (!ewk_view_base_smart_set(api))
249         return EINA_FALSE;
250 
251     if (EINA_UNLIKELY(!_parent_sc.sc.add))
252         ewk_view_base_smart_set(&_parent_sc);
253 
254     api->sc.add = _ewk_view_tiled_smart_add;
255 
256     api->backing_store_add = _ewk_view_tiled_smart_backing_store_add;
257     api->scrolls_process = _ewk_view_tiled_smart_scrolls_process;
258     api->repaints_process = _ewk_view_tiled_smart_repaints_process;
259     api->contents_resize = _ewk_view_tiled_smart_contents_resize;
260     api->zoom_set = _ewk_view_tiled_smart_zoom_set;
261     api->zoom_weak_set = _ewk_view_tiled_smart_zoom_weak_set;
262     api->zoom_weak_smooth_scale_set = _ewk_view_tiled_smart_zoom_weak_smooth_scale_set;
263     api->flush = _ewk_view_tiled_smart_flush;
264     api->pre_render_region = _ewk_view_tiled_smart_pre_render_region;
265     api->pre_render_relative_radius = _ewk_view_tiled_smart_pre_render_relative_radius;
266     api->pre_render_cancel = _ewk_view_tiled_smart_pre_render_cancel;
267     api->disable_render = _ewk_view_tiled_smart_disable_render;
268     api->enable_render = _ewk_view_tiled_smart_enable_render;
269     return EINA_TRUE;
270 }
271 
_ewk_view_tiled_smart_class_new(void)272 static inline Evas_Smart *_ewk_view_tiled_smart_class_new(void)
273 {
274     static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("EWK_View_Tiled");
275     static Evas_Smart *smart = 0;
276 
277     if (EINA_UNLIKELY(!smart)) {
278         ewk_view_tiled_smart_set(&api);
279         smart = evas_smart_class_new(&api.sc);
280     }
281 
282     return smart;
283 }
284 
285 /**
286  * Creates a new EFL WebKit View object using tiled backing store.
287  *
288  * View objects are the recommended way to deal with EFL WebKit as it
289  * abstracts the complex pieces of the process.
290  *
291  * This object is almost the same as the one returned by the ewk_view_add()
292  * function, but it uses the tiled backing store instead of the default
293  * backing store.
294  *
295  * @param e canvas where to create the view object.
296  *
297  * @return view object or @c NULL if errors.
298  *
299  * @see ewk_view_uri_set()
300  */
ewk_view_tiled_add(Evas * e)301 Evas_Object *ewk_view_tiled_add(Evas *e)
302 {
303     return evas_object_smart_add(e, _ewk_view_tiled_smart_class_new());
304 }
305 
306 /**
307  * Get the cache of unused tiles used by this view.
308  *
309  * @param o view object to get cache.
310  * @return instance of "cache of unused tiles" or @c NULL on errors.
311  */
ewk_view_tiled_unused_cache_get(const Evas_Object * o)312 Ewk_Tile_Unused_Cache *ewk_view_tiled_unused_cache_get(const Evas_Object *o)
313 {
314     Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o);
315     EINA_SAFETY_ON_NULL_RETURN_VAL(sd, 0);
316     return ewk_tiled_backing_store_tile_unused_cache_get(sd->backing_store);
317 }
318 
319 /**
320  * Set the cache of unused tiles used by this view.
321  *
322  * @param o view object to get cache.
323  * @param cache instance of "cache of unused tiles". This can be used
324  *        to share a single cache amongst different views. The tiles
325  *        from one view will not be used by the other! This is just to
326  *        limit the group with amount of unused memory.
327  *        If @c NULL is provided, then a new cache is created.
328  */
ewk_view_tiled_unused_cache_set(Evas_Object * o,Ewk_Tile_Unused_Cache * cache)329 void ewk_view_tiled_unused_cache_set(Evas_Object *o, Ewk_Tile_Unused_Cache *cache)
330 {
331     Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o);
332     EINA_SAFETY_ON_NULL_RETURN(sd);
333     ewk_tiled_backing_store_tile_unused_cache_set(sd->backing_store, cache);
334 }
335 
336 /**
337  * Set the function with the same name of the tiled backing store.
338  * @param o the tiled backing store object.
339  * @param flag value of the tiled backing store flag to set.
340  */
ewk_view_tiled_process_entire_queue_set(Evas_Object * o,Eina_Bool flag)341 void ewk_view_tiled_process_entire_queue_set(Evas_Object *o, Eina_Bool flag)
342 {
343     Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o);
344     EINA_SAFETY_ON_NULL_RETURN(sd);
345     ewk_tiled_backing_store_process_entire_queue_set(sd->backing_store, flag);
346 }
347