add multi-threaded precache

Because the lua reader is single threaded on which both user inputloop
and background page rendering is processed. Although there is a pretty
good precache system to save user's time spending on waiting for the
rendering when going to the next page, user input is indeed blocked when
running the precache thing. The situation is even worse in koptreader as
reflowing on page would usually take several second, in this period
users cannot move to the next page view even it's already in the cache.
This patch will let precache run in the background in a seperate thread
so that the koptreader is still responsive when precaching the next
page. Now it only just works. Welcome to find out bugs in it.
pull/2/merge
chrox 12 years ago
parent 0fe8f18591
commit f981b70ac0

@ -18,6 +18,7 @@
#include <math.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <libdjvu/miniexp.h>
#include <libdjvu/ddjvuapi.h>
@ -476,7 +477,6 @@ static int reflowPage(lua_State *L) {
DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage");
KOPTContext *kctx = (KOPTContext*) luaL_checkudata(L, 2, "koptcontext");
ddjvu_render_mode_t mode = (int) luaL_checkint(L, 3);
WILLUSBITMAP _src, *src;
ddjvu_rect_t prect;
ddjvu_rect_t rrect;
@ -510,7 +510,7 @@ static int reflowPage(lua_State *L) {
dpi *= kctx->shrink_factor;
} while (rrect.w > kctx->read_max_width | rrect.h > kctx->read_max_height);
src = &_src;
WILLUSBITMAP *src = malloc(sizeof(WILLUSBITMAP));
bmp_init(src);
src->width = rrect.w;
src->height = rrect.h;
@ -528,8 +528,13 @@ static int reflowPage(lua_State *L) {
status = ddjvu_page_render(page->page_ref, mode, &prect, &rrect, page->doc->pixelformat,
bmp_bytewidth(src), (char *) src->data);
k2pdfopt_reflow_bmp(kctx, src);
bmp_free(src);
kctx->src = src;
if (kctx->precache) {
pthread_t rf_thread;
pthread_create(&rf_thread, NULL, k2pdfopt_reflow_bmp, (void*) kctx);
} else {
k2pdfopt_reflow_bmp(kctx);
}
return 0;
}

@ -46,6 +46,8 @@ static int newKOPTContext(lua_State *L) {
uint8_t *data = NULL;
BBox bbox = {0, 0, 0, 0};
WILLUSBITMAP *src;
int precache = 0;
KOPTContext *kc = (KOPTContext*) lua_newuserdata(L, sizeof(KOPTContext));
@ -76,6 +78,8 @@ static int newKOPTContext(lua_State *L) {
kc->data = data;
kc->bbox = bbox;
kc->src = src;
kc->precache = precache;
luaL_getmetatable(L, "koptcontext");
lua_setmetatable(L, -2);
@ -216,6 +220,18 @@ static int kcSetWordSpacing(lua_State *L) {
return 0;
}
static int kcSetPreCache(lua_State *L) {
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
kc->precache = 1;
return 0;
}
static int kcIsPreCache(lua_State *L) {
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
lua_pushinteger(L, kc->precache);
return 1;
}
static const struct luaL_Reg koptcontext_meth[] = {
{"setBBox", kcSetBBox},
{"setTrim", kcSetTrim},
@ -239,6 +255,9 @@ static const struct luaL_Reg koptcontext_meth[] = {
{"setDefectSize", kcSetDefectSize},
{"setLineSpacing", kcSetLineSpacing},
{"setWordSpacing", kcSetWordSpacing},
{"setPreCache", kcSetPreCache},
{"isPreCache", kcIsPreCache},
{NULL, NULL}
};

21
pdf.c

@ -15,6 +15,11 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <math.h>
#include <stddef.h>
#include <pthread.h>
#include <fitz/fitz-internal.h>
#include "blitbuffer.h"
@ -22,10 +27,6 @@
#include "koptcontext.h"
#include "k2pdfopt.h"
#include "pdf.h"
#include <stdio.h>
#include <math.h>
#include <stddef.h>
typedef struct PdfDocument {
fz_document *xref;
@ -563,7 +564,6 @@ static int reflowPage(lua_State *L) {
fz_rect bounds,bounds2;
fz_matrix ctm;
fz_bbox bbox;
WILLUSBITMAP _src, *src;
pix = NULL;
fz_var(pix);
@ -606,14 +606,19 @@ static int reflowPage(lua_State *L) {
fz_run_page(page->doc->xref, page->page, dev, ctm, NULL);
fz_free_device(dev);
src = &_src;
WILLUSBITMAP *src = malloc(sizeof(WILLUSBITMAP));
bmp_init(src);
int status = bmpmupdf_pixmap_to_bmp(src, page->doc->context, pix);
fz_drop_pixmap(page->doc->context, pix);
k2pdfopt_reflow_bmp(kctx, src);
bmp_free(src);
kctx->src = src;
if (kctx->precache) {
pthread_t rf_thread;
pthread_create( &rf_thread, NULL, k2pdfopt_reflow_bmp, (void*) kctx);
} else {
k2pdfopt_reflow_bmp(kctx);
}
return 0;
}

Loading…
Cancel
Save