Changeset 104282 in webkit


Ignore:
Timestamp:
Jan 6, 2012 3:25:24 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Source/WebKit/efl: [EFL] Add new pre-rendering code.
https://bugs.webkit.org/show_bug.cgi?id=73430

Patch by JungJik Lee <jungjik.lee@samsung.com> on 2012-01-06
Reviewed by Zoltan Herczeg.

Add new pre-rendering code to pre-render the view area more efficiently.
At first find centered view position where backing store starts to queuing the render request from.
And append the request into the tiled backing store in spiral order.

  • ewk/ewk_private.h:
  • ewk/ewk_tiled_backing_store.cpp:

(ewk_tiled_backing_store_pre_render_tile_add):
(ewk_tiled_backing_store_pre_render_spiral_queue):

  • ewk/ewk_tiled_backing_store.h:
  • ewk/ewk_view.cpp:

(_ewk_view_smart_pre_render_start):
(ewk_view_base_smart_set):
(ewk_view_pre_render_start):

  • ewk/ewk_view.h:
  • ewk/ewk_view_tiled.cpp:

(_ewk_view_tiled_rect_collision_check):
(_ewk_view_tiled_rect_collision_resolve):
(_ewk_view_tiled_smart_pre_render_start):
(ewk_view_tiled_smart_set):

Tools: [EFL] Add pre-render handling code in EWebLauncher.
https://bugs.webkit.org/show_bug.cgi?id=73430

Patch by JungJik Lee <jungjik.lee@samsung.com> on 2012-01-06
Reviewed by Zoltan Herczeg.

Add pre-render handling code by pressing Insert key.

  • EWebLauncher/main.c:

(on_key_down):

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/efl/ChangeLog

    r104160 r104282  
     12012-01-06  JungJik Lee  <jungjik.lee@samsung.com>
     2
     3        [EFL] Add new pre-rendering code.
     4        https://bugs.webkit.org/show_bug.cgi?id=73430
     5
     6        Reviewed by Zoltan Herczeg.
     7
     8        Add new pre-rendering code to pre-render the view area more efficiently.
     9        At first find centered view position where backing store starts to queuing the render request from.
     10        And append the request into the tiled backing store in spiral order.
     11
     12        * ewk/ewk_private.h:
     13        * ewk/ewk_tiled_backing_store.cpp:
     14        (ewk_tiled_backing_store_pre_render_tile_add):
     15        (ewk_tiled_backing_store_pre_render_spiral_queue):
     16        * ewk/ewk_tiled_backing_store.h:
     17        * ewk/ewk_view.cpp:
     18        (_ewk_view_smart_pre_render_start):
     19        (ewk_view_base_smart_set):
     20        (ewk_view_pre_render_start):
     21        * ewk/ewk_view.h:
     22        * ewk/ewk_view_tiled.cpp:
     23        (_ewk_view_tiled_rect_collision_check):
     24        (_ewk_view_tiled_rect_collision_resolve):
     25        (_ewk_view_tiled_smart_pre_render_start):
     26        (ewk_view_tiled_smart_set):
     27
    1282012-01-05  KwangHyuk Kim  <hyuki.kim@samsung.com>
    229
  • trunk/Source/WebKit/efl/ewk/ewk_private.h

    r104160 r104282  
    4646// If defined, ewk will do type checking to ensure objects are of correct type
    4747#define EWK_TYPE_CHECK 1
     48#define EWK_ARGB_BYTES_SIZE 4
    4849
    4950#if ENABLE(NETSCAPE_PLUGIN_API)
  • trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.cpp

    r101585 r104282  
    2222#include "ewk_tiled_backing_store.h"
    2323
     24#include "ewk_private.h"
    2425#include "ewk_tiled_matrix.h"
    2526#include "ewk_tiled_private.h"
     
    18391840}
    18401841
     1842Eina_Bool ewk_tiled_backing_store_pre_render_tile_add(Evas_Object* ewkBackingStore, int column, int row, float zoom)
     1843{
     1844    PRIV_DATA_GET_OR_RETURN(ewkBackingStore, priv, false);
     1845
     1846    if (ewk_tile_matrix_tile_exact_exists(priv->model.matrix, column, row, zoom))
     1847        return false;
     1848
     1849    if (!_ewk_tiled_backing_store_pre_render_request_add(priv, column, row, zoom))
     1850        return false;
     1851
     1852    return true;
     1853}
     1854
     1855Eina_Bool ewk_tiled_backing_store_pre_render_spiral_queue(Evas_Object* ewkBackingStore, Eina_Rectangle* viewRect, Eina_Rectangle* renderRect, int maxMemory, float zoom)
     1856{
     1857    PRIV_DATA_GET_OR_RETURN(ewkBackingStore, priv, false);
     1858    EINA_SAFETY_ON_NULL_RETURN_VAL(viewRect, false);
     1859    EINA_SAFETY_ON_NULL_RETURN_VAL(renderRect, false);
     1860
     1861    const int tileWidth = priv->view.tile.width;
     1862    const int tileHeight = priv->view.tile.height;
     1863
     1864    Eina_Tile_Grid_Slicer viewSlicer;
     1865    Eina_Tile_Grid_Slicer renderSlicer;
     1866
     1867    if (!eina_tile_grid_slicer_setup(&viewSlicer,
     1868        viewRect->x, viewRect->y, viewRect->w, viewRect->h, tileWidth, tileHeight)) {
     1869        ERR("could not setup grid viewSlicer for %d,%d+%dx%d tile=%dx%d", viewRect->x, viewRect->y, viewRect->w, viewRect->h, tileWidth, tileHeight);
     1870        return false;
     1871    }
     1872
     1873    if (!eina_tile_grid_slicer_setup(&renderSlicer,
     1874        renderRect->x, renderRect->y, renderRect->w, renderRect->h, tileWidth, tileHeight)) {
     1875        ERR("could not setup grid RenderSlicer for %d,%d+%dx%d tile=%dx%d", renderRect->y, renderRect->y, renderRect->w, renderRect->h, tileWidth, tileHeight);
     1876        return false;
     1877    }
     1878
     1879    // set limits of the loop.
     1880    int memoryLimits = maxMemory / (EWK_ARGB_BYTES_SIZE * tileWidth * tileHeight);
     1881    const int maxViewSideLength = std::max(viewSlicer.col2 - viewSlicer.col1, viewSlicer.row2 - viewSlicer.row1);
     1882    const int maxRenderSideLength = std::max(renderSlicer.col2 - renderSlicer.col1, renderSlicer.row2 - renderSlicer.row1);
     1883    const int maxLoopCount = maxViewSideLength + maxRenderSideLength;
     1884
     1885    // spire starts from the center of the view area.
     1886    int centerColumn = (viewSlicer.col1 + viewSlicer.col2) / 2;
     1887    int centerRow = (viewSlicer.row1 + viewSlicer.row2) / 2;
     1888
     1889    int step = 1;
     1890    const int squareSide = 4;
     1891    for (int loop = 0; loop < maxLoopCount; loop++) {
     1892        for (int i = 1; i < step * squareSide + 1; i++) {
     1893            if (memoryLimits <= 0)
     1894                goto memoryLimitsReached;
     1895            /*
     1896            this code means the loop runs like spiral. (i.g. left->down->right->up)
     1897            when it moves back to original place and then walk 1 tile left and up.
     1898            the loop keeps on doing this until it reaches max memory to draw tiles.
     1899            e.g. )
     1900                         333333
     1901                         322223
     1902                         321123
     1903                         321123
     1904                         322223
     1905                         333333
     1906            */
     1907            if (i > 0 && i <= step)
     1908                centerColumn++; // move left.
     1909            else if (i > step && i <= step * 2)
     1910                centerRow++; // move down.
     1911            else if (i > step * 2 && i <= step * 3)
     1912                centerColumn--; // move right.
     1913            else if (i > step * 3 && i <= step * 4)
     1914                centerRow--; // move up.
     1915            else
     1916                ERR("ERROR : out of bounds\r\n");
     1917
     1918            // skip in view port area.
     1919            if (static_cast<int>(viewSlicer.col1) < centerColumn
     1920                && static_cast<int>(viewSlicer.col2) > centerColumn
     1921                && static_cast<int>(viewSlicer.row1) < centerRow
     1922                && static_cast<int>(viewSlicer.row2) > centerRow)
     1923                continue;
     1924
     1925            if (static_cast<int>(renderSlicer.col1) <= centerColumn
     1926                && static_cast<int>(renderSlicer.col2) >= centerColumn
     1927                && static_cast<int>(renderSlicer.row1) <= centerRow
     1928                && static_cast<int>(renderSlicer.row2) >= centerRow) {
     1929
     1930                if (!ewk_tiled_backing_store_pre_render_tile_add(ewkBackingStore, centerColumn, centerRow, zoom))
     1931                    continue;
     1932                DBG("R>[%d %d] ", centerColumn, centerRow);
     1933                memoryLimits--;
     1934            }
     1935        }
     1936        centerRow--;
     1937        centerColumn--;
     1938        step = step + 2;
     1939    }
     1940
     1941memoryLimitsReached:
     1942    _ewk_tiled_backing_store_item_process_idler_start(priv);
     1943
     1944    return true;
     1945}
     1946
    18411947Eina_Bool ewk_tiled_backing_store_pre_render_region(Evas_Object* ewkBackingStore, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height, float zoom)
    18421948{
  • trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.h

    r104021 r104282  
    113113Eina_Bool ewk_tiled_backing_store_pre_render_region(Evas_Object* o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom);
    114114Eina_Bool ewk_tiled_backing_store_pre_render_relative_radius(Evas_Object* o, unsigned int n, float zoom);
     115Eina_Bool ewk_tiled_backing_store_pre_render_spiral_queue(Evas_Object* o, Eina_Rectangle* view_rect, Eina_Rectangle* render_rect, int max_memory, float zoom);
    115116void ewk_tiled_backing_store_pre_render_cancel(Evas_Object* o);
    116117
  • trunk/Source/WebKit/efl/ewk/ewk_view.cpp

    r104160 r104282  
    10061006}
    10071007
     1008static Eina_Bool _ewk_view_smart_pre_render_start(Ewk_View_Smart_Data* smartData)
     1009{
     1010    WRN("not supported by engine. smartData=%p", smartData);
     1011    return false;
     1012}
     1013
    10081014static void _ewk_view_smart_pre_render_cancel(Ewk_View_Smart_Data* smartData)
    10091015{
     
    11381144    api->pre_render_region = _ewk_view_smart_pre_render_region;
    11391145    api->pre_render_relative_radius = _ewk_view_smart_pre_render_relative_radius;
     1146    api->pre_render_start = _ewk_view_smart_pre_render_start;
    11401147    api->pre_render_cancel = _ewk_view_smart_pre_render_cancel;
    11411148    api->disable_render = _ewk_view_smart_disable_render;
     
    18331840    currentZoom = ewk_frame_page_zoom_get(smartData->main_frame);
    18341841    return smartData->api->pre_render_relative_radius(smartData, number, currentZoom);
     1842}
     1843
     1844Eina_Bool ewk_view_pre_render_start(Evas_Object* ewkView)
     1845{
     1846    EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
     1847    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->pre_render_start, false);
     1848
     1849    return smartData->api->pre_render_start(smartData);
    18351850}
    18361851
  • trunk/Source/WebKit/efl/ewk/ewk_view.h

    r103696 r104282  
    136136    Eina_Bool (*pre_render_region)(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom);
    137137    Eina_Bool (*pre_render_relative_radius)(Ewk_View_Smart_Data *sd, unsigned int n, float zoom);
     138    Eina_Bool (*pre_render_start)(Ewk_View_Smart_Data *sd);
    138139    void (*pre_render_cancel)(Ewk_View_Smart_Data *sd);
    139140    Eina_Bool (*disable_render)(Ewk_View_Smart_Data *sd);
     
    169170 * in the @a Ewk_View_Smart_Class structure.
    170171 */
    171 #define EWK_VIEW_SMART_CLASS_VERSION 3UL
     172#define EWK_VIEW_SMART_CLASS_VERSION 4UL
    172173
    173174/**
     
    181182 * @see EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION
    182183 */
    183 #define EWK_VIEW_SMART_CLASS_INIT(smart_class_init) {smart_class_init, EWK_VIEW_SMART_CLASS_VERSION, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
     184#define EWK_VIEW_SMART_CLASS_INIT(smart_class_init) {smart_class_init, EWK_VIEW_SMART_CLASS_VERSION, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    184185
    185186/**
     
    315316        Eina_Bool frame_rect:1;
    316317    } changed; /**< Keeps what changed since last smart_calculate. */
     318    struct {
     319        Evas_Coord x, y;
     320        float zoom;
     321    } previousView;
    317322};
    318323
     
    12501255
    12511256/**
     1257 * Asks engine to start pre-rendering.
     1258 *
     1259 * This is an alternative method to pre-render around the view area.
     1260 * The first step is to find the center view area where to start pre-rendering.
     1261 * And then from the center of the view area the backing store append the render request
     1262 * outward in spiral order. So that the tiles which are close to view area are displayed
     1263 * sooner than outside.
     1264 *
     1265 * @param o view to ask pre-render
     1266 *
     1267 * @return @c EINA_TRUE if request was accepted, @c EINA_FALSE
     1268 *         otherwise (errors, pre-render feature not supported, etc)
     1269 *
     1270 */
     1271EAPI Eina_Bool    ewk_view_pre_render_start(Evas_Object *o);
     1272
     1273/**
    12521274 * Cancels and clears previous the pre-render requests.
    12531275 *
  • trunk/Source/WebKit/efl/ewk/ewk_view_tiled.cpp

    r104160 r104282  
    210210}
    211211
     212static inline int _ewk_view_tiled_rect_collision_check(Eina_Rectangle destination, Eina_Rectangle source)
     213{
     214    int direction = 0;
     215    if (destination.x < source.x)
     216        direction = direction | (1 << 0); // 0 bit shift, left
     217    if (destination.y < source.y)
     218        direction = direction | (1 << 1); // 1 bit shift, top
     219    if (destination.x + destination.w > source.x + source.w)
     220        direction = direction | (1 << 2); // 2 bit shift, right
     221    if (destination.y + destination.h > source.y + source.h)
     222        direction = direction | (1 << 3); // 3 bit shift, bottom
     223    DBG("check collision %d\r\n", direction);
     224    return direction;
     225}
     226
     227static inline void _ewk_view_tiled_rect_collision_resolve(int direction, Eina_Rectangle* destination, Eina_Rectangle source)
     228{
     229    if (direction & (1 << 0)) // 0 bit shift, left
     230        destination->x = source.x;
     231    if (direction & (1 << 1)) // 1 bit shift, top
     232        destination->y = source.y;
     233    if (direction & (1 << 2)) // 2 bit shift, right
     234        destination->x = destination->x - ((destination->x + destination->w) - (source.x + source.w));
     235    if (direction & (1 << 3)) // 3 bit shift, bottom
     236        destination->y = destination->y - ((destination->y + destination->h) - (source.y + source.h));
     237}
     238
     239static Eina_Bool _ewk_view_tiled_smart_pre_render_start(Ewk_View_Smart_Data* smartData)
     240{
     241    int contentWidth, contentHeight;
     242    ewk_frame_contents_size_get(smartData->main_frame, &contentWidth, &contentHeight);
     243
     244    int viewX, viewY, viewWidth, viewHeight;
     245    ewk_frame_visible_content_geometry_get(smartData->main_frame, false, &viewX, &viewY, &viewWidth, &viewHeight);
     246
     247    if (viewWidth <= 0 || viewHeight <= 0 || contentWidth <= 0 || contentHeight <= 0)
     248        return false;
     249
     250    if (viewWidth >= contentWidth && viewHeight >= contentHeight)
     251        return false;
     252
     253    int previousViewX, previousViewY;
     254    previousViewX = smartData->previousView.x;
     255    previousViewY = smartData->previousView.y;
     256
     257    if (previousViewX < 0 || previousViewX > contentWidth || previousViewY < 0 || previousViewY > contentHeight)
     258        previousViewX = previousViewY = 0;
     259
     260    float currentViewZoom = ewk_view_zoom_get(smartData->self);
     261
     262    // pre-render works when two conditions are met.
     263    // zoom has been changed.
     264    // and the view has been moved more than tile size.
     265    if (abs(previousViewX - viewX) < DEFAULT_TILE_W
     266        && abs(previousViewY - viewY) < DEFAULT_TILE_H
     267        && smartData->previousView.zoom == currentViewZoom) {
     268        return false;
     269    }
     270
     271    // store previous view position and zoom.
     272    smartData->previousView.x = viewX;
     273    smartData->previousView.y = viewY;
     274    smartData->previousView.zoom = currentViewZoom;
     275
     276    // cancelling previous pre-rendering list if exists.
     277    ewk_view_pre_render_cancel(smartData->self);
     278
     279    Ewk_Tile_Unused_Cache* tileUnusedCache = ewk_view_tiled_unused_cache_get(smartData->self);
     280    int maxMemory = ewk_tile_unused_cache_max_get(tileUnusedCache);
     281    if (maxMemory <= viewWidth * viewHeight * EWK_ARGB_BYTES_SIZE)
     282        return false;
     283
     284    Eina_Rectangle viewRect = {viewX, viewY, viewWidth, viewHeight};
     285    Eina_Rectangle contentRect = {0, 0, contentWidth, contentHeight};
     286
     287    // get a base render rect.
     288    const int contentMemory = contentWidth * contentHeight * EWK_ARGB_BYTES_SIZE;
     289
     290    // get render rect's width and height.
     291    Eina_Rectangle renderRect;
     292    if (maxMemory > contentMemory)
     293        renderRect = contentRect;
     294    else {
     295        // Make a base rectangle as big as possible with using maxMemory.
     296        // and then reshape the base rectangle to fit to contents.
     297        const int baseSize = static_cast<int>(sqrt(maxMemory / 4.0f));
     298        const float widthRate = (viewRect.w + (DEFAULT_TILE_W * 2)) / static_cast<float>(baseSize);
     299        const float heightRate = baseSize / static_cast<float>(contentHeight);
     300        const float rectRate = std::max(widthRate, heightRate);
     301
     302        renderRect.w = static_cast<int>(baseSize * rectRate);
     303        renderRect.h = static_cast<int>(baseSize / rectRate);
     304        renderRect.x = viewRect.x + (viewRect.w / 2) - (renderRect.w / 2);
     305        renderRect.y = viewRect.y + (viewRect.h / 2) - (renderRect.h / 2);
     306
     307        // reposition of renderRect, if the renderRect overlapped the content rect, this code moves the renderRect inside the content rect.
     308        int collisionSide = _ewk_view_tiled_rect_collision_check(renderRect, contentRect);
     309        if (collisionSide > 0)
     310            _ewk_view_tiled_rect_collision_resolve(collisionSide, &renderRect, contentRect);
     311
     312        // check abnormal render rect
     313        if (renderRect.x < 0)
     314            renderRect.x = 0;
     315        if (renderRect.y < 0)
     316            renderRect.y = 0;
     317        if (renderRect.w > contentWidth)
     318            renderRect.w = contentWidth;
     319        if (renderRect.h > contentHeight)
     320            renderRect.h = contentHeight;
     321    }
     322
     323    // enqueue tiles into tiled backing store in spiral order.
     324    ewk_tiled_backing_store_pre_render_spiral_queue(smartData->backing_store, &viewRect, &renderRect, maxMemory, currentViewZoom);
     325
     326    return true;
     327}
     328
    212329static void _ewk_view_tiled_smart_pre_render_cancel(Ewk_View_Smart_Data* smartData)
    213330{
     
    249366    api->pre_render_region = _ewk_view_tiled_smart_pre_render_region;
    250367    api->pre_render_relative_radius = _ewk_view_tiled_smart_pre_render_relative_radius;
     368    api->pre_render_start = _ewk_view_tiled_smart_pre_render_start;
    251369    api->pre_render_cancel = _ewk_view_tiled_smart_pre_render_cancel;
    252370    api->disable_render = _ewk_view_tiled_smart_disable_render;
  • trunk/Tools/ChangeLog

    r104273 r104282  
     12012-01-06  JungJik Lee  <jungjik.lee@samsung.com>
     2
     3        [EFL] Add pre-render handling code in EWebLauncher.
     4        https://bugs.webkit.org/show_bug.cgi?id=73430
     5
     6        Reviewed by Zoltan Herczeg.
     7
     8        Add pre-render handling code by pressing Insert key.
     9
     10        * EWebLauncher/main.c:
     11        (on_key_down):
     12
    1132012-01-06  Csaba Osztrogonác  <ossy@webkit.org>
    214
  • trunk/Tools/EWebLauncher/main.c

    r98444 r104282  
    549549        info("Render resumed");
    550550        ewk_view_enable_render(obj);
     551    } else if (!strcmp(ev->key, "Insert")) {
     552        info("Pre-rendering start");
     553        ewk_view_pre_render_start(obj);
    551554    }
    552555}
Note: See TracChangeset for help on using the changeset viewer.