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() end
for i = 1, #cache do repeat
if cache[i].page ~= nil then for k, v in pairs(cache) do
print("freeing slot="..i.." oldpage="..cache[i].no) if v.age > 0 then
cache[i].page:close() print("aging slot="..k)
cache[i].page = nil v.age = v.age - 1
else
cache_current_memsize = cache_current_memsize - v.size
cache[k] = nil
break -- out of for loop
end end
end end
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 end
function checkcache(no) function draworcache(no, zoom, offset_x, offset_y, width, height, gamma)
for i = 1, #cache do local hash = cachehash(no, zoom, offset_x, offset_y, width, height, gamma)
if cache[i].no == no and cache[i].page ~= nil then if cache[hash] == nil then
print("cache hit: slot="..i.." page="..no) cacheclaim(width * height / 2);
return i cache[hash] = {
end 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 end
print("cache miss") return hash
return nil
end end
function cacheslot() function cachehash(no, zoom, offset_x, offset_y, width, height, gamma)
freeslot = nil return no..'_'..zoom..'_'..offset_x..','..offset_y..'-'..width..'x'..height..'_'..gamma;
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
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
end
end
end
print("returning free slot="..freeslot)
return freeslot
end end
function clearcache()
function draworcache(no) cache = {}
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)
end
return slot
end end

Loading…
Cancel
Save