From 46fa29a1564e584db0e79324759d55c4adb1f6b1 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Fri, 25 Jul 2014 14:22:03 +0200 Subject: [PATCH] nitpicker: reduce artifacts during mode change --- repos/os/src/server/nitpicker/main.cc | 41 +++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/repos/os/src/server/nitpicker/main.cc b/repos/os/src/server/nitpicker/main.cc index afb753c67e..bd1e7fe84b 100644 --- a/repos/os/src/server/nitpicker/main.cc +++ b/repos/os/src/server/nitpicker/main.cc @@ -928,18 +928,43 @@ class Nitpicker::Session_component : public Genode::Rpc_object, Buffer *realloc_buffer(Framebuffer::Mode mode, bool use_alpha) { - _release_buffer(); + typedef Pixel_rgb565 PT; Area const size(mode.width(), mode.height()); - typedef Pixel_rgb565 PT; - _buffer_size = Chunky_dataspace_texture::calc_num_bytes(size, use_alpha); + /* + * Preserve the content of the original buffer if nitpicker has + * enough lack memory to temporarily keep the original pixels. + */ + Texture const *src_texture = nullptr; + if (::Session::texture()) { + + enum { PRESERVED_RAM = 128*1024 }; + if (env()->ram_session()->avail() > _buffer_size + PRESERVED_RAM) { + src_texture = static_cast const *>(::Session::texture()); + } else { + PWRN("not enough RAM to preserve buffer content during resize"); + _release_buffer(); + } + } + Chunky_dataspace_texture * const texture = new (&_session_alloc) Chunky_dataspace_texture(size, use_alpha); + /* copy old buffer content into new buffer and release old buffer */ + if (src_texture) { + + Genode::Surface surface(texture->pixel(), + texture->Texture_base::size()); + + Texture_painter::paint(surface, *src_texture, Color(), Point(0, 0), + Texture_painter::SOLID, false); + _release_buffer(); + } + if (!_session_alloc.withdraw(_buffer_size)) { destroy(&_session_alloc, texture); _buffer_size = 0; @@ -1141,6 +1166,16 @@ struct Nitpicker::Main */ Timer::Connection timer; + /** + * Perform redraw and flush pixels to the framebuffer + */ + void draw_and_flush() + { + user_state.draw(fb_screen->screen).flush([&] (Rect const &rect) { + framebuffer.refresh(rect.x1(), rect.y1(), + rect.w(), rect.h()); }); + } + Main(Server::Entrypoint &ep) : ep(ep) { // tmp_fb = &framebuffer;