Introduce Global Font Memory allocator

This commit is contained in:
jaby 2023-12-20 12:02:15 -05:00
parent 746a2577c0
commit d7fce900f9
6 changed files with 88 additions and 56 deletions

View File

@ -8,7 +8,7 @@ using JabyEngine::Make::PositionI8;
static constexpr auto FontWriterTIM = JabyEngine::SimpleTIM(320, 0, 320, JabyEngine::DefaultFont::Info.texture_size.height);
static JabyEngine::FontPrimitive font_buffer[2][256];
static JabyEngine::FontPrimitive font_buffer[2*256];
static JabyEngine::Wiggle wiggle = {PositionI8(0, 0), PositionI8(1, -2), PositionI8(0, -4), PositionI8(-1, -2), PositionI8(0, 0), PositionI8(1, 2), PositionI8(0, 4), PositionI8(-1, 2)};
static JabyEngine::FontWriter new_font_writer = JabyEngine::FontWriter::empty();
static JabyEngine::SimpleTimer<uint8_t> timer;
@ -16,7 +16,9 @@ static uint8_t wiggle_count = 0;
void font_writer_setup() {
JabyEngine::DefaultFont::load(&__heap_start, FontWriterTIM);
new_font_writer.setup(JabyEngine::FontBufferInfo::from(font_buffer), FontWriterTIM, JabyEngine::DefaultFont::Info);
JabyEngine::GlobalFontPrimitivePool::setup(font_buffer);
new_font_writer.setup(FontWriterTIM, JabyEngine::DefaultFont::Info);
timer.reset();
}

View File

@ -20,20 +20,6 @@ namespace JabyEngine {
}
};
struct FontBufferInfo {
FontPrimitive* double_buffer[2];
size_t single_buffer_length;
static constexpr FontBufferInfo empty() {
return FontBufferInfo{.double_buffer = {nullptr, nullptr}, .single_buffer_length = 0};
}
template<size_t N>
static constexpr FontBufferInfo from(FontPrimitive (&buffer)[2][N]) {
return FontBufferInfo{.double_buffer = {buffer[0], buffer[1]}, .single_buffer_length = N};
}
};
using Wiggle = GPU::PositionI8[8];
/*struct Wiggle {

View File

@ -11,24 +11,26 @@ namespace JabyEngine {
FontWriter::write(state, str, color, wiggle, list); \
va_end(list)
FontBufferInfo prim_buffer;
GPU::TexPage::Linked tex_page;
FontPrimitive* cur_primitive;
GPU::SizeI16 font_size;
GPU::PageClut clut;
GPU::Link* last_primitive;
void setup(const FontBufferInfo& buffer_info, const SimpleTIM& vram_dst, const GPU::SizeI16& font_size);
void setup(const SimpleTIM& vram_dst, const GPU::SizeI16& font_size);
public:
static constexpr FontWriter empty() {
FontWriter instance;
instance.prim_buffer = FontBufferInfo::empty();
instance.tex_page = {0};
instance.cur_primitive = nullptr;
instance.tex_page = {0};
instance.font_size = Make::SizeI16();
instance.clut = Make::PageClut();
instance.last_primitive = nullptr;
return instance;
}
void setup(const FontBufferInfo& buffer_info, const SimpleTIM& vram_dst, const FontInfo& font_info) {
FontWriter::setup(buffer_info, vram_dst, Make::SizeI16(font_info.font_size.width, font_info.font_size.height));
void setup(const SimpleTIM& vram_dst, const FontInfo& font_info) {
FontWriter::setup(vram_dst, Make::SizeI16(font_info.font_size.width, font_info.font_size.height));
}
void write(State& state, const char* str, ...) {
@ -45,4 +47,13 @@ namespace JabyEngine {
#undef __write_impl
};
struct GlobalFontPrimitivePool {
static void setup(FontPrimitive* start, size_t length);
template<size_t Size>
static void setup(FontPrimitive (&buffer)[Size]) {
GlobalFontPrimitivePool::setup(buffer, Size);
}
};
}

View File

@ -1,3 +1,4 @@
#include "include/global_primitive_buffer.hpp"
#include <PSX/GPU/gpu.hpp>
#include <PSX/GPU/make_gpu_primitives.hpp>
#include <FontWriter/font_writer.hpp>
@ -46,19 +47,11 @@ namespace JabyEngine {
return &buffer[BufferStartID];
}
void FontWriter :: setup(const FontBufferInfo& buffer_info, const SimpleTIM& vram_dst, const GPU::SizeI16& font_size) {
this->prim_buffer = buffer_info;
this->tex_page = Make::TexPage(vram_dst.get_texture_position(), GPU::TexturePageColor::$4bit).linked();
this->cur_primitive = buffer_info.double_buffer[GPU::Display::current_id];
for(size_t buffer_id = 0; buffer_id < 2; buffer_id++) {
for(size_t buffer_element_id = 0; buffer_element_id < buffer_info.single_buffer_length; buffer_element_id++) {
this->prim_buffer.double_buffer[buffer_id][buffer_element_id] = Make::SPRT(
Make::AreaI16(Make::PositionI16(0, 0), font_size),
Make::OffsetPageWithClut(Make::PageOffset(0, 0), Make::PageClut(vram_dst.get_clut_position()))
).linked();
}
}
void FontWriter :: setup(const SimpleTIM& vram_dst, const GPU::SizeI16& font_size) {
this->tex_page = Make::TexPage(vram_dst.get_texture_position(), GPU::TexturePageColor::$4bit).linked();
this->font_size = font_size;
this->clut = Make::PageClut(vram_dst.get_clut_position());
this->last_primitive = &this->tex_page;
}
void FontWriter :: write(State& state, const char* str, GPU::Color24 color, Wiggle* wiggle, va_list list) {
@ -66,23 +59,24 @@ namespace JabyEngine {
return {str + 1, new_str};
};
const auto* primitive_end = &this->prim_buffer.double_buffer[GPU::Display::current_id][this->prim_buffer.single_buffer_length];
const auto font_size = this->prim_buffer.double_buffer[0][0]->size;
const auto row_count = 256/font_size.width;
const auto push_char = [&](State& state, FontPrimitive& primitive, char cur_char) -> bool {
if(&primitive >= primitive_end) {
return false;
}
const auto row_count = 256/font_size.width;
const auto push_char = [&](State& state, char cur_char) -> bool {
auto& primitive = GlobalPrimitiveFactory.new_primitive();
primitive->position = state.pos;
primitive->size = this->font_size;
if(wiggle) {
const auto [off_x, off_y] = (*wiggle)[(state.wiggle_count++)&0x7];
primitive->position.move(off_x, off_y);
}
primitive->tex_offset = GPU::PageOffset::from_tile_id(cur_char - '!', row_count, font_size);
primitive->clut = this->clut;
primitive->color = color;
primitive.concat(*this->cur_primitive);
state.pos.move(primitive->size.width, 0);
this->last_primitive->concat(primitive);
this->last_primitive = &primitive;
state.pos.move(this->font_size.width, 0);
return true;
};
const auto old_x = state.pos.x;
@ -129,8 +123,7 @@ namespace JabyEngine {
}
default:
auto& primitive = *this->cur_primitive++;
if(!push_char(state, primitive, cur_char)) {
if(!push_char(state, cur_char)) {
return;
}
}
@ -141,14 +134,9 @@ namespace JabyEngine {
const auto update_id = GPU::Display::current_id;
const auto render_id = update_id ^ 1;
this->cur_primitive -= 1;
if(this->cur_primitive >= this->prim_buffer.double_buffer[render_id]) {
this->cur_primitive->terminate();
this->tex_page.concat(*this->prim_buffer.double_buffer[render_id]);
this->last_primitive->terminate();
this->last_primitive = &this->tex_page;
GPU::render(this->tex_page);
}
this->cur_primitive = this->prim_buffer.double_buffer[update_id];
GPU::render(this->tex_page);
}
}

View File

@ -0,0 +1,16 @@
#include "include/global_primitive_buffer.hpp"
#include <FontWriter/font_writer.hpp>
namespace JabyEngine {
PrimitiveFactory GlobalPrimitiveFactory = PrimitiveFactory::empty();
void GlobalFontPrimitivePool :: setup(FontPrimitive* start, size_t length) {
const auto*const buffer_end = start + length;
for(auto* cur_prim = start; cur_prim < buffer_end; cur_prim++) {
*cur_prim = FontPrimitive::create(GPU::SPRT::create(Make::AreaI16(), Make::OffsetPageWithClut()));
}
GlobalPrimitiveFactory = PrimitiveFactory::create(start, length);
}
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <FontWriter/Type/types.hpp>
namespace JabyEngine {
struct PrimitiveFactory {
FontPrimitive* start_adr;
FontPrimitive* end_adr;
FontPrimitive* cur_element;
static constexpr PrimitiveFactory empty() {
return PrimitiveFactory{.start_adr = nullptr, .end_adr = nullptr, .cur_element = nullptr};
}
static constexpr PrimitiveFactory create(FontPrimitive* start, size_t length) {
return PrimitiveFactory{.start_adr = start, .end_adr = start + length, .cur_element = start};
}
FontPrimitive& new_primitive() {
auto& new_primitive = *this->cur_element++;
if(this->cur_element == this->end_adr) {
this->cur_element = this->start_adr;
}
return new_primitive;
}
};
extern PrimitiveFactory GlobalPrimitiveFactory;
}