예제 #1
0
void benchrenderpage(fz_context *ctx, pdf_document *xref, pdf_page *page, int pagenum)
{
	fz_device *dev;
	fz_pixmap *pix;
	fz_bbox bbox;
	mstimer timer;

	timerstart(&timer);

	bbox = fz_round_rect(pdf_bound_page(xref, page));
	pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, bbox);
	fz_clear_pixmap_with_value(ctx, pix, 0xFF);
	dev = fz_new_draw_device(ctx, pix);
	fz_try(ctx) {
		pdf_run_page(xref, page, dev, fz_identity, NULL);
		timerstop(&timer);
		logbench("pagerender %3d: %.2f ms\n", pagenum, timeinms(&timer));
	}
	fz_catch(ctx) {
		logbench("Error: pdf_run_page() failed\n");
	}

	fz_drop_pixmap(ctx, pix);
	fz_free_device(dev);
}
예제 #2
0
static void BenchLoadRender(BaseEngine *engine, int pagenum)
{
    Timer t(true);
    bool ok = engine->BenchLoadPage(pagenum);
    t.Stop();

    if (!ok) {
        logbench("Error: failed to load page %d", pagenum);
        return;
    }
    double timems = t.GetTimeInMs();
    logbench("pageload   %3d: %.2f ms", pagenum, timems);

    t.Start();
    RenderedBitmap *rendered = engine->RenderBitmap(pagenum, 1.0, 0);
    t.Stop();

    if (!rendered) {
        logbench("Error: failed to render page %d", pagenum);
        return;
    }
    delete rendered;
    timems = t.GetTimeInMs();
    logbench("pagerender %3d: %.2f ms", pagenum, timems);
}
예제 #3
0
static void BenchFile(const WCHAR *filePath, const WCHAR *pagesSpec)
{
    if (!file::Exists(filePath)) {
        return;
    }

    // ad-hoc: if enabled times layout instead of rendering and does layout
    // using all text rendering methods, so that we can compare and find
    // docs that take a long time to load

    if (Doc::IsSupportedFile(filePath) && !gGlobalPrefs->ebookUI.useFixedPageUI) {
        BenchEbookLayout(filePath);
        return;
    }

    if (ChmModel::IsSupportedFile(filePath) && !gGlobalPrefs->chmUI.useFixedPageUI) {
        BenchChmLoadOnly(filePath);
        return;
    }

    Timer total;
    logbench(L"Starting: %s", filePath);

    Timer t;
    BaseEngine *engine = EngineManager::CreateEngine(filePath);
    if (!engine) {
        logbench(L"Error: failed to load %s", filePath);
        return;
    }

    double timeMs = t.Stop();
    logbench(L"load: %.2f ms", timeMs);
    int pages = engine->PageCount();
    logbench(L"page count: %d", pages);

    if (nullptr == pagesSpec) {
        for (int i = 1; i <= pages; i++) {
            BenchLoadRender(engine, i);
        }
    }

    assert(!pagesSpec || IsBenchPagesInfo(pagesSpec));
    Vec<PageRange> ranges;
    if (ParsePageRanges(pagesSpec, ranges)) {
        for (size_t i = 0; i < ranges.Count(); i++) {
            for (int j = ranges.At(i).start; j <= ranges.At(i).end; j++) {
                if (1 <= j && j <= pages)
                    BenchLoadRender(engine, j);
            }
        }
    }

    delete engine;
    total.Stop();

    logbench(L"Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath);
}
예제 #4
0
void benchfile(char *pdffilename, int loadonly, int pageNo)
{
	pdf_document *xref = NULL;
	mstimer timer;
	int page_count;
	int curpage;

	fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
	if (!ctx) {
		logbench("Error: fz_new_context() failed\n");
		return;
	}

	logbench("Starting: %s\n", pdffilename);
	timerstart(&timer);
	fz_var(xref);
	fz_try(ctx) {
		xref = openxref(ctx, pdffilename);
	}
	fz_catch(ctx) {
		goto Exit;
	}
	timerstop(&timer);
	logbench("load: %.2f ms\n", timeinms(&timer));

	page_count = pdf_count_pages(xref);
	logbench("page count: %d\n", page_count);

	if (loadonly)
		goto Exit;
	for (curpage = 1; curpage <= page_count; curpage++) {
		pdf_page *page;
		if ((-1 != pageNo) && (pageNo != curpage))
			continue;
		page = benchloadpage(ctx, xref, curpage);
		if (page) {
			benchrenderpage(ctx, xref, page, curpage);
			pdf_free_page(xref, page);
		}
	}

Exit:
	logbench("Finished: %s\n", pdffilename);
	pdf_close_document(xref);
	fz_free_context(ctx);
}
예제 #5
0
static int TimeOneMethod(Doc&doc, TextRenderMethod method, const WCHAR *methodName) {
    SetTextRenderMethod(method);
    Timer t;
    int nPages = FormatWholeDoc(doc);
    double timesms = t.Stop();
    logbench(L"%s: %.2f ms", methodName, timesms);
    return nPages;
}
예제 #6
0
static void BenchFile(TCHAR *filePath, const TCHAR *pagesSpec)
{
    if (!file::Exists(filePath)) {
        return;
    }

    Timer total(true);
    logbench("Starting: %s", filePath);

    Timer t(true);
    BaseEngine *engine = EngineManager(!gUseEbookUI).CreateEngine(filePath);
    t.Stop();

    if (!engine) {
        logbench("Error: failed to load %s", filePath);
        return;
    }

    double timems = t.GetTimeInMs();
    logbench("load: %.2f ms", timems);
    int pages = engine->PageCount();
    logbench("page count: %d", pages);

    if (NULL == pagesSpec) {
        for (int i = 1; i <= pages; i++) {
            BenchLoadRender(engine, i);
        }
    }

    assert(!pagesSpec || IsBenchPagesInfo(pagesSpec));
    Vec<PageRange> ranges;
    if (ParsePageRanges(pagesSpec, ranges)) {
        for (size_t i = 0; i < ranges.Count(); i++) {
            for (int j = ranges.At(i).start; j <= ranges.At(i).end; j++) {
                if (1 <= j && j <= pages)
                    BenchLoadRender(engine, j);
            }
        }
    }

    delete engine;
    total.Stop();

    logbench("Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath);
}
예제 #7
0
pdf_page *benchloadpage(fz_context *ctx, pdf_document *xref, int pagenum)
{
	pdf_page *page = NULL;
	mstimer timer;

	timerstart(&timer);
	fz_try(ctx) {
		page = pdf_load_page(xref, pagenum - 1);
	}
	fz_catch(ctx) {
		logbench("Error: failed to load page %d\n", pagenum);
		return NULL;
	}
	timerstop(&timer);
	logbench("pageload   %3d: %.2f ms\n", pagenum, timeinms(&timer));

	return page;
}
예제 #8
0
static void BenchChmLoadOnly(const WCHAR* filePath) {
    Timer total;
    logbench(L"Starting: %s", filePath);

    Timer t;
    ChmModel* chmModel = ChmModel::Create(filePath, nullptr);
    if (!chmModel) {
        logbench(L"Error: failed to load %s", filePath);
        return;
    }

    double timeMs = t.Stop();
    logbench(L"load: %.2f ms", timeMs);

    delete chmModel;
    total.Stop();

    logbench(L"Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath);
}
예제 #9
0
void BenchFileOrDir(WStrVec& pathsToBench) {
    gLog = new slog::StderrLogger();

    size_t n = pathsToBench.size() / 2;
    for (size_t i = 0; i < n; i++) {
        WCHAR* path = pathsToBench.at(2 * i);
        if (file::Exists(path))
            BenchFile(path, pathsToBench.at(2 * i + 1));
        else if (dir::Exists(path))
            BenchDir(path);
        else
            logbench(L"Error: file or dir %s doesn't exist", path);
    }

    delete gLog;
}
예제 #10
0
pdf_document *openxref(fz_context *ctx, char *filename)
{
	pdf_document *xref = pdf_open_document(ctx, filename);

	fz_try(ctx)
	{
		if (pdf_needs_password(xref))
		{
			logbench("Warning: password protected document\n");
			fz_throw(ctx, "document requires password");
		}

		pdf_count_pages(xref);
	}
	fz_catch(ctx)
	{
		pdf_close_document(xref);
		fz_rethrow(ctx);
	}

	return xref;
}
예제 #11
0
// this is to compare the time it takes to layout a whole ebook file
// using different text measurement method (since the time is mostly
// dominated by text measure)
void BenchEbookLayout(const WCHAR *filePath) {
    bool deleteLog = false;
    if (!gLog) {
        gLog = new slog::StderrLogger();
        deleteLog = true;
    }
    logbench(L"Starting: %s", filePath);
    if (!file::Exists(filePath)) {
        logbench(L"Error: file doesn't exist");
        return;
    }
    if (!Doc::IsSupportedFile(filePath)) {
        logbench(L"Error: not an ebook file");
        return;
    }
    Timer t;
    Doc doc = Doc::CreateFromFile(filePath);
    if (doc.LoadingFailed()) {
        logbench(L"Error: failed to load the file as doc");
        doc.Delete();
        return;
    }
    double timeMs = t.Stop();
    logbench(L"load: %.2f ms", timeMs);

    int nPages = TimeOneMethod(doc, TextRenderMethodGdi,          L"gdi       ");
    TimeOneMethod(doc, TextRenderMethodGdiplus,      L"gdi+      ");
    TimeOneMethod(doc, TextRenderMethodGdiplusQuick, L"gdi+ quick");

    // do it twice because the first run is very unfair to the first version that runs
    // (probably because of font caching)
    TimeOneMethod(doc, TextRenderMethodGdi,          L"gdi       ");
    TimeOneMethod(doc, TextRenderMethodGdiplus,      L"gdi+      ");
    TimeOneMethod(doc, TextRenderMethodGdiplusQuick, L"gdi+ quick");

    doc.Delete();

    logbench(L"pages: %d", nPages);
    if (deleteLog) {
        delete gLog;
    }
}