taisei/src/renderer/common/state.c
2024-05-17 14:11:48 +02:00

146 lines
2.7 KiB
C

/*
* This software is licensed under the terms of the MIT License.
* See COPYING for further information.
* ---
* Copyright (c) 2011-2024, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2024, Andrei Alexeyev <akari@taisei-project.org>.
*/
#include "state.h"
#include "backend.h"
#define RSTATE_STACK_SIZE 16
static struct {
RendererStateRollback *head;
RendererStateRollback stack[RSTATE_STACK_SIZE];
} _r_state;
void _r_state_init(void) {
memset(&_r_state, 0, sizeof(_r_state));
}
void _r_state_shutdown(void) {
}
#define S (*_r_state.head)
#define B (_r_backend.funcs)
#define TAINT(db, code) do {\
if(_r_state.head && !(S.dirty_bits & (db))) { \
S.dirty_bits |= (db); \
do { code } while(0); \
} \
} while(0);
// #define RESTORE(db) if(S.dirty_bits & (db)) log_debug(#db); if(S.dirty_bits & (db))
#define RESTORE(db) if(S.dirty_bits & (db))
void r_state_push(void) {
if(_r_state.head) {
assert(_r_state.head < _r_state.stack + RSTATE_STACK_SIZE - 1);
_r_state.head++;
} else {
_r_state.head = _r_state.stack;
}
// memset(_r_state.head, 0, sizeof(*_r_state.head));
_r_state.head->dirty_bits = 0;
}
void r_state_pop(void) {
assert(_r_state.head >= _r_state.stack);
RESTORE(RSTATE_CAPABILITIES) {
B.capabilities(S.capabilities);
}
RESTORE(RSTATE_COLOR) {
B.color4(S.color.r, S.color.g, S.color.b, S.color.a);
}
RESTORE(RSTATE_BLENDMODE) {
B.blend(S.blend_mode);
}
RESTORE(RSTATE_CULLMODE) {
B.cull(S.cull_mode);
}
RESTORE(RSTATE_DEPTHFUNC) {
B.depth_func(S.depth_func);
}
RESTORE(RSTATE_SHADER) {
B.shader(S.shader);
}
RESTORE(RSTATE_SHADER_UNIFORMS) {
// TODO
}
RESTORE(RSTATE_RENDERTARGET) {
B.framebuffer(S.framebuffer);
}
RESTORE(RSTATE_SCISSOR) {
B.scissor(S.scissor);
}
if(_r_state.head == _r_state.stack) {
_r_state.head = NULL;
} else {
_r_state.head--;
}
}
void _r_state_touch_capabilities(void) {
TAINT(RSTATE_CAPABILITIES, {
S.capabilities = B.capabilities_current();
});
}
void _r_state_touch_color(void) {
TAINT(RSTATE_COLOR, {
S.color = *B.color_current();
});
}
void _r_state_touch_blend_mode(void) {
TAINT(RSTATE_BLENDMODE, {
S.blend_mode = B.blend_current();
});
}
void _r_state_touch_cull_mode(void) {
TAINT(RSTATE_CULLMODE, {
S.cull_mode = B.cull_current();
});
}
void _r_state_touch_depth_func(void) {
TAINT(RSTATE_DEPTHFUNC, {
S.depth_func = B.depth_func_current();
});
}
void _r_state_touch_shader(void) {
TAINT(RSTATE_SHADER, {
S.shader = B.shader_current();
});
}
void _r_state_touch_uniform(Uniform *uniform) {
// TODO
}
void _r_state_touch_framebuffer(void) {
TAINT(RSTATE_RENDERTARGET, {
S.framebuffer = B.framebuffer_current();
});
}
void _r_state_touch_scissor(void) {
TAINT(RSTATE_SCISSOR, {
B.scissor_current(&S.scissor);
});
}