Diff
Modified: trunk/Source/WebKit/efl/ChangeLog (104281 => 104282)
--- trunk/Source/WebKit/efl/ChangeLog 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Source/WebKit/efl/ChangeLog 2012-01-06 11:25:24 UTC (rev 104282)
@@ -1,3 +1,30 @@
+2012-01-06 JungJik Lee <[email protected]>
+
+ [EFL] Add new pre-rendering code.
+ https://bugs.webkit.org/show_bug.cgi?id=73430
+
+ 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):
+
2012-01-05 KwangHyuk Kim <[email protected]>
[EFL] Invalidation request for ewk_view can be discarded without rendering.
Modified: trunk/Source/WebKit/efl/ewk/ewk_private.h (104281 => 104282)
--- trunk/Source/WebKit/efl/ewk/ewk_private.h 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Source/WebKit/efl/ewk/ewk_private.h 2012-01-06 11:25:24 UTC (rev 104282)
@@ -45,6 +45,7 @@
// If defined, ewk will do type checking to ensure objects are of correct type
#define EWK_TYPE_CHECK 1
+#define EWK_ARGB_BYTES_SIZE 4
#if ENABLE(NETSCAPE_PLUGIN_API)
#define EWK_JS_OBJECT_MAGIC 0x696969
Modified: trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.cpp (104281 => 104282)
--- trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.cpp 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.cpp 2012-01-06 11:25:24 UTC (rev 104282)
@@ -21,6 +21,7 @@
#include "config.h"
#include "ewk_tiled_backing_store.h"
+#include "ewk_private.h"
#include "ewk_tiled_matrix.h"
#include "ewk_tiled_private.h"
#include <Ecore.h>
@@ -1838,6 +1839,111 @@
#endif
}
+Eina_Bool ewk_tiled_backing_store_pre_render_tile_add(Evas_Object* ewkBackingStore, int column, int row, float zoom)
+{
+ PRIV_DATA_GET_OR_RETURN(ewkBackingStore, priv, false);
+
+ if (ewk_tile_matrix_tile_exact_exists(priv->model.matrix, column, row, zoom))
+ return false;
+
+ if (!_ewk_tiled_backing_store_pre_render_request_add(priv, column, row, zoom))
+ return false;
+
+ return true;
+}
+
+Eina_Bool ewk_tiled_backing_store_pre_render_spiral_queue(Evas_Object* ewkBackingStore, Eina_Rectangle* viewRect, Eina_Rectangle* renderRect, int maxMemory, float zoom)
+{
+ PRIV_DATA_GET_OR_RETURN(ewkBackingStore, priv, false);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(viewRect, false);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(renderRect, false);
+
+ const int tileWidth = priv->view.tile.width;
+ const int tileHeight = priv->view.tile.height;
+
+ Eina_Tile_Grid_Slicer viewSlicer;
+ Eina_Tile_Grid_Slicer renderSlicer;
+
+ if (!eina_tile_grid_slicer_setup(&viewSlicer,
+ viewRect->x, viewRect->y, viewRect->w, viewRect->h, tileWidth, tileHeight)) {
+ ERR("could not setup grid viewSlicer for %d,%d+%dx%d tile=%dx%d", viewRect->x, viewRect->y, viewRect->w, viewRect->h, tileWidth, tileHeight);
+ return false;
+ }
+
+ if (!eina_tile_grid_slicer_setup(&renderSlicer,
+ renderRect->x, renderRect->y, renderRect->w, renderRect->h, tileWidth, tileHeight)) {
+ ERR("could not setup grid RenderSlicer for %d,%d+%dx%d tile=%dx%d", renderRect->y, renderRect->y, renderRect->w, renderRect->h, tileWidth, tileHeight);
+ return false;
+ }
+
+ // set limits of the loop.
+ int memoryLimits = maxMemory / (EWK_ARGB_BYTES_SIZE * tileWidth * tileHeight);
+ const int maxViewSideLength = std::max(viewSlicer.col2 - viewSlicer.col1, viewSlicer.row2 - viewSlicer.row1);
+ const int maxRenderSideLength = std::max(renderSlicer.col2 - renderSlicer.col1, renderSlicer.row2 - renderSlicer.row1);
+ const int maxLoopCount = maxViewSideLength + maxRenderSideLength;
+
+ // spire starts from the center of the view area.
+ int centerColumn = (viewSlicer.col1 + viewSlicer.col2) / 2;
+ int centerRow = (viewSlicer.row1 + viewSlicer.row2) / 2;
+
+ int step = 1;
+ const int squareSide = 4;
+ for (int loop = 0; loop < maxLoopCount; loop++) {
+ for (int i = 1; i < step * squareSide + 1; i++) {
+ if (memoryLimits <= 0)
+ goto memoryLimitsReached;
+ /*
+ this code means the loop runs like spiral. (i.g. left->down->right->up)
+ when it moves back to original place and then walk 1 tile left and up.
+ the loop keeps on doing this until it reaches max memory to draw tiles.
+ e.g. )
+ 333333
+ 322223
+ 321123
+ 321123
+ 322223
+ 333333
+ */
+ if (i > 0 && i <= step)
+ centerColumn++; // move left.
+ else if (i > step && i <= step * 2)
+ centerRow++; // move down.
+ else if (i > step * 2 && i <= step * 3)
+ centerColumn--; // move right.
+ else if (i > step * 3 && i <= step * 4)
+ centerRow--; // move up.
+ else
+ ERR("ERROR : out of bounds\r\n");
+
+ // skip in view port area.
+ if (static_cast<int>(viewSlicer.col1) < centerColumn
+ && static_cast<int>(viewSlicer.col2) > centerColumn
+ && static_cast<int>(viewSlicer.row1) < centerRow
+ && static_cast<int>(viewSlicer.row2) > centerRow)
+ continue;
+
+ if (static_cast<int>(renderSlicer.col1) <= centerColumn
+ && static_cast<int>(renderSlicer.col2) >= centerColumn
+ && static_cast<int>(renderSlicer.row1) <= centerRow
+ && static_cast<int>(renderSlicer.row2) >= centerRow) {
+
+ if (!ewk_tiled_backing_store_pre_render_tile_add(ewkBackingStore, centerColumn, centerRow, zoom))
+ continue;
+ DBG("R>[%d %d] ", centerColumn, centerRow);
+ memoryLimits--;
+ }
+ }
+ centerRow--;
+ centerColumn--;
+ step = step + 2;
+ }
+
+memoryLimitsReached:
+ _ewk_tiled_backing_store_item_process_idler_start(priv);
+
+ return true;
+}
+
Eina_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)
{
PRIV_DATA_GET_OR_RETURN(ewkBackingStore, priv, false);
Modified: trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.h (104281 => 104282)
--- trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.h 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Source/WebKit/efl/ewk/ewk_tiled_backing_store.h 2012-01-06 11:25:24 UTC (rev 104282)
@@ -112,6 +112,7 @@
Eina_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);
Eina_Bool ewk_tiled_backing_store_pre_render_relative_radius(Evas_Object* o, unsigned int n, float zoom);
+Eina_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);
void ewk_tiled_backing_store_pre_render_cancel(Evas_Object* o);
Eina_Bool ewk_tiled_backing_store_disable_render(Evas_Object* o);
Modified: trunk/Source/WebKit/efl/ewk/ewk_view.cpp (104281 => 104282)
--- trunk/Source/WebKit/efl/ewk/ewk_view.cpp 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Source/WebKit/efl/ewk/ewk_view.cpp 2012-01-06 11:25:24 UTC (rev 104282)
@@ -1005,6 +1005,12 @@
return false;
}
+static Eina_Bool _ewk_view_smart_pre_render_start(Ewk_View_Smart_Data* smartData)
+{
+ WRN("not supported by engine. smartData=%p", smartData);
+ return false;
+}
+
static void _ewk_view_smart_pre_render_cancel(Ewk_View_Smart_Data* smartData)
{
WRN("not supported by engine. smartData=%p", smartData);
@@ -1137,6 +1143,7 @@
api->flush = _ewk_view_smart_flush;
api->pre_render_region = _ewk_view_smart_pre_render_region;
api->pre_render_relative_radius = _ewk_view_smart_pre_render_relative_radius;
+ api->pre_render_start = _ewk_view_smart_pre_render_start;
api->pre_render_cancel = _ewk_view_smart_pre_render_cancel;
api->disable_render = _ewk_view_smart_disable_render;
api->enable_render = _ewk_view_smart_enable_render;
@@ -1834,6 +1841,14 @@
return smartData->api->pre_render_relative_radius(smartData, number, currentZoom);
}
+Eina_Bool ewk_view_pre_render_start(Evas_Object* ewkView)
+{
+ EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->pre_render_start, false);
+
+ return smartData->api->pre_render_start(smartData);
+}
+
unsigned int ewk_view_imh_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
Modified: trunk/Source/WebKit/efl/ewk/ewk_view.h (104281 => 104282)
--- trunk/Source/WebKit/efl/ewk/ewk_view.h 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Source/WebKit/efl/ewk/ewk_view.h 2012-01-06 11:25:24 UTC (rev 104282)
@@ -135,6 +135,7 @@
void (*flush)(Ewk_View_Smart_Data *sd);
Eina_Bool (*pre_render_region)(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom);
Eina_Bool (*pre_render_relative_radius)(Ewk_View_Smart_Data *sd, unsigned int n, float zoom);
+ Eina_Bool (*pre_render_start)(Ewk_View_Smart_Data *sd);
void (*pre_render_cancel)(Ewk_View_Smart_Data *sd);
Eina_Bool (*disable_render)(Ewk_View_Smart_Data *sd);
Eina_Bool (*enable_render)(Ewk_View_Smart_Data *sd);
@@ -168,7 +169,7 @@
* The version you have to put into the version field
* in the @a Ewk_View_Smart_Class structure.
*/
-#define EWK_VIEW_SMART_CLASS_VERSION 3UL
+#define EWK_VIEW_SMART_CLASS_VERSION 4UL
/**
* Initializes a whole @a Ewk_View_Smart_Class structure.
@@ -180,7 +181,7 @@
* @see EWK_VIEW_SMART_CLASS_INIT_VERSION
* @see EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION
*/
-#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}
+#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}
/**
* Initializes to zero a whole @a Ewk_View_Smart_Class structure.
@@ -314,6 +315,10 @@
Eina_Bool position:1;
Eina_Bool frame_rect:1;
} changed; /**< Keeps what changed since last smart_calculate. */
+ struct {
+ Evas_Coord x, y;
+ float zoom;
+ } previousView;
};
/// Defines the modes of view.
@@ -1249,6 +1254,23 @@
EAPI Eina_Bool ewk_view_pre_render_relative_radius(Evas_Object *o, unsigned int n);
/**
+ * Asks engine to start pre-rendering.
+ *
+ * This is an alternative method to pre-render around the view area.
+ * The first step is to find the center view area where to start pre-rendering.
+ * And then from the center of the view area the backing store append the render request
+ * outward in spiral order. So that the tiles which are close to view area are displayed
+ * sooner than outside.
+ *
+ * @param o view to ask pre-render
+ *
+ * @return @c EINA_TRUE if request was accepted, @c EINA_FALSE
+ * otherwise (errors, pre-render feature not supported, etc)
+ *
+ */
+EAPI Eina_Bool ewk_view_pre_render_start(Evas_Object *o);
+
+/**
* Cancels and clears previous the pre-render requests.
*
* @param o view to clear pre-render requests
Modified: trunk/Source/WebKit/efl/ewk/ewk_view_tiled.cpp (104281 => 104282)
--- trunk/Source/WebKit/efl/ewk/ewk_view_tiled.cpp 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Source/WebKit/efl/ewk/ewk_view_tiled.cpp 2012-01-06 11:25:24 UTC (rev 104282)
@@ -209,6 +209,123 @@
(smartData->backing_store, n, zoom);
}
+static inline int _ewk_view_tiled_rect_collision_check(Eina_Rectangle destination, Eina_Rectangle source)
+{
+ int direction = 0;
+ if (destination.x < source.x)
+ direction = direction | (1 << 0); // 0 bit shift, left
+ if (destination.y < source.y)
+ direction = direction | (1 << 1); // 1 bit shift, top
+ if (destination.x + destination.w > source.x + source.w)
+ direction = direction | (1 << 2); // 2 bit shift, right
+ if (destination.y + destination.h > source.y + source.h)
+ direction = direction | (1 << 3); // 3 bit shift, bottom
+ DBG("check collision %d\r\n", direction);
+ return direction;
+}
+
+static inline void _ewk_view_tiled_rect_collision_resolve(int direction, Eina_Rectangle* destination, Eina_Rectangle source)
+{
+ if (direction & (1 << 0)) // 0 bit shift, left
+ destination->x = source.x;
+ if (direction & (1 << 1)) // 1 bit shift, top
+ destination->y = source.y;
+ if (direction & (1 << 2)) // 2 bit shift, right
+ destination->x = destination->x - ((destination->x + destination->w) - (source.x + source.w));
+ if (direction & (1 << 3)) // 3 bit shift, bottom
+ destination->y = destination->y - ((destination->y + destination->h) - (source.y + source.h));
+}
+
+static Eina_Bool _ewk_view_tiled_smart_pre_render_start(Ewk_View_Smart_Data* smartData)
+{
+ int contentWidth, contentHeight;
+ ewk_frame_contents_size_get(smartData->main_frame, &contentWidth, &contentHeight);
+
+ int viewX, viewY, viewWidth, viewHeight;
+ ewk_frame_visible_content_geometry_get(smartData->main_frame, false, &viewX, &viewY, &viewWidth, &viewHeight);
+
+ if (viewWidth <= 0 || viewHeight <= 0 || contentWidth <= 0 || contentHeight <= 0)
+ return false;
+
+ if (viewWidth >= contentWidth && viewHeight >= contentHeight)
+ return false;
+
+ int previousViewX, previousViewY;
+ previousViewX = smartData->previousView.x;
+ previousViewY = smartData->previousView.y;
+
+ if (previousViewX < 0 || previousViewX > contentWidth || previousViewY < 0 || previousViewY > contentHeight)
+ previousViewX = previousViewY = 0;
+
+ float currentViewZoom = ewk_view_zoom_get(smartData->self);
+
+ // pre-render works when two conditions are met.
+ // zoom has been changed.
+ // and the view has been moved more than tile size.
+ if (abs(previousViewX - viewX) < DEFAULT_TILE_W
+ && abs(previousViewY - viewY) < DEFAULT_TILE_H
+ && smartData->previousView.zoom == currentViewZoom) {
+ return false;
+ }
+
+ // store previous view position and zoom.
+ smartData->previousView.x = viewX;
+ smartData->previousView.y = viewY;
+ smartData->previousView.zoom = currentViewZoom;
+
+ // cancelling previous pre-rendering list if exists.
+ ewk_view_pre_render_cancel(smartData->self);
+
+ Ewk_Tile_Unused_Cache* tileUnusedCache = ewk_view_tiled_unused_cache_get(smartData->self);
+ int maxMemory = ewk_tile_unused_cache_max_get(tileUnusedCache);
+ if (maxMemory <= viewWidth * viewHeight * EWK_ARGB_BYTES_SIZE)
+ return false;
+
+ Eina_Rectangle viewRect = {viewX, viewY, viewWidth, viewHeight};
+ Eina_Rectangle contentRect = {0, 0, contentWidth, contentHeight};
+
+ // get a base render rect.
+ const int contentMemory = contentWidth * contentHeight * EWK_ARGB_BYTES_SIZE;
+
+ // get render rect's width and height.
+ Eina_Rectangle renderRect;
+ if (maxMemory > contentMemory)
+ renderRect = contentRect;
+ else {
+ // Make a base rectangle as big as possible with using maxMemory.
+ // and then reshape the base rectangle to fit to contents.
+ const int baseSize = static_cast<int>(sqrt(maxMemory / 4.0f));
+ const float widthRate = (viewRect.w + (DEFAULT_TILE_W * 2)) / static_cast<float>(baseSize);
+ const float heightRate = baseSize / static_cast<float>(contentHeight);
+ const float rectRate = std::max(widthRate, heightRate);
+
+ renderRect.w = static_cast<int>(baseSize * rectRate);
+ renderRect.h = static_cast<int>(baseSize / rectRate);
+ renderRect.x = viewRect.x + (viewRect.w / 2) - (renderRect.w / 2);
+ renderRect.y = viewRect.y + (viewRect.h / 2) - (renderRect.h / 2);
+
+ // reposition of renderRect, if the renderRect overlapped the content rect, this code moves the renderRect inside the content rect.
+ int collisionSide = _ewk_view_tiled_rect_collision_check(renderRect, contentRect);
+ if (collisionSide > 0)
+ _ewk_view_tiled_rect_collision_resolve(collisionSide, &renderRect, contentRect);
+
+ // check abnormal render rect
+ if (renderRect.x < 0)
+ renderRect.x = 0;
+ if (renderRect.y < 0)
+ renderRect.y = 0;
+ if (renderRect.w > contentWidth)
+ renderRect.w = contentWidth;
+ if (renderRect.h > contentHeight)
+ renderRect.h = contentHeight;
+ }
+
+ // enqueue tiles into tiled backing store in spiral order.
+ ewk_tiled_backing_store_pre_render_spiral_queue(smartData->backing_store, &viewRect, &renderRect, maxMemory, currentViewZoom);
+
+ return true;
+}
+
static void _ewk_view_tiled_smart_pre_render_cancel(Ewk_View_Smart_Data* smartData)
{
ewk_tiled_backing_store_pre_render_cancel(smartData->backing_store);
@@ -248,6 +365,7 @@
api->flush = _ewk_view_tiled_smart_flush;
api->pre_render_region = _ewk_view_tiled_smart_pre_render_region;
api->pre_render_relative_radius = _ewk_view_tiled_smart_pre_render_relative_radius;
+ api->pre_render_start = _ewk_view_tiled_smart_pre_render_start;
api->pre_render_cancel = _ewk_view_tiled_smart_pre_render_cancel;
api->disable_render = _ewk_view_tiled_smart_disable_render;
api->enable_render = _ewk_view_tiled_smart_enable_render;
Modified: trunk/Tools/ChangeLog (104281 => 104282)
--- trunk/Tools/ChangeLog 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Tools/ChangeLog 2012-01-06 11:25:24 UTC (rev 104282)
@@ -1,3 +1,15 @@
+2012-01-06 JungJik Lee <[email protected]>
+
+ [EFL] Add pre-render handling code in EWebLauncher.
+ https://bugs.webkit.org/show_bug.cgi?id=73430
+
+ Reviewed by Zoltan Herczeg.
+
+ Add pre-render handling code by pressing Insert key.
+
+ * EWebLauncher/main.c:
+ (on_key_down):
+
2012-01-06 Csaba Osztrogonác <[email protected]>
NRWT should use test_expectation.txt on wk2 platforms
Modified: trunk/Tools/EWebLauncher/main.c (104281 => 104282)
--- trunk/Tools/EWebLauncher/main.c 2012-01-06 10:55:22 UTC (rev 104281)
+++ trunk/Tools/EWebLauncher/main.c 2012-01-06 11:25:24 UTC (rev 104282)
@@ -548,6 +548,9 @@
} else if (!strcmp(ev->key, "e")) {
info("Render resumed");
ewk_view_enable_render(obj);
+ } else if (!strcmp(ev->key, "Insert")) {
+ info("Pre-rendering start");
+ ewk_view_pre_render_start(obj);
}
}