mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-27 02:31:45 +02:00
Same treatment for image and render data arrays
This commit is contained in:
140
kitty/graphics.c
140
kitty/graphics.c
@@ -59,14 +59,21 @@ cache_size(const GraphicsManager *self) { return disk_cache_total_size(self->dis
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
|
||||||
|
static inline id_type
|
||||||
|
next_id(id_type *counter) {
|
||||||
|
id_type ans = ++(*counter);
|
||||||
|
if (UNLIKELY(ans == 0)) ans = ++(*counter);
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
GraphicsManager*
|
GraphicsManager*
|
||||||
grman_alloc(void) {
|
grman_alloc(void) {
|
||||||
GraphicsManager *self = (GraphicsManager *)GraphicsManager_Type.tp_alloc(&GraphicsManager_Type, 0);
|
GraphicsManager *self = (GraphicsManager *)GraphicsManager_Type.tp_alloc(&GraphicsManager_Type, 0);
|
||||||
self->images_capacity = self->capacity = 64;
|
self->images.capacity = self->render_data.capacity = 64;
|
||||||
self->images = calloc(self->images_capacity, sizeof(Image));
|
self->images.img = calloc(self->images.capacity, sizeof(self->images.img[0]));
|
||||||
self->render_data = calloc(self->capacity, sizeof(ImageRenderData));
|
self->render_data.item = calloc(self->render_data.capacity, sizeof(self->render_data.item[0]));
|
||||||
self->storage_limit = DEFAULT_STORAGE_LIMIT;
|
self->storage_limit = DEFAULT_STORAGE_LIMIT;
|
||||||
if (self->images == NULL || self->render_data == NULL) {
|
if (self->images.img == NULL || self->render_data.item == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
Py_CLEAR(self); return NULL;
|
Py_CLEAR(self); return NULL;
|
||||||
}
|
}
|
||||||
@@ -78,7 +85,7 @@ grman_alloc(void) {
|
|||||||
static void
|
static void
|
||||||
free_refs_data(Image *img) {
|
free_refs_data(Image *img) {
|
||||||
free(img->refs.ref);
|
free(img->refs.ref);
|
||||||
memset(&(img->refs), 0, sizeof(img->refs));
|
zero_at_ptr(&(img->refs));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -110,29 +117,27 @@ free_image(GraphicsManager *self, Image *img) {
|
|||||||
static void
|
static void
|
||||||
dealloc(GraphicsManager* self) {
|
dealloc(GraphicsManager* self) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if (self->images) {
|
if (self->images.img) {
|
||||||
for (i = 0; i < self->image_count; i++) free_image(self, self->images + i);
|
for (i = 0; i < self->images.count; i++) free_image(self, self->images.img + i);
|
||||||
free(self->images);
|
free(self->images.img);
|
||||||
}
|
}
|
||||||
free(self->render_data);
|
free(self->render_data.item);
|
||||||
Py_CLEAR(self->disk_cache);
|
Py_CLEAR(self->disk_cache);
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static id_type internal_id_counter = 1;
|
|
||||||
|
|
||||||
static Image*
|
static Image*
|
||||||
img_by_internal_id(GraphicsManager *self, id_type id) {
|
img_by_internal_id(GraphicsManager *self, id_type id) {
|
||||||
for (size_t i = 0; i < self->image_count; i++) {
|
for (size_t i = 0; i < self->images.count; i++) {
|
||||||
if (self->images[i].internal_id == id) return self->images + i;
|
if (self->images.img[i].internal_id == id) return self->images.img + i;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Image*
|
static Image*
|
||||||
img_by_client_id(GraphicsManager *self, uint32_t id) {
|
img_by_client_id(GraphicsManager *self, uint32_t id) {
|
||||||
for (size_t i = 0; i < self->image_count; i++) {
|
for (size_t i = 0; i < self->images.count; i++) {
|
||||||
if (self->images[i].client_id == id) return self->images + i;
|
if (self->images.img[i].client_id == id) return self->images.img + i;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -140,25 +145,24 @@ img_by_client_id(GraphicsManager *self, uint32_t id) {
|
|||||||
static Image*
|
static Image*
|
||||||
img_by_client_number(GraphicsManager *self, uint32_t number) {
|
img_by_client_number(GraphicsManager *self, uint32_t number) {
|
||||||
// get the newest image with the specified number
|
// get the newest image with the specified number
|
||||||
for (size_t i = self->image_count; i-- > 0; ) {
|
for (size_t i = self->images.count; i-- > 0; ) {
|
||||||
if (self->images[i].client_number == number) return self->images + i;
|
if (self->images.img[i].client_number == number) return self->images.img + i;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_image(GraphicsManager *self, size_t idx) {
|
remove_image(GraphicsManager *self, size_t idx) {
|
||||||
assert(idx < self->image_count);
|
assert(idx < self->images.count);
|
||||||
free_image(self, self->images + idx);
|
free_image(self, self->images.img + idx);
|
||||||
remove_i_from_array(self->images, idx, self->image_count);
|
remove_i_from_array(self->images.img, idx, self->images.count);
|
||||||
self->layers_dirty = true;
|
self->layers_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_images(GraphicsManager *self, bool(*predicate)(Image*), id_type skip_image_internal_id) {
|
remove_images(GraphicsManager *self, bool(*predicate)(Image*), id_type skip_image_internal_id) {
|
||||||
for (size_t i = self->image_count; i-- > 0;) {
|
for (size_t i = self->images.count; i-- > 0;) {
|
||||||
Image *img = self->images + i;
|
Image *img = self->images.img + i;
|
||||||
if (img->internal_id != skip_image_internal_id && predicate(img)) {
|
if (img->internal_id != skip_image_internal_id && predicate(img)) {
|
||||||
remove_image(self, i);
|
remove_image(self, i);
|
||||||
}
|
}
|
||||||
@@ -181,12 +185,12 @@ apply_storage_quota(GraphicsManager *self, size_t storage_limit, id_type current
|
|||||||
if (self->used_storage < storage_limit) return;
|
if (self->used_storage < storage_limit) return;
|
||||||
|
|
||||||
#define oldest_last(a, b) ((b)->atime < (a)->atime)
|
#define oldest_last(a, b) ((b)->atime < (a)->atime)
|
||||||
QSORT(Image, self->images, self->image_count, oldest_last)
|
QSORT(Image, self->images.img, self->images.count, oldest_last)
|
||||||
#undef oldest_last
|
#undef oldest_last
|
||||||
while (self->used_storage > storage_limit && self->image_count > 0) {
|
while (self->used_storage > storage_limit && self->images.count > 0) {
|
||||||
remove_image(self, self->image_count - 1);
|
remove_image(self, self->images.count - 1);
|
||||||
}
|
}
|
||||||
if (!self->image_count) self->used_storage = 0; // sanity check
|
if (!self->images.count) self->used_storage = 0; // sanity check
|
||||||
}
|
}
|
||||||
|
|
||||||
static char command_response[512] = {0};
|
static char command_response[512] = {0};
|
||||||
@@ -351,27 +355,28 @@ png_path_to_bitmap(const char* path, uint8_t** data, unsigned int* width, unsign
|
|||||||
static Image*
|
static Image*
|
||||||
find_or_create_image(GraphicsManager *self, uint32_t id, bool *existing) {
|
find_or_create_image(GraphicsManager *self, uint32_t id, bool *existing) {
|
||||||
if (id) {
|
if (id) {
|
||||||
for (size_t i = 0; i < self->image_count; i++) {
|
for (size_t i = 0; i < self->images.count; i++) {
|
||||||
if (self->images[i].client_id == id) {
|
if (self->images.img[i].client_id == id) {
|
||||||
*existing = true;
|
*existing = true;
|
||||||
return self->images + i;
|
return self->images.img + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*existing = false;
|
*existing = false;
|
||||||
ensure_space_for(self, images, Image, self->image_count + 1, images_capacity, 64, true);
|
ensure_space_for(&(self->images), img, Image, self->images.count + 1, capacity, 64, true);
|
||||||
Image *ans = self->images + self->image_count++;
|
Image *ans = self->images.img + self->images.count++;
|
||||||
zero_at_ptr(ans);
|
zero_at_ptr(ans);
|
||||||
|
ans->internal_id = next_id(&self->images.id_counter);
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
get_free_client_id(const GraphicsManager *self) {
|
get_free_client_id(const GraphicsManager *self) {
|
||||||
if (!self->image_count) return 1;
|
if (!self->images.count) return 1;
|
||||||
uint32_t *client_ids = malloc(sizeof(uint32_t) * self->image_count);
|
uint32_t *client_ids = malloc(sizeof(uint32_t) * self->images.count);
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for (size_t i = 0; i < self->image_count; i++) {
|
for (size_t i = 0; i < self->images.count; i++) {
|
||||||
Image *q = self->images + i;
|
Image *q = self->images.img + i;
|
||||||
if (q->client_id) client_ids[count++] = q->client_id;
|
if (q->client_id) client_ids[count++] = q->client_id;
|
||||||
}
|
}
|
||||||
if (!count) { free(client_ids); return 1; }
|
if (!count) { free(client_ids); return 1; }
|
||||||
@@ -577,7 +582,6 @@ handle_add_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_
|
|||||||
*is_dirty = true;
|
*is_dirty = true;
|
||||||
self->layers_dirty = true;
|
self->layers_dirty = true;
|
||||||
} else {
|
} else {
|
||||||
img->internal_id = internal_id_counter++;
|
|
||||||
img->client_id = iid;
|
img->client_id = iid;
|
||||||
img->client_number = g->image_number;
|
img->client_number = g->image_number;
|
||||||
if (!img->client_id && img->client_number) {
|
if (!img->client_id && img->client_number) {
|
||||||
@@ -844,7 +848,7 @@ Image *grman_put_cell_image(GraphicsManager *self, uint32_t screen_row,
|
|||||||
self->layers_dirty = true;
|
self->layers_dirty = true;
|
||||||
ImageRef *real_ref = img->refs.ref + img->refs.count++;
|
ImageRef *real_ref = img->refs.ref + img->refs.count++;
|
||||||
*real_ref = ref;
|
*real_ref = ref;
|
||||||
real_ref->internal_id = ++img->refs.id_counter;
|
real_ref->internal_id = next_id(&img->refs.id_counter);
|
||||||
img->atime = monotonic();
|
img->atime = monotonic();
|
||||||
|
|
||||||
update_src_rect(real_ref, img);
|
update_src_rect(real_ref, img);
|
||||||
@@ -875,7 +879,7 @@ handle_put_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c, b
|
|||||||
if (ref == NULL) {
|
if (ref == NULL) {
|
||||||
ref = img->refs.ref + img->refs.count++;
|
ref = img->refs.ref + img->refs.count++;
|
||||||
zero_at_ptr(ref);
|
zero_at_ptr(ref);
|
||||||
ref->internal_id = ++img->refs.id_counter;
|
ref->internal_id = next_id(&img->refs.id_counter);
|
||||||
}
|
}
|
||||||
img->atime = monotonic();
|
img->atime = monotonic();
|
||||||
ref->src_x = g->x_offset; ref->src_y = g->y_offset; ref->src_width = g->width ? g->width : img->width; ref->src_height = g->height ? g->height : img->height;
|
ref->src_x = g->x_offset; ref->src_y = g->y_offset; ref->src_width = g->width ? g->width : img->width; ref->src_height = g->height ? g->height : img->height;
|
||||||
@@ -939,9 +943,9 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree
|
|||||||
float y0 = screen_top - dy * scrolled_by;
|
float y0 = screen_top - dy * scrolled_by;
|
||||||
|
|
||||||
// Iterate over all visible refs and create render data
|
// Iterate over all visible refs and create render data
|
||||||
self->count = 0;
|
self->render_data.count = 0;
|
||||||
for (i = 0; i < self->image_count; i++) {
|
for (i = 0; i < self->images.count; i++) {
|
||||||
img = self->images + i;
|
img = self->images.img + i;
|
||||||
bool was_drawn = img->is_drawn;
|
bool was_drawn = img->is_drawn;
|
||||||
img->is_drawn = false;
|
img->is_drawn = false;
|
||||||
|
|
||||||
@@ -962,11 +966,11 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree
|
|||||||
self->num_of_negative_refs++;
|
self->num_of_negative_refs++;
|
||||||
else
|
else
|
||||||
self->num_of_positive_refs++;
|
self->num_of_positive_refs++;
|
||||||
ensure_space_for(self, render_data, ImageRenderData, self->count + 1, capacity, 64, true);
|
ensure_space_for(&(self->render_data), item, ImageRenderData, self->render_data.count + 1, capacity, 64, true);
|
||||||
ImageRenderData *rd = self->render_data + self->count;
|
ImageRenderData *rd = self->render_data.item + self->render_data.count;
|
||||||
zero_at_ptr(rd);
|
zero_at_ptr(rd);
|
||||||
rd->dest_rect = r; rd->src_rect = ref->src_rect;
|
rd->dest_rect = r; rd->src_rect = ref->src_rect;
|
||||||
self->count++;
|
self->render_data.count++;
|
||||||
rd->z_index = ref->z_index; rd->image_id = img->internal_id;
|
rd->z_index = ref->z_index; rd->image_id = img->internal_id;
|
||||||
rd->texture_id = img->texture_id;
|
rd->texture_id = img->texture_id;
|
||||||
img->is_drawn = true;
|
img->is_drawn = true;
|
||||||
@@ -976,21 +980,21 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree
|
|||||||
global_state.check_for_active_animated_images = true;
|
global_state.check_for_active_animated_images = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!self->count) return false;
|
if (!self->render_data.count) return false;
|
||||||
// Sort visible refs in draw order (z-index, img)
|
// Sort visible refs in draw order (z-index, img)
|
||||||
#define lt(a, b) ( (a)->z_index < (b)->z_index || ((a)->z_index == (b)->z_index && (a)->image_id < (b)->image_id) )
|
#define lt(a, b) ( (a)->z_index < (b)->z_index || ((a)->z_index == (b)->z_index && (a)->image_id < (b)->image_id) )
|
||||||
QSORT(ImageRenderData, self->render_data, self->count, lt);
|
QSORT(ImageRenderData, self->render_data.item, self->render_data.count, lt);
|
||||||
#undef lt
|
#undef lt
|
||||||
// Calculate the group counts
|
// Calculate the group counts
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < self->count) {
|
while (i < self->render_data.count) {
|
||||||
id_type num_identical = 1, image_id = self->render_data[i].image_id, start = i;
|
id_type num_identical = 1, image_id = self->render_data.item[i].image_id, start = i;
|
||||||
while (++i < self->count) {
|
while (++i < self->render_data.count) {
|
||||||
if (self->render_data[i].image_id != image_id) break;
|
if (self->render_data.item[i].image_id != image_id) break;
|
||||||
num_identical++;
|
num_identical++;
|
||||||
}
|
}
|
||||||
while (num_identical > 0) {
|
while (num_identical > 0) {
|
||||||
self->render_data[start++].group_count = num_identical--;
|
self->render_data.item[start++].group_count = num_identical--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -1467,8 +1471,8 @@ scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t
|
|||||||
if (!self->has_images_needing_animation) return dirtied;
|
if (!self->has_images_needing_animation) return dirtied;
|
||||||
self->has_images_needing_animation = false;
|
self->has_images_needing_animation = false;
|
||||||
self->context_made_current_for_this_command = os_window_context_set;
|
self->context_made_current_for_this_command = os_window_context_set;
|
||||||
for (size_t i = self->image_count; i-- > 0;) {
|
for (size_t i = self->images.count; i-- > 0;) {
|
||||||
Image *img = self->images + i;
|
Image *img = self->images.img + i;
|
||||||
if (image_is_animatable(img)) {
|
if (image_is_animatable(img)) {
|
||||||
Frame *f = current_frame(img);
|
Frame *f = current_frame(img);
|
||||||
if (f) {
|
if (f) {
|
||||||
@@ -1570,8 +1574,8 @@ handle_compose_command(GraphicsManager *self, bool *is_dirty, const GraphicsComm
|
|||||||
static void
|
static void
|
||||||
filter_refs(GraphicsManager *self, const void* data, bool free_images, bool (*filter_func)(const ImageRef*, Image*, const void*, CellPixelSize), CellPixelSize cell, bool only_first_image) {
|
filter_refs(GraphicsManager *self, const void* data, bool free_images, bool (*filter_func)(const ImageRef*, Image*, const void*, CellPixelSize), CellPixelSize cell, bool only_first_image) {
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (size_t i = self->image_count; i-- > 0;) {
|
for (size_t i = self->images.count; i-- > 0;) {
|
||||||
Image *img = self->images + i;
|
Image *img = self->images.img + i;
|
||||||
for (size_t j = img->refs.count; j-- > 0;) {
|
for (size_t j = img->refs.count; j-- > 0;) {
|
||||||
ImageRef *ref = img->refs.ref + j;
|
ImageRef *ref = img->refs.ref + j;
|
||||||
if (filter_func(ref, img, data, cell)) {
|
if (filter_func(ref, img, data, cell)) {
|
||||||
@@ -1588,8 +1592,8 @@ filter_refs(GraphicsManager *self, const void* data, bool free_images, bool (*fi
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
modify_refs(GraphicsManager *self, const void* data, bool (*filter_func)(ImageRef*, Image*, const void*, CellPixelSize), CellPixelSize cell) {
|
modify_refs(GraphicsManager *self, const void* data, bool (*filter_func)(ImageRef*, Image*, const void*, CellPixelSize), CellPixelSize cell) {
|
||||||
for (size_t i = self->image_count; i-- > 0;) {
|
for (size_t i = self->images.count; i-- > 0;) {
|
||||||
Image *img = self->images + i;
|
Image *img = self->images.img + i;
|
||||||
for (size_t j = img->refs.count; j-- > 0;) {
|
for (size_t j = img->refs.count; j-- > 0;) {
|
||||||
if (filter_func(img->refs.ref + j, img, data, cell)) remove_i_from_array(img->refs.ref, j, img->refs.count);
|
if (filter_func(img->refs.ref + j, img, data, cell)) remove_i_from_array(img->refs.ref, j, img->refs.count);
|
||||||
}
|
}
|
||||||
@@ -1654,7 +1658,7 @@ scroll_filter_margins_func(ImageRef* ref, Image* img, const void* data, CellPixe
|
|||||||
|
|
||||||
void
|
void
|
||||||
grman_scroll_images(GraphicsManager *self, const ScrollData *data, CellPixelSize cell) {
|
grman_scroll_images(GraphicsManager *self, const ScrollData *data, CellPixelSize cell) {
|
||||||
if (self->image_count) {
|
if (self->images.count) {
|
||||||
self->layers_dirty = true;
|
self->layers_dirty = true;
|
||||||
modify_refs(self, data, data->has_margins ? scroll_filter_margins_func : scroll_filter_func, cell);
|
modify_refs(self, data, data->has_margins ? scroll_filter_margins_func : scroll_filter_func, cell);
|
||||||
}
|
}
|
||||||
@@ -1800,7 +1804,7 @@ handle_delete_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c
|
|||||||
#undef D
|
#undef D
|
||||||
#undef I
|
#undef I
|
||||||
}
|
}
|
||||||
if (!self->image_count && self->count) self->count = 0;
|
if (!self->images.count && self->render_data.count) self->render_data.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
@@ -1811,8 +1815,8 @@ grman_resize(GraphicsManager *self, index_type old_lines UNUSED, index_type line
|
|||||||
self->layers_dirty = true;
|
self->layers_dirty = true;
|
||||||
if (columns == old_columns && num_content_lines_before > num_content_lines_after) {
|
if (columns == old_columns && num_content_lines_before > num_content_lines_after) {
|
||||||
const unsigned int vertical_shrink_size = num_content_lines_before - num_content_lines_after;
|
const unsigned int vertical_shrink_size = num_content_lines_before - num_content_lines_after;
|
||||||
for (size_t i = self->image_count; i-- > 0;) {
|
for (size_t i = self->images.count; i-- > 0;) {
|
||||||
img = self->images + i;
|
img = self->images.img + i;
|
||||||
for (size_t j = img->refs.count; j-- > 0;) {
|
for (size_t j = img->refs.count; j-- > 0;) {
|
||||||
ref = img->refs.ref + j;
|
ref = img->refs.ref + j;
|
||||||
if (ref->is_virtual_ref || ref->is_cell_image) continue;
|
if (ref->is_virtual_ref || ref->is_cell_image) continue;
|
||||||
@@ -1826,8 +1830,8 @@ void
|
|||||||
grman_rescale(GraphicsManager *self, CellPixelSize cell) {
|
grman_rescale(GraphicsManager *self, CellPixelSize cell) {
|
||||||
ImageRef *ref; Image *img;
|
ImageRef *ref; Image *img;
|
||||||
self->layers_dirty = true;
|
self->layers_dirty = true;
|
||||||
for (size_t i = self->image_count; i-- > 0;) {
|
for (size_t i = self->images.count; i-- > 0;) {
|
||||||
img = self->images + i;
|
img = self->images.img + i;
|
||||||
for (size_t j = img->refs.count; j-- > 0;) {
|
for (size_t j = img->refs.count; j-- > 0;) {
|
||||||
ref = img->refs.ref + j;
|
ref = img->refs.ref + j;
|
||||||
if (ref->is_virtual_ref || ref->is_cell_image) continue;
|
if (ref->is_virtual_ref || ref->is_cell_image) continue;
|
||||||
@@ -2020,9 +2024,9 @@ W(update_layers) {
|
|||||||
CellPixelSize cell;
|
CellPixelSize cell;
|
||||||
PA("IffffIIII", &scrolled_by, &xstart, &ystart, &dx, &dy, &sx, &sy, &cell.width, &cell.height);
|
PA("IffffIIII", &scrolled_by, &xstart, &ystart, &dx, &dy, &sx, &sy, &cell.width, &cell.height);
|
||||||
grman_update_layers(self, scrolled_by, xstart, ystart, dx, dy, sx, sy, cell);
|
grman_update_layers(self, scrolled_by, xstart, ystart, dx, dy, sx, sy, cell);
|
||||||
PyObject *ans = PyTuple_New(self->count);
|
PyObject *ans = PyTuple_New(self->render_data.count);
|
||||||
for (size_t i = 0; i < self->count; i++) {
|
for (size_t i = 0; i < self->render_data.count; i++) {
|
||||||
ImageRenderData *r = self->render_data + i;
|
ImageRenderData *r = self->render_data.item + i;
|
||||||
#define R(which) Py_BuildValue("{sf sf sf sf}", "left", r->which.left, "top", r->which.top, "right", r->which.right, "bottom", r->which.bottom)
|
#define R(which) Py_BuildValue("{sf sf sf sf}", "left", r->which.left, "top", r->which.top, "right", r->which.right, "bottom", r->which.bottom)
|
||||||
PyTuple_SET_ITEM(ans, i,
|
PyTuple_SET_ITEM(ans, i,
|
||||||
Py_BuildValue("{sN sN sI si sK}", "src_rect", R(src_rect), "dest_rect", R(dest_rect), "group_count", r->group_count, "z_index", r->z_index, "image_id", r->image_id)
|
Py_BuildValue("{sN sN sI si sK}", "src_rect", R(src_rect), "dest_rect", R(dest_rect), "group_count", r->group_count, "z_index", r->z_index, "image_id", r->image_id)
|
||||||
@@ -2042,7 +2046,7 @@ static PyMethodDef methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static PyMemberDef members[] = {
|
static PyMemberDef members[] = {
|
||||||
{"image_count", T_PYSSIZET, offsetof(GraphicsManager, image_count), READONLY, "image_count"},
|
{"image_count", T_PYSSIZET, offsetof(GraphicsManager, images), READONLY, "image_count"},
|
||||||
{"storage_limit", T_PYSSIZET, offsetof(GraphicsManager, storage_limit), 0, "storage_limit"},
|
{"storage_limit", T_PYSSIZET, offsetof(GraphicsManager, storage_limit), 0, "storage_limit"},
|
||||||
{"disk_cache", T_OBJECT_EX, offsetof(GraphicsManager, disk_cache), READONLY, "disk_cache"},
|
{"disk_cache", T_OBJECT_EX, offsetof(GraphicsManager, disk_cache), READONLY, "disk_cache"},
|
||||||
{NULL},
|
{NULL},
|
||||||
|
|||||||
@@ -111,11 +111,17 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
size_t image_count, images_capacity, storage_limit;
|
size_t storage_limit;
|
||||||
LoadData currently_loading;
|
LoadData currently_loading;
|
||||||
Image *images;
|
struct {
|
||||||
size_t count, capacity;
|
size_t count, capacity;
|
||||||
ImageRenderData *render_data;
|
Image *img;
|
||||||
|
id_type id_counter;
|
||||||
|
} images;
|
||||||
|
struct {
|
||||||
|
size_t count, capacity;
|
||||||
|
ImageRenderData *item;
|
||||||
|
} render_data;
|
||||||
bool layers_dirty;
|
bool layers_dirty;
|
||||||
// The number of images below MIN_ZINDEX / 2, then the number of refs between MIN_ZINDEX / 2 and -1 inclusive, then the number of refs above 0 inclusive.
|
// The number of images below MIN_ZINDEX / 2, then the number of refs between MIN_ZINDEX / 2 and -1 inclusive, then the number of refs above 0 inclusive.
|
||||||
size_t num_of_below_refs, num_of_negative_refs, num_of_positive_refs;
|
size_t num_of_below_refs, num_of_negative_refs, num_of_positive_refs;
|
||||||
|
|||||||
@@ -543,11 +543,11 @@ static void
|
|||||||
draw_cells_simple(ssize_t vao_idx, Screen *screen, const CellRenderData *crd, bool is_semi_transparent) {
|
draw_cells_simple(ssize_t vao_idx, Screen *screen, const CellRenderData *crd, bool is_semi_transparent) {
|
||||||
bind_program(CELL_PROGRAM);
|
bind_program(CELL_PROGRAM);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
if (screen->grman->count) {
|
if (screen->grman->render_data.count) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
int program = GRAPHICS_PROGRAM;
|
int program = GRAPHICS_PROGRAM;
|
||||||
if (is_semi_transparent) { BLEND_PREMULT; program = GRAPHICS_PREMULT_PROGRAM; } else { BLEND_ONTO_OPAQUE; }
|
if (is_semi_transparent) { BLEND_PREMULT; program = GRAPHICS_PREMULT_PROGRAM; } else { BLEND_ONTO_OPAQUE; }
|
||||||
draw_graphics(program, vao_idx, screen->grman->render_data, 0, screen->grman->count, viewport_for_cells(crd));
|
draw_graphics(program, vao_idx, screen->grman->render_data.item, 0, screen->grman->render_data.count, viewport_for_cells(crd));
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -790,14 +790,14 @@ draw_cells_interleaved(ssize_t vao_idx, Screen *screen, OSWindow *w, const CellR
|
|||||||
BLEND_ONTO_OPAQUE;
|
BLEND_ONTO_OPAQUE;
|
||||||
}
|
}
|
||||||
if (screen->grman->num_of_below_refs) draw_graphics(
|
if (screen->grman->num_of_below_refs) draw_graphics(
|
||||||
GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data, 0, screen->grman->num_of_below_refs, viewport_for_cells(crd));
|
GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data.item, 0, screen->grman->num_of_below_refs, viewport_for_cells(crd));
|
||||||
bind_program(CELL_BG_PROGRAM);
|
bind_program(CELL_BG_PROGRAM);
|
||||||
// draw background for non-default bg cells
|
// draw background for non-default bg cells
|
||||||
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screen->grman->num_of_negative_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data, screen->grman->num_of_below_refs, screen->grman->num_of_negative_refs, viewport_for_cells(crd));
|
if (screen->grman->num_of_negative_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_below_refs, screen->grman->num_of_negative_refs, viewport_for_cells(crd));
|
||||||
|
|
||||||
bind_program(CELL_SPECIAL_PROGRAM);
|
bind_program(CELL_SPECIAL_PROGRAM);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
@@ -807,7 +807,7 @@ draw_cells_interleaved(ssize_t vao_idx, Screen *screen, OSWindow *w, const CellR
|
|||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
BLEND_ONTO_OPAQUE;
|
BLEND_ONTO_OPAQUE;
|
||||||
|
|
||||||
if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data, screen->grman->num_of_negative_refs + screen->grman->num_of_below_refs, screen->grman->num_of_positive_refs, viewport_for_cells(crd));
|
if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_negative_refs + screen->grman->num_of_below_refs, screen->grman->num_of_positive_refs, viewport_for_cells(crd));
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
@@ -834,7 +834,7 @@ draw_cells_interleaved_premult(ssize_t vao_idx, Screen *screen, OSWindow *os_win
|
|||||||
BLEND_PREMULT;
|
BLEND_PREMULT;
|
||||||
}
|
}
|
||||||
if (screen->grman->num_of_below_refs) draw_graphics(
|
if (screen->grman->num_of_below_refs) draw_graphics(
|
||||||
GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data, 0, screen->grman->num_of_below_refs, viewport_for_cells(crd));
|
GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data.item, 0, screen->grman->num_of_below_refs, viewport_for_cells(crd));
|
||||||
bind_program(CELL_BG_PROGRAM);
|
bind_program(CELL_BG_PROGRAM);
|
||||||
// Draw background for non-default bg cells
|
// Draw background for non-default bg cells
|
||||||
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
||||||
@@ -846,7 +846,7 @@ draw_cells_interleaved_premult(ssize_t vao_idx, Screen *screen, OSWindow *os_win
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (screen->grman->num_of_negative_refs) {
|
if (screen->grman->num_of_negative_refs) {
|
||||||
draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data, screen->grman->num_of_below_refs, screen->grman->num_of_negative_refs, viewport_for_cells(crd));
|
draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_below_refs, screen->grman->num_of_negative_refs, viewport_for_cells(crd));
|
||||||
}
|
}
|
||||||
|
|
||||||
bind_program(CELL_SPECIAL_PROGRAM);
|
bind_program(CELL_SPECIAL_PROGRAM);
|
||||||
@@ -855,7 +855,7 @@ draw_cells_interleaved_premult(ssize_t vao_idx, Screen *screen, OSWindow *os_win
|
|||||||
bind_program(CELL_FG_PROGRAM);
|
bind_program(CELL_FG_PROGRAM);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
|
|
||||||
if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data, screen->grman->num_of_negative_refs + screen->grman->num_of_below_refs, screen->grman->num_of_positive_refs, viewport_for_cells(crd));
|
if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_negative_refs + screen->grman->num_of_below_refs, screen->grman->num_of_positive_refs, viewport_for_cells(crd));
|
||||||
|
|
||||||
if (!has_bgimage(os_window)) glDisable(GL_BLEND);
|
if (!has_bgimage(os_window)) glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
@@ -938,12 +938,12 @@ draw_cells(ssize_t vao_idx, const ScreenRenderData *srd, OSWindow *os_window, bo
|
|||||||
set_on_gpu_state(window->window_logo.instance, true);
|
set_on_gpu_state(window->window_logo.instance, true);
|
||||||
} else wl = NULL;
|
} else wl = NULL;
|
||||||
ImageRenderData *previous_graphics_render_data = NULL;
|
ImageRenderData *previous_graphics_render_data = NULL;
|
||||||
if (os_window->live_resize.in_progress && screen->grman->count && (crd.x_ratio != 1 || crd.y_ratio != 1)) {
|
if (os_window->live_resize.in_progress && screen->grman->render_data.count && (crd.x_ratio != 1 || crd.y_ratio != 1)) {
|
||||||
previous_graphics_render_data = malloc(sizeof(previous_graphics_render_data[0]) * screen->grman->capacity);
|
previous_graphics_render_data = malloc(sizeof(previous_graphics_render_data[0]) * screen->grman->render_data.capacity);
|
||||||
if (previous_graphics_render_data) {
|
if (previous_graphics_render_data) {
|
||||||
memcpy(previous_graphics_render_data, screen->grman->render_data, sizeof(previous_graphics_render_data[0]) * screen->grman->count);
|
memcpy(previous_graphics_render_data, screen->grman->render_data.item, sizeof(previous_graphics_render_data[0]) * screen->grman->render_data.count);
|
||||||
for (size_t i = 0; i < screen->grman->count; i++)
|
for (size_t i = 0; i < screen->grman->render_data.count; i++)
|
||||||
scale_rendered_graphic(screen->grman->render_data + i, srd->xstart, srd->ystart, crd.x_ratio, crd.y_ratio);
|
scale_rendered_graphic(screen->grman->render_data.item + i, srd->xstart, srd->ystart, crd.x_ratio, crd.y_ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
has_underlying_image |= screen->grman->num_of_below_refs > 0 || screen->grman->num_of_negative_refs > 0;
|
has_underlying_image |= screen->grman->num_of_below_refs > 0 || screen->grman->num_of_negative_refs > 0;
|
||||||
@@ -963,8 +963,8 @@ draw_cells(ssize_t vao_idx, const ScreenRenderData *srd, OSWindow *os_window, bo
|
|||||||
if (window && screen->display_window_char) draw_window_number(os_window, screen, &crd, window);
|
if (window && screen->display_window_char) draw_window_number(os_window, screen, &crd, window);
|
||||||
if (OPT(show_hyperlink_targets) && window && screen->current_hyperlink_under_mouse.id && !is_mouse_hidden(os_window)) draw_hyperlink_target(os_window, screen, &crd, window);
|
if (OPT(show_hyperlink_targets) && window && screen->current_hyperlink_under_mouse.id && !is_mouse_hidden(os_window)) draw_hyperlink_target(os_window, screen, &crd, window);
|
||||||
if (previous_graphics_render_data) {
|
if (previous_graphics_render_data) {
|
||||||
free(screen->grman->render_data);
|
free(screen->grman->render_data.item);
|
||||||
screen->grman->render_data = previous_graphics_render_data;
|
screen->grman->render_data.item = previous_graphics_render_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|||||||
Reference in New Issue
Block a user