loader = Gdk::PixbufLoader.new
loader.signal_connect('size-prepared') { |l, w, h|
r = specify_size.call(w, h)
- msg 3, "specified sizes: #{r[0]} #{r[1]}"
+ #msg 3, "specified sizes: #{r[0]} #{r[1]}"
loader.set_size(*specify_size.call(w, h))
}
loader.signal_connect('area-prepared') { pixbuf = loader.pixbuf }
- file = File.new(image_path)
- while (chunk = file.read(4096)) != nil
- loader.write(chunk)
- Gtk.main_iteration while Gtk.events_pending?
- end
- file.close
+ loader.load_not_freezing_ui(image_path)
loader.close
if pixbuf.nil?
raise "Loaded pixbuf nil - #{path} #{image_path}"
$allentries = []
+def gc
+ start = Time.now
+ GC.start
+ msg 3, "GC in #{Time.now - start} s"
+end
+
+def free_cache
+ i = $allentries.index($mainview.get_shown_entry)
+ return if i.nil?
+ start = Time.now
+ ($allentries.size - 1).downto($config['preload-distance'].to_i + 1) { |j|
+ index = i + j
+ if i + j < $allentries.size
+ $allentries[i+j].free_pixbuf_full
+ $allentries[i+j].free_pixbuf_main
+ end
+ if i - j > 0
+ $allentries[i-j].free_pixbuf_full
+ $allentries[i-j].free_pixbuf_main
+ end
+ }
+ msg 3, "freeing done in #{Time.now - start} s"
+ if get_mem > $config['cache-memory-use-figure'] * 3 / 4
+ gc
+ get_mem
+ end
+end
+
def run_preloader_real
msg 3, "*** >> main preloading triggered..."
if $preloader_running
end
$preloader_running = true
if $mainview.get_shown_entry
- mem = get_mem
- if mem > $config['cache-memory-use-figure']
+ if get_mem > $config['cache-memory-use-figure']
msg 3, "too much RSS, stopping preloading, triggering GC"
$preloader_running = false
- GC.start
- msg 3, "GC finished"
+ gc
+ get_mem
return
end
index = $allentries.index($mainview.get_shown_entry)
return
end
end
- check_memory_free_cache_if_needed
+ free_cache
end
$preloader_running = false
msg 3, "*** << main preloading finished"
end
end
@entry = entry
- redraw
+ redraw
run_preloader
msg 3, "entry shown in: #{Time.now - t1} s"
end
window.clear
draw
window.end_paint
+ Gtk.main_iteration while Gtk.events_pending?
end
def update_shown
end
end
-def check_memory_free_cache_if_needed
- i = $allentries.index($mainview.get_shown_entry)
- return if i.nil?
- if get_mem < $config['cache-memory-use-figure'] * 2 / 3
- return
- end
- msg 3, "too much RSS, triggering GC"
- GC.start
- msg 3, "GC finished"
- ($allentries.size - 1).downto(1) { |j|
- if get_mem < $config['cache-memory-use-figure'] / 2
- break
- end
- index = i + j
- msg 3, "too much RSS, freeing full size of #{i+j} and #{i-j}..."
- if i + j < $allentries.size
- $allentries[i+j].free_pixbuf_full
- end
- if i - j > 0
- $allentries[i-j].free_pixbuf_full
- end
- }
-end
-
def autoscroll_if_needed(button)
xpos_left = button.allocation.x
xpos_right = button.allocation.x + button.allocation.width
def show_entry(entry, i, tips)
#- scope entry
- msg 3, "showing entry #{entry}"
+ #msg 3, "showing entry #{entry}"
entry.image = Gtk::Image.new(entry.pixbuf_thumbnail)
if entry.type == 'video'
entry.button = Gtk::Button.new.add(Gtk::HBox.new.pack_start(da1 = Gtk::DrawingArea.new.set_size_request($videoborder_pixbuf.width, -1), false, false).
end
total_loaded_size += file_size(entry.path)
- if i % 4 == 0
- check_memory_free_cache_if_needed
- end
total_loaded_files += 1
i += 1
if i > $config['preload-distance'].to_i && i <= $config['preload-distance'].to_i * 2
return self;
}
+// internalize pixbuf loading for 30% more speedup
+static VALUE load_not_freezing_ui(VALUE self, VALUE path) {
+ char buf[65536];
+ size_t amount;
+ GdkPixbufLoader* loader = GDK_PIXBUF_LOADER(RVAL2GOBJ(self));
+ GError* error = NULL;
+ FILE* f = fopen(RVAL2CSTR(path), "r");
+ while ((amount = fread(buf, 1, 65536, f)) > 0) {
+ if (!gdk_pixbuf_loader_write(loader, (const guchar*) buf, amount, &error)) {
+ fclose(f);
+ RAISE_GERROR(error);
+ }
+ while (gtk_events_pending()) {
+ gtk_main_iteration();
+ }
+ }
+ fclose(f);
+ return self;
+}
+
extern "C" {
void
Init_libadds()
cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(GTK_TYPE_WIDGET, Qnil);
rb_define_method(cinfo->klass, "modify_bg", (VALUE (*)(...)) modify_bg, 2);
+ cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(GDK_TYPE_PIXBUF_LOADER, Qnil);
+ rb_define_method(cinfo->klass, "load_not_freezing_ui", (VALUE (*)(...)) load_not_freezing_ui, 1);
+
VALUE exif = rb_define_module("Exif");
rb_define_module_function(exif, "orientation", (VALUE (*)(...)) exif_orientation, 1);
rb_define_module_function(exif, "set_orientation", (VALUE (*)(...)) exif_set_orientation, 2);