core: move to hyprgraphics

This commit is contained in:
Vaxry 2024-11-28 15:55:23 +00:00
parent 578246b996
commit acb1e10190
9 changed files with 43 additions and 253 deletions

View file

@ -57,7 +57,8 @@ pkg_check_modules(
libdrm
gbm
hyprutils>=0.2.3
sdbus-c++>=2.0.0)
sdbus-c++>=2.0.0
hyprgraphics)
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
add_executable(hyprlock ${SRCFILES})

6
src/defines.hpp Normal file
View file

@ -0,0 +1,6 @@
#pragma once
#include <hyprutils/memory/WeakPtr.hpp>
using namespace Hyprutils::Memory;
#define SP CSharedPointer
#define WP CWeakPointer

View file

@ -1,75 +0,0 @@
#include "Jpeg.hpp"
#include "Log.hpp"
#include <jpeglib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
cairo_surface_t* JPEG::createSurfaceFromJPEG(const std::filesystem::path& path) {
if (!std::filesystem::exists(path)) {
Debug::log(ERR, "createSurfaceFromJPEG: file doesn't exist??");
return nullptr;
}
if (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__) {
Debug::log(CRIT, "tried to load a jpeg on a big endian system! ping vaxry he is lazy.");
return nullptr;
}
void* imageRawData;
struct stat fileInfo = {};
const auto FD = open(path.c_str(), O_RDONLY);
fstat(FD, &fileInfo);
imageRawData = malloc(fileInfo.st_size);
read(FD, imageRawData, fileInfo.st_size);
close(FD);
// now the JPEG is in the memory
jpeg_decompress_struct decompressStruct = {};
jpeg_error_mgr errorManager = {};
decompressStruct.err = jpeg_std_error(&errorManager);
jpeg_create_decompress(&decompressStruct);
jpeg_mem_src(&decompressStruct, (const unsigned char*)imageRawData, fileInfo.st_size);
jpeg_read_header(&decompressStruct, true);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
decompressStruct.out_color_space = JCS_EXT_BGRA;
#else
decompressStruct.out_color_space = JCS_EXT_ARGB;
#endif
// decompress
jpeg_start_decompress(&decompressStruct);
auto cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, decompressStruct.output_width, decompressStruct.output_height);
if (cairo_surface_status(cairoSurface) != CAIRO_STATUS_SUCCESS) {
Debug::log(ERR, "createSurfaceFromJPEG: Cairo Failed (?)");
return nullptr;
}
const auto CAIRODATA = cairo_image_surface_get_data(cairoSurface);
const auto CAIROSTRIDE = cairo_image_surface_get_stride(cairoSurface);
JSAMPROW rowRead;
while (decompressStruct.output_scanline < decompressStruct.output_height) {
const auto PROW = CAIRODATA + (decompressStruct.output_scanline * CAIROSTRIDE);
rowRead = PROW;
jpeg_read_scanlines(&decompressStruct, &rowRead, 1);
}
cairo_surface_flush(cairoSurface);
cairo_surface_mark_dirty(cairoSurface);
cairo_surface_set_mime_data(cairoSurface, CAIRO_MIME_TYPE_JPEG, (const unsigned char*)imageRawData, fileInfo.st_size, free, imageRawData);
jpeg_finish_decompress(&decompressStruct);
jpeg_destroy_decompress(&decompressStruct);
return cairoSurface;
}

View file

@ -1,8 +0,0 @@
#pragma once
#include <filesystem>
#include <cairo/cairo.h>
namespace JPEG {
cairo_surface_t* createSurfaceFromJPEG(const std::filesystem::path&);
};

View file

@ -1,84 +0,0 @@
#include "Webp.hpp"
#include "Log.hpp"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <webp/decode.h>
cairo_surface_t* WEBP::createSurfaceFromWEBP(const std::filesystem::path& path) {
if (!std::filesystem::exists(path)) {
Debug::log(ERR, "createSurfaceFromWEBP: file doesn't exist??");
return nullptr;
}
void* imageRawData;
struct stat fileInfo = {};
const auto FD = open(path.c_str(), O_RDONLY);
fstat(FD, &fileInfo);
imageRawData = malloc(fileInfo.st_size);
read(FD, imageRawData, fileInfo.st_size);
close(FD);
// now the WebP is in the memory
WebPDecoderConfig config;
if (!WebPInitDecoderConfig(&config)) {
Debug::log(CRIT, "WebPInitDecoderConfig Failed");
return nullptr;
}
if (WebPGetFeatures((const unsigned char*)imageRawData, fileInfo.st_size, &config.input) != VP8_STATUS_OK) {
Debug::log(ERR, "createSurfaceFromWEBP: file is not webp format");
free(imageRawData);
return nullptr;
}
const auto HEIGHT = config.input.height;
const auto WIDTH = config.input.width;
auto cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
if (cairo_surface_status(cairoSurface) != CAIRO_STATUS_SUCCESS) {
Debug::log(CRIT, "createSurfaceFromWEBP: Cairo Failed (?)");
cairo_surface_destroy(cairoSurface);
return nullptr;
}
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
config.output.colorspace = MODE_bgrA;
#else
config.output.colorspace = MODE_Argb;
#endif
const auto CAIRODATA = cairo_image_surface_get_data(cairoSurface);
const auto CAIROSTRIDE = cairo_image_surface_get_stride(cairoSurface);
config.options.no_fancy_upsampling = 1;
config.output.u.RGBA.rgba = CAIRODATA;
config.output.u.RGBA.stride = CAIROSTRIDE;
config.output.u.RGBA.size = CAIROSTRIDE * HEIGHT;
config.output.is_external_memory = 1;
config.output.width = WIDTH;
config.output.height = HEIGHT;
if (WebPDecode((const unsigned char*)imageRawData, fileInfo.st_size, &config) != VP8_STATUS_OK) {
Debug::log(CRIT, "createSurfaceFromWEBP: WebP Decode Failed (?)");
return nullptr;
}
cairo_surface_flush(cairoSurface);
cairo_surface_mark_dirty(cairoSurface);
cairo_surface_set_mime_data(cairoSurface, CAIRO_MIME_TYPE_PNG, (const unsigned char*)imageRawData, fileInfo.st_size, free, imageRawData);
WebPFreeDecBuffer(&config.output);
return cairoSurface;
}

View file

@ -1,8 +0,0 @@
#pragma once
#include <filesystem>
#include <cairo/cairo.h>
namespace WEBP {
cairo_surface_t* createSurfaceFromWEBP(const std::filesystem::path&);
};

View file

@ -8,10 +8,10 @@
#include <filesystem>
#include "../core/hyprlock.hpp"
#include "../helpers/MiscFunctions.hpp"
#include "../helpers/Jpeg.hpp"
#include "../helpers/Webp.hpp"
#include "src/helpers/Color.hpp"
#include "src/helpers/Log.hpp"
#include <hyprgraphics/image/Image.hpp>
using namespace Hyprgraphics;
CAsyncResourceGatherer::CAsyncResourceGatherer() {
if (g_pHyprlock->getScreencopy())
@ -81,56 +81,15 @@ SPreloadedAsset* CAsyncResourceGatherer::getAssetByID(const std::string& id) {
return nullptr;
}
enum class FileType {
PNG,
JPEG,
WEBP,
UNKNOWN,
};
static SP<CCairoSurface> getCairoSurfaceFromImageFile(const std::filesystem::path& path) {
FileType getFileType(const std::filesystem::path& path) {
std::string ext = path.extension().string();
// convert the extension to lower case
std::transform(ext.begin(), ext.end(), ext.begin(), [](char c) { return c <= 'Z' && c >= 'A' ? c - ('Z' - 'z') : c; });
FileType ft = FileType::UNKNOWN;
Debug::log(TRACE, "Extension: {}", ext);
if (ext == ".png")
ft = FileType::PNG;
else if (ext == ".jpg" || ext == ".jpeg")
ft = FileType::JPEG;
else if (ext == ".webp")
ft = FileType::WEBP;
else {
// magic is slow, so only use it when no recognized extension is found
auto handle = magic_open(MAGIC_NONE | MAGIC_COMPRESS | MAGIC_SYMLINK);
magic_load(handle, nullptr);
const auto type_str = std::string(magic_file(handle, path.c_str()));
const auto first_word = type_str.substr(0, type_str.find(" "));
magic_close(handle);
if (first_word == "PNG")
ft = FileType::PNG;
else if (first_word == "JPEG")
ft = FileType::JPEG;
else if (first_word == "RIFF" && type_str.find("Web/P image") != std::string::npos)
ft = FileType::WEBP;
auto image = CImage(path);
if (!image.success()) {
Debug::log(ERR, "Image {} could not be loaded: {}", path.string(), image.getError());
return nullptr;
}
return ft;
}
cairo_surface_t* getCairoSurfaceFromImageFile(const std::filesystem::path& path) {
cairo_surface_t* cairoSurface = nullptr;
switch (getFileType(path)) {
case FileType::PNG: cairoSurface = cairo_image_surface_create_from_png(path.c_str()); break;
case FileType::JPEG: cairoSurface = JPEG::createSurfaceFromJPEG(path); break;
case FileType::WEBP: cairoSurface = WEBP::createSurfaceFromWEBP(path); break;
default: Debug::log(ERR, "unrecognized image format of {}", path.c_str());
}
return cairoSurface;
return image.cairoSurface();
}
void CAsyncResourceGatherer::gather() {
@ -194,8 +153,8 @@ bool CAsyncResourceGatherer::apply() {
if (t.type == TARGET_IMAGE) {
const auto ASSET = &assets[t.id];
const auto SURFACESTATUS = cairo_surface_status((cairo_surface_t*)t.cairosurface);
const auto CAIROFORMAT = cairo_image_surface_get_format((cairo_surface_t*)t.cairosurface);
const cairo_status_t SURFACESTATUS = (cairo_status_t)t.cairosurface->status();
const auto CAIROFORMAT = cairo_image_surface_get_format(t.cairosurface->cairo());
const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA;
const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA;
const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE;
@ -218,11 +177,9 @@ bool CAsyncResourceGatherer::apply() {
glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, ASSET->texture.m_vSize.x, ASSET->texture.m_vSize.y, 0, glFormat, glType, t.data);
cairo_destroy((cairo_t*)t.cairo);
cairo_surface_destroy((cairo_surface_t*)t.cairosurface);
} else {
Debug::log(ERR, "Unsupported type in ::apply() {}", (int)t.type);
}
t.cairosurface.reset();
} else
Debug::log(ERR, "Unsupported type in ::apply(): {}", (int)t.type);
}
return true;
@ -237,17 +194,17 @@ void CAsyncResourceGatherer::renderImage(const SPreloadRequest& rq) {
const auto CAIROISURFACE = getCairoSurfaceFromImageFile(ABSOLUTEPATH);
if (!CAIROISURFACE) {
Debug::log(ERR, "No cairo surface!");
Debug::log(ERR, "renderImage: No cairo surface!");
return;
}
const auto CAIRO = cairo_create(CAIROISURFACE);
const auto CAIRO = cairo_create(CAIROISURFACE->cairo());
cairo_scale(CAIRO, 1, 1);
target.cairo = CAIRO;
target.cairosurface = CAIROISURFACE;
target.data = cairo_image_surface_get_data(CAIROISURFACE);
target.size = {(double)cairo_image_surface_get_width(CAIROISURFACE), (double)cairo_image_surface_get_height(CAIROISURFACE)};
target.data = CAIROISURFACE->data();
target.size = CAIROISURFACE->size();
std::lock_guard lg{preloadTargetsMutex};
preloadTargets.push_back(target);
@ -271,8 +228,8 @@ void CAsyncResourceGatherer::renderText(const SPreloadRequest& rq) {
TEXT.erase(TEXT.find_last_not_of(" \n\r\t") + 1);
}
auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1920, 1080 /* dummy value */);
auto CAIRO = cairo_create(CAIROSURFACE);
auto CAIROSURFACE = makeShared<CCairoSurface>(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1920, 1080 /* dummy value */));
auto CAIRO = cairo_create(CAIROSURFACE->cairo());
// draw title using Pango
PangoLayout* layout = pango_cairo_create_layout(CAIRO);
@ -319,9 +276,8 @@ void CAsyncResourceGatherer::renderText(const SPreloadRequest& rq) {
// TODO: avoid this?
cairo_destroy(CAIRO);
cairo_surface_destroy(CAIROSURFACE);
CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, layoutWidth / PANGO_SCALE, layoutHeight / PANGO_SCALE);
CAIRO = cairo_create(CAIROSURFACE);
CAIROSURFACE = makeShared<CCairoSurface>(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, layoutWidth / PANGO_SCALE, layoutHeight / PANGO_SCALE));
CAIRO = cairo_create(CAIROSURFACE->cairo());
// clear the pixmap
cairo_save(CAIRO);
@ -337,11 +293,11 @@ void CAsyncResourceGatherer::renderText(const SPreloadRequest& rq) {
g_object_unref(layout);
cairo_surface_flush(CAIROSURFACE);
cairo_surface_flush(CAIROSURFACE->cairo());
target.cairo = CAIRO;
target.cairosurface = CAIROSURFACE;
target.data = cairo_image_surface_get_data(CAIROSURFACE);
target.data = CAIROSURFACE->data();
target.size = {layoutWidth / (double)PANGO_SCALE, layoutHeight / (double)PANGO_SCALE};
std::lock_guard lg{preloadTargetsMutex};

View file

@ -8,6 +8,7 @@
#include <condition_variable>
#include <any>
#include "Shared.hpp"
#include <hyprgraphics/cairo/CairoSurface.hpp>
class CAsyncResourceGatherer {
public:
@ -67,9 +68,9 @@ class CAsyncResourceGatherer {
eTargetType type = TARGET_IMAGE;
std::string id = "";
void* data;
void* cairo;
void* cairosurface;
void* data = nullptr;
void* cairo = nullptr;
SP<Hyprgraphics::CCairoSurface> cairosurface;
Vector2D size;
};

View file

@ -1,5 +1,6 @@
#pragma once
#include "Texture.hpp"
#include "../defines.hpp"
struct SPreloadedAsset {
CTexture texture;