#include "core_widget.hpp" core_widget::core_widget() { clear_all(); } void core_widget::clear_all() { for (int i = 0; i < LIB94_CORE_SIZE; ++i) { if (write_values[i] != 0) to_draw_write.insert(i); write_values[i] = 0; if (read_values[i] != 0) to_draw_read.insert(i); read_values[i] = 0; if (execute_values[i] != 0) to_draw_execute.insert(i); execute_values[i] = 0; } } void core_widget::age_all() { for (int i = 0; i < LIB94_CORE_SIZE; ++i) { if (write_values[i] != 0) { to_draw_write.insert(i); write_values[i] = (uint8_t)((float)write_values[i] * age_scale); } if (read_values[i] != 0) { to_draw_read.insert(i); read_values[i] = (uint8_t)((float)read_values[i] * age_scale); } if (execute_values[i] != 0) { to_draw_execute.insert(i); execute_values[i] = (uint8_t)((float)execute_values[i] * age_scale); } } } void core_widget::add_new_writes(const std::set &writes) { for (lib94::number_t n : writes) { write_values[n] = 255; to_draw_write.insert(n); } } void core_widget::add_new_reads(const std::set &reads) { for (lib94::number_t n : reads) { read_values[n] = 255; to_draw_read.insert(n); } } void core_widget::add_new_executions(const std::set &executions) { for (lib94::number_t n : executions) { execute_values[n] = 255; to_draw_execute.insert(n); } } void core_widget::measure_vfunc(Gtk::Orientation, int for_size, int &minimum, int &natural, int &minimum_baseline, int &natural_baseline) const { minimum = (LIB94_CORE_SIZE - 1) / for_size + 1; natural = (LIB94_CORE_SIZE - 1) / for_size + 1; minimum_baseline = -1; natural_baseline = -1; } void core_widget::draw(int width, int height) { mut.lock(); if (width == last_width && height == last_height) { uint8_t *buffer = (uint8_t *)pixbuf->property_pixels().get_value(); for (lib94::number_t i : to_draw_write) { int cy = i / cpr * scale + ypad; int cx = i % cpr * scale + xpad; for (int dy = 0; dy < scale; ++dy) for (int dx = 0; dx < scale; ++dx) buffer[(cy + dy) * pixbuf->property_rowstride() + (cx + dx) * 4] = write_values[i]; } for (lib94::number_t i : to_draw_read) { int cy = i / cpr * scale + ypad; int cx = i % cpr * scale + xpad; for (int dy = 0; dy < scale; ++dy) for (int dx = 0; dx < scale; ++dx) buffer[(cy + dy) * pixbuf->property_rowstride() + (cx + dx) * 4 + 2] = read_values[i]; } for (lib94::number_t i : to_draw_execute) { int cy = i / cpr * scale + ypad; int cx = i % cpr * scale + xpad; for (int dy = 0; dy < scale; ++dy) for (int dx = 0; dx < scale; ++dx) buffer[(cy + dy) * pixbuf->property_rowstride() + (cx + dx) * 4 + 1] = execute_values[i]; } } else { pixbuf = Gdk::Pixbuf::create(Gdk::Colorspace::RGB, true, 8, width, height); last_width = width; last_height = height; scale = 1; while (true) { ++scale; if ((width / scale) * (height / scale) < LIB94_CORE_SIZE) { --scale; break; } } cpr = width / scale + 1; xpad = INT_MAX; ypad = 0; while (cpr >= 1) { --cpr; int rows = (LIB94_CORE_SIZE - 1) / cpr + 1; int new_xpad = (width - cpr * scale) / 2; int new_ypad = (height - rows * scale) / 2; if (abs(new_xpad - new_ypad) < abs(xpad - ypad)) { xpad = new_xpad; ypad = new_ypad; } else { ++cpr; break; } } uint8_t *buffer = (uint8_t *)pixbuf->property_pixels().get_value(); for (lib94::number_t i = 0; i < LIB94_CORE_SIZE; ++i) { int cy = i / cpr * scale + ypad; int cx = i % cpr * scale + xpad; for (int dy = 0; dy < scale; ++dy) for (int dx = 0; dx < scale; ++dx) { buffer[(cy + dy) * pixbuf->property_rowstride() + (cx + dx) * 4] = write_values[i]; buffer[(cy + dy) * pixbuf->property_rowstride() + (cx + dx) * 4 + 2] = read_values[i]; buffer[(cy + dy) * pixbuf->property_rowstride() + (cx + dx) * 4 + 1] = execute_values[i]; buffer[(cy + dy) * pixbuf->property_rowstride() + (cx + dx) * 4 + 3] = 255; } } } to_draw_write.clear(); to_draw_read.clear(); to_draw_execute.clear(); mut.unlock(); } void core_widget::snapshot_vfunc(const Glib::RefPtr &snapshot) { auto start_time = std::chrono::system_clock::now(); Gtk::Allocation allocation = get_allocation(); Gdk::Rectangle allocation_rect(0, 0, allocation.get_width(), allocation.get_height()); draw(allocation.get_width(), allocation.get_height()); auto texture = Gdk::Texture::create_for_pixbuf(pixbuf); snapshot->append_texture(texture, allocation_rect); auto end_time = std::chrono::system_clock::now(); last_draw_time = end_time - start_time; }