/* SPDX-License-Identifier: GPL-2.0-or-later * Copyright 2019 Blender Foundation. All rights reserved. */ /** \file * \ingroup editors */ #include #include /* #include */ #include #include "MEM_guardedalloc.h" #include "MOD_lineart.h" #include "BLI_math.h" #include "lineart_intern.h" /* Line art memory and list helper */ void *lineart_list_append_pointer_pool(ListBase *h, LineartStaticMemPool *smp, void *data) { LinkData *lip; if (h == NULL) { return 0; } lip = lineart_mem_acquire(smp, sizeof(LinkData)); lip->data = data; BLI_addtail(h, lip); return lip; } void *lineart_list_append_pointer_pool_sized(ListBase *h, LineartStaticMemPool *smp, void *data, int size) { LinkData *lip; if (h == NULL) { return 0; } lip = lineart_mem_acquire(smp, size); lip->data = data; BLI_addtail(h, lip); return lip; } void *lineart_list_append_pointer_pool_thread(ListBase *h, LineartStaticMemPool *smp, void *data) { LinkData *lip; if (h == NULL) { return 0; } lip = lineart_mem_acquire_thread(smp, sizeof(LinkData)); lip->data = data; BLI_addtail(h, lip); return lip; } void *lineart_list_append_pointer_pool_sized_thread(ListBase *h, LineartStaticMemPool *smp, void *data, int size) { LinkData *lip; if (h == NULL) { return 0; } lip = lineart_mem_acquire_thread(smp, size); lip->data = data; BLI_addtail(h, lip); return lip; } void *lineart_list_pop_pointer_no_free(ListBase *h) { LinkData *lip; void *rev = 0; if (h == NULL) { return 0; } lip = BLI_pophead(h); rev = lip ? lip->data : 0; return rev; } void lineart_list_remove_pointer_item_no_free(ListBase *h, LinkData *lip) { BLI_remlink(h, (void *)lip); } LineartStaticMemPoolNode *lineart_mem_new_static_pool(LineartStaticMemPool *smp, size_t size) { size_t set_size = size; if (set_size < LRT_MEMORY_POOL_1MB) { set_size = LRT_MEMORY_POOL_1MB; /* Prevent too many small allocations. */ } size_t total_size = set_size + sizeof(LineartStaticMemPoolNode); LineartStaticMemPoolNode *smpn = MEM_callocN(total_size, "mempool"); smpn->size = total_size; smpn->used_byte = sizeof(LineartStaticMemPoolNode); BLI_addhead(&smp->pools, smpn); return smpn; } void *lineart_mem_acquire(LineartStaticMemPool *smp, size_t size) { LineartStaticMemPoolNode *smpn = smp->pools.first; void *ret; if (!smpn || (smpn->used_byte + size) > smpn->size) { smpn = lineart_mem_new_static_pool(smp, size); } ret = ((uchar *)smpn) + smpn->used_byte; smpn->used_byte += size; return ret; } void *lineart_mem_acquire_thread(LineartStaticMemPool *smp, size_t size) { void *ret; BLI_spin_lock(&smp->lock_mem); LineartStaticMemPoolNode *smpn = smp->pools.first; if (!smpn || (smpn->used_byte + size) > smpn->size) { smpn = lineart_mem_new_static_pool(smp, size); } ret = ((uchar *)smpn) + smpn->used_byte; smpn->used_byte += size; BLI_spin_unlock(&smp->lock_mem); return ret; } void lineart_mem_destroy(LineartStaticMemPool *smp) { LineartStaticMemPoolNode *smpn; while ((smpn = BLI_pophead(&smp->pools)) != NULL) { MEM_freeN(smpn); } } void lineart_prepend_pool(LinkNode **first, LineartStaticMemPool *smp, void *link) { LinkNode *ln = lineart_mem_acquire_thread(smp, sizeof(LinkNode)); ln->next = (*first); ln->link = link; (*first) = ln; } /* =======================================================================[str] */ void lineart_matrix_perspective_44d( double (*mProjection)[4], double fFov_rad, double fAspect, double zMin, double zMax) { double yMax; double yMin; double xMin; double xMax; if (fAspect < 1) { yMax = zMin * tan(fFov_rad * 0.5f); yMin = -yMax; xMin = yMin * fAspect; xMax = -xMin; } else { xMax = zMin * tan(fFov_rad * 0.5f); xMin = -xMax; yMin = xMin / fAspect; yMax = -yMin; } unit_m4_db(mProjection); mProjection[0][0] = (2.0f * zMin) / (xMax - xMin); mProjection[1][1] = (2.0f * zMin) / (yMax - yMin); mProjection[2][0] = (xMax + xMin) / (xMax - xMin); mProjection[2][1] = (yMax + yMin) / (yMax - yMin); mProjection[2][2] = -((zMax + zMin) / (zMax - zMin)); mProjection[2][3] = -1.0f; mProjection[3][2] = -((2.0f * (zMax * zMin)) / (zMax - zMin)); mProjection[3][3] = 0.0f; } void lineart_matrix_ortho_44d(double (*mProjection)[4], double xMin, double xMax, double yMin, double yMax, double zMin, double zMax) { unit_m4_db(mProjection); mProjection[0][0] = 2.0f / (xMax - xMin); mProjection[1][1] = 2.0f / (yMax - yMin); mProjection[2][2] = -2.0f / (zMax - zMin); mProjection[3][0] = -((xMax + xMin) / (xMax - xMin)); mProjection[3][1] = -((yMax + yMin) / (yMax - yMin)); mProjection[3][2] = -((zMax + zMin) / (zMax - zMin)); mProjection[3][3] = 1.0f; } void lineart_count_and_print_render_buffer_memory(LineartData *ld) { size_t total = 0; size_t sum_this = 0; size_t count_this = 0; LISTBASE_FOREACH (LineartStaticMemPoolNode *, smpn, &ld->render_data_pool.pools) { count_this++; sum_this += LRT_MEMORY_POOL_1MB; } printf("LANPR Memory allocated %zu Standalone nodes, total %zu Bytes.\n", count_this, sum_this); total += sum_this; sum_this = 0; count_this = 0; LISTBASE_FOREACH (LineartElementLinkNode *, reln, &ld->geom.line_buffer_pointers) { count_this++; sum_this += reln->element_count * sizeof(LineartEdge); } printf(" allocated %zu edge blocks, total %zu Bytes.\n", count_this, sum_this); total += sum_this; sum_this = 0; count_this = 0; LISTBASE_FOREACH (LineartElementLinkNode *, reln, &ld->geom.triangle_buffer_pointers) { count_this++; sum_this += reln->element_count * ld->sizeof_triangle; } printf(" allocated %zu triangle blocks, total %zu Bytes.\n", count_this, sum_this); total += sum_this; sum_this = 0; count_this = 0; (void)total; /* Ignored. */ }