[EFL] Add matrix list to reuse tile matrix for each different zoom level.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Nov 2011 05:52:34 +0000 (05:52 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Nov 2011 05:52:34 +0000 (05:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=68595

Patch by KwangHyuk Kim <hyuki.kim@samsung.com> on 2011-11-17
Reviewed by Kenneth Rohde Christiansen.

Add matrix list to keep each tile matrix corresponding to each different zoom level when zoom level is changed.
Then backing store can reuse tile matrix by getting it from this matrix list.

* ewk/ewk_tiled_backing_store.cpp:
(_ewk_tiled_backing_store_model_matrix_create):
(_ewk_tiled_backing_store_smart_calculate):
(_ewk_tiled_backing_store_zoom_set_internal):
* ewk/ewk_tiled_matrix.cpp:
(ewk_tile_matrix_entry_get):
(_ewk_tile_matrix_cell_free):
(_ewk_tile_matrix_tile_free):
(ewk_tile_matrix_new):
(ewk_tile_matrix_zoom_level_set):
(ewk_tile_matrix_invalidate):
(ewk_tile_matrix_free):
(ewk_tile_matrix_tile_new):
* ewk/ewk_tiled_matrix.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@100724 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/efl/ChangeLog
Source/WebKit/efl/ewk/ewk_tiled_backing_store.cpp
Source/WebKit/efl/ewk/ewk_tiled_matrix.cpp
Source/WebKit/efl/ewk/ewk_tiled_matrix.h

index 24d92c4ffd687cdfaafdfda15ed79ab988806c69..3735d134def563417e37bb92aa6570a794bdf5a9 100755 (executable)
@@ -1,3 +1,28 @@
+2011-11-17  KwangHyuk Kim  <hyuki.kim@samsung.com>
+
+        [EFL] Add matrix list to reuse tile matrix for each different zoom level.
+        https://bugs.webkit.org/show_bug.cgi?id=68595
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Add matrix list to keep each tile matrix corresponding to each different zoom level when zoom level is changed.
+        Then backing store can reuse tile matrix by getting it from this matrix list.
+
+        * ewk/ewk_tiled_backing_store.cpp:
+        (_ewk_tiled_backing_store_model_matrix_create):
+        (_ewk_tiled_backing_store_smart_calculate):
+        (_ewk_tiled_backing_store_zoom_set_internal):
+        * ewk/ewk_tiled_matrix.cpp:
+        (ewk_tile_matrix_entry_get):
+        (_ewk_tile_matrix_cell_free):
+        (_ewk_tile_matrix_tile_free):
+        (ewk_tile_matrix_new):
+        (ewk_tile_matrix_zoom_level_set):
+        (ewk_tile_matrix_invalidate):
+        (ewk_tile_matrix_free):
+        (ewk_tile_matrix_tile_new):
+        * ewk/ewk_tiled_matrix.h:
+
 2011-11-17  Raphael Kubo da Costa  <kubo@profusion.mobi>
 
         [EFL] Clean up the use of DATA_DIR in the buildsystem
index 58a7c59845fdcf5a31336998d837d30d173760f0..a9b7812f880a78e57bae7cb077fa7f04c9ccbbd8 100644 (file)
@@ -619,7 +619,7 @@ static inline void _ewk_tiled_backing_store_model_matrix_create(Ewk_Tiled_Backin
         ewk_tile_matrix_free(priv->model.matrix);
     }
 
-    priv->model.matrix = ewk_tile_matrix_new(tileUnusedCache, priv->model.current.columns, priv->model.current.rows, priv->colorSpace, _ewk_tiled_backing_store_render, priv);
+    priv->model.matrix = ewk_tile_matrix_new(tileUnusedCache, priv->model.current.columns, priv->model.current.rows, priv->view.tile.zoom, priv->colorSpace, _ewk_tiled_backing_store_render, priv);
 }
 
 static void _ewk_tiled_backing_store_smart_member_del(Evas_Object* ewkBackingStore, Evas_Object* member)
@@ -1298,6 +1298,9 @@ static void _ewk_tiled_backing_store_smart_calculate(Evas_Object* ewkBackingStor
 
     ewk_tile_matrix_freeze(priv->model.matrix);
 
+    if (priv->changed.model && !priv->changed.size)
+        ewk_tile_matrix_invalidate(priv->model.matrix);
+
     if (!priv->render.suspend && priv->changed.model) {
         unsigned long columns, rows;
 
@@ -1477,6 +1480,7 @@ static Eina_Bool _ewk_tiled_backing_store_zoom_set_internal(Ewk_Tiled_Backing_St
     priv->view.offset.zoomCenter.x = currentX;
     priv->view.offset.zoomCenter.y = currentY;
 
+    ewk_tile_matrix_zoom_level_set(priv->model.matrix, *zoom);
 
     if (!priv->view.width || !priv->view.height) {
         priv->view.offset.base.x = 0;
index 2d55544bf324ddbf791bbf9e85c681207281e3d4..ef536881c7361c51655b69ae27f2052eeed3eacc 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+struct _Ewk_Tile_Matrix_Entry {
+    EINA_INLIST;
+    float zoom;
+    unsigned long count;
+    Eina_Matrixsparse* matrix;
+};
+
+typedef struct _Ewk_Tile_Matrix_Entry Ewk_Tile_Matrix_Entry;
+
 struct _Ewk_Tile_Matrix {
     Eina_Matrixsparse* matrix;
+    Eina_Inlist* matrices;
     Ewk_Tile_Unused_Cache* tilieUnusedCache;
     Evas_Colorspace cspace;
     struct {
@@ -59,6 +69,19 @@ static uint64_t tiles_leaked = 0;
 static uint64_t bytes_leaked = 0;
 #endif
 
+static Ewk_Tile_Matrix_Entry* ewk_tile_matrix_entry_get(Ewk_Tile_Matrix* tileMatrix, float zoom)
+{
+    EINA_SAFETY_ON_NULL_RETURN_VAL(tileMatrix, 0);
+    Ewk_Tile_Matrix_Entry* iterator;
+
+    EINA_INLIST_FOREACH(tileMatrix->matrices, iterator) {
+        if (iterator->zoom == zoom)
+            return iterator;
+    }
+
+    return 0;
+}
+
 /* called when matrixsparse is resized or freed */
 static void _ewk_tile_matrix_cell_free(void* userData, void* cellData)
 {
@@ -79,11 +102,18 @@ static void _ewk_tile_matrix_cell_free(void* userData, void* cellData)
         if (!ewk_tile_unused_cache_tile_get(tileMatrix->tilieUnusedCache, tile))
             ERR("tile %p was not in cache %p? leaking...", tile, tileMatrix->tilieUnusedCache);
         else {
+            Ewk_Tile_Matrix_Entry* entry;
             DBG("tile cell does not exist anymore, free it %p", tile);
 #ifdef DEBUG_MEM_LEAKS
             tileMatrix->stats.bytes.freed += tile->bytes;
             tileMatrix->stats.tiles.freed++;
 #endif
+            entry = ewk_tile_matrix_entry_get(tileMatrix, tile->zoom);
+            if (!entry)
+                ERR("can't find matrix for zoom %0.3f", tile->zoom);
+            else
+                entry->count--;
+
             ewk_tile_free(tile);
         }
     }
@@ -95,9 +125,17 @@ static void _ewk_tile_matrix_cell_free(void* userData, void* cellData)
 static void _ewk_tile_matrix_tile_free(void* data, Ewk_Tile* tile)
 {
     Ewk_Tile_Matrix* tileMatrix = static_cast<Ewk_Tile_Matrix*>(data);
+    Ewk_Tile_Matrix_Entry* entry;
     Eina_Matrixsparse_Cell* cell;
 
-    if (!eina_matrixsparse_cell_idx_get(tileMatrix->matrix, tile->row, tile->col, &cell)) {
+    entry = ewk_tile_matrix_entry_get(tileMatrix, tile->zoom);
+    if (!entry) {
+        ERR("removing tile %p that was not in any matrix? Leaking...", tile);
+        return;
+    }
+
+    if (!eina_matrixsparse_cell_idx_get(entry->matrix, tile->row, tile->col, &cell)) {
+
         ERR("removing tile %p that was not in the matrix? Leaking...", tile);
         return;
     }
@@ -125,6 +163,13 @@ static void _ewk_tile_matrix_tile_free(void* data, Ewk_Tile* tile)
     tileMatrix->stats.tiles.freed++;
 #endif
 
+    entry->count--;
+    if (!entry->count && entry->matrix != tileMatrix->matrix) {
+        eina_matrixsparse_free(entry->matrix);
+        tileMatrix->matrices = eina_inlist_remove(tileMatrix->matrices, EINA_INLIST_GET(entry));
+        free(entry);
+    }
+
     ewk_tile_free(tile);
 }
 
@@ -140,13 +185,14 @@ static void _ewk_tile_matrix_tile_free(void* data, Ewk_Tile* tile)
  *        automatically.
  * @param columns number of columns in the matrix.
  * @param rows number of rows in the matrix.
+ * @param zoomLevel zoom level for the matrix.
  * @param cspace the color space used to create tiles in this matrix.
  * @param render_cb function used to render given tile update.
  * @param render_data context to give back to @a render_cb.
  *
  * @return newly allocated instance on success, @c 0 on failure.
  */
-Ewk_Tile_Matrix* ewk_tile_matrix_new(Ewk_Tile_Unused_Cache* tileUnusedCache, unsigned long columns, unsigned long rows, Evas_Colorspace colorSpace, void (*renderCallback)(void* data, Ewk_Tile* tile, const Eina_Rectangle* update), const void* renderData)
+Ewk_Tile_Matrix* ewk_tile_matrix_new(Ewk_Tile_Unused_Cache* tileUnusedCache, unsigned long columns, unsigned long rows, float zoomLevel, Evas_Colorspace colorSpace, void (*renderCallback)(void* data, Ewk_Tile* tile, const Eina_Rectangle* update), const void* renderData)
 {
     Ewk_Tile_Matrix* tileMatrix = static_cast<Ewk_Tile_Matrix*>(calloc(1, sizeof(Ewk_Tile_Matrix)));
     if (!tileMatrix)
@@ -159,6 +205,8 @@ Ewk_Tile_Matrix* ewk_tile_matrix_new(Ewk_Tile_Unused_Cache* tileUnusedCache, uns
         return 0;
     }
 
+    ewk_tile_matrix_zoom_level_set(tileMatrix, zoomLevel);
+
     if (tileUnusedCache)
         tileMatrix->tilieUnusedCache = ewk_tile_unused_cache_ref(tileUnusedCache);
     else {
@@ -180,6 +228,59 @@ Ewk_Tile_Matrix* ewk_tile_matrix_new(Ewk_Tile_Unused_Cache* tileUnusedCache, uns
     return tileMatrix;
 }
 
+void ewk_tile_matrix_zoom_level_set(Ewk_Tile_Matrix* tileMatrix, float zoom)
+{
+    EINA_SAFETY_ON_NULL_RETURN(tileMatrix);
+    Ewk_Tile_Matrix_Entry* iterator = 0;
+    Ewk_Tile_Matrix_Entry* entry = 0;
+    unsigned long rows = 0, columns = 0;
+
+    eina_matrixsparse_size_get(tileMatrix->matrix, &rows, &columns);
+
+    EINA_INLIST_FOREACH(tileMatrix->matrices, iterator) {
+        if (iterator->zoom != zoom)
+            continue;
+        entry = iterator;
+        tileMatrix->matrices = eina_inlist_promote(tileMatrix->matrices, EINA_INLIST_GET(entry));
+        eina_matrixsparse_size_set(entry->matrix, rows, columns);
+    }
+
+    if (!entry) {
+        entry = static_cast<Ewk_Tile_Matrix_Entry*>(calloc(1, sizeof(Ewk_Tile_Matrix_Entry)));
+        entry->zoom = zoom;
+        entry->matrix = eina_matrixsparse_new(rows, columns, _ewk_tile_matrix_cell_free, tileMatrix);
+        if (!entry->matrix) {
+            ERR("could not create sparse matrix.");
+            free(entry);
+            return;
+        }
+        tileMatrix->matrices = eina_inlist_prepend(tileMatrix->matrices, EINA_INLIST_GET(entry));
+    }
+
+    tileMatrix->matrix = entry->matrix;
+}
+
+void ewk_tile_matrix_invalidate(Ewk_Tile_Matrix* tileMatrix)
+{
+    EINA_SAFETY_ON_NULL_RETURN(tileMatrix);
+    Ewk_Tile_Matrix_Entry* iterator;
+    Eina_Inlist* matrixList;
+
+    matrixList = tileMatrix->matrices;
+    while (matrixList) {
+        iterator = EINA_INLIST_CONTAINER_GET(matrixList, Ewk_Tile_Matrix_Entry);
+        Eina_Inlist *next = (matrixList->next) ? matrixList->next : 0;
+
+        if (iterator->matrix != tileMatrix->matrix) {
+            eina_matrixsparse_free(iterator->matrix);
+            tileMatrix->matrices = eina_inlist_remove(tileMatrix->matrices, matrixList);
+            free(iterator);
+        }
+
+        matrixList = next;
+    }
+}
+
 /**
  * Destroys tiles matrix, releasing its resources.
  *
@@ -187,6 +288,7 @@ Ewk_Tile_Matrix* ewk_tile_matrix_new(Ewk_Tile_Unused_Cache* tileUnusedCache, uns
  */
 void ewk_tile_matrix_free(Ewk_Tile_Matrix* tileMatrix)
 {
+    Ewk_Tile_Matrix_Entry* entry;
 #ifdef DEBUG_MEM_LEAKS
     uint64_t tiles, bytes;
 #endif
@@ -194,7 +296,12 @@ void ewk_tile_matrix_free(Ewk_Tile_Matrix* tileMatrix)
     EINA_SAFETY_ON_NULL_RETURN(tileMatrix);
     ewk_tile_unused_cache_freeze(tileMatrix->tilieUnusedCache);
 
-    eina_matrixsparse_free(tileMatrix->matrix);
+    ewk_tile_unused_cache_freeze(tileMatrix->tilieUnusedCache);
+    ewk_tile_matrix_invalidate(tileMatrix);
+    entry = EINA_INLIST_CONTAINER_GET(tileMatrix->matrices, Ewk_Tile_Matrix_Entry);
+    eina_matrixsparse_free(entry->matrix);    
+    free(entry);
+    tileMatrix->matrices = 0;
 
     ewk_tile_unused_cache_thaw(tileMatrix->tilieUnusedCache);
     ewk_tile_unused_cache_unref(tileMatrix->tilieUnusedCache);
@@ -323,9 +430,16 @@ Ewk_Tile* ewk_tile_matrix_tile_new(Ewk_Tile_Matrix* tileMatrix, Evas* canvas, un
 {
     Evas_Coord tileWidth, tileHeight;
     Ewk_Tile* tile;
+    Ewk_Tile_Matrix_Entry* entry;
 
     EINA_SAFETY_ON_NULL_RETURN_VAL(tileMatrix, 0);
     EINA_SAFETY_ON_FALSE_RETURN_VAL(zoom > 0.0, 0);
+    entry = ewk_tile_matrix_entry_get(tileMatrix, zoom);
+    if (!entry) {
+        ERR("could not get matrix at zoom %f for tile", zoom);
+        return 0;
+    }
+    entry->count++;
 
     tileWidth = tileMatrix->tile.width;
     tileHeight = tileMatrix->tile.height;
index d3dc517125623047680bf76d962d4c04ffc22a8b..fe6b668501c5215a6d14af7f87fa10c105f8bfc0 100644 (file)
 #include <Evas.h>
 
 /* matrix of tiles */
-Ewk_Tile_Matrix* ewk_tile_matrix_new(Ewk_Tile_Unused_Cache* tuc, unsigned long cols, unsigned long rows, Evas_Colorspace cspace, void (* render_cb)(void* data, Ewk_Tile* t, const Eina_Rectangle* update), const void* render_data);
+Ewk_Tile_Matrix* ewk_tile_matrix_new(Ewk_Tile_Unused_Cache* tileUnusedCache, unsigned long columns, unsigned long rows, float zoomLevel, Evas_Colorspace colorSpace, void (*render_callback)(void* data, Ewk_Tile* tile, const Eina_Rectangle* update), const void* renderData);
 void ewk_tile_matrix_free(Ewk_Tile_Matrix* tm);
 
 void ewk_tile_matrix_resize(Ewk_Tile_Matrix* tm, unsigned long cols, unsigned long rows);
+void ewk_tile_matrix_zoom_level_set(Ewk_Tile_Matrix* tileMatrix, float zoom);
+void ewk_tile_matrix_invalidate(Ewk_Tile_Matrix* tileMatrix);
 
 Ewk_Tile_Unused_Cache* ewk_tile_matrix_unused_cache_get(const Ewk_Tile_Matrix* tm);