rendering element rewrite
This commit is contained in:
parent
4c286e1fd8
commit
3d40256bde
22 changed files with 799 additions and 795 deletions
|
|
@ -23,7 +23,6 @@ module;
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "../lib/xdg-shell-client-protocol.h"
|
||||
#include "../lib/wayland-xdg-decoration-unstable-v1-client-protocol.h"
|
||||
#include <string.h>
|
||||
|
|
@ -155,7 +154,7 @@ inline void blend_pixel_optimized(Pixel_BU8_GU8_RU8_AU8& dst, const Pixel_BU8_GU
|
|||
}
|
||||
|
||||
void WindowWayland::RenderElement(Transform* transform) {
|
||||
RenderingElement* element = dynamic_cast<RenderingElement*>(transform);
|
||||
RenderingElementBase* element = dynamic_cast<RenderingElementBase*>(transform);
|
||||
if(element) {
|
||||
#ifdef CRAFTER_TIMING
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
|
@ -171,7 +170,7 @@ void WindowWayland::RenderElement(Transform* transform) {
|
|||
dirty.right = std::min(element->scaled.x+element->scaled.width, dirty.right);
|
||||
dirty.bottom = std::min(element->scaled.y+element->scaled.height, dirty.bottom);
|
||||
|
||||
const Pixel_BU8_GU8_RU8_AU8* src_buffer = element->bufferScaled.data();
|
||||
const Pixel_BU8_GU8_RU8_AU8* src_buffer = element->buffer.data();
|
||||
std::int_fast32_t src_width = element->scaled.width;
|
||||
std::int_fast32_t src_height = element->scaled.height;
|
||||
|
||||
|
|
@ -226,7 +225,7 @@ void WindowWayland::RenderElement(Transform* transform) {
|
|||
#endif
|
||||
}
|
||||
|
||||
std::sort(transform->children.begin(), transform->children.end(), [](Transform* a, Transform* b){ return a->z < b->z; });
|
||||
std::sort(transform->children.begin(), transform->children.end(), [](Transform* a, Transform* b){ return a->anchor.z < b->anchor.z; });
|
||||
for(Transform* child : transform->children) {
|
||||
this->RenderElement(child);
|
||||
}
|
||||
|
|
@ -234,87 +233,107 @@ void WindowWayland::RenderElement(Transform* transform) {
|
|||
|
||||
void WindowWayland::Render() {
|
||||
elements.erase(std::remove(elements.begin(), elements.end(), static_cast<Transform*>(nullptr)), elements.end());
|
||||
std::sort(elements.begin(), elements.end(), [](Transform* a, Transform* b){ return a->z < b->z; });
|
||||
std::sort(elements.begin(), elements.end(), [](Transform* a, Transform* b){ return a->anchor.z < b->anchor.z; });
|
||||
|
||||
std::vector<ClipRect> newClip;
|
||||
//std::vector<ClipRect> newClip;
|
||||
|
||||
for (std::uint_fast32_t i = 0; i < dirtyRects.size(); i++) {
|
||||
ClipRect rect = dirtyRects[i];
|
||||
for (std::uint_fast32_t i2 = i + 1; i2 < dirtyRects.size(); i2++) {
|
||||
ClipRect existing = dirtyRects[i2];
|
||||
if(rect.bottom >= existing.top && rect.top <= existing.top) {
|
||||
newClip.push_back({
|
||||
.left = rect.left,
|
||||
.right = rect.right,
|
||||
.top = rect.top,
|
||||
.bottom = existing.top,
|
||||
});
|
||||
//-| shape
|
||||
if(rect.right > existing.right) {
|
||||
newClip.push_back({
|
||||
.left = existing.right,
|
||||
.right = rect.right,
|
||||
.top = existing.top,
|
||||
.bottom = existing.bottom,
|
||||
});
|
||||
}
|
||||
//|- shape
|
||||
if(rect.left < existing.left) {
|
||||
newClip.push_back({
|
||||
.left = rect.left,
|
||||
.right = existing.left,
|
||||
.top = existing.top,
|
||||
.bottom = existing.bottom,
|
||||
});
|
||||
}
|
||||
//-| or |- shape where rect extends further down
|
||||
if(rect.bottom > existing.bottom) {
|
||||
newClip.push_back({
|
||||
.left = rect.left,
|
||||
.right = rect.right,
|
||||
.top = existing.bottom,
|
||||
.bottom = rect.bottom,
|
||||
});
|
||||
}
|
||||
goto inner;
|
||||
}
|
||||
if (rect.left <= existing.right && rect.right >= existing.left) {
|
||||
newClip.push_back({
|
||||
.left = rect.left,
|
||||
.right = existing.left,
|
||||
.top = rect.top,
|
||||
.bottom = rect.bottom,
|
||||
});
|
||||
if (rect.right > existing.right) {
|
||||
newClip.push_back({
|
||||
.left = existing.right,
|
||||
.right = rect.right,
|
||||
.top = rect.top,
|
||||
.bottom = rect.bottom,
|
||||
});
|
||||
}
|
||||
goto inner;
|
||||
}
|
||||
}
|
||||
newClip.push_back(rect);
|
||||
inner:;
|
||||
}
|
||||
|
||||
dirtyRects = std::move(newClip);
|
||||
|
||||
// for(uint_fast32_t i = 0; i < width*height; i++) {
|
||||
// framebuffer[i] = {0, 0, 0, 255};
|
||||
// for (std::uint_fast32_t i = 0; i < dirtyRects.size(); i++) {
|
||||
// ClipRect rect = dirtyRects[i];
|
||||
// for (std::uint_fast32_t i2 = i + 1; i2 < dirtyRects.size(); i2++) {
|
||||
// ClipRect existing = dirtyRects[i2];
|
||||
// if(rect.bottom >= existing.top && rect.top <= existing.top) {
|
||||
// newClip.push_back({
|
||||
// .left = rect.left,
|
||||
// .right = rect.right,
|
||||
// .top = rect.top,
|
||||
// .bottom = existing.top,
|
||||
// });
|
||||
// //-| shape
|
||||
// if(rect.right > existing.right) {
|
||||
// newClip.push_back({
|
||||
// .left = existing.right,
|
||||
// .right = rect.right,
|
||||
// .top = existing.top,
|
||||
// .bottom = existing.bottom,
|
||||
// });
|
||||
// }
|
||||
// //|- shape
|
||||
// if(rect.left < existing.left) {
|
||||
// newClip.push_back({
|
||||
// .left = rect.left,
|
||||
// .right = existing.left,
|
||||
// .top = existing.top,
|
||||
// .bottom = existing.bottom,
|
||||
// });
|
||||
// }
|
||||
// //-| or |- shape where rect extends further down
|
||||
// if(rect.bottom > existing.bottom) {
|
||||
// newClip.push_back({
|
||||
// .left = rect.left,
|
||||
// .right = rect.right,
|
||||
// .top = existing.bottom,
|
||||
// .bottom = rect.bottom,
|
||||
// });
|
||||
// }
|
||||
// goto inner;
|
||||
// }
|
||||
// if (rect.left <= existing.right && rect.right >= existing.left) {
|
||||
// newClip.push_back({
|
||||
// .left = rect.left,
|
||||
// .right = existing.left,
|
||||
// .top = rect.top,
|
||||
// .bottom = rect.bottom,
|
||||
// });
|
||||
// if (rect.right > existing.right) {
|
||||
// newClip.push_back({
|
||||
// .left = existing.right,
|
||||
// .right = rect.right,
|
||||
// .top = rect.top,
|
||||
// .bottom = rect.bottom,
|
||||
// });
|
||||
// }
|
||||
// goto inner;
|
||||
// }
|
||||
// }
|
||||
// newClip.push_back(rect);
|
||||
// inner:;
|
||||
// }
|
||||
|
||||
//dirtyRects = std::move(newClip);
|
||||
|
||||
// std::memset(framebuffer, 0, width*height*4);
|
||||
|
||||
// std::cout << dirtyRects.size() << std::endl;
|
||||
// for (ClipRect rect : dirtyRects) {
|
||||
// //std::cout << std::format("{}, {}, {}, {}", rect.left, rect.top, rect.right, rect.bottom) << std::endl;
|
||||
// for (std::int_fast32_t y = rect.top; y < rect.bottom; y++) {
|
||||
// for (std::int_fast32_t x = rect.left; x < rect.right; x++) {
|
||||
// framebuffer[y * width + x].r += 30;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // Color palette
|
||||
// static const std::vector<Pixel_BU8_GU8_RU8_AU8> colors = {
|
||||
// {255, 0, 0, 255}, // red
|
||||
// { 0, 255, 0, 255}, // green
|
||||
// { 0, 0, 255, 255}, // blue
|
||||
// {255, 255, 0, 255}, // yellow
|
||||
// {255, 0, 255, 255}, // magenta
|
||||
// { 0, 255, 255, 255}, // cyan
|
||||
// };
|
||||
|
||||
// std::size_t rectIndex = 0;
|
||||
|
||||
// for (const ClipRect& rect : dirtyRects) {
|
||||
// const Pixel_BU8_GU8_RU8_AU8& color = colors[rectIndex % colors.size()];
|
||||
|
||||
// std::cout << std::format(
|
||||
// "ClipRect {}: [{}, {}, {}, {}] Color = RGBA({}, {}, {}, {})",
|
||||
// rectIndex,
|
||||
// rect.left, rect.top, rect.right, rect.bottom,
|
||||
// color.r, color.g, color.b, color.a
|
||||
// ) << std::endl;
|
||||
|
||||
// for (std::int_fast32_t y = rect.top; y < rect.bottom; ++y) {
|
||||
// for (std::int_fast32_t x = rect.left; x < rect.right; ++x) {
|
||||
// framebuffer[y * width + x] = color;
|
||||
// }
|
||||
// }
|
||||
|
||||
// ++rectIndex;
|
||||
// }
|
||||
|
||||
if (!dirtyRects.empty()) {
|
||||
for (ClipRect rect : dirtyRects) {
|
||||
|
|
@ -335,11 +354,17 @@ void WindowWayland::Render() {
|
|||
dirtyRects.clear();
|
||||
}
|
||||
|
||||
dirtyRects.clear();
|
||||
wl_surface_damage(surface, 0, 0, width, height);
|
||||
|
||||
wl_surface_attach(surface, buffer, 0, 0);
|
||||
wl_surface_commit(surface);
|
||||
wl_surface_commit(surface);
|
||||
wl_surface_damage(surface, 0, 0, 10000, 100000);
|
||||
}
|
||||
|
||||
void WindowWayland::QueueRender() {
|
||||
std::cout << cb << std::endl;
|
||||
if(cb == nullptr) {
|
||||
cb = wl_surface_frame(surface);
|
||||
wl_callback_add_listener(cb, &wl_callback_listener, this);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowWayland::StartUpdate() {
|
||||
|
|
@ -396,6 +421,7 @@ void WindowWayland::wl_surface_frame_done(void* data, struct wl_callback *cb, ui
|
|||
{
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
wl_callback_destroy(cb);
|
||||
cb = nullptr;
|
||||
WindowWayland* window = reinterpret_cast<WindowWayland*>(data);
|
||||
#ifdef CRAFTER_TIMING
|
||||
window->vblank = duration_cast<std::chrono::milliseconds>(start - window->frameEnd);
|
||||
|
|
@ -413,18 +439,18 @@ void WindowWayland::wl_surface_frame_done(void* data, struct wl_callback *cb, ui
|
|||
window->totalUpdate += entry.second;
|
||||
}
|
||||
#endif
|
||||
#ifdef CRAFTER_TIMING
|
||||
auto renderStart = std::chrono::high_resolution_clock::now();
|
||||
window->renderTimings.clear();
|
||||
#endif
|
||||
window->Render();
|
||||
#ifdef CRAFTER_TIMING
|
||||
auto renderEnd = std::chrono::high_resolution_clock::now();
|
||||
window->totalRender = renderEnd - renderStart;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef CRAFTER_TIMING
|
||||
auto renderStart = std::chrono::high_resolution_clock::now();
|
||||
window->renderTimings.clear();
|
||||
#endif
|
||||
window->Render();
|
||||
#ifdef CRAFTER_TIMING
|
||||
auto renderEnd = std::chrono::high_resolution_clock::now();
|
||||
window->totalRender = renderEnd - renderStart;
|
||||
#endif
|
||||
|
||||
#ifdef CRAFTER_TIMING
|
||||
window->frameEnd = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
|
@ -557,6 +583,132 @@ void WindowWayland::keyboard_leave(void *data, wl_keyboard *keyboard, uint32_t s
|
|||
|
||||
}
|
||||
|
||||
CrafterKeys keysym_to_crafter_key(xkb_keysym_t sym)
|
||||
{
|
||||
switch (sym)
|
||||
{
|
||||
// Alphabet
|
||||
case XKB_KEY_a: return CrafterKeys::A;
|
||||
case XKB_KEY_b: return CrafterKeys::B;
|
||||
case XKB_KEY_c: return CrafterKeys::C;
|
||||
case XKB_KEY_d: return CrafterKeys::D;
|
||||
case XKB_KEY_e: return CrafterKeys::E;
|
||||
case XKB_KEY_f: return CrafterKeys::F;
|
||||
case XKB_KEY_g: return CrafterKeys::G;
|
||||
case XKB_KEY_h: return CrafterKeys::H;
|
||||
case XKB_KEY_i: return CrafterKeys::I;
|
||||
case XKB_KEY_j: return CrafterKeys::J;
|
||||
case XKB_KEY_k: return CrafterKeys::K;
|
||||
case XKB_KEY_l: return CrafterKeys::L;
|
||||
case XKB_KEY_m: return CrafterKeys::M;
|
||||
case XKB_KEY_n: return CrafterKeys::N;
|
||||
case XKB_KEY_o: return CrafterKeys::O;
|
||||
case XKB_KEY_p: return CrafterKeys::P;
|
||||
case XKB_KEY_q: return CrafterKeys::Q;
|
||||
case XKB_KEY_r: return CrafterKeys::R;
|
||||
case XKB_KEY_s: return CrafterKeys::S;
|
||||
case XKB_KEY_t: return CrafterKeys::T;
|
||||
case XKB_KEY_u: return CrafterKeys::U;
|
||||
case XKB_KEY_v: return CrafterKeys::V;
|
||||
case XKB_KEY_w: return CrafterKeys::W;
|
||||
case XKB_KEY_x: return CrafterKeys::X;
|
||||
case XKB_KEY_y: return CrafterKeys::Y;
|
||||
case XKB_KEY_z: return CrafterKeys::Z;
|
||||
|
||||
// Numbers
|
||||
case XKB_KEY_0: return CrafterKeys::_0;
|
||||
case XKB_KEY_1: return CrafterKeys::_1;
|
||||
case XKB_KEY_2: return CrafterKeys::_2;
|
||||
case XKB_KEY_3: return CrafterKeys::_3;
|
||||
case XKB_KEY_4: return CrafterKeys::_4;
|
||||
case XKB_KEY_5: return CrafterKeys::_5;
|
||||
case XKB_KEY_6: return CrafterKeys::_6;
|
||||
case XKB_KEY_7: return CrafterKeys::_7;
|
||||
case XKB_KEY_8: return CrafterKeys::_8;
|
||||
case XKB_KEY_9: return CrafterKeys::_9;
|
||||
|
||||
// Function keys
|
||||
case XKB_KEY_F1: return CrafterKeys::F1;
|
||||
case XKB_KEY_F2: return CrafterKeys::F2;
|
||||
case XKB_KEY_F3: return CrafterKeys::F3;
|
||||
case XKB_KEY_F4: return CrafterKeys::F4;
|
||||
case XKB_KEY_F5: return CrafterKeys::F5;
|
||||
case XKB_KEY_F6: return CrafterKeys::F6;
|
||||
case XKB_KEY_F7: return CrafterKeys::F7;
|
||||
case XKB_KEY_F8: return CrafterKeys::F8;
|
||||
case XKB_KEY_F9: return CrafterKeys::F9;
|
||||
case XKB_KEY_F10: return CrafterKeys::F10;
|
||||
case XKB_KEY_F11: return CrafterKeys::F11;
|
||||
case XKB_KEY_F12: return CrafterKeys::F12;
|
||||
|
||||
// Control keys
|
||||
case XKB_KEY_Escape: return CrafterKeys::Escape;
|
||||
case XKB_KEY_Tab: return CrafterKeys::Tab;
|
||||
case XKB_KEY_Return: return CrafterKeys::Enter;
|
||||
case XKB_KEY_space: return CrafterKeys::Space;
|
||||
case XKB_KEY_BackSpace: return CrafterKeys::Backspace;
|
||||
case XKB_KEY_Delete: return CrafterKeys::Delete;
|
||||
case XKB_KEY_Insert: return CrafterKeys::Insert;
|
||||
case XKB_KEY_Home: return CrafterKeys::Home;
|
||||
case XKB_KEY_End: return CrafterKeys::End;
|
||||
case XKB_KEY_Page_Up: return CrafterKeys::PageUp;
|
||||
case XKB_KEY_Page_Down: return CrafterKeys::PageDown;
|
||||
case XKB_KEY_Caps_Lock: return CrafterKeys::CapsLock;
|
||||
case XKB_KEY_Num_Lock: return CrafterKeys::NumLock;
|
||||
case XKB_KEY_Scroll_Lock:return CrafterKeys::ScrollLock;
|
||||
|
||||
// Modifiers
|
||||
case XKB_KEY_Shift_L: return CrafterKeys::LeftShift;
|
||||
case XKB_KEY_Shift_R: return CrafterKeys::RightShift;
|
||||
case XKB_KEY_Control_L: return CrafterKeys::LeftCtrl;
|
||||
case XKB_KEY_Control_R: return CrafterKeys::RightCtrl;
|
||||
case XKB_KEY_Alt_L: return CrafterKeys::LeftAlt;
|
||||
case XKB_KEY_Alt_R: return CrafterKeys::RightAlt;
|
||||
case XKB_KEY_Super_L: return CrafterKeys::LeftSuper;
|
||||
case XKB_KEY_Super_R: return CrafterKeys::RightSuper;
|
||||
|
||||
// Arrows
|
||||
case XKB_KEY_Up: return CrafterKeys::Up;
|
||||
case XKB_KEY_Down: return CrafterKeys::Down;
|
||||
case XKB_KEY_Left: return CrafterKeys::Left;
|
||||
case XKB_KEY_Right: return CrafterKeys::Right;
|
||||
|
||||
// Keypad
|
||||
case XKB_KEY_KP_0: return CrafterKeys::keypad_0;
|
||||
case XKB_KEY_KP_1: return CrafterKeys::keypad_1;
|
||||
case XKB_KEY_KP_2: return CrafterKeys::keypad_2;
|
||||
case XKB_KEY_KP_3: return CrafterKeys::keypad_3;
|
||||
case XKB_KEY_KP_4: return CrafterKeys::keypad_4;
|
||||
case XKB_KEY_KP_5: return CrafterKeys::keypad_5;
|
||||
case XKB_KEY_KP_6: return CrafterKeys::keypad_6;
|
||||
case XKB_KEY_KP_7: return CrafterKeys::keypad_7;
|
||||
case XKB_KEY_KP_8: return CrafterKeys::keypad_8;
|
||||
case XKB_KEY_KP_9: return CrafterKeys::keypad_9;
|
||||
case XKB_KEY_KP_Enter: return CrafterKeys::keypad_enter;
|
||||
case XKB_KEY_KP_Add: return CrafterKeys::keypad_plus;
|
||||
case XKB_KEY_KP_Subtract: return CrafterKeys::keypad_minus;
|
||||
case XKB_KEY_KP_Multiply: return CrafterKeys::keypad_multiply;
|
||||
case XKB_KEY_KP_Divide: return CrafterKeys::keypad_divide;
|
||||
case XKB_KEY_KP_Decimal: return CrafterKeys::keypad_decimal;
|
||||
|
||||
// Punctuation
|
||||
case XKB_KEY_grave: return CrafterKeys::grave;
|
||||
case XKB_KEY_minus: return CrafterKeys::minus;
|
||||
case XKB_KEY_equal: return CrafterKeys::equal;
|
||||
case XKB_KEY_bracketleft: return CrafterKeys::bracket_left;
|
||||
case XKB_KEY_bracketright:return CrafterKeys::bracket_right;
|
||||
case XKB_KEY_backslash: return CrafterKeys::backslash;
|
||||
case XKB_KEY_semicolon: return CrafterKeys::semicolon;
|
||||
case XKB_KEY_apostrophe: return CrafterKeys::quote;
|
||||
case XKB_KEY_comma: return CrafterKeys::comma;
|
||||
case XKB_KEY_period: return CrafterKeys::period;
|
||||
case XKB_KEY_slash: return CrafterKeys::slash;
|
||||
|
||||
default:
|
||||
return CrafterKeys::CrafterKeysMax;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowWayland::keyboard_key(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
|
||||
WindowWayland* window = reinterpret_cast<WindowWayland*>(data);
|
||||
|
||||
|
|
@ -566,33 +718,22 @@ void WindowWayland::keyboard_key(void *data, wl_keyboard *keyboard, uint32_t ser
|
|||
|
||||
xkb_keycode_t keycode = key + 8;
|
||||
xkb_keysym_t keysym = xkb_state_key_get_one_sym(window->xkb_state, keycode);
|
||||
CrafterKeys crafterKey = keysym_to_crafter_key(keysym);
|
||||
|
||||
char utf8[8] = {0};
|
||||
int len = xkb_keysym_to_utf8(keysym, utf8, sizeof(utf8));
|
||||
if (len != 0) {
|
||||
char keypress = utf8[0];
|
||||
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
if(window->heldkeys[keypress]) {
|
||||
window->onKeyHold[keypress].Invoke();
|
||||
window->onAnyKeyHold.Invoke(keypress);
|
||||
} else{
|
||||
window->heldkeys[keypress] = true;
|
||||
window->onKeyDown[keypress].Invoke();
|
||||
window->onAnyKeyDown.Invoke(keypress);
|
||||
}
|
||||
} else{
|
||||
window->heldkeys[keypress] = false;
|
||||
window->onKeyUp[keypress].Invoke();
|
||||
window->onAnyKeyUp.Invoke(keypress);
|
||||
}
|
||||
|
||||
} else {
|
||||
// // fallback for keys like Return, Escape, etc.
|
||||
// char name[64];
|
||||
// if (xkb_keysym_get_name(keysym, name, sizeof(name)) > 0) {
|
||||
// printf("Key %s pressed (non-printable or multi-char)\n", name);
|
||||
// }
|
||||
}
|
||||
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
if(window->heldkeys[static_cast<std::uint8_t>(crafterKey)]) {
|
||||
window->onKeyHold[static_cast<std::uint8_t>(crafterKey)].Invoke();
|
||||
window->onAnyKeyHold.Invoke(crafterKey);
|
||||
} else{
|
||||
window->heldkeys[static_cast<std::uint8_t>(crafterKey)] = true;
|
||||
window->onKeyDown[static_cast<std::uint8_t>(crafterKey)].Invoke();
|
||||
window->onAnyKeyDown.Invoke(crafterKey);
|
||||
}
|
||||
} else{
|
||||
window->heldkeys[static_cast<std::uint8_t>(crafterKey)] = false;
|
||||
window->onKeyUp[static_cast<std::uint8_t>(crafterKey)].Invoke();
|
||||
window->onAnyKeyUp.Invoke(crafterKey);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowWayland::keyboard_modifiers(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue