diff --git a/reader.lua b/reader.lua index 2866025f7..139a2c4a7 100755 --- a/reader.lua +++ b/reader.lua @@ -51,6 +51,7 @@ rcount = 5 rcountmax = 5 globalzoom = -1 +globalgamma = -1.0 if optarg["d"] == "k3" then -- for now, the only difference is the additional input device @@ -66,6 +67,10 @@ else input.open("/dev/input/event1") end +if optarg["G"] ~= nil then + globalgamma = optarg["G"] +end + doc = pdf.openDocument(ARGV[optind], optarg["p"] or "") print("pdf has "..doc:getPages().." pages.") @@ -73,12 +78,11 @@ print("pdf has "..doc:getPages().." pages.") fb = einkfb.open("/dev/fb0") width, height = fb:getSize() -init_tilecache() - nulldc = pdf.newDC() -function setzoom(cacheslot) - local pwidth, pheight = cache[cacheslot].page:getSize(nulldc) +function setzoom(page, cacheslot) + local dc = pdf.newDC() + local pwidth, pheight = page:getSize(nulldc) -- default zoom: fit to page local zoom = width / pwidth @@ -90,18 +94,19 @@ function setzoom(cacheslot) offset_y = 0 end - cache[cacheslot].dc:setZoom(zoom) - cache[cacheslot].dc:setOffset(offset_x, offset_y) + dc:setZoom(zoom) + dc:setOffset(offset_x, offset_y) -- set gamma here, we don't have any other good place for this right now: - if optarg["G"] then - print("gamma correction: "..optarg["G"]) - cache[cacheslot].dc:setGamma(optarg["G"]) + if globalgamma ~= -1.0 then + print("gamma correction: "..globalgamma) + dc:setGamma(globalgamma) end + return dc end function show(no) - local slot = draworcache(no) + local slot = draworcache(no,globalzoom,0,0,width,height,globalgamma) fb:blitFullFrom(cache[slot].bb) if rcount == rcountmax then print("full refresh") @@ -123,22 +128,18 @@ function goto(no) show(no) if no < doc:getPages() then -- always pre-cache next page - draworcache(no+1) + draworcache(no+1,globalzoom,0,0,width,height,globalgamma) end end function modify_gamma(offset) - local slot = slot_visible - local gamma = cache[slot].dc:getGamma(); - if gamma == -1 then - gamma = 1 + if globalgamma == -1 then + globalgamma = 1 end - local no = cache[slot].no - print("modify_gamma "..no.." slot="..slot.." gamma="..gamma.." offset="..offset) - gamma = gamma + offset; - optarg["G"] = gamma; -- for next page - freecache() - goto(no) + print("modify_gamma, gamma="..globalgamma.." offset="..offset) + globalgamma = globalgamma + offset; + clearcache() + goto(pageno) end function mainloop() @@ -147,13 +148,9 @@ function mainloop() if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then local secs, usecs = util.gettime() if ev.code == KEY_PAGEUP then - print(cache) goto(pageno + 1) - print(cache) elseif ev.code == KEY_PAGEDOWN then - print(cache) goto(pageno - 1) - print(cache) elseif ev.code == KEY_BACK then return elseif ev.code == KEY_UP then diff --git a/tilecache.lua b/tilecache.lua index 31c9e1040..8aa7657a3 100755 --- a/tilecache.lua +++ b/tilecache.lua @@ -1,64 +1,51 @@ --[[ a cache for rendered tiles ]]-- - -function init_tilecache() - cache = { - { age = 0, no = 0, bb = blitbuffer.new(width, height), dc = pdf.newDC(), page = nil }, - { age = 0, no = 0, bb = blitbuffer.new(width, height), dc = pdf.newDC(), page = nil }, - { age = 0, no = 0, bb = blitbuffer.new(width, height), dc = pdf.newDC(), page = nil } - } -end -function freecache() - for i = 1, #cache do - if cache[i].page ~= nil then - print("freeing slot="..i.." oldpage="..cache[i].no) - cache[i].page:close() - cache[i].page = nil - end - end -end -function checkcache(no) - for i = 1, #cache do - if cache[i].no == no and cache[i].page ~= nil then - print("cache hit: slot="..i.." page="..no) - return i - end +cache_max_memsize = 1024*1024*5 -- 5MB tile cache +cache_current_memsize = 0 +cache = {} +cache_max_age = 20 +function cacheclaim(size) + if(size > cache_max_memsize) then + error("too much memory claimed") + return false end - print("cache miss") - return nil -end -function cacheslot() - freeslot = nil - while freeslot == nil do - for i = 1, #cache do - if cache[i].age > 0 then - print("aging slot="..i) - cache[i].age = cache[i].age - 1 + repeat + for k, v in pairs(cache) do + if v.age > 0 then + print("aging slot="..k) + v.age = v.age - 1 else - if cache[i].page ~= nil then - print("freeing slot="..i.." oldpage="..cache[i].no) - cache[i].page:close() - cache[i].page = nil - end - freeslot = i + cache_current_memsize = cache_current_memsize - v.size + cache[k] = nil + break -- out of for loop end end - end - print("returning free slot="..freeslot) - return freeslot + until cache_current_memsize + size <= cache_max_memsize + cache_current_memsize = cache_current_memsize + size + print("cleaned cache to fit new tile (size="..size..")") + return true end - -function draworcache(no) - local slot = checkcache(no) - if slot == nil then - slot = cacheslot() - cache[slot].no = no - cache[slot].age = #cache - cache[slot].page = doc:openPage(no) - setzoom(slot) - print("drawing page="..no.." to slot="..slot) - cache[slot].page:draw(cache[slot].dc, cache[slot].bb, 0, 0) +function draworcache(no, zoom, offset_x, offset_y, width, height, gamma) + local hash = cachehash(no, zoom, offset_x, offset_y, width, height, gamma) + if cache[hash] == nil then + cacheclaim(width * height / 2); + cache[hash] = { + age = cache_max_age, + size = width * height / 2, + bb = blitbuffer.new(width, height) + } + print("drawing page="..no.." to slot="..hash) + local page = doc:openPage(no) + local dc = setzoom(page, hash) + page:draw(dc, cache[hash].bb, 0, 0) + page:close() end - return slot + return hash +end +function cachehash(no, zoom, offset_x, offset_y, width, height, gamma) + return no..'_'..zoom..'_'..offset_x..','..offset_y..'-'..width..'x'..height..'_'..gamma; +end +function clearcache() + cache = {} end