[EFL] Added DEFAULT_CACHE_SIZE define.
[WebKit-https.git] / Source / WebKit / efl / ewk / ewk_tiled_matrix.cpp
index 2d55544bf324ddbf791bbf9e85c681207281e3d4..c3a596d418c836a89d718e97b69b1266d64278f8 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 {
@@ -54,11 +64,27 @@ struct _Ewk_Tile_Matrix {
 #endif
 };
 
+// Default 40 MB size of newly created cache
+static const size_t DEFAULT_CACHE_SIZE = 40 * 1024 * 1024;
+
 #ifdef DEBUG_MEM_LEAKS
 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 +105,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 +128,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 +166,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 +188,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,10 +208,12 @@ 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 {
-        tileMatrix->tilieUnusedCache = ewk_tile_unused_cache_new(40960000);
+        tileMatrix->tilieUnusedCache = ewk_tile_unused_cache_new(DEFAULT_CACHE_SIZE);
         if (!tileMatrix->tilieUnusedCache) {
             ERR("no cache of unused tile!");
             eina_matrixsparse_free(tileMatrix->matrix);
@@ -180,6 +231,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 +291,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 +299,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 +433,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;