new cache organization in preparation for more complex tile data

in order to use the tile cache for variable zoomed tiles, we need more
flexibility. thus, now cache tiles are hashed (well, in fact it's a
concatenation) of their metadata.

also, we close pages right after opening them - there was no re-use
before and now we have opening and closing at one place. this should
also make it easier for the garbage collector.
pull/2/merge
HW 13 years ago
parent a07ea2f8b8
commit d96666f4b1

@ -51,6 +51,7 @@ rcount = 5
rcountmax = 5 rcountmax = 5
globalzoom = -1 globalzoom = -1
globalgamma = -1.0
if optarg["d"] == "k3" then if optarg["d"] == "k3" then
-- for now, the only difference is the additional input device -- for now, the only difference is the additional input device
@ -66,6 +67,10 @@ else
input.open("/dev/input/event1") input.open("/dev/input/event1")
end end
if optarg["G"] ~= nil then
globalgamma = optarg["G"]
end
doc = pdf.openDocument(ARGV[optind], optarg["p"] or "") doc = pdf.openDocument(ARGV[optind], optarg["p"] or "")
print("pdf has "..doc:getPages().." pages.") print("pdf has "..doc:getPages().." pages.")
@ -73,12 +78,11 @@ print("pdf has "..doc:getPages().." pages.")
fb = einkfb.open("/dev/fb0") fb = einkfb.open("/dev/fb0")
width, height = fb:getSize() width, height = fb:getSize()
init_tilecache()
nulldc = pdf.newDC() nulldc = pdf.newDC()
function setzoom(cacheslot) function setzoom(page, cacheslot)
local pwidth, pheight = cache[cacheslot].page:getSize(nulldc) local dc = pdf.newDC()
local pwidth, pheight = page:getSize(nulldc)
-- default zoom: fit to page -- default zoom: fit to page
local zoom = width / pwidth local zoom = width / pwidth
@ -90,18 +94,19 @@ function setzoom(cacheslot)
offset_y = 0 offset_y = 0
end end
cache[cacheslot].dc:setZoom(zoom) dc:setZoom(zoom)
cache[cacheslot].dc:setOffset(offset_x, offset_y) dc:setOffset(offset_x, offset_y)
-- set gamma here, we don't have any other good place for this right now: -- set gamma here, we don't have any other good place for this right now:
if optarg["G"] then if globalgamma ~= -1.0 then
print("gamma correction: "..optarg["G"]) print("gamma correction: "..globalgamma)
cache[cacheslot].dc:setGamma(optarg["G"]) dc:setGamma(globalgamma)
end end
return dc
end end
function show(no) function show(no)
local slot = draworcache(no) local slot = draworcache(no,globalzoom,0,0,width,height,globalgamma)
fb:blitFullFrom(cache[slot].bb) fb:blitFullFrom(cache[slot].bb)
if rcount == rcountmax then if rcount == rcountmax then
print("full refresh") print("full refresh")
@ -123,22 +128,18 @@ function goto(no)
show(no) show(no)
if no < doc:getPages() then if no < doc:getPages() then
-- always pre-cache next page -- always pre-cache next page
draworcache(no+1) draworcache(no+1,globalzoom,0,0,width,height,globalgamma)
end end
end end
function modify_gamma(offset) function modify_gamma(offset)
local slot = slot_visible if globalgamma == -1 then
local gamma = cache[slot].dc:getGamma(); globalgamma = 1
if gamma == -1 then
gamma = 1
end end
local no = cache[slot].no print("modify_gamma, gamma="..globalgamma.." offset="..offset)
print("modify_gamma "..no.." slot="..slot.." gamma="..gamma.." offset="..offset) globalgamma = globalgamma + offset;
gamma = gamma + offset; clearcache()
optarg["G"] = gamma; -- for next page goto(pageno)
freecache()
goto(no)
end end
function mainloop() function mainloop()
@ -147,13 +148,9 @@ function mainloop()
if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then
local secs, usecs = util.gettime() local secs, usecs = util.gettime()
if ev.code == KEY_PAGEUP then if ev.code == KEY_PAGEUP then
print(cache)
goto(pageno + 1) goto(pageno + 1)
print(cache)
elseif ev.code == KEY_PAGEDOWN then elseif ev.code == KEY_PAGEDOWN then
print(cache)
goto(pageno - 1) goto(pageno - 1)
print(cache)
elseif ev.code == KEY_BACK then elseif ev.code == KEY_BACK then
return return
elseif ev.code == KEY_UP then elseif ev.code == KEY_UP then

@ -1,64 +1,51 @@
--[[ --[[
a cache for rendered tiles a cache for rendered tiles
]]-- ]]--
cache_max_memsize = 1024*1024*5 -- 5MB tile cache
function init_tilecache() cache_current_memsize = 0
cache = { cache = {}
{ age = 0, no = 0, bb = blitbuffer.new(width, height), dc = pdf.newDC(), page = nil }, cache_max_age = 20
{ age = 0, no = 0, bb = blitbuffer.new(width, height), dc = pdf.newDC(), page = nil }, function cacheclaim(size)
{ age = 0, no = 0, bb = blitbuffer.new(width, height), dc = pdf.newDC(), page = nil } if(size > cache_max_memsize) then
} error("too much memory claimed")
end return false
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
end end
print("cache miss") repeat
return nil for k, v in pairs(cache) do
end if v.age > 0 then
function cacheslot() print("aging slot="..k)
freeslot = nil v.age = v.age - 1
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
else else
if cache[i].page ~= nil then cache_current_memsize = cache_current_memsize - v.size
print("freeing slot="..i.." oldpage="..cache[i].no) cache[k] = nil
cache[i].page:close() break -- out of for loop
cache[i].page = nil
end
freeslot = i
end end
end end
end until cache_current_memsize + size <= cache_max_memsize
print("returning free slot="..freeslot) cache_current_memsize = cache_current_memsize + size
return freeslot print("cleaned cache to fit new tile (size="..size..")")
return true
end end
function draworcache(no, zoom, offset_x, offset_y, width, height, gamma)
function draworcache(no) local hash = cachehash(no, zoom, offset_x, offset_y, width, height, gamma)
local slot = checkcache(no) if cache[hash] == nil then
if slot == nil then cacheclaim(width * height / 2);
slot = cacheslot() cache[hash] = {
cache[slot].no = no age = cache_max_age,
cache[slot].age = #cache size = width * height / 2,
cache[slot].page = doc:openPage(no) bb = blitbuffer.new(width, height)
setzoom(slot) }
print("drawing page="..no.." to slot="..slot) print("drawing page="..no.." to slot="..hash)
cache[slot].page:draw(cache[slot].dc, cache[slot].bb, 0, 0) local page = doc:openPage(no)
local dc = setzoom(page, hash)
page:draw(dc, cache[hash].bb, 0, 0)
page:close()
end 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 end

Loading…
Cancel
Save