got nonbinary partitioning working yippie

This commit is contained in:
Emile Clark-Boman 2025-09-15 19:26:04 +10:00
parent 6b5bcff1a4
commit 330755591b
6 changed files with 170 additions and 57 deletions

View file

@ -7,6 +7,7 @@
#include "dims.h"
#include "node.h"
#include "surface.h"
#include "util.h"
/* Internal allocator method for ct_node structures.
*/
@ -74,9 +75,12 @@ void satisfy_node(struct ct_node *const node, struct ct_dims *const dims) {
}
}
struct ct_whdims {
/* Surface Partition Dimensions */
/* TODO: can I use unsigned short instead of int? */
struct ct_spdims {
// Main Axis & Orthogonal Axis Sizes
int axm_size, axo_size;
int axm_size;
// int axo_size;
bool fixed;
int min, max;
};
@ -98,75 +102,136 @@ int resize_node(struct ct_node *const node, struct ct_dims *const dims) {
return 1;
}
struct ct_whdims cwhdims[node->cindex];
struct ct_whdims *const parts[node->cindex];
int cunfixedn = node->cindex; // number of non-fixed children
memset(cwhdims, 0, sizeof(struct ct_whdims) * node->cindex);
int axm_size, axm_free, axo_size;
size_t axm_min_offset, axm_max_offset;
int axm_size, axm_free;
// int axo_size;
size_t bounds_axm_min_offset, bounds_axm_max_offset;
size_t dims_axm_pos_offset, dims_axm_size_offset;
// size_t dims_axo_pos_offset, dims_axo_size_offset;
if (node->axis == AXIS_X) {
axm_free = dims->width;
axm_size = dims->width;
axo_size = dims->height;
// axo_size = dims->height;
axm_min_offset = offsetof(struct ct_bounds, wmin);
axm_max_offset = offsetof(struct ct_bounds, wmax);
bounds_axm_min_offset = offsetof(struct ct_bounds, wmin);
bounds_axm_max_offset = offsetof(struct ct_bounds, wmax);
dims_axm_pos_offset = offsetof(struct ct_dims, x);
// dims_axo_pos_offset = offsetof(struct ct_dims, y);
dims_axm_size_offset = offsetof(struct ct_dims, width);
// dims_axo_size_offset = offsetof(struct ct_dims, height);
} else {
assert(node->axis == AXIS_Y);
axm_free = dims->height;
axm_size = dims->height;
axo_size = dims->width;
// axo_size = dims->width;
axm_min_offset = offsetof(struct ct_bounds, hmin);
axm_max_offset = offsetof(struct ct_bounds, hmax);
bounds_axm_min_offset = offsetof(struct ct_bounds, hmin);
bounds_axm_max_offset = offsetof(struct ct_bounds, hmax);
dims_axm_pos_offset = offsetof(struct ct_dims, y);
// dims_axo_pos_offset = offsetof(struct ct_dims, x);
dims_axm_size_offset = offsetof(struct ct_dims, height);
// dims_axo_size_offset = offsetof(struct ct_dims, width);
}
int split = axm_free / node->cindex;
for (int j = 0; j < node->cindex; j++) {
cwhdims[j].min = *(int*)(node->child[j]->surface->bounds + axm_min_offset);
cwhdims[j].max = *(int*)(node->child[j]->surface->bounds + axm_max_offset);
if (node->child[j]->surface->bounds->type == BOUND_RELATIVE) {
cwhdims[j].min *= axm_size;
cwhdims[j].max *= axm_size;
struct ct_spdims cspdims[node->cindex];
// struct ct_spdims *parts[node->cindex];
cindex parts_n = node->cindex;
memset(cspdims, 0, sizeof(struct ct_spdims) * node->cindex);
for (int i = 0; i < node->cindex; i++) {
cspdims[i].min = *(int *)(node->child[i]->surface->bounds + bounds_axm_min_offset);
cspdims[i].max = *(int *)(node->child[i]->surface->bounds + bounds_axm_max_offset);
if (node->child[i]->surface->bounds->type == BOUND_RELATIVE) {
cspdims[i].min *= axm_size;
cspdims[i].max *= axm_size;
}
cwhdims[j].axm_size = fmax(fmin(split, cwhdims[j].max), cwhdims[j].min);
cwhdims[j].axo_size = axo_size;
axm_free -= cwhdims[j].axm_size;
cspdims[i].axm_size = 0;
// cspdims[i].axo_size = axo_size;
// parts[i] = &cspdims[i];
}
int delta;
while (axm_free) {
if (axm_free < cunfixedn) {
int progress = 0;
for (int j = 0; j < node->cindex; j++) {
if (cwhdims[j].fixed)
continue;
cwhdims[j].axm_size--;
axm_free--;
}
}
// split is guaranteed to be >0
split = axm_free / node->cindex;
for (int j = 0; j < node->cindex; j++) {
if (cwhdims[j].fixed)
int split, new_size;
while (parts_n) {
split = axm_free / parts_n;
for (int i = 0; i < node->cindex; i++) {
if (cspdims[i].fixed)
continue;
delta = cwhdims[j].axm_size - fmax(cwhdims[j].axm_size - split, bounds->wmin);
if (delta == 0) {
cwhdims[j].fixed = true;
cunfixedn++;
new_size =
clampi(cspdims[i].axm_size + split, cspdims[i].min, cspdims[i].max);
if (new_size == cspdims[i].axm_size) {
cspdims[i].fixed = true;
parts_n--;
continue;
}
cwhdims[j].axm_size -= delta;
axm_free -= delta;
axm_free -= (new_size - cspdims[i].axm_size);
cspdims[i].axm_size = new_size;
}
}
/* TODO: using axo_size this way means cspdims doesn't need an axo field!! */
struct ct_dims * cdims = dup_dims(dims);
/* NOTE: the statements below are done implicitly by dup_dims */
// *(int*)(cdims + dims_axm_pos_offset) = *(int*)(dims + dims_axm_pos_offset);
// *(int*)(cdims + dims_axo_pos_offset) = *(int*)(dims + dims_axo_pos_offset);
// *(int*)(cdims + dims_axo_size_offset) = axo_size;
for (int i = 0; i < node->cindex; i++) {
*(int*)(cdims + dims_axm_size_offset) = cspdims[i].axm_size;
resize_node(node->child[i], dup_dims(cdims));
*(int*)(cdims + dims_axm_pos_offset) += cspdims[i].axm_size;
}
free(cdims);
// int split = axm_free / node->cindex;
// for (int j = 0; j < node->cindex; j++) {
// cwhdims[j].min = *(int*)(node->child[j]->surface->bounds +
// axm_min_offset); cwhdims[j].max = *(int*)(node->child[j]->surface->bounds
// + axm_max_offset); if (node->child[j]->surface->bounds->type ==
// BOUND_RELATIVE) {
// cwhdims[j].min *= axm_size;
// cwhdims[j].max *= axm_size;
// }
// cwhdims[j].axm_size = fmax(fmin(split, cwhdims[j].max), cwhdims[j].min);
// cwhdims[j].axo_size = axo_size;
// axm_free -= cwhdims[j].axm_size;
// }
// int delta;
// while (axm_free) {
// if (axm_free < cunfixedn) {
// int progress = 0;
// for (int j = 0; j < node->cindex; j++) {
// if (cwhdims[j].fixed)
// continue;
// cwhdims[j].axm_size--;
// axm_free--;
// }
// }
// // split is guaranteed to be >0
// split = axm_free / node->cindex;
// for (int j = 0; j < node->cindex; j++) {
// if (cwhdims[j].fixed)
// continue;
// delta = cwhdims[j].axm_size - fmax(cwhdims[j].axm_size - split,
// bounds->wmin); if (delta == 0) {
// cwhdims[j].fixed = true;
// cunfixedn++;
// continue;
// }
// cwhdims[j].axm_size -= delta;
// axm_free -= delta;
// }
// }
// bifurcate_dims(dims, node->axis, node->ratio, &dims0, &dims1);
// resize_node(node->child[0], dims0);