You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Example code is below. Window + renderer/texture are done through SDL3. Paining is done with cairomm (github). In an attempt to isolate what causes this, I allocate a very large texture (as large as would fit on display) and do not resize any of the data structures even when the window is resized - I simply paint the background color again.
// toy-sdlwintmain(int argc, char* argv[]) {
auto sdl = rlib::SdlHandle::Create();
auto window = rlib::SdlWindow::Create(*sdl, {});
auto bkg_painter = [](Cairo::Context* cairo_context) {
cairo_context->set_source_rgb(1.0, 0.75, 0.0);
cairo_context->paint();
returnabsl::OkStatus();
};
bool should_exit = false;
while (!should_exit) {
auto event = (*window)->GetNextEvent();
if (!event.has_value()) continue;
switch (event.value().type) {
case SDL_EVENT_KEY_DOWN: {
std::cout << "KEY!\n";
break;
}
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
std::cout << "MOUSE!\n";
break;
}
case SDL_EVENT_WINDOW_MOVED: {
std::cout << "WINDOW MOVED!\n";
break;
}
case SDL_EVENT_WINDOW_RESIZED: {
std::cout << "WINDOW RESIZED!\n";
(*window)->Paint(bkg_painter);
break;
}
case SDL_EVENT_QUIT: {
should_exit = true;
break;
}
default: {
std::cout << "(default) Event type: " << event.value().type << "\n";
break;
}
};
}
return0;
}
// sdlw.cpp
absl::StatusOr<std::unique_ptr<SdlWindow>> SdlWindow::Create(
std::shared_ptr<SdlHandle> sdl_handle, WindowSpec window_spec) {
SDL_Window* window =
SDL_CreateWindow(window_spec.name.data(), window_spec.width,
window_spec.height, window_spec.window_mode);
if (!window) returnabsl::InternalError(SDL_GetError());
SDL_DisplayID display_id = SDL_GetDisplayForWindow(window);
if (!display_id) returnabsl::InternalError(SDL_GetError());
const SDL_DisplayMode* display_mode = SDL_GetCurrentDisplayMode(display_id);
if (!display_mode) returnabsl::InternalError(SDL_GetError());
SDL_SetHint(SDL_HINT_RENDER_DRIVER, kRenderDriverHint.data());
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr);
if (!renderer) returnabsl::InternalError(SDL_GetError());
std::cout << "SDL renderer: " << SDL_GetRendererName(renderer) << "\n";
// Create a texture to fit the biggest window on this screen.
SDL_Texture* texture =
SDL_CreateTexture(renderer, kTexturePixelFormat, kTextureAccess,
display_mode->w, display_mode->h);
if (!texture) returnabsl::InternalError(SDL_GetError());
void* texture_pixels;
int texture_pitch;
if (!SDL_LockTexture(texture, nullptr, &texture_pixels, &texture_pitch))
returnabsl::InternalError(SDL_GetError());
auto cairo_surface = Cairo::ImageSurface::create(
reinterpret_cast<unsignedchar*>(texture_pixels),
Cairo::ImageSurface::Format::ARGB32, display_mode->w, display_mode->h,
texture_pitch);
auto cairo_context = Cairo::Context::create(cairo_surface);
SDL_UnlockTexture(texture);
auto result = std::unique_ptr<SdlWindow>(
newSdlWindow(std::move(sdl_handle), window, display_id, display_mode,
renderer, texture, cairo_surface, cairo_context));
auto paint_result = result->Paint([](Cairo::Context* cairo_context) {
cairo_context->set_source_rgb(1.0, 0.75, 0.0);
cairo_context->paint();
returnabsl::OkStatus();
});
if (!paint_result.ok()) return paint_result;
return result;
}
std::optional<SDL_Event> SdlWindow::GetNextEvent() {
SDL_Event event;
if (SDL_PollEvent(&event)) {
return event;
}
return std::nullopt;
}
absl::Status SdlWindow::Paint(
absl::AnyInvocable<absl::Status(Cairo::Context*)> painter) {
void* texture_pixels;
int texture_pitch;
if (!SDL_LockTexture(sdl_texture_, nullptr, &texture_pixels, &texture_pitch))
returnabsl::InternalError(SDL_GetError());
auto res = painter(cairo_context_.get());
SDL_UnlockTexture(sdl_texture_);
// TODO: b/??? - Understand what locking actually does.// Why is it OK to unlock the texture that still needs to be read.SDL_RenderClear(sdl_renderer_);
SDL_RenderTexture(sdl_renderer_, sdl_texture_, nullptr, nullptr);
SDL_RenderPresent(sdl_renderer_);
return res;
}
Thanks for the quick response! No perceptible change even with SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED. In fact, even just painting in the event loop, outside of the case statement has the same laggy behavior.
Please see the attached screen capture and perf report below. What is the recommended way to set up window updates to avoid the problem?
OS: Ubuntu 24.04
SDL: 3 (github) + opengl renderer
compiler: clang w/ -O3
Desktop: ubuntu:GNOME
Example code is below. Window + renderer/texture are done through SDL3. Paining is done with cairomm (github). In an attempt to isolate what causes this, I allocate a very large texture (as large as would fit on display) and do not resize any of the data structures even when the window is resized - I simply paint the background color again.
Perf was not super illuminating
SDL3_window_resize_update_lag.webm
The text was updated successfully, but these errors were encountered: