OHP3D.cpp
branchv_0
changeset 30 02972f051744
parent 29 dc3c102e1264
child 31 ed3caeea978a
--- a/OHP3D.cpp	Wed Dec 27 01:50:38 2023 +0100
+++ b/OHP3D.cpp	Wed Dec 27 10:34:12 2023 +0100
@@ -23,13 +23,21 @@
 #include <functional>
 #include <sstream>
 #include <vector>
+#include <chrono>
+#include <unistd.h>
+
+#include <poppler/cpp/poppler-document.h>
+#include <poppler/cpp/poppler-page.h>
+#include <poppler/cpp/poppler-toc.h>
+#include <sys/stat.h>
+#include <poppler/cpp/poppler-page-renderer.h>
 
 #include "x11.h"
 #include "opengl.h"
 #include "EPoll.h"
 #include "Logger.h"
 #include "MappedFile.h"
-#include "ImageLoader.h"
+#include "PageBuffer.h"
 #include "Texture.h"
 #include "Shader.h"
 #include "Program.h"
@@ -166,7 +174,6 @@
 
 	FileMonitor fileMonitor;
 	std::vector<WatchedFile> watchedFiles;
-	ImageLoader imageLoader;
 	std::vector<std::shared_ptr<Shader>> shaders;
 	std::shared_ptr<Program> shaderProgram;
 	std::vector<std::shared_ptr<Texture>> textures;
@@ -184,9 +191,7 @@
 	void log(LogLevel level, std::string message);
 	int setNonBlocking(int fd);
 	void loadVertices();
-	void parametrizeTexture(std::shared_ptr<Texture> tex);
-	bool reloadTexture(const std::string& fileName);
-	void loadTextures();
+	void loadDocuments();
 	void loadShaders();
 	void updateVariableLocations();
 	bool reloadShader(const std::string& fileName);
@@ -271,9 +276,8 @@
 	glXSwapBuffers(dpy, win);
 
 
-	// Load GLSL shaders:
 	loadShaders();
-	loadTextures();
+	loadDocuments();
 	loadVertices();
 
 	auto toggleFullscreen = [&]() {
@@ -409,7 +413,6 @@
 							<< " mask=" << fe.mask
 							<< std::endl;
 					try {
-						redraw |= reloadTexture(fe.fileName);
 						redraw |= reloadShader(fe.fileName);
 						setTitle();
 					} catch (const std::exception& e) {
@@ -548,66 +551,57 @@
 	}
 }
 
-void OHP3D::Impl::parametrizeTexture(std::shared_ptr<Texture> tex) {
-	XAttrs xa(tex->getFileName());
-	std::string magf = xa["ohp3d.texture.mag-filter"];
-	std::string minf = xa["ohp3d.texture.min-filter"];
-	std::string scale = xa["ohp3d.texture.scale"];
+void OHP3D::Impl::loadDocuments() {
+	for (const Configuration::File& document : cfg.documents) {
+		std::cerr << "loading document: " << document.fileName.c_str() << "\n";
+
+		MappedFile buffer(document.fileName);
 
-	auto GLT2D = GL_TEXTURE_2D;
-	auto MAG = GL_TEXTURE_MAG_FILTER;
-	auto MIN = GL_TEXTURE_MIN_FILTER;
+		namespace pp = poppler;
+		using Document = pp::document;
+
+		std::shared_ptr<Document> doc = std::shared_ptr<Document>(
+				Document::load_from_raw_data(buffer.getData(), buffer.getSize()));
 
-	if (magf == "linear") glTexParameteri(GLT2D, MAG, GL_LINEAR);
-	else if (magf == "nearest") glTexParameteri(GLT2D, MAG, GL_NEAREST);
-
-	if (minf == "linear") glTexParameteri(GLT2D, MIN, GL_LINEAR);
-	else if (minf == "nearest") glTexParameteri(GLT2D, MIN, GL_NEAREST);
+		log(LogLevel::INFO, std::string("PDF parsed:")
+				+ " pages=" + std::to_string(doc->pages()));
 
-	if (scale.size()) {
-		float sc;
-		if (std::from_chars(scale.data(), scale.data() + scale.size(), sc).ec
-				== std::errc{}) tex->setScale(sc);
-		else std::cerr << "Invalid texture scale value - expecting float\n";
-		// tex->setScale(std::stof(scale)); // locale-dependent (. vs ,)
-	}
-}
+		log(LogLevel::INFO, "loadig pages to textures...");
+		auto timingStart = std::chrono::steady_clock::now();
+		pp::page_renderer renderer;
+		renderer.set_image_format(pp::image::format_rgb24);
+		double dpi = cfg.dpi;
+		for (int i = 0, limit = doc->pages(); i < limit; i++) {
+			std::shared_ptr<pp::page> page(doc->create_page(i));
+			pp::image pageImage = renderer.render_page(page.get(), dpi, dpi);
 
-void OHP3D::Impl::loadTextures() {
-	// Load default texture if there is no configured:
-	if (cfg.textures.empty())
-		cfg.textures.push_back({getDefaultFile("textures/default.png")});
+			PageBuffer img(
+					pageImage.data(),
+					pageImage.bytes_per_row() * pageImage.height(),
+					pageImage.width(), pageImage.height());
+
+			textures.push_back(std::make_shared<Texture>(
+					pageImage.width(), pageImage.height(),
+					img, document.fileName));
+			log(LogLevel::INFO, "  page " + std::to_string(i + 1)
+					+ "/" + std::to_string(limit));
+		}
 
-	for (const Configuration::Texture& tex : cfg.textures) {
-		std::shared_ptr<ImageLoader::ImageBuffer>
-				img(imageLoader.loadImage(MappedFile(tex.fileName)));
-		textures.push_back(std::make_shared<Texture>(
-				img->width, img->height, *img, tex.fileName));
-		parametrizeTexture(textures.back());
-		// static const uint32_t watchMask = IN_CLOSE_WRITE | IN_ATTRIB;
-		// watchedFiles.push_back(fileMonitor.watch(tex.fileName, watchMask));
-		watchedFiles.push_back(fileMonitor.watch(tex.fileName));
-		// TODO: review texture loading and binding
-		// works even without this - default texture
-		// glUniform1i(..., ...);
-		// checkError(&std::cerr);
+		auto timingEnd = std::chrono::steady_clock::now();
+		auto timingTotal = std::chrono::duration_cast<std::chrono::microseconds>
+				(timingEnd - timingStart).count();
+
+		std::stringstream timingMsg;
+		timingMsg.imbue(std::locale(""));
+		timingMsg << "PDF to texture load time:"
+				<< " page average = " << (timingTotal / doc->pages()) << " µs,"
+				<< " total = " << timingTotal << " µs ("
+				<< doc->pages() << " pages)";
+		log(LogLevel::INFO, timingMsg.str());
+		if (timingTotal < 400000) logOutput << ">>> Doherty threshold met! <<<\n";
 	}
 }
 
-bool OHP3D::Impl::reloadTexture(const std::string& fileName) {
-	for (std::shared_ptr<Texture> tex : textures) {
-		if (tex->getFileName() == fileName) {
-			std::shared_ptr<ImageLoader::ImageBuffer>
-					img(imageLoader.loadImage(MappedFile(fileName)));
-			tex->update(img->width, img->height, *img);
-			parametrizeTexture(tex);
-			loadVertices();
-			return true;
-		}
-	}
-	return false;
-}
-
 void OHP3D::Impl::loadShaders() {
 	// Vertex Array Object (VAO)
 	GLuint vao;