/** * Creates a new matrix of tiles. * * The tile matrix is responsible for keeping tiles around and * providing fast access to them. One can use it to retrieve new or * existing tiles and give them back, allowing them to be * freed/replaced by the cache. * * @param tuc cache of unused tiles or @c NULL to create one * automatically. * @param cols number of columns in the matrix. * @param rows number of rows in 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 data context to give back to @a render_cb. * * @return newly allocated instance on success, @c NULL on failure. */ 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 *data) { Ewk_Tile_Matrix *tm; CALLOC_OR_OOM_RET(tm, sizeof(Ewk_Tile_Matrix), NULL); tm->matrix = eina_matrixsparse_new(rows, cols, _ewk_tile_matrix_cell_free, tm); if (!tm->matrix) { ERR("could not create sparse matrix."); free(tm); return NULL; } if (tuc) tm->tuc = ewk_tile_unused_cache_ref(tuc); else { tm->tuc = ewk_tile_unused_cache_new(40960000); if (!tm->tuc) { ERR("no cache of unused tile!"); eina_matrixsparse_free(tm->matrix); free(tm); return NULL; } } tm->cspace = cspace; tm->render.cb = render_cb; tm->render.data = (void *)data; return tm; }
/** * Destroys tiles matrix, releasing its resources. * * The cache instance is unreferenced, possibly freeing it. */ void ewk_tile_matrix_free(Ewk_Tile_Matrix *tm) { #ifdef DEBUG_MEM_LEAKS uint64_t tiles, bytes; #endif EINA_SAFETY_ON_NULL_RETURN(tm); ewk_tile_unused_cache_freeze(tm->tuc); eina_matrixsparse_free(tm->matrix); ewk_tile_unused_cache_thaw(tm->tuc); ewk_tile_unused_cache_unref(tm->tuc); #ifdef DEBUG_MEM_LEAKS tiles = tm->stats.tiles.allocated - tm->stats.tiles.freed; bytes = tm->stats.bytes.allocated - tm->stats.bytes.freed; tiles_leaked += tiles; bytes_leaked += bytes; if (tiles || bytes) ERR("tiled matrix leaked: tiles[+%"PRIu64",-%"PRIu64":%"PRIu64"] " "bytes[+%"PRIu64",-%"PRIu64":%"PRIu64"]", tm->stats.tiles.allocated, tm->stats.tiles.freed, tiles, tm->stats.bytes.allocated, tm->stats.bytes.freed, bytes); else if (tiles_leaked || bytes_leaked) WRN("tiled matrix had no leaks: tiles[+%"PRIu64",-%"PRIu64"] " "bytes[+%"PRIu64",-%"PRIu64"], but some other leaked " "%"PRIu64" tiles (%"PRIu64" bytes)", tm->stats.tiles.allocated, tm->stats.tiles.freed, tm->stats.bytes.allocated, tm->stats.bytes.freed, tiles_leaked, bytes_leaked); else INF("tiled matrix had no leaks: tiles[+%"PRIu64",-%"PRIu64"] " "bytes[+%"PRIu64",-%"PRIu64"]", tm->stats.tiles.allocated, tm->stats.tiles.freed, tm->stats.bytes.allocated, tm->stats.bytes.freed); #endif free(tm); }
END_TEST START_TEST(eina_test_resize) { Eina_Matrixsparse *matrix = NULL; Eina_Bool r; unsigned long i, j; unsigned long nrows, ncols; long data[MAX_ROWS][MAX_COLS]; for (i = 0; i < MAX_ROWS; i++) for (j = 0; j < MAX_COLS; j++) data[i][j] = 0; eina_init(); matrix = eina_matrixsparse_new(MAX_ROWS, MAX_COLS, eina_matrixsparse_free_cell_cb, data); fail_if(matrix == NULL); /* cell insertion */ data[0][5] = 5; data[1][0] = 10; data[1][3] = 13; data[1][6] = 16; data[1][9] = 19; data[1][8] = 18; data[1][7] = 17; data[2][8] = 28; data[2][7] = 27; data[2][6] = 26; data[3][0] = 30; data[3][5] = 35; data[3][6] = 36; data[3][7] = 37; data[3][9] = 39; data[3][0] = 30; data[4][8] = 48; data[4][2] = 42; data[4][3] = 43; data[4][7] = 47; data[4][6] = 46; data[5][3] = 53; data[6][3] = 63; data[6][4] = 64; data[6][6] = 66; data[7][3] = 73; data[7][7] = 77; data[8][8] = 88; matrixsparse_initialize(matrix, data, MAX_ROWS, MAX_COLS); eina_matrixsparse_size_get(matrix, &nrows, &ncols); fail_if(nrows != MAX_ROWS || ncols != MAX_COLS); r = eina_matrixsparse_size_set(matrix, nrows - 2, ncols - 2); fail_if(r == EINA_FALSE); data[1][9] = 0; data[1][8] = 0; data[2][8] = 0; data[3][9] = 0; data[4][8] = 0; data[8][8] = 0; matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS); r = eina_matrixsparse_size_set(matrix, 5, 1); fail_if(r == EINA_FALSE); data[0][5] = 0; data[1][3] = 0; data[1][6] = 0; data[1][7] = 0; data[2][7] = 0; data[2][6] = 0; data[3][5] = 0; data[3][6] = 0; data[3][7] = 0; data[4][2] = 0; data[4][3] = 0; data[4][7] = 0; data[4][6] = 0; data[5][3] = 0; data[6][3] = 0; data[6][4] = 0; data[6][6] = 0; data[7][3] = 0; data[7][7] = 0; matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS); r = eina_matrixsparse_size_set(matrix, 1, 1); fail_if(r == EINA_FALSE); data[3][0] = 0; data[1][0] = 0; matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS); r = eina_matrixsparse_size_set(matrix, 5, 4); fail_if(r == EINA_FALSE); r = eina_matrixsparse_data_idx_set(matrix, 4, 2, &data[4][2]); fail_if(r == EINA_FALSE); data[4][2] = 42; matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS); r = eina_matrixsparse_size_set(matrix, 5, 1); fail_if(r == EINA_FALSE); data[4][2] = 0; matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS); eina_matrixsparse_free(matrix); eina_shutdown(); }