Apply the style guide

This commit is contained in:
p
2026-09-07 16:16:29 +02:00
parent b702bdbaf1
commit 58d1f7980c
59 changed files with 655 additions and 630 deletions
+2 -2
View File
@@ -150,8 +150,8 @@ std::span<const Action> window_keys();
std::span<const Action> browser_keys();
std::span<const Action> viewer_keys();
void copy_files(QMimeData *mime, std::span<const QUrl> urls, bool cut = false);
void copy_files(std::span<const QUrl> urls, bool cut = false);
void copy_files(QMimeData *mime, std::span<const QUrl> urls, bool cut);
void copy_files(std::span<const QUrl> urls, bool cut);
bool move_to_trash(const QString &abs_path);
} // namespace dn
+3 -3
View File
@@ -163,7 +163,7 @@ sync_hidden(NSMenu *main, id delegate, span<const dn::MenuNode> tree)
- (BOOL)performKeyEquivalent:(NSEvent *)event
{
(void)event;
(void) event;
return NO;
}
@@ -334,8 +334,8 @@ adopt_app_menu(id target)
if ([loader respondsToSelector:@selector(aboutMenuItem)])
claim_item([loader aboutMenuItem], Action::About, target, @"", 0);
if ([loader respondsToSelector:@selector(preferencesMenuItem)])
claim_item([loader preferencesMenuItem], Action::Settings, target,
@",", NSEventModifierFlagCommand);
claim_item([loader preferencesMenuItem], Action::Settings, target, @",",
NSEventModifierFlagCommand);
}
void
+3 -4
View File
@@ -305,8 +305,7 @@ void
Settings::toggle_bookmark(const string &path)
{
const string want = canonical_dir(path);
const auto it =
find(this->bookmarks.begin(), this->bookmarks.end(), want);
const auto it = find(this->bookmarks.begin(), this->bookmarks.end(), want);
if (it != this->bookmarks.end())
this->bookmarks.erase(it);
else
@@ -350,7 +349,7 @@ App::event(QEvent *event)
return true;
}
if (event->type() == QEvent::FileOpen) {
open(url_normalized(((QFileOpenEvent *) event)->url()));
open(url_normalized(((QFileOpenEvent *) event)->url()), {}, {}, false);
return true;
}
return QGuiApplication::event(event);
@@ -473,7 +472,7 @@ App::open(const QUrl &url, const QString &activation_token, BrowseSetup setup,
}
#endif
auto window = make_unique<Window>(this);
auto window = make_unique<Window>(this, nullptr);
if (!window->initialize(resolved, setup, browse))
return OpenResult::Internal;
apply_activation_token(activation_token);
+6 -3
View File
@@ -84,7 +84,10 @@ protected:
bool event(QEvent *event) override;
public:
App(int &argc, char **argv) : QGuiApplication(argc, argv) {}
App(int &argc, char **argv)
: QGuiApplication(argc, argv), thumbnailer(nullptr, 0)
{
}
QVulkanInstance vulkan_instance;
GpuContext gpu;
@@ -96,8 +99,8 @@ public:
bool needs_csd = false;
bool init();
OpenResult open(const QUrl &url, const QString &activation_token = {},
BrowseSetup setup = {}, bool browse = false);
OpenResult open(const QUrl &url, const QString &activation_token,
BrowseSetup setup, bool browse);
void close(const QWindow *top);
void close_later(const QWindow *top);
// Not quit(): that name is taken by a static QCoreApplication slot,
+6 -6
View File
@@ -125,7 +125,7 @@ recommended_for(const QString &path)
const Handler def = default_for(path);
vector<Handler> out;
const CFIndex n = CFArrayGetCount(handlers);
for (CFIndex i = 0; i < n; ++i) {
for (CFIndex i = 0; i < n; i++) {
NSString *bid =
(__bridge NSString *) CFArrayGetValueAtIndex(handlers, i);
NSURL *app_url = app_url_for_bundle_id(bid);
@@ -172,11 +172,11 @@ launch(const Handler &app, const QString &path)
// The launch is asynchronous, so failures can only be reported later,
// and the caller has nothing to do with them anyway.
[[NSWorkspace sharedWorkspace] openURLs:@[ file ]
withApplicationAtURL:app_url
configuration:[NSWorkspaceOpenConfiguration
configuration]
completionHandler:nil];
[[NSWorkspace sharedWorkspace]
openURLs:@[ file ]
withApplicationAtURL:app_url
configuration:[NSWorkspaceOpenConfiguration configuration]
completionHandler:nil];
return true;
}
+25 -26
View File
@@ -218,19 +218,19 @@ apply_mimeapps(AssocSets &acc, const IniFile &ini, const QString &type)
const string type_utf8 = type.toUtf8().toStdString();
for (const IniGroup &group : ini.groups) {
if (group.name == "Default Applications") {
for (const QString &id : split_semicolons(
dawn::detail::ini_get(group, type_utf8)))
for (const QString &id :
split_semicolons(dawn::detail::ini_get(group, type_utf8)))
append_unique(acc.defaults, normalize_desktop_id(id));
} else if (group.name == "Added Associations") {
for (const QString &id : split_semicolons(
dawn::detail::ini_get(group, type_utf8))) {
for (const QString &id :
split_semicolons(dawn::detail::ini_get(group, type_utf8))) {
const QString nid = normalize_desktop_id(id);
if (!acc.removed.contains(nid))
append_unique(acc.added, nid);
}
} else if (group.name == "Removed Associations") {
for (const QString &id : split_semicolons(
dawn::detail::ini_get(group, type_utf8))) {
for (const QString &id :
split_semicolons(dawn::detail::ini_get(group, type_utf8))) {
const QString nid = normalize_desktop_id(id);
if (find(acc.added.begin(), acc.added.end(), nid) ==
acc.added.end())
@@ -268,8 +268,8 @@ cache_ids_for_type(const QString &type)
for (const IniGroup &group : ini.groups) {
if (group.name != "MIME Cache")
continue;
for (const QString &id : split_semicolons(
dawn::detail::ini_get(group, type_utf8)))
for (const QString &id :
split_semicolons(dawn::detail::ini_get(group, type_utf8)))
append_unique(ids, normalize_desktop_id(id));
}
}
@@ -283,7 +283,7 @@ desktop_path_for_name(const QString &dir, QString name, int from)
if (QFileInfo::exists(path))
return path;
for (int i = from; i < name.size(); ++i) {
for (int i = from; i < name.size(); i++) {
if (name[i] != u'-')
continue;
@@ -345,10 +345,10 @@ localized_value(const IniGroup &entry, const QString &key)
}
if (!item_key.startsWith(prefix) || !item_key.endsWith(u']'))
continue;
const QString loc = item_key.mid(
prefix.size(), item_key.size() - prefix.size() - 1);
localized.insert({loc, QString::fromStdString(
dawn::detail::desktop_unescape(kv.second))});
const QString loc =
item_key.mid(prefix.size(), item_key.size() - prefix.size() - 1);
localized.insert({loc,
QString::fromStdString(dawn::detail::desktop_unescape(kv.second))});
}
for (const QString &loc : locale_candidates()) {
const auto it = localized.find(loc);
@@ -434,15 +434,14 @@ load_desktop(const QString &id)
if (!entry)
return d;
const QString type = QString::fromStdString(
dawn::detail::ini_get(*entry, "Type"))
.trimmed();
const QString type =
QString::fromStdString(dawn::detail::ini_get(*entry, "Type")).trimmed();
d.application = type.isEmpty() || type == QLatin1String("Application");
d.name = localized_name(*entry);
d.icon = QString::fromStdString(dawn::detail::desktop_unescape(
dawn::detail::ini_get(*entry, "Icon")));
d.exec = QString::fromStdString(dawn::detail::desktop_unescape(
dawn::detail::ini_get(*entry, "Exec")));
d.icon = QString::fromStdString(
dawn::detail::desktop_unescape(dawn::detail::ini_get(*entry, "Icon")));
d.exec = QString::fromStdString(
dawn::detail::desktop_unescape(dawn::detail::ini_get(*entry, "Exec")));
d.try_exec = QString::fromStdString(dawn::detail::desktop_unescape(
dawn::detail::ini_get(*entry, "TryExec")));
d.hidden = parse_bool(dawn::detail::ini_get(*entry, "Hidden"));
@@ -535,7 +534,7 @@ split_exec(const QString &exec)
vector<QString> args;
QString cur;
bool in_quote = false;
for (int i = 0; i < exec.size(); ++i) {
for (int i = 0; i < exec.size(); i++) {
const QChar c = exec[i];
if (in_quote) {
if (c == u'\\' && i + 1 < exec.size()) {
@@ -590,7 +589,7 @@ expand_exec(const Desktop &d, const QString &path)
continue;
}
QString built;
for (int i = 0; i < arg.size(); ++i) {
for (int i = 0; i < arg.size(); i++) {
if (arg[i] != u'%' || i + 1 >= arg.size()) {
built += arg[i];
continue;
@@ -797,10 +796,10 @@ set_last_used(const Handler &app, const QString &path)
}
};
const string type_utf8 = type.toUtf8().toStdString();
const QString previous = QString::fromStdString(
dawn::detail::ini_get(*added, type_utf8));
dawn::detail::ini_set(*added, type_utf8,
prepend_id(previous, id).toUtf8().toStdString());
const QString previous =
QString::fromStdString(dawn::detail::ini_get(*added, type_utf8));
dawn::detail::ini_set(
*added, type_utf8, prepend_id(previous, id).toUtf8().toStdString());
if (removed)
drop_id(*removed, type);
write_text_file(dest, dawn::detail::ini_serialize(ini));
+2 -2
View File
@@ -107,7 +107,7 @@ load_from_client(CdClient *client, const QScreen *screen)
CdDevice *matched = nullptr;
string method;
for (guint i = 0; i < devices->len; ++i) {
for (guint i = 0; i < devices->len; i++) {
auto *device = static_cast<CdDevice *>(g_ptr_array_index(devices, i));
if (!cd_device_connect_sync(device, nullptr, &error)) {
g_clear_error(&error);
@@ -123,7 +123,7 @@ load_from_client(CdClient *client, const QScreen *screen)
}
if (!matched) {
if (auto edid_md5 = edid_md5_for_connector(connector)) {
for (guint i = 0; i < devices->len; ++i) {
for (guint i = 0; i < devices->len; i++) {
auto *device =
static_cast<CdDevice *>(g_ptr_array_index(devices, i));
const char *md5 = cd_device_get_metadata_item(
+1 -1
View File
@@ -47,7 +47,7 @@ load_display_profile(QScreen *screen)
return result;
MONITORINFOEXW monitor{};
monitor.cbSize = sizeof(monitor);
monitor.cbSize = sizeof monitor;
if (!GetMonitorInfoW(native->handle(), &monitor))
return result;
HDC dc = CreateDCW(L"DISPLAY", monitor.szDevice, nullptr, nullptr);
+1 -1
View File
@@ -24,7 +24,7 @@ class InstanceHost : public QObject
public:
// Takes over the bound listener. Forwards Open requests to app.open.
InstanceHost(dawn::ipc::Listener listener, App &app, QString session,
QObject *parent = nullptr);
QObject *parent);
~InstanceHost() override;
private:
+31 -30
View File
@@ -270,7 +270,7 @@ url_of(const string &path)
static int
thumb_size_index(int size)
{
for (int i = 0; i < kThumbSizeN; ++i) {
for (int i = 0; i < kThumbSizeN; i++) {
if (kThumbSizes[i] == size)
return i;
}
@@ -315,7 +315,7 @@ profile_from_icc(dawn::Cmm &cmm, const shared_ptr<const vector<uint8_t>> &icc)
if (auto profile = cmm.get_profile(*icc))
return profile;
}
return cmm.get_profile_sRGB();
return cmm.get_profile_sRGB(false);
}
static int
@@ -565,7 +565,7 @@ static void
copy_bgra16(const dawn::Image &src, uint16_t *dst, uint32_t dw, uint32_t dh)
{
const size_t packed = size_t(dw) * dawn::kBytesPerPixel;
for (uint32_t y = 0; y < dh; ++y)
for (uint32_t y = 0; y < dh; y++)
memcpy(dst + size_t(y) * dw * 4, dawn::row_u16(src, y), packed);
}
@@ -585,7 +585,7 @@ make_thumb(shared_ptr<dawn::Cmm> cmm, const ThumbJob &job)
if (job.pending) {
if (const ThumbnailTierPixels *pixels = job.pending->find(tier)) {
result.ram = *pixels->pixels;
shared_ptr<dawn::Profile> p3 = cmm->get_profile_display_p3();
shared_ptr<dawn::Profile> p3 = cmm->get_profile_display_p3(false);
if (p3 && screen && !result.ram.empty() &&
cmm->transform_bgra16(
reinterpret_cast<uint8_t *>(result.ram.data()),
@@ -634,7 +634,8 @@ make_thumb(shared_ptr<dawn::Cmm> cmm, const ThumbJob &job)
dawn::OpenContext ctx;
ctx.uri = job.path;
ctx.cmm = cmm;
ctx.screen_profile = job.cacheable ? cmm->get_profile_display_p3() : screen;
ctx.screen_profile =
job.cacheable ? cmm->get_profile_display_p3(false) : screen;
ctx.first_frame_only = true;
ctx.screen_dpi = 96;
@@ -722,7 +723,7 @@ display_thumb(Browser *browser, FinishJob job)
update.ram_tier = job.tier;
auto cmm = worker_cmm();
shared_ptr<dawn::Profile> p3 = cmm->get_profile_display_p3();
shared_ptr<dawn::Profile> p3 = cmm->get_profile_display_p3(false);
shared_ptr<dawn::Profile> screen = profile_from_icc(*cmm, job.screen_icc);
vector<uint16_t> display = job.pixels ? *job.pixels : vector<uint16_t>{};
if (p3 && screen && !display.empty() &&
@@ -829,7 +830,7 @@ clear_gpu(Browser &b)
static void
invalidate_thumbs(Browser &b)
{
++b.thumb_gen_;
b.thumb_gen_++;
b.thumbnailer_.set_epoch(b.thumbnail_client_, b.thumb_gen_);
b.thumb_inflight_.clear();
reset_thumb_atlas(b);
@@ -865,7 +866,7 @@ trim_ram(Browser &b)
const float pad = row_h(b) * kPrefetchRows;
const float mid = b.r.y + b.r.h * 0.5f;
vector<int> idx;
for (int i = 0; i < int(b.files_.size()); ++i) {
for (int i = 0; i < int(b.files_.size()); i++) {
const Browser::File &f = b.files_[size_t(i)];
if (f.ram.empty() || f.ram_pending || thumb_in_band(b, f, pad))
continue;
@@ -906,8 +907,8 @@ push_gpu(Browser &b, Browser::File &f, const Sheet::Packed &slot)
for (Browser::File &o : b.files_) {
if (o.gpu.empty() || o.ram.empty())
continue;
if (!r->upload_thumb(
o.ram.data(), o.ram_w, o.ram_h, o.gpu.x, o.gpu.y, b.sheet_.w))
if (!r->upload_thumb(o.ram.data(), o.ram_w, o.ram_h, o.gpu.x, o.gpu.y,
b.sheet_.w, nullptr))
return false;
}
return true;
@@ -954,7 +955,7 @@ repack_atlas(Browser &b, Browser::File &wanted)
continue;
vector<ThumbUpload> uploads;
uploads.reserve(active.size());
for (size_t i = 0; i < active.size(); ++i) {
for (size_t i = 0; i < active.size(); i++) {
Browser::File &f = *active[i];
const Sheet::Packed &slot = placements[i];
uploads.push_back(
@@ -964,7 +965,7 @@ repack_atlas(Browser &b, Browser::File &wanted)
return false;
for (Browser::File &f : b.files_)
f.gpu = {};
for (size_t i = 0; i < active.size(); ++i)
for (size_t i = 0; i < active.size(); i++)
active[i]->gpu = placements[i];
b.sheet_ = std::move(fresh);
return !wanted.gpu.empty();
@@ -1205,7 +1206,7 @@ enqueue_thumbs(Browser &b)
const int target_tier = thumbnail_tier_for_height(
max(1, int(ceil(double(b.thumb_size_) * double(b.kit_.dpr_)))));
vector<int> vis, pre, background;
for (int i = 0; i < int(b.files_.size()); ++i) {
for (int i = 0; i < int(b.files_.size()); i++) {
const Browser::File &f = b.files_[size_t(i)];
const bool visible = thumb_in_band(b, f, 0.f);
const bool prefetched = !visible && thumb_in_band(b, f, pad);
@@ -1324,7 +1325,7 @@ find_cursor_row(const Browser &b)
{
if (b.cursor_ < 0)
return -1;
for (int i = 0; i < int(b.rows_.size()); ++i) {
for (int i = 0; i < int(b.rows_.size()); i++) {
const Browser::GridRow &row = b.rows_[size_t(i)];
if (b.cursor_ >= row.first && b.cursor_ < row.first + row.count)
return i;
@@ -1372,7 +1373,7 @@ static void
select_closest(Browser &b, const Browser::GridRow &row, float target_x)
{
float closest = 1e30f;
for (int i = 0; i < row.count; ++i) {
for (int i = 0; i < row.count; i++) {
const int fi = row.first + i;
if (fi < 0 || fi >= int(b.files_.size()))
break;
@@ -1541,7 +1542,7 @@ layout_grid(Browser &b, Rect area)
row_w = 0;
};
for (int i = 0; i < int(b.files_.size()); ++i) {
for (int i = 0; i < int(b.files_.size()); i++) {
Browser::File &f = b.files_[size_t(i)];
// thumb_dest() answers in pixels, which is what the grid wants:
// no round trip through points, and nothing to snap back.
@@ -1625,8 +1626,8 @@ draw_checkers(Kit &kit, const Rect &tile)
kit.draw_fill(tile, bg);
const int nx = max(1, (tile.w + kCheck - 1) / kCheck);
const int ny = max(1, (tile.h + kCheck - 1) / kCheck);
for (int j = 0; j < ny; ++j) {
for (int i = 0; i < nx; ++i) {
for (int j = 0; j < ny; j++) {
for (int i = 0; i < nx; i++) {
if (((i + j) & 1) == 0)
continue;
const int x0 = tile.x + i * kCheck;
@@ -1640,7 +1641,7 @@ draw_checkers(Kit &kit, const Rect &tile)
static int
hit_file(const Browser &b, float x, float y)
{
for (int i = 0; i < int(b.files_.size()); ++i) {
for (int i = 0; i < int(b.files_.size()); i++) {
if (b.files_[size_t(i)].tile.contains(x, y))
return i;
}
@@ -1765,7 +1766,7 @@ list_subdirs(const filesystem::path &dir, const BrowseSetup &setup)
static int
index_of_dir(const vector<string> &dirs, const filesystem::path &self)
{
for (int i = 0; i < int(dirs.size()); ++i) {
for (int i = 0; i < int(dirs.size()); i++) {
if (same_path(dirs[size_t(i)], self))
return i;
}
@@ -1980,7 +1981,7 @@ scan_dir(Browser &b)
b.files_ = std::move(files);
clear_cursor(b);
if (!keep.empty()) {
for (int i = 0; i < int(b.files_.size()); ++i) {
for (int i = 0; i < int(b.files_.size()); i++) {
if (b.files_[size_t(i)].path == keep) {
b.cursor_ = i;
remember_cursor_x(b);
@@ -1999,7 +2000,7 @@ scan_dir(Browser &b)
// respond to DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE,
// and/or maybe just DBT_DEVNODES_CHANGED (trivially reload here).
DWORD mask = GetLogicalDrives();
for (int i = 0; i < 26; ++i) {
for (int i = 0; i < 26; i++) {
wchar_t letter = L'A' + i;
if (!(mask & (1 << i)))
continue;
@@ -2103,7 +2104,7 @@ open_directory(
}
b.dir_url_ = dir;
b.size_cache_.clear();
++b.thumb_gen_;
b.thumb_gen_++;
b.thumbnailer_.set_epoch(b.thumbnail_client_, b.thumb_gen_);
b.thumb_inflight_.clear();
reset_thumb_atlas(b);
@@ -2121,7 +2122,7 @@ set_thumb_size(Browser &b, int size)
if (size == b.thumb_size_)
return;
b.thumb_size_ = size;
++b.thumb_gen_;
b.thumb_gen_++;
b.thumbnailer_.set_epoch(b.thumbnail_client_, b.thumb_gen_);
b.thumb_inflight_.clear();
const int target_tier = thumbnail_tier_for_height(
@@ -2366,7 +2367,7 @@ fill_places(Browser &b)
b.kit_.forget_tree(list);
b.place_items_.clear();
list->erase_children();
for (int i = 0; i < int(b.side_dirs_.size()); ++i) {
for (int i = 0; i < int(b.side_dirs_.size()); i++) {
const Browser::DirRow &d = b.side_dirs_[size_t(i)];
if (d.path.empty()) {
list->add_child(make_unique<Sep>());
@@ -2413,7 +2414,7 @@ sync_ui(Browser &b, Page &ui)
fill_places(b);
else {
const size_t n = min(b.place_items_.size(), b.side_dirs_.size());
for (size_t i = 0; i < n; ++i) {
for (size_t i = 0; i < n; i++) {
if (Button *button = b.place_items_[i].button)
button->active = b.side_dirs_[i].current;
}
@@ -2536,7 +2537,7 @@ apply_action(Browser &b, Action action)
case Action::Copy:
if (b.cursor_ >= 0 && b.cursor_ < int(b.files_.size())) {
const QUrl files[] = {b.file_url(b.cursor_)};
copy_files(files);
copy_files(files, false);
}
return true;
case Action::Trash:
@@ -2623,7 +2624,7 @@ Browser::select_file(const QUrl &url)
clear_cursor(*this);
const string path = url_to_path(url).toStdString();
if (!path.empty()) {
for (int i = 0; i < int(this->files_.size()); ++i) {
for (int i = 0; i < int(this->files_.size()); i++) {
if (this->files_[size_t(i)].path == path) {
this->cursor_ = i;
remember_cursor_x(*this);
@@ -2685,7 +2686,7 @@ void
Browser::paint(Kit &kit) const
{
if (kit.renderer_)
kit.renderer_->set_view(1.f, 0.f, 0.f, dawn::Orientation::Rotate0);
kit.renderer_->set_view(1.f, 0.f, 0.f, dawn::Orientation::Rotate0, 0.f);
kit.clip_to(this->r);
kit.draw_fill(this->r, kit.colours_[ColourWell]);
const int th = kit.px(float(this->thumb_size_));
@@ -2694,7 +2695,7 @@ Browser::paint(Kit &kit) const
const Colour glow_hot = {ink.r, ink.g, ink.b, ink.a * glow_a};
const Colour glow_idle = {ink.r, ink.g, ink.b, ink.a * kGlowAlpha * glow_a};
const Colour frame = kit.colours_[ColourFrame];
for (int i = 0; i < int(this->files_.size()); ++i) {
for (int i = 0; i < int(this->files_.size()); i++) {
const File &f = this->files_[size_t(i)];
if (!thumb_in_band(*this, f, 0.f))
continue;
+3 -4
View File
@@ -162,7 +162,7 @@ struct Browser : Widget {
void init();
void destroy();
void set_host(float width_pts, float height_pts, float dpr);
void open_dir(const QUrl &url, bool record = true);
void open_dir(const QUrl &url, bool record);
void rescan();
bool hist_back();
bool hist_forward();
@@ -173,9 +173,8 @@ struct Browser : Widget {
void file_gone(const QUrl &url);
[[nodiscard]] QUrl file_url(int index) const;
[[nodiscard]] BrowseSetup browse_setup() const { return this->setup_; }
void set_screen_profile(
std::shared_ptr<dawn::Cmm> cmm, std::shared_ptr<dawn::Profile> profile,
bool force_reload = false);
void set_screen_profile(std::shared_ptr<dawn::Cmm> cmm,
std::shared_ptr<dawn::Profile> profile, bool force_reload);
void present(Page &ui);
bool press(Kit &kit, float x, float y, Qt::MouseButton button) override;
bool release(Kit &kit, float x, float y, Qt::MouseButton button) override;
+20 -23
View File
@@ -172,8 +172,8 @@ dialog_action(const QString &text, function<void(Kit &)> on_click)
static unique_ptr<Button>
dialog_close_action(Dialog &dialog)
{
return dialog_action(QStringLiteral("_Close"),
[&dialog](Kit &kit) { dialog.close(kit); });
return dialog_action(
QStringLiteral("_Close"), [&dialog](Kit &kit) { dialog.close(kit); });
}
static QString
@@ -235,13 +235,12 @@ dialog_about(Kit &kit, Dialog &dialog)
col->add_child(
dialog_label(QStringLiteral("Colour-managed image browser and viewer."),
false, true));
dialog.show(
kit, std::move(col), 360.f, dialog_close_action(dialog));
dialog.show(kit, std::move(col), 360.f, dialog_close_action(dialog));
}
void
dialog_location(Kit &kit, Dialog &dialog,
function<void(const QString &)> on_open)
dialog_location(
Kit &kit, Dialog &dialog, function<void(const QString &)> on_open)
{
auto col = make_unique<Column>();
col->gap = 8.f;
@@ -346,8 +345,7 @@ dialog_shortcuts(Kit &kit, Dialog &dialog, span<const MenuNode> tree,
emit_other(Action::Cancel);
if (viewer)
emit_other(Action::ZoomLevel);
dialog.show(
kit, std::move(col), 520.f, dialog_close_action(dialog));
dialog.show(kit, std::move(col), 520.f, dialog_close_action(dialog));
}
// --- Settings dialog ---------------------------------------------------------
@@ -468,7 +466,7 @@ dialog_settings(Kit &kit, Dialog &dialog, SettingsDraft draft,
auto combo = make_unique<Combo>();
for (const QString &name : kThumbSizeNames)
combo->items.push_back(name);
for (int i = 0; i < int(std::size(kThumbSizes)); i++) {
for (int i = 0; i < int(size(kThumbSizes)); i++) {
if (kThumbSizes[i] == state->thumbnail_size)
combo->current = i;
}
@@ -477,8 +475,8 @@ dialog_settings(Kit &kit, Dialog &dialog, SettingsDraft draft,
};
col->add_child(settings_row(thumb_label, label_w, std::move(combo)));
auto names = settings_check("Show _filenames by default",
state->show_filenames);
auto names =
settings_check("Show _filenames by default", state->show_filenames);
Checkbox *names_ref = names.get();
names->on_click = [state, names_ref](Kit &) {
state->show_filenames = names_ref->checked;
@@ -494,8 +492,8 @@ dialog_settings(Kit &kit, Dialog &dialog, SettingsDraft draft,
};
col->add_child(settings_row(icc_label, label_w, std::move(entry)));
auto dither = settings_check("Disable _dithering on 8-bit swapchains",
state->disable_dithering);
auto dither = settings_check(
"Disable _dithering on 8-bit swapchains", state->disable_dithering);
Checkbox *dither_ref = dither.get();
dither->on_click = [state, dither_ref](Kit &) {
state->disable_dithering = dither_ref->checked;
@@ -619,7 +617,7 @@ collect_targets(Widget *w, Rect host, vector<Widget *> &out)
if (w->focusable() && visible_rect(w, host).w > 0.f)
out.push_back(w);
const size_t n = w->child_count();
for (size_t i = 0; i < n; ++i)
for (size_t i = 0; i < n; i++)
collect_targets(w->child(i), host, out);
}
@@ -643,7 +641,7 @@ label_len(int n)
int len = 1;
int cap = kNChars;
while (cap < n && len < 8) {
++len;
len++;
cap *= kNChars;
}
return len;
@@ -757,7 +755,7 @@ Hint::key(Kit &kit, const Key &ev)
any = true;
if (t.label == next) {
exact = &t;
++exact_n;
exact_n++;
}
}
if (!any)
@@ -833,7 +831,7 @@ Hint::collect(Widget *scope)
return;
const Rect well = browser->r;
for (int i = 0; i < int(browser->files_.size()); ++i) {
for (int i = 0; i < int(browser->files_.size()); i++) {
const Browser::File &f = browser->files_[size_t(i)];
if (f.tile.empty())
continue;
@@ -855,7 +853,7 @@ Hint::assign_labels()
{
const int n = int(this->targets_.size());
const int len = label_len(n);
for (int i = 0; i < n; ++i)
for (int i = 0; i < n; i++)
this->targets_[size_t(i)].label = label_at(i, len);
}
@@ -867,8 +865,7 @@ Hint::refresh_rects()
for (Target &t : this->targets_) {
if (t.widget) {
const Rect visible = visible_rect(t.widget, this->page->r);
if (!t.widget->focusable() || visible.w <= 0.f ||
visible.h <= 0.f)
if (!t.widget->focusable() || visible.w <= 0.f || visible.h <= 0.f)
continue;
t.at = visible;
keep.push_back(t);
@@ -1121,8 +1118,8 @@ Page::arrange(Kit &kit, Rect alloc)
const int sw = kit.px(this->splitter->min_w);
// The grab strip straddles the boundary, half on each side.
const int sx = (this->sidebar_side == Side::Right
? this->well_.x + this->well_.w
: this->well_.x) -
? this->well_.x + this->well_.w
: this->well_.x) -
sw / 2;
this->splitter->arrange(kit, {sx, body_y, sw, body_h});
} else {
@@ -1153,7 +1150,7 @@ Page::key(Kit &kit, const Key &ev)
}
Widget *panes[3];
int n = 0, i = 0;
for (size_t c = 0; c < child_count(); ++c) {
for (size_t c = 0; c < child_count(); c++) {
Widget *k = child(c);
if (!k || !k->visible ||
(k != this->toolbar && k != this->sidebar && k != this->content))
+2 -2
View File
@@ -73,8 +73,8 @@ struct SettingsDraft {
void dialog_about(Kit &kit, Dialog &dialog);
void dialog_shortcuts(Kit &kit, Dialog &dialog, std::span<const MenuNode> tree,
std::span<const Action> keys);
void dialog_location(Kit &kit, Dialog &dialog,
std::function<void(const QString &)> on_open);
void dialog_location(
Kit &kit, Dialog &dialog, std::function<void(const QString &)> on_open);
// Takes the draft by value: the dialog edits its own copy, and Save is the
// only way anything gets back out.
+11 -11
View File
@@ -82,7 +82,7 @@ locus_path(int w, int h)
};
QPointF p0 = xy(0);
path.moveTo(xy_to_px(p0.x(), p0.y(), w, h));
for (int i = 1; i < kCmfN; ++i) {
for (int i = 1; i < kCmfN; i++) {
QPointF p = xy(i);
path.lineTo(xy_to_px(p.x(), p.y(), w, h));
}
@@ -140,7 +140,7 @@ stroke_poly(
return;
QPainterPath path;
path.moveTo(xy_to_px(c.x[0], c.y[0], w, h));
for (int i = 1; i < c.n; ++i)
for (int i = 1; i < c.n; i++)
path.lineTo(xy_to_px(c.x[i], c.y[i], w, h));
path.closeSubpath();
p.strokePath(path, pen);
@@ -164,11 +164,11 @@ raster_diagram(int w, int h, const dawn::Chromaticities &image,
mp.fillPath(locus_path(w, h), Qt::white);
}
for (int py = 0; py < h; ++py) {
for (int py = 0; py < h; py++) {
auto *dst = (QRgb *) img.scanLine(py);
const auto *ms = (const QRgb *) mask.constScanLine(py);
const double y = double(kYMax) * (1.0 - (py + 0.5) / h);
for (int px = 0; px < w; ++px) {
for (int px = 0; px < w; px++) {
if (!qAlpha(ms[px]))
continue;
const double x = double(kXMax) * (px + 0.5) / w;
@@ -219,7 +219,7 @@ same_chroma(const dawn::Chromaticities &a, const dawn::Chromaticities &b)
return false;
if (a.have_white && (a.wx != b.wx || a.wy != b.wy))
return false;
for (int i = 0; i < a.n; ++i) {
for (int i = 0; i < a.n; i++) {
if (a.x[i] != b.x[i] || a.y[i] != b.y[i])
return false;
}
@@ -251,8 +251,8 @@ CieDiagram::prepare(Kit &kit)
kit.cache_text(kTargetLab, false);
const int cap = caption_h(kit);
const Rect plot = plot_rect(
{this->r.x, this->r.y, this->r.w, max(0, this->r.h - cap)});
const Rect plot =
plot_rect({this->r.x, this->r.y, this->r.w, max(0, this->r.h - cap)});
if (plot.w < 8.f || plot.h < 8.f)
return;
@@ -285,8 +285,8 @@ void
CieDiagram::paint(Kit &kit) const
{
const int cap = caption_h(kit);
const Rect plot = plot_rect(
{this->r.x, this->r.y, this->r.w, max(0, this->r.h - cap)});
const Rect plot =
plot_rect({this->r.x, this->r.y, this->r.w, max(0, this->r.h - cap)});
const int x0 = plot.x > 0 ? plot.x : this->r.x;
const int cap_y0 = plot.h >= 8 ? plot.y + plot.h : this->r.y;
const int y = cap_y0 + kit.px(kCapGap);
@@ -300,8 +300,8 @@ CieDiagram::paint(Kit &kit) const
const int cx = x0 + cap_w / 2;
const int gap = kit.px(4.f);
const int widthS = kit.text_width(kSourceLab, true);
kit.emit_text(float(cx - gap - widthS), float(y), kSourceLab, kBlackCol,
true);
kit.emit_text(
float(cx - gap - widthS), float(y), kSourceLab, kBlackCol, true);
kit.emit_text(float(cx + gap), float(y), kTargetLab, kWhiteCol, true);
}
+34 -39
View File
@@ -194,7 +194,7 @@ static void
sync_scale_label(Viewer &v)
{
char scale_buf[16];
snprintf(scale_buf, sizeof(scale_buf), "%.f%%", double(v.scale_ * 100.f));
snprintf(scale_buf, sizeof scale_buf, "%.f%%", double(v.scale_ * 100.f));
v.scale_text_ = QString::fromUtf8(scale_buf);
if (!v.scale_label_)
return;
@@ -279,7 +279,7 @@ dim_text(uint32_t v)
if (!v)
return QStringLiteral("-");
char buf[16];
snprintf(buf, sizeof(buf), "%u", v);
snprintf(buf, sizeof buf, "%u", v);
return QString::fromUtf8(buf);
}
@@ -361,7 +361,7 @@ join_load_text(const vector<string> &warnings, const dawn::Error &error,
else if (empty_image && parts.empty())
parts.push_back("empty image");
string out;
for (size_t i = 0; i < parts.size(); ++i) {
for (size_t i = 0; i < parts.size(); i++) {
if (i)
out += '\n';
out += parts[i];
@@ -370,14 +370,13 @@ join_load_text(const vector<string> &warnings, const dawn::Error &error,
}
static shared_ptr<dawn::Profile>
profile_from_icc(
dawn::Cmm &cmm, const shared_ptr<const vector<uint8_t>> &icc)
profile_from_icc(dawn::Cmm &cmm, const shared_ptr<const vector<uint8_t>> &icc)
{
if (icc && !icc->empty()) {
if (auto profile = cmm.get_profile(*icc))
return profile;
}
return cmm.get_profile_sRGB();
return cmm.get_profile_sRGB(false);
}
static bool apply_action(Viewer &v, Action action);
@@ -622,7 +621,7 @@ stop_worker(Viewer &v)
{
if (!v.worker_)
return;
++v.load_epoch_;
v.load_epoch_++;
{
lock_guard<mutex> lock(v.worker_->mu);
v.worker_->stop = true;
@@ -690,8 +689,8 @@ static unique_ptr<Sidebar>
make_sidebar(Viewer &v)
{
// FIXME: This needs proper layouting.
const float label_w = v.kit_.text_width(QStringLiteral("Height:"), true)
/ v.kit_.dpr_;
const float label_w =
v.kit_.text_width(QStringLiteral("Height:"), true) / v.kit_.dpr_;
auto col = make_unique<ScrollColumn>();
v.info_ = col.get();
@@ -700,8 +699,8 @@ make_sidebar(Viewer &v)
col->pad_y = kWinPadX * 2.f;
col->grow = true;
col->add_child(meta_row(QStringLiteral("Name:"), QStringLiteral("-"),
label_w, v.name_label_));
col->add_child(meta_row(
QStringLiteral("Name:"), QStringLiteral("-"), label_w, v.name_label_));
col->add_child(meta_row(QStringLiteral("Loader:"), QStringLiteral("-"),
label_w, v.loader_label_));
col->add_child(meta_row(QStringLiteral("Width:"), QStringLiteral("-"),
@@ -794,7 +793,7 @@ sync_ui(Viewer &v, Page &ui)
shared_ptr<dawn::Profile> srgb;
if (!img.have_primaries) {
auto cmm = v.cmm_ ? v.cmm_ : dawn::Cmm::get_default();
srgb = cmm->get_profile_sRGB();
srgb = cmm->get_profile_sRGB(false);
img = profile_chromaticities(srgb.get());
image_dashed = true;
}
@@ -917,25 +916,23 @@ apply_open_result(Viewer &v, OpenLoad result)
return;
const string current = viewer_local_path(v);
if (!v.detached_ && result.key.path != current &&
result.key.path != v.previous_path_ &&
result.key.path != v.next_path_)
result.key.path != v.previous_path_ && result.key.path != v.next_path_)
return;
auto found = find_if(v.open_cache_.begin(), v.open_cache_.end(),
[&](const Viewer::CachedOpen &entry) {
return entry.key == result.key;
});
if (found == v.open_cache_.end()) {
v.open_cache_.push_back(
{std::move(result.key), std::move(result.image),
std::move(result.message)});
v.open_cache_.push_back({std::move(result.key), std::move(result.image),
std::move(result.message)});
found = prev(v.open_cache_.end());
} else {
found->image = std::move(result.image);
found->message = std::move(result.message);
}
Viewer::CachedOpen *cached = &*found;
if (!v.detached_ && cached->key ==
Viewer::OpenKey{current, v.enhance_jpeg_})
if (!v.detached_ &&
cached->key == Viewer::OpenKey{current, v.enhance_jpeg_})
apply_open(v, v.open_gen_, cached->image, cached->message);
if (v.open_cache_.size() > 3)
v.open_cache_.erase(v.open_cache_.begin());
@@ -1107,8 +1104,8 @@ make_open_job(const Viewer &v, Viewer::OpenKey key)
job.epoch = v.load_epoch_;
job.key = std::move(key);
job.uri = path_to_url(QString::fromStdString(job.key.path))
.toEncoded()
.toStdString();
.toEncoded()
.toStdString();
job.dpi = v.kit_.dpi_;
job.enable_cms = v.enable_cms_;
job.screen_icc = v.enable_cms_ ? v.screen_icc_ : nullptr;
@@ -1143,11 +1140,11 @@ start_open(Viewer &v, bool invalidate)
if (!v.worker_ || v.url_.isEmpty())
return;
if (invalidate) {
++v.load_epoch_;
v.load_epoch_++;
v.open_cache_.clear();
}
++v.open_gen_;
++v.scale_gen_;
v.open_gen_++;
v.scale_gen_++;
v.opening_ = true;
v.open_done_ = false;
v.detached_ = false;
@@ -1155,8 +1152,7 @@ start_open(Viewer &v, bool invalidate)
v.scale_failed_ = false;
const string path = viewer_local_path(v);
const Viewer::OpenKey key{path, v.enhance_jpeg_};
Viewer::CachedOpen *cached =
invalidate ? nullptr : find_cached(v, key);
Viewer::CachedOpen *cached = invalidate ? nullptr : find_cached(v, key);
{
lock_guard lock(v.worker_->mu);
v.worker_->epoch = v.load_epoch_;
@@ -1251,7 +1247,7 @@ post_scale(Viewer &v)
{
if (!v.worker_ || !v.current_ || !v.current_->render)
return;
++v.scale_gen_;
v.scale_gen_++;
v.scale_job_pending_ = true;
v.scale_job_target_ = v.scale_;
v.scale_failed_ = false;
@@ -1276,7 +1272,7 @@ ensure_vector_frame(Viewer &v)
if (v.scale_ == 1.f) {
if (v.scale_job_pending_) {
++v.scale_gen_;
v.scale_gen_++;
v.scale_job_pending_ = false;
if (v.worker_) {
lock_guard<mutex> lock(v.worker_->mu);
@@ -1594,7 +1590,7 @@ snap_pan_to_pixels(float *pan, float disp, float vp, float scale)
static void
cancel_scale(Viewer &v)
{
++v.scale_gen_;
v.scale_gen_++;
v.scale_job_pending_ = false;
v.scale_failed_ = false;
v.page_scaled_.reset();
@@ -1689,10 +1685,10 @@ copy_image(QMimeData *mime, const dawn::Image &im)
const uint32_t w = im.width;
const uint32_t h = im.height;
vector<uint8_t> bgra(size_t(w) * h * 4);
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < h; y++) {
const uint16_t *s = row_u16(im, y);
uint8_t *d = bgra.data() + size_t(y) * w * 4;
for (uint32_t x = 0; x < w; ++x) {
for (uint32_t x = 0; x < w; x++) {
d[0] = uint8_t(s[0] >> 8);
d[1] = uint8_t(s[1] >> 8);
d[2] = uint8_t(s[2] >> 8);
@@ -1703,10 +1699,10 @@ copy_image(QMimeData *mime, const dawn::Image &im)
}
dawn::unpremultiply_bgra8(bgra.data(), w, h, size_t(w) * 4);
QImage image(int(w), int(h), QImage::Format_ARGB32);
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < h; y++) {
const uint8_t *s = bgra.data() + size_t(y) * w * 4;
auto *d = reinterpret_cast<QRgb *>(image.scanLine(int(y)));
for (uint32_t x = 0; x < w; ++x) {
for (uint32_t x = 0; x < w; x++) {
d[x] = qRgba(s[2], s[1], s[0], s[3]);
s += 4;
}
@@ -1722,7 +1718,7 @@ copy_frame(const Viewer &v)
copy_image(mime, *v.frame_);
if (!v.url_.isEmpty()) {
const QUrl files[] = {v.url_};
copy_files(mime, files);
copy_files(mime, files, false);
}
QGuiApplication::clipboard()->setMimeData(mime);
}
@@ -2059,8 +2055,8 @@ void
Viewer::cancel_loads()
{
const bool discard_current = this->opening_;
++this->open_gen_;
++this->scale_gen_;
this->open_gen_++;
this->scale_gen_++;
this->opening_ = false;
this->open_done_ = false;
this->detached_ = true;
@@ -2104,9 +2100,8 @@ Viewer::consume_open_done()
}
void
Viewer::set_screen_profile(
shared_ptr<dawn::Cmm> cmm, shared_ptr<dawn::Profile> profile, bool fallback,
bool force_reload)
Viewer::set_screen_profile(shared_ptr<dawn::Cmm> cmm,
shared_ptr<dawn::Profile> profile, bool fallback, bool force_reload)
{
auto screen_icc = profile
? make_shared<const vector<uint8_t>>(profile->to_bytes())
+2 -2
View File
@@ -146,8 +146,8 @@ struct Viewer : Widget {
[[nodiscard]] bool has_view() const;
[[nodiscard]] bool consume_open_done();
void set_screen_profile(std::shared_ptr<dawn::Cmm> cmm,
std::shared_ptr<dawn::Profile> profile, bool fallback = true,
bool force_reload = false);
std::shared_ptr<dawn::Profile> profile, bool fallback,
bool force_reload);
void present(Page &ui);
[[nodiscard]] int wake_ms() const override;
bool press(Kit &kit, float x, float y, Qt::MouseButton button) override;
+74 -56
View File
@@ -72,7 +72,7 @@ bake_rgb(dawn::Cmm *cmm, dawn::Profile *target, uint8_t r, uint8_t g, uint8_t b)
return colour;
uint16_t pixel[4] = {
uint16_t(b * 257), uint16_t(g * 257), uint16_t(r * 257), 65535};
auto srgb = cmm->get_profile_sRGB();
auto srgb = cmm->get_profile_sRGB(false);
if (!srgb)
return colour;
if (!cmm->transform_bgra16(
@@ -122,11 +122,11 @@ raster_symbolic(const char *name, int px)
QImage image(px, px, QImage::Format_ARGB32_Premultiplied);
const size_t stride = size_t(px) * 4;
for (int y = 0; y < px; ++y) {
for (int y = 0; y < px; y++) {
auto *row = (QRgb *) image.scanLine(y);
const auto *src =
(const unsigned char *) (pixmap.data() + size_t(y) * stride);
for (int x = 0; x < px; ++x) {
for (int x = 0; x < px; x++) {
const int a = src[x * 4 + 3];
row[x] = qRgba(a, a, a, a);
}
@@ -212,9 +212,9 @@ raster_glyph(const QRawFont &raw, quint32 gid, float phase, QPoint *origin)
painter.end();
QRect ink;
for (int y = 0; y < img.height(); ++y) {
for (int y = 0; y < img.height(); y++) {
const auto *row = (const QRgb *) img.constScanLine(y);
for (int x = 0; x < img.width(); ++x) {
for (int x = 0; x < img.width(); x++) {
if (qAlpha(row[x]))
ink |= QRect(x, y, 1, 1);
}
@@ -333,18 +333,18 @@ blit(Kit &kit, const Kit::Packed &rect, const QImage &src, bool coverage)
const int rows = min(rect.h, img.height());
const int cols = min(rect.w, img.width());
for (int y = 0; y < rows; ++y) {
for (int y = 0; y < rows; y++) {
uint16_t *dst = kit.atlas_.pixels.data() +
(size_t(rect.y + y) * size_t(kit.atlas_.w) + size_t(rect.x)) * 4;
if (coverage) {
const uchar *row = img.constScanLine(y);
for (int x = 0; x < cols; ++x) {
for (int x = 0; x < cols; x++) {
const uint16_t a = widen8(row[x]);
fill_n(dst + x * 4, 4, a);
}
} else {
const auto *row = (const QRgb *) img.constScanLine(y);
for (int x = 0; x < cols; ++x) {
for (int x = 0; x < cols; x++) {
dst[x * 4 + 0] = widen8(uint8_t(qRed(row[x])));
dst[x * 4 + 1] = widen8(uint8_t(qGreen(row[x])));
dst[x * 4 + 2] = widen8(uint8_t(qBlue(row[x])));
@@ -358,7 +358,7 @@ blit(Kit &kit, const Kit::Packed &rect, const QImage &src, bool coverage)
static int
font_id(Kit &kit, const QRawFont &raw)
{
for (size_t i = 0; i < kit.fonts_.size(); ++i) {
for (size_t i = 0; i < kit.fonts_.size(); i++) {
if (kit.fonts_[i] == raw)
return int(i);
}
@@ -401,7 +401,7 @@ cache_ascii(Kit &kit, bool bold)
const QRawFont &raw = bold ? kit.raw_bold_ : kit.raw_;
if (!raw.isValid())
return;
for (int cp = 0x20; cp <= 0x7E; ++cp) {
for (int cp = 0x20; cp <= 0x7E; cp++) {
const QList<quint32> indexes =
raw.glyphIndexesForString(QString(QChar(cp)));
if (indexes.isEmpty())
@@ -432,7 +432,7 @@ cache_text(Kit &kit, const QString &text, bool bold, int wrap)
static void
rebuild_atlas(Kit &kit)
{
++kit.atlas_epoch_;
kit.atlas_epoch_++;
kit.icons_.clear();
kit.glyphs_.clear();
kit.fonts_.clear();
@@ -444,11 +444,11 @@ rebuild_atlas(Kit &kit)
if (white.empty())
return;
kit.white_ = white;
for (int y = 0; y < white.h; ++y) {
for (int y = 0; y < white.h; y++) {
uint16_t *dst = kit.atlas_.pixels.data() +
size_t(white.y + y) * size_t(kit.atlas_.w) * 4 +
size_t(white.x) * 4;
for (int x = 0; x < white.w; ++x) {
for (int x = 0; x < white.w; x++) {
dst[x * 4 + 0] = 65535;
dst[x * 4 + 1] = 65535;
dst[x * 4 + 2] = 65535;
@@ -465,11 +465,11 @@ rebuild_atlas(Kit &kit)
const int y_max = gn - 1;
const double x_scale = 1.0 / double(max(1, x_max));
const double y_scale = 1.0 / double(max(1, y_max));
for (int y = 0; y <= y_max; ++y) {
for (int y = 0; y <= y_max; y++) {
uint16_t *dst = kit.atlas_.pixels.data() +
size_t(glow.y + y) * size_t(kit.atlas_.w) * 4 +
size_t(glow.x) * 4;
for (int x = 0; x <= x_max; ++x) {
for (int x = 0; x <= x_max; x++) {
const double xn = x_scale * double(x_max - x);
const double yn = y_scale * double(y_max - y);
const double v = min(sqrt(xn * xn + yn * yn), 1.0);
@@ -520,7 +520,7 @@ emit_text(Kit &kit, float x, float y, const QString &text, Colour colour,
const QList<quint32> gids = run.glyphIndexes();
const QList<QPointF> pos = run.positions();
const int n = int(min(gids.size(), pos.size()));
for (int i = 0; i < n; ++i) {
for (int i = 0; i < n; i++) {
// The shaper positions the pen in fractions of a pixel, and
// kerning lives in those fractions. Split one off into the
// phase the glyph was rasterised at, so that the quad can stay
@@ -610,7 +610,7 @@ void
Widget::paint_children(Kit &kit) const
{
const size_t n = child_count();
for (size_t i = 0; i < n; ++i) {
for (size_t i = 0; i < n; i++) {
if (const Widget *k = child(i))
k->paint(kit);
}
@@ -643,7 +643,7 @@ Widget::prepare(Kit &kit)
if (!shown())
return;
const size_t n = child_count();
for (size_t i = 0; i < n; ++i) {
for (size_t i = 0; i < n; i++) {
if (Widget *k = child(i))
k->prepare(kit);
}
@@ -1517,6 +1517,12 @@ Splitter::release(Kit &, float, float, Qt::MouseButton button)
// --- Composite ---------------------------------------------------------------
Widget *
Composite::add_child(unique_ptr<Widget> child)
{
return add_child(std::move(child), size_t(-1));
}
Widget *
Composite::add_child(unique_ptr<Widget> child, size_t at)
{
@@ -1541,11 +1547,17 @@ Composite::take_child(size_t at)
return child;
}
void
Composite::erase_children()
{
erase_children(0);
}
void
Composite::erase_children(size_t from)
{
from = min(from, this->kids.size());
for (size_t i = from; i < this->kids.size(); ++i) {
for (size_t i = from; i < this->kids.size(); i++) {
if (this->kids[i])
this->kids[i]->parent_ = nullptr;
}
@@ -1579,14 +1591,14 @@ Container::measure_pack(Kit &kit, int max_w, int max_h, bool hz)
if (!k || !k->shown())
continue;
if (k->grows()) {
++growers;
++vis;
growers++;
vis++;
continue;
}
k->measure(kit, hz ? kUnlim : iw, hz ? ih : kUnlim);
used += hz ? k->r.w : k->r.h;
cross = max(cross, hz ? k->r.h : k->r.w);
++vis;
vis++;
}
const int gaps = kit.px(this->gap) * max(0, vis - 1);
if (growers) {
@@ -1631,9 +1643,9 @@ Container::arrange_pack(Kit &kit, Rect alloc, bool hz, Align align)
Widget *k = child.get();
if (!k || !k->shown())
continue;
++vis;
vis++;
if (k->grows()) {
++growers;
growers++;
continue;
}
k->measure(kit, hz ? kUnlim : in.w, hz ? in.h : kUnlim);
@@ -1662,7 +1674,7 @@ Container::arrange_pack(Kit &kit, Rect alloc, bool hz, Align align)
if (!k || !k->shown())
continue;
packed += (hz ? k->r.w : k->r.h) + gap;
++nv;
nv++;
}
if (nv)
packed -= gap;
@@ -1745,7 +1757,7 @@ Flow::wrap(Kit &kit, int inner_w, int *total_h, vector<Line> *lines)
};
const size_t n = this->kids.size();
for (size_t i = 0; i < n; ++i) {
for (size_t i = 0; i < n; i++) {
Widget *k = this->kids[i].get();
// A hidden child keeps whatever rect it had: clearing it here would
// be measuring as a side effect, and a width is what focusable()
@@ -1767,7 +1779,7 @@ Flow::wrap(Kit &kit, int inner_w, int *total_h, vector<Line> *lines)
flush(i);
line_w += kept ? need : k->r.w;
line_h = max(line_h, k->r.h);
++kept;
kept++;
}
flush(n);
if (y)
@@ -1813,19 +1825,19 @@ Flow::arrange(Kit &kit, Rect alloc)
// field then fills its line the way it fills the bar, instead of
// sitting at its minimum with a ragged gap after it.
int used = 0, growers = 0, vis = 0;
for (size_t i = line.first; i < line.first + line.count; ++i) {
for (size_t i = line.first; i < line.first + line.count; i++) {
Widget *k = this->kids[i].get();
if (!k || !k->shown())
continue;
used += k->r.w;
++vis;
vis++;
if (k->grows())
++growers;
growers++;
}
const int slack = max(0, in.w - used - gap * max(0, vis - 1));
int x = in.x, got = 0;
for (size_t i = line.first; i < line.first + line.count; ++i) {
for (size_t i = line.first; i < line.first + line.count; i++) {
Widget *k = this->kids[i].get();
if (!k || !k->shown())
continue;
@@ -2563,7 +2575,7 @@ collect_focusable(Widget *w, vector<Widget *> &out)
if (w->focusable())
out.push_back(w);
const size_t n = w->child_count();
for (size_t i = 0; i < n; ++i)
for (size_t i = 0; i < n; i++)
collect_focusable(w->child(i), out);
}
@@ -2578,7 +2590,7 @@ collect_mnemonics(Widget *w, QChar letter, vector<Widget *> &out)
if (w->mnemonic_key().toLower() == letter)
out.push_back(w);
const size_t n = w->child_count();
for (size_t i = 0; i < n; ++i)
for (size_t i = 0; i < n; i++)
collect_mnemonics(w->child(i), letter, out);
}
@@ -2650,7 +2662,7 @@ MenuPopup::key(Kit &kit, const Key &ev)
switch (ev.key) {
case Qt::Key_Up:
case Qt::Key_Down:
kit.cycle_focus(this, ev.key == Qt::Key_Up ? -1 : 1);
kit.cycle_focus(this, ev.key == Qt::Key_Up ? -1 : 1, true);
focus_item(kit, kit.focus_, true);
return true;
case Qt::Key_Right:
@@ -2790,7 +2802,7 @@ Overflow::step_line(Kit &kit, int dir)
const auto it = find(items.begin(), items.end(), kit.focus_);
if (it == items.end()) {
this->want_x_ = -1;
kit.cycle_focus(this, dir);
kit.cycle_focus(this, dir, true);
return;
}
@@ -2813,7 +2825,7 @@ Overflow::step_line(Kit &kit, int dir)
const int line_y = items[size_t(j)]->r.y;
int best = j;
float least = 1e30f;
for (int k = 0; k < n; ++k) {
for (int k = 0; k < n; k++) {
if (items[size_t(k)]->r.y != line_y)
continue;
const float d = abs(centre_of(items[size_t(k)]) - this->want_x_);
@@ -2845,7 +2857,7 @@ Overflow::key(Kit &kit, const Key &ev)
case Qt::Key_Right:
// The items read as one strip that happens to be folded.
this->want_x_ = -1;
kit.cycle_focus(this, ev.key == Qt::Key_Left ? -1 : 1);
kit.cycle_focus(this, ev.key == Qt::Key_Left ? -1 : 1, true);
break;
case Qt::Key_Home:
this->want_x_ = -1;
@@ -2855,7 +2867,7 @@ Overflow::key(Kit &kit, const Key &ev)
// Entering the strip backwards from nowhere lands on its last item.
this->want_x_ = -1;
kit.set_focus(nullptr, true);
kit.cycle_focus(this, -1);
kit.cycle_focus(this, -1, true);
break;
case Qt::Key_Up:
case Qt::Key_Down:
@@ -3446,6 +3458,12 @@ ToolbarSlot::ToolbarSlot()
Composite::add_child(std::move(button));
}
Widget *
ToolbarSlot::add_item(unique_ptr<Widget> item)
{
return add_item(std::move(item), size_t(-1));
}
Widget *
ToolbarSlot::add_item(unique_ptr<Widget> item, size_t at)
{
@@ -3460,14 +3478,14 @@ ToolbarSlot::add_item(unique_ptr<Widget> item, size_t at)
Composite::add_child(std::move(item), at);
this->items_.insert(this->items_.begin() + ptrdiff_t(at), raw);
if (at < this->split_)
++this->split_;
this->split_++;
return raw;
}
void
ToolbarSlot::sync_layout_visible()
{
for (size_t i = 0; i < this->items_.size(); ++i) {
for (size_t i = 0; i < this->items_.size(); i++) {
// Only ever one of the two: what is lent starts at the split, so an
// item is either shown in the popup's Flow or kept here by the bar.
this->items_[i]->layout_visible =
@@ -3492,13 +3510,13 @@ ToolbarSlot::lend_to(Overflow &overflow)
const size_t end = this->items_.size();
size_t a = min(this->split_, end), b = end;
while (a < b && is_sep(this->items_[a]))
++a;
a++;
while (b > a && is_sep(this->items_[b - 1]))
--b;
for (size_t i = a; i < b; ++i) {
for (size_t i = a; i < b; i++) {
Widget *item = this->items_[i];
// Ownership follows the widget: whoever lays it out holds it.
for (size_t j = 0; j < this->kids.size(); ++j) {
for (size_t j = 0; j < this->kids.size(); j++) {
if (this->kids[j].get() != item)
continue;
overflow.col->add_child(take_child(j));
@@ -3529,9 +3547,9 @@ ToolbarSlot::reclaim()
// Back in bar order, ahead of more, which is the last child throughout.
// Everything below the run stayed here, so that is where it resumes.
size_t at = first;
for (size_t i = first; i < last; ++i) {
for (size_t i = first; i < last; i++) {
Widget *item = this->items_[i];
for (size_t j = 0; j < overflow->col->kids.size(); ++j) {
for (size_t j = 0; j < overflow->col->kids.size(); j++) {
if (overflow->col->kids[j].get() != item)
continue;
Composite::add_child(overflow->col->take_child(j), at++);
@@ -3587,7 +3605,7 @@ ToolbarSlot::arrange(Kit &kit, Rect alloc)
// decide nothing overflows, and close the popup that is holding them.
int total = 0;
int shown = 0;
for (size_t i = 0; i < end; ++i) {
for (size_t i = 0; i < end; i++) {
Widget *item = this->items_[i];
if (!item->visible)
continue;
@@ -3605,7 +3623,7 @@ ToolbarSlot::arrange(Kit &kit, Rect alloc)
int kept = 0;
bool full = false;
this->split_ = 0;
for (size_t i = 0; i < end; ++i) {
for (size_t i = 0; i < end; i++) {
Widget *item = this->items_[i];
if (!item->visible) {
if (!full)
@@ -3618,7 +3636,7 @@ ToolbarSlot::arrange(Kit &kit, Rect alloc)
continue;
}
used += need;
++kept;
kept++;
this->split_ = i + 1;
}
while (this->split_ > 0 && is_sep(this->items_[this->split_ - 1]))
@@ -4426,7 +4444,7 @@ Kit::focus_scope() const
void
Kit::cycle_focus(int dir)
{
cycle_focus(focus_scope(), dir);
cycle_focus(focus_scope(), dir, true);
}
bool
@@ -4437,7 +4455,7 @@ Kit::cycle_focus(Widget *scope, int dir, bool wrap)
if (items.empty())
return false;
int i = -1;
for (int k = 0, n = int(items.size()); k < n; ++k) {
for (int k = 0, n = int(items.size()); k < n; k++) {
if (items[size_t(k)] == this->focus_) {
i = k;
break;
@@ -4612,7 +4630,7 @@ Kit::mouse_motion(float x, float y)
bool
Kit::track_popups(float x, float y)
{
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); ++it) {
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); it++) {
if (*it && (*it)->motion(*this, x, y))
return true;
}
@@ -4718,7 +4736,7 @@ Kit::destroy()
this->inited_ = false;
this->popups_.clear();
this->scrim_.reset();
++this->atlas_epoch_;
this->atlas_epoch_++;
this->icons_.clear();
this->glyphs_.clear();
this->fonts_.clear();
@@ -4955,7 +4973,7 @@ wake_tree(const Widget *w)
return -1;
int ms = w->wake_ms();
const size_t n = w->child_count();
for (size_t i = 0; i < n; ++i)
for (size_t i = 0; i < n; i++)
ms = sooner(ms, wake_tree(w->child(i)));
return ms;
}
@@ -5044,7 +5062,7 @@ Kit::close_popups()
void
Kit::close_transient_popups()
{
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); ++it) {
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); it++) {
if (*it && !(*it)->transient()) {
close_above(*it);
return;
@@ -5097,7 +5115,7 @@ Kit::hit(float x, float y)
if (p && p->shown() && p->transient())
transient_open = true;
}
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); ++it) {
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); it++) {
Popup *p = *it;
if (!p || !p->shown() || (transient_open && !p->transient()))
continue;
@@ -5106,7 +5124,7 @@ Kit::hit(float x, float y)
}
// Before the scrim: pressing the button a list came out of has to reach
// the button, which is what closes it again.
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); ++it) {
for (auto it = this->popups_.rbegin(); it != this->popups_.rend(); it++) {
Popup *p = *it;
if (!p || !p->shown())
continue;
+10 -13
View File
@@ -19,8 +19,8 @@
#include <Qt>
#include <chrono>
#include <cstddef>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
@@ -194,11 +194,12 @@ struct Widget {
struct Composite : Widget {
std::vector<std::unique_ptr<Widget>> kids;
Widget *add_child(
std::unique_ptr<Widget> child, std::size_t at = std::size_t(-1));
Widget *add_child(std::unique_ptr<Widget> child);
Widget *add_child(std::unique_ptr<Widget> child, std::size_t at);
// The inverse: detaches one child and hands its ownership back.
std::unique_ptr<Widget> take_child(std::size_t at);
void erase_children(std::size_t from = 0);
void erase_children();
void erase_children(std::size_t from);
std::size_t child_count() const override { return this->kids.size(); }
Widget *child(std::size_t i) const override
{
@@ -658,8 +659,8 @@ struct ToolbarSlot : Row {
std::vector<Widget *> items_;
ToolbarSlot();
Widget *add_item(
std::unique_ptr<Widget> item, std::size_t at = std::size_t(-1));
Widget *add_item(std::unique_ptr<Widget> item);
Widget *add_item(std::unique_ptr<Widget> item, std::size_t at);
// Moves everything past the split into the popup, or brings it back.
void lend_to(Overflow &overflow);
void reclaim();
@@ -841,13 +842,12 @@ struct Kit {
bool activate_mnemonic(Widget *scope, int key);
Widget *focus_scope() const;
void cycle_focus(int dir);
bool cycle_focus(Widget *scope, int dir, bool wrap = true);
bool cycle_focus(Widget *scope, int dir, bool wrap);
void focus_first(Widget *scope);
bool key(const Key &ev);
bool input_method(const QString &commit, const QString &preedit, int caret);
[[nodiscard]] bool text_target(TextTarget &out) const;
bool mouse_press(
float x, float y, Qt::MouseButton button, unsigned mods = 0);
bool mouse_press(float x, float y, Qt::MouseButton button, unsigned mods);
bool mouse_release(float x, float y, Qt::MouseButton button);
bool mouse_motion(float x, float y);
bool mouse_scroll(float x, float y, int delta);
@@ -865,10 +865,7 @@ struct Kit {
float x, float y, const QString &text, Colour colour, bool bold);
void draw_glow(Rect w, Colour col);
// An inactive window halves whatever alpha its ink already had.
[[nodiscard]] float ink_alpha() const
{
return this->active_ ? 1.f : 0.5f;
}
[[nodiscard]] float ink_alpha() const { return this->active_ ? 1.f : 0.5f; }
void focus_ring(Rect w); // 1pt inset ring
void draw_shadow(Rect w); // popup/tooltip drop shadow
// Rect-shaped wrappers over the corner-based draw list.
+1 -1
View File
@@ -238,7 +238,7 @@ main(int argc, char **argv)
// Notifiers armed; Qt delivers them only in exec().
// A Hello during init may time out (250ms) and isolate.
host = make_unique<dn::InstanceHost>(
std::move(listen.listener), app, session);
std::move(listen.listener), app, session, nullptr);
}
}
#endif
+5 -5
View File
@@ -161,7 +161,7 @@ OverlayList::add_thumb(Box b, Uv uv, int transfer, Colour col)
this->tex_ = kOverlayTexThumbs;
add_quad(b, uv, col, col, col, col);
const size_t first = this->mesh_.vertices.size() - 4;
for (size_t i = first; i < this->mesh_.vertices.size(); ++i) {
for (size_t i = first; i < this->mesh_.vertices.size(); i++) {
OverlayVertex &vertex = this->mesh_.vertices[i];
vertex.atlas_x0 = uv.u0;
vertex.atlas_y0 = uv.v0;
@@ -186,7 +186,7 @@ merge_free(vector<Sheet::Packed> &free)
});
vector<Sheet::Packed> out;
out.push_back(free.front());
for (size_t i = 1; i < free.size(); ++i) {
for (size_t i = 1; i < free.size(); i++) {
Sheet::Packed &last = out.back();
if (last.x + last.w == free[i].x)
last.w += free[i].w;
@@ -226,7 +226,7 @@ Sheet::grow(int side)
return;
vector<uint16_t> next(size_t(nw) * size_t(nh) * 4, 0);
if (this->w > 0 && this->h > 0 && !this->pixels.empty()) {
for (int y = 0; y < this->h; ++y) {
for (int y = 0; y < this->h; y++) {
memcpy(next.data() + size_t(y) * size_t(nw) * 4,
this->pixels.data() + size_t(y) * size_t(this->w) * 4,
size_t(this->w) * 8);
@@ -250,7 +250,7 @@ Sheet::alloc(int tw, int th)
for (Shelf &shelf : this->shelves_) {
if (shelf.h != th)
continue;
for (size_t i = 0; i < shelf.free.size(); ++i) {
for (size_t i = 0; i < shelf.free.size(); i++) {
Packed &span = shelf.free[i];
if (span.w < tw)
continue;
@@ -313,7 +313,7 @@ Sheet::blit(Packed slot, const uint16_t *src, int src_w, int src_h, int stride)
stride = src_w * int(sizeof(uint16_t) * 4);
const int cols = min(slot.w, src_w);
const int rows = min(slot.h, src_h);
for (int y = 0; y < rows; ++y) {
for (int y = 0; y < rows; y++) {
uint16_t *dst = this->pixels.data() +
(size_t(slot.y + y) * size_t(this->w) + size_t(slot.x)) * 4;
const auto *row = (const uint16_t *) ((const uint8_t *) src +
+1 -1
View File
@@ -131,7 +131,7 @@ struct Sheet {
std::vector<Shelf> shelves_;
Sheet() = default;
explicit Sheet(int side, bool keep_pixels = true);
explicit Sheet(int side, bool keep_pixels);
void clear();
void grow(int side);
+131 -135
View File
@@ -37,7 +37,7 @@ check_vk(VkResult result, const char *what)
}
}
#define CALL_VK(name, suffix, ...) \
#define CALL_VK(name, suffix, ...) \
check_vk(vk##name(__VA_ARGS__), "vk" #name suffix)
[[noreturn]] static void
@@ -119,7 +119,7 @@ pick_surface_format(const vector<VkSurfaceFormatKHR> &formats)
{
VkSurfaceFormatKHR best = formats.front();
int best_score = surface_format_score(best);
for (size_t i = 1; i < formats.size(); ++i) {
for (size_t i = 1; i < formats.size(); i++) {
const int score = surface_format_score(formats[i]);
if (score > best_score) {
best = formats[i];
@@ -134,11 +134,11 @@ pick_present_mode(
VkPhysicalDevice phys, VkSurfaceKHR surface, VkPresentModeKHR preferred)
{
uint32_t count = 0;
CALL_VK(GetPhysicalDeviceSurfacePresentModesKHR, " count",
phys, surface, &count, nullptr);
CALL_VK(GetPhysicalDeviceSurfacePresentModesKHR, " count", phys, surface,
&count, nullptr);
vector<VkPresentModeKHR> modes(count);
CALL_VK(GetPhysicalDeviceSurfacePresentModesKHR, "",
phys, surface, &count, modes.data());
CALL_VK(GetPhysicalDeviceSurfacePresentModesKHR, "", phys, surface, &count,
modes.data());
if (find(modes.begin(), modes.end(), preferred) != modes.end())
return preferred;
// TODO: A silent MAILBOX-to-FIFO fallback restores Mesa's legacy Wayland
@@ -208,30 +208,30 @@ Renderer::init(const GpuContext &gpu, VkSurfaceKHR surface, Extent pixel,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = this->queue_family_,
};
CALL_VK(CreateCommandPool, "",
this->device_, &pool_info, nullptr, &this->cmd_pool_);
CALL_VK(CreateCommandPool, "", this->device_, &pool_info, nullptr,
&this->cmd_pool_);
VkCommandBufferAllocateInfo command_info{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = this->cmd_pool_,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1,
};
CALL_VK(AllocateCommandBuffers, "",
this->device_, &command_info, &this->cmd_);
CALL_VK(
AllocateCommandBuffers, "", this->device_, &command_info, &this->cmd_);
VkFenceCreateInfo fence_info{
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
};
CALL_VK(CreateFence, "",
this->device_, &fence_info, nullptr, &this->fence_);
CALL_VK(
CreateFence, "", this->device_, &fence_info, nullptr, &this->fence_);
VkSemaphoreCreateInfo semaphore_info{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
};
CALL_VK(CreateSemaphore, " image_available",
this->device_, &semaphore_info, nullptr, &this->image_available_);
CALL_VK(CreateSemaphore, " render_finished",
this->device_, &semaphore_info, nullptr, &this->render_finished_);
CALL_VK(CreateSemaphore, " image_available", this->device_, &semaphore_info,
nullptr, &this->image_available_);
CALL_VK(CreateSemaphore, " render_finished", this->device_, &semaphore_info,
nullptr, &this->render_finished_);
this->want_extent_ = {pixel.width, pixel.height};
create_swapchain();
@@ -317,8 +317,8 @@ Renderer::create_swapchain()
{
destroy_swapchain();
VkSurfaceCapabilitiesKHR capabilities{};
CALL_VK(GetPhysicalDeviceSurfaceCapabilitiesKHR, "",
this->phys_, this->surface_, &capabilities);
CALL_VK(GetPhysicalDeviceSurfaceCapabilitiesKHR, "", this->phys_,
this->surface_, &capabilities);
this->extent_.width = clamp(this->want_extent_.width,
capabilities.minImageExtent.width,
@@ -404,18 +404,18 @@ Renderer::create_swapchain()
.presentMode = this->present_mode_,
.clipped = VK_TRUE,
};
CALL_VK(CreateSwapchainKHR, "",
this->device_, &swapchain_info, nullptr, &this->swapchain_);
CALL_VK(CreateSwapchainKHR, "", this->device_, &swapchain_info, nullptr,
&this->swapchain_);
uint32_t count = 0;
CALL_VK(GetSwapchainImagesKHR, " count",
this->device_, this->swapchain_, &count, nullptr);
CALL_VK(GetSwapchainImagesKHR, " count", this->device_, this->swapchain_,
&count, nullptr);
this->images_.resize(count);
CALL_VK(GetSwapchainImagesKHR, "",
this->device_, this->swapchain_, &count, this->images_.data());
CALL_VK(GetSwapchainImagesKHR, "", this->device_, this->swapchain_, &count,
this->images_.data());
this->views_.resize(count);
this->framebuffers_.resize(count);
for (uint32_t i = 0; i < count; ++i) {
for (uint32_t i = 0; i < count; i++) {
VkImageViewCreateInfo view_info{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = this->images_[i],
@@ -425,14 +425,14 @@ Renderer::create_swapchain()
.levelCount = 1,
.layerCount = 1},
};
CALL_VK(CreateImageView, " swap",
this->device_, &view_info, nullptr, &this->views_[i]);
CALL_VK(CreateImageView, " swap", this->device_, &view_info, nullptr,
&this->views_[i]);
}
if (dither)
create_dither();
const VkRenderPass swap_rp =
dither ? this->dither_rp_ : this->engine_.dest_render_pass();
for (uint32_t i = 0; i < count; ++i) {
for (uint32_t i = 0; i < count; i++) {
VkFramebufferCreateInfo framebuffer_info{
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = swap_rp,
@@ -442,9 +442,8 @@ Renderer::create_swapchain()
.height = this->extent_.height,
.layers = 1,
};
CALL_VK(CreateFramebuffer, "",
this->device_, &framebuffer_info, nullptr,
&this->framebuffers_[i]);
CALL_VK(CreateFramebuffer, "", this->device_, &framebuffer_info,
nullptr, &this->framebuffers_[i]);
}
if (this->overlay_format_ != dest_format ||
this->overlay_layout_ != dest_layout) {
@@ -471,8 +470,8 @@ Renderer::wait_idle() const
{
if (!this->device_ || !this->fence_)
return;
CALL_VK(WaitForFences, "",
this->device_, 1, &this->fence_, VK_TRUE, UINT64_MAX);
CALL_VK(WaitForFences, "", this->device_, 1, &this->fence_, VK_TRUE,
UINT64_MAX);
}
void
@@ -575,8 +574,8 @@ Renderer::draw_frame(const OverlayMesh &mesh)
if (!this->device_ || !this->swapchain_ || !this->extent_.width ||
!this->extent_.height)
return true;
CALL_VK(WaitForFences, "",
this->device_, 1, &this->fence_, VK_TRUE, UINT64_MAX);
CALL_VK(WaitForFences, "", this->device_, 1, &this->fence_, VK_TRUE,
UINT64_MAX);
uint32_t index = 0;
// A hidden Wayland surface has no guaranteed presentation progress, so an
// infinite acquire timeout is invalid. Keep the latest frame dirty and let
@@ -660,8 +659,7 @@ Renderer::draw_frame(const OverlayMesh &mesh)
.signalSemaphoreCount = 1,
.pSignalSemaphores = &this->render_finished_,
};
CALL_VK(QueueSubmit, "",
this->queue_, 1, &submit_info, this->fence_);
CALL_VK(QueueSubmit, "", this->queue_, 1, &submit_info, this->fence_);
VkPresentInfoKHR present_info{
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 1,
@@ -749,13 +747,14 @@ Renderer::create_dither()
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
CALL_VK(CreateImage, " compose",
this->device_, &image_info, nullptr, &this->compose_image_);
CALL_VK(CreateImage, " compose", this->device_, &image_info, nullptr,
&this->compose_image_);
VkMemoryRequirements requirements{};
vkGetImageMemoryRequirements(
this->device_, this->compose_image_, &requirements);
const uint32_t type = dawn::vk_memory_type(this->phys_,
requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
const uint32_t type =
dawn::vk_memory_type(this->phys_, requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, nullptr, nullptr);
if (type == UINT32_MAX)
die("dither compose: no device-local memory");
VkMemoryAllocateInfo allocate{
@@ -763,10 +762,10 @@ Renderer::create_dither()
.allocationSize = requirements.size,
.memoryTypeIndex = type,
};
CALL_VK(AllocateMemory, " compose",
this->device_, &allocate, nullptr, &this->compose_memory_);
CALL_VK(BindImageMemory, " compose",
this->device_, this->compose_image_, this->compose_memory_, 0);
CALL_VK(AllocateMemory, " compose", this->device_, &allocate, nullptr,
&this->compose_memory_);
CALL_VK(BindImageMemory, " compose", this->device_, this->compose_image_,
this->compose_memory_, 0);
VkImageViewCreateInfo view_info{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = this->compose_image_,
@@ -776,8 +775,8 @@ Renderer::create_dither()
.levelCount = 1,
.layerCount = 1},
};
CALL_VK(CreateImageView, " compose",
this->device_, &view_info, nullptr, &this->compose_view_);
CALL_VK(CreateImageView, " compose", this->device_, &view_info, nullptr,
&this->compose_view_);
VkFramebufferCreateInfo fb_info{
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = this->engine_.dest_render_pass(),
@@ -787,8 +786,8 @@ Renderer::create_dither()
.height = this->extent_.height,
.layers = 1,
};
CALL_VK(CreateFramebuffer, " compose",
this->device_, &fb_info, nullptr, &this->compose_fb_);
CALL_VK(CreateFramebuffer, " compose", this->device_, &fb_info, nullptr,
&this->compose_fb_);
VkAttachmentDescription color{
.format = this->format_,
@@ -826,8 +825,8 @@ Renderer::create_dither()
.dependencyCount = 1,
.pDependencies = &dependency,
};
CALL_VK(CreateRenderPass, " dither",
this->device_, &rp_info, nullptr, &this->dither_rp_);
CALL_VK(CreateRenderPass, " dither", this->device_, &rp_info, nullptr,
&this->dither_rp_);
VkSamplerCreateInfo sampler_info{
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
@@ -838,8 +837,8 @@ Renderer::create_dither()
.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
};
CALL_VK(CreateSampler, " dither",
this->device_, &sampler_info, nullptr, &this->dither_sampler_);
CALL_VK(CreateSampler, " dither", this->device_, &sampler_info, nullptr,
&this->dither_sampler_);
VkDescriptorSetLayoutBinding binding{
.binding = 0,
@@ -852,8 +851,8 @@ Renderer::create_dither()
.bindingCount = 1,
.pBindings = &binding,
};
CALL_VK(CreateDescriptorSetLayout, " dither",
this->device_, &set_info, nullptr, &this->dither_set_layout_);
CALL_VK(CreateDescriptorSetLayout, " dither", this->device_, &set_info,
nullptr, &this->dither_set_layout_);
VkDescriptorPoolSize pool_size{
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
@@ -864,16 +863,16 @@ Renderer::create_dither()
.poolSizeCount = 1,
.pPoolSizes = &pool_size,
};
CALL_VK(CreateDescriptorPool, " dither",
this->device_, &pool_info, nullptr, &this->dither_pool_);
CALL_VK(CreateDescriptorPool, " dither", this->device_, &pool_info, nullptr,
&this->dither_pool_);
VkDescriptorSetAllocateInfo set_alloc{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = this->dither_pool_,
.descriptorSetCount = 1,
.pSetLayouts = &this->dither_set_layout_,
};
CALL_VK(AllocateDescriptorSets, " dither",
this->device_, &set_alloc, &this->dither_set_);
CALL_VK(AllocateDescriptorSets, " dither", this->device_, &set_alloc,
&this->dither_set_);
VkDescriptorImageInfo image_descriptor{
.sampler = this->dither_sampler_,
.imageView = this->compose_view_,
@@ -894,23 +893,23 @@ Renderer::create_dither()
.codeSize = fullscreen_vert_words * sizeof(uint32_t),
.pCode = fullscreen_vert,
};
CALL_VK(CreateShaderModule, " dither vert",
this->device_, &vert_info, nullptr, &this->dither_vert_);
CALL_VK(CreateShaderModule, " dither vert", this->device_, &vert_info,
nullptr, &this->dither_vert_);
VkShaderModuleCreateInfo frag_info{
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = dn_dither_frag_words * sizeof(uint32_t),
.pCode = dn_dither_frag,
};
CALL_VK(CreateShaderModule, " dither frag",
this->device_, &frag_info, nullptr, &this->dither_frag_);
CALL_VK(CreateShaderModule, " dither frag", this->device_, &frag_info,
nullptr, &this->dither_frag_);
VkPipelineLayoutCreateInfo layout_info{
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = &this->dither_set_layout_,
};
CALL_VK(CreatePipelineLayout, " dither",
this->device_, &layout_info, nullptr, &this->dither_layout_);
CALL_VK(CreatePipelineLayout, " dither", this->device_, &layout_info,
nullptr, &this->dither_layout_);
VkPipelineShaderStageCreateInfo stages[2]{};
stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@@ -974,9 +973,8 @@ Renderer::create_dither()
.layout = this->dither_layout_,
.renderPass = this->dither_rp_,
};
CALL_VK(CreateGraphicsPipelines, " dither",
this->device_, VK_NULL_HANDLE, 1, &pipeline_info, nullptr,
&this->dither_pipe_);
CALL_VK(CreateGraphicsPipelines, " dither", this->device_, VK_NULL_HANDLE,
1, &pipeline_info, nullptr, &this->dither_pipe_);
}
void
@@ -1046,8 +1044,8 @@ OverlayVulkan::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
.queueFamilyIndex = this->queue_family_,
};
CALL_VK(CreateCommandPool, " overlay upload",
this->device_, &pool_info, nullptr, &this->upload_pool_);
CALL_VK(CreateCommandPool, " overlay upload", this->device_, &pool_info,
nullptr, &this->upload_pool_);
compute_thumb_atlas_max();
VkAttachmentDescription color{
@@ -1087,8 +1085,8 @@ OverlayVulkan::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
.dependencyCount = 1,
.pDependencies = &dependency,
};
CALL_VK(CreateRenderPass, " overlay",
this->device_, &render_pass_info, nullptr, &this->render_pass_);
CALL_VK(CreateRenderPass, " overlay", this->device_, &render_pass_info,
nullptr, &this->render_pass_);
VkSamplerCreateInfo sampler_info{
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
@@ -1100,8 +1098,8 @@ OverlayVulkan::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.maxLod = 1.f,
};
CALL_VK(CreateSampler, " overlay",
this->device_, &sampler_info, nullptr, &this->sampler_);
CALL_VK(CreateSampler, " overlay", this->device_, &sampler_info, nullptr,
&this->sampler_);
VkDescriptorSetLayoutBinding binding{
.binding = 0,
@@ -1114,8 +1112,8 @@ OverlayVulkan::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
.bindingCount = 1,
.pBindings = &binding,
};
CALL_VK(CreateDescriptorSetLayout, " overlay",
this->device_, &layout_info, nullptr, &this->set_layout_);
CALL_VK(CreateDescriptorSetLayout, " overlay", this->device_, &layout_info,
nullptr, &this->set_layout_);
VkDescriptorPoolSize pool_size{
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
@@ -1127,9 +1125,8 @@ OverlayVulkan::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
.poolSizeCount = 1,
.pPoolSizes = &pool_size,
};
CALL_VK(CreateDescriptorPool, " overlay",
this->device_, &descriptor_pool_info, nullptr,
&this->descriptor_pool_);
CALL_VK(CreateDescriptorPool, " overlay", this->device_,
&descriptor_pool_info, nullptr, &this->descriptor_pool_);
VkDescriptorSetLayout layouts[2] = {this->set_layout_, this->set_layout_};
VkDescriptorSetAllocateInfo allocate_info{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
@@ -1137,8 +1134,8 @@ OverlayVulkan::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
.descriptorSetCount = 2,
.pSetLayouts = layouts,
};
CALL_VK(AllocateDescriptorSets, " overlay",
this->device_, &allocate_info, this->descriptor_sets_);
CALL_VK(AllocateDescriptorSets, " overlay", this->device_, &allocate_info,
this->descriptor_sets_);
return create_pipeline();
}
@@ -1161,12 +1158,12 @@ OverlayVulkan::create_pipeline()
.codeSize = dn_thumb_frag_words * sizeof(uint32_t),
.pCode = dn_thumb_frag,
};
CALL_VK(CreateShaderModule, " overlay vert",
this->device_, &vert_info, nullptr, &this->vert_);
CALL_VK(CreateShaderModule, " overlay frag",
this->device_, &frag_info, nullptr, &this->frag_);
CALL_VK(CreateShaderModule, " thumb frag",
this->device_, &thumb_frag_info, nullptr, &this->thumb_frag_);
CALL_VK(CreateShaderModule, " overlay vert", this->device_, &vert_info,
nullptr, &this->vert_);
CALL_VK(CreateShaderModule, " overlay frag", this->device_, &frag_info,
nullptr, &this->frag_);
CALL_VK(CreateShaderModule, " thumb frag", this->device_, &thumb_frag_info,
nullptr, &this->thumb_frag_);
VkPushConstantRange push{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
@@ -1180,9 +1177,8 @@ OverlayVulkan::create_pipeline()
.pushConstantRangeCount = 1,
.pPushConstantRanges = &push,
};
CALL_VK(CreatePipelineLayout, " overlay",
this->device_, &pipeline_layout_info, nullptr,
&this->pipeline_layout_);
CALL_VK(CreatePipelineLayout, " overlay", this->device_,
&pipeline_layout_info, nullptr, &this->pipeline_layout_);
VkPipelineShaderStageCreateInfo stages[2]{};
stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@@ -1289,13 +1285,11 @@ OverlayVulkan::create_pipeline()
.layout = this->pipeline_layout_,
.renderPass = this->render_pass_,
};
CALL_VK(CreateGraphicsPipelines, " overlay",
this->device_, VK_NULL_HANDLE, 1, &pipeline_info, nullptr,
&this->pipeline_);
CALL_VK(CreateGraphicsPipelines, " overlay", this->device_, VK_NULL_HANDLE,
1, &pipeline_info, nullptr, &this->pipeline_);
stages[1].module = this->thumb_frag_;
CALL_VK(CreateGraphicsPipelines, " thumbnails",
this->device_, VK_NULL_HANDLE, 1, &pipeline_info, nullptr,
&this->thumb_pipeline_);
CALL_VK(CreateGraphicsPipelines, " thumbnails", this->device_,
VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &this->thumb_pipeline_);
return true;
}
@@ -1309,7 +1303,7 @@ OverlayVulkan::set_swapchain(
!extent.width || !extent.height)
return;
this->framebuffers_.resize(views.size());
for (size_t i = 0; i < views.size(); ++i) {
for (size_t i = 0; i < views.size(); i++) {
VkFramebufferCreateInfo info{
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = this->render_pass_,
@@ -1319,8 +1313,8 @@ OverlayVulkan::set_swapchain(
.height = extent.height,
.layers = 1,
};
CALL_VK(CreateFramebuffer, " overlay",
this->device_, &info, nullptr, &this->framebuffers_[i]);
CALL_VK(CreateFramebuffer, " overlay", this->device_, &info, nullptr,
&this->framebuffers_[i]);
}
}
@@ -1378,12 +1372,13 @@ OverlayVulkan::create_sampled(
if (!this->device_ || width <= 0 || height <= 0 || !image || !memory)
return false;
const VkImageCreateInfo image_info = sampled_info(width, height);
CALL_VK(CreateImage, " overlay tex",
this->device_, &image_info, nullptr, image);
CALL_VK(CreateImage, " overlay tex", this->device_, &image_info, nullptr,
image);
VkMemoryRequirements requirements{};
vkGetImageMemoryRequirements(this->device_, *image, &requirements);
const uint32_t image_type = dawn::vk_memory_type(this->phys_,
requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
const uint32_t image_type =
dawn::vk_memory_type(this->phys_, requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, nullptr, nullptr);
if (image_type == UINT32_MAX) {
vkDestroyImage(this->device_, *image, nullptr);
*image = VK_NULL_HANDLE;
@@ -1394,10 +1389,9 @@ OverlayVulkan::create_sampled(
.allocationSize = requirements.size,
.memoryTypeIndex = image_type,
};
CALL_VK(AllocateMemory, " overlay tex",
this->device_, &allocate, nullptr, memory);
CALL_VK(BindImageMemory, " overlay tex",
this->device_, *image, *memory, 0);
CALL_VK(AllocateMemory, " overlay tex", this->device_, &allocate, nullptr,
memory);
CALL_VK(BindImageMemory, " overlay tex", this->device_, *image, *memory, 0);
return true;
}
@@ -1415,8 +1409,8 @@ OverlayVulkan::bind_sampled(VkImage image, VkImageView *view,
.levelCount = 1,
.layerCount = 1},
};
CALL_VK(CreateImageView, " overlay tex",
this->device_, &view_info, nullptr, view);
CALL_VK(CreateImageView, " overlay tex", this->device_, &view_info, nullptr,
view);
if (!set)
return;
VkDescriptorImageInfo image_descriptor{
@@ -1451,15 +1445,16 @@ OverlayVulkan::copy_rgba16(const void *pixels, int width, int height,
.size = size,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
};
CALL_VK(CreateBuffer, " overlay tex staging",
this->device_, &buffer_info, nullptr, &staging);
CALL_VK(CreateBuffer, " overlay tex staging", this->device_, &buffer_info,
nullptr, &staging);
VkMemoryRequirements requirements{};
vkGetBufferMemoryRequirements(this->device_, staging, &requirements);
const uint32_t host_type =
dawn::vk_memory_type(this->phys_, requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
nullptr, nullptr);
if (host_type == UINT32_MAX) {
vkDestroyBuffer(this->device_, staging, nullptr);
return false;
@@ -1470,13 +1465,13 @@ OverlayVulkan::copy_rgba16(const void *pixels, int width, int height,
.allocationSize = requirements.size,
.memoryTypeIndex = host_type,
};
CALL_VK(AllocateMemory, " overlay tex staging",
this->device_, &allocate, nullptr, &staging_memory);
CALL_VK(BindBufferMemory, " overlay tex staging",
this->device_, staging, staging_memory, 0);
CALL_VK(AllocateMemory, " overlay tex staging", this->device_, &allocate,
nullptr, &staging_memory);
CALL_VK(BindBufferMemory, " overlay tex staging", this->device_, staging,
staging_memory, 0);
void *mapped = nullptr;
CALL_VK(MapMemory, " overlay tex staging",
this->device_, staging_memory, 0, size, 0, &mapped);
CALL_VK(MapMemory, " overlay tex staging", this->device_, staging_memory, 0,
size, 0, &mapped);
memcpy(mapped, pixels, size_t(size));
vkUnmapMemory(this->device_, staging_memory);
@@ -1487,8 +1482,8 @@ OverlayVulkan::copy_rgba16(const void *pixels, int width, int height,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1,
};
CALL_VK(AllocateCommandBuffers, " overlay tex",
this->device_, &cmd_info, &cmd);
CALL_VK(
AllocateCommandBuffers, " overlay tex", this->device_, &cmd_info, &cmd);
VkCommandBufferBeginInfo begin{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
@@ -1536,8 +1531,8 @@ OverlayVulkan::copy_rgba16(const void *pixels, int width, int height,
.commandBufferCount = 1,
.pCommandBuffers = &cmd,
};
CALL_VK(QueueSubmit, " overlay tex",
this->queue_, 1, &submit, VK_NULL_HANDLE);
CALL_VK(
QueueSubmit, " overlay tex", this->queue_, 1, &submit, VK_NULL_HANDLE);
CALL_VK(QueueWaitIdle, " overlay tex", this->queue_);
vkFreeCommandBuffers(this->device_, this->upload_pool_, 1, &cmd);
vkDestroyBuffer(this->device_, staging, nullptr);
@@ -1556,7 +1551,7 @@ OverlayVulkan::upload_rgba16(const void *pixels, int width, int height,
if (!create_sampled(width, height, image, memory))
return false;
if (!copy_rgba16(
pixels, width, height, *image, VK_IMAGE_LAYOUT_UNDEFINED)) {
pixels, width, height, *image, VK_IMAGE_LAYOUT_UNDEFINED, 0, 0)) {
destroy_sampled(image, memory, view);
return false;
}
@@ -1703,14 +1698,15 @@ OverlayVulkan::ensure_buffers(
.size = *current,
.usage = usage,
};
CALL_VK(CreateBuffer, " overlay",
this->device_, &info, nullptr, buffer);
CALL_VK(
CreateBuffer, " overlay", this->device_, &info, nullptr, buffer);
VkMemoryRequirements requirements{};
vkGetBufferMemoryRequirements(this->device_, *buffer, &requirements);
const uint32_t type =
dawn::vk_memory_type(this->phys_, requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
nullptr, nullptr);
if (type == UINT32_MAX)
return false;
VkMemoryAllocateInfo allocate{
@@ -1718,10 +1714,10 @@ OverlayVulkan::ensure_buffers(
.allocationSize = requirements.size,
.memoryTypeIndex = type,
};
CALL_VK(AllocateMemory, " overlay",
this->device_, &allocate, nullptr, memory);
CALL_VK(BindBufferMemory, " overlay",
this->device_, *buffer, *memory, 0);
CALL_VK(AllocateMemory, " overlay", this->device_, &allocate, nullptr,
memory);
CALL_VK(
BindBufferMemory, " overlay", this->device_, *buffer, *memory, 0);
return true;
};
return recreate(&this->vertex_buffer_, &this->vertex_memory_,
@@ -1753,10 +1749,10 @@ OverlayVulkan::record(
void *vertices = nullptr;
void *indices = nullptr;
CALL_VK(MapMemory, " overlay vtx",
this->device_, this->vertex_memory_, 0, vertex_bytes, 0, &vertices);
CALL_VK(MapMemory, " overlay idx",
this->device_, this->index_memory_, 0, index_bytes, 0, &indices);
CALL_VK(MapMemory, " overlay vtx", this->device_, this->vertex_memory_, 0,
vertex_bytes, 0, &vertices);
CALL_VK(MapMemory, " overlay idx", this->device_, this->index_memory_, 0,
index_bytes, 0, &indices);
memcpy(vertices, mesh.vertices.data(), size_t(vertex_bytes));
memcpy(indices, mesh.indices.data(), size_t(index_bytes));
vkUnmapMemory(this->device_, this->vertex_memory_);
@@ -1788,7 +1784,7 @@ OverlayVulkan::record(
push.translate[0] = -1.f;
push.translate[1] = -1.f;
vkCmdPushConstants(cmd, this->pipeline_layout_, VK_SHADER_STAGE_VERTEX_BIT,
0, sizeof(push), &push);
0, sizeof push, &push);
uint32_t bound_tex = ~0u;
VkPipeline bound_pipeline = VK_NULL_HANDLE;
+4 -4
View File
@@ -51,7 +51,7 @@ class OverlayVulkan
VkImage *image, VkDeviceMemory *memory, VkImageView *view,
VkDescriptorSet set, VkComponentMapping swizzle) const;
bool copy_rgba16(const void *pixels, int width, int height, VkImage image,
VkImageLayout layout, int dst_x = 0, int dst_y = 0) const;
VkImageLayout layout, int dst_x, int dst_y) const;
bool create_sampled(
int width, int height, VkImage *image, VkDeviceMemory *memory) const;
void bind_sampled(VkImage image, VkImageView *view, VkDescriptorSet set,
@@ -113,7 +113,7 @@ public:
bool upload_font(const unsigned char *pixels, int width, int height);
[[nodiscard]] int thumb_atlas_max() const { return this->thumb_atlas_max_; }
bool upload_thumb(const uint16_t *pixels, int width, int height, int dst_x,
int dst_y, int atlas_side, bool *recreated = nullptr);
int dst_y, int atlas_side, bool *recreated);
bool rebuild_thumbs(
const std::vector<ThumbUpload> &uploads, int atlas_side);
void reset_thumbs();
@@ -206,7 +206,7 @@ public:
uint32_t w, uint32_t h, const uint8_t *pixels, size_t stride);
void clear_image();
void set_view(float scale, float pan_x, float pan_y,
dawn::Orientation orientation, float angle = 0.f);
dawn::Orientation orientation, float angle);
void set_well_colour(float r, float g, float b);
void set_prefer_premultiplied(bool enabled)
{
@@ -224,7 +224,7 @@ public:
bool upload_font(const unsigned char *pixels, int width, int height);
[[nodiscard]] int thumb_atlas_max() const;
bool upload_thumb(const uint16_t *pixels, int width, int height, int dst_x,
int dst_y, int atlas_side, bool *recreated = nullptr);
int dst_y, int atlas_side, bool *recreated);
bool rebuild_thumbs(
const std::vector<ThumbUpload> &uploads, int atlas_side);
void reset_thumbs();
+4 -4
View File
@@ -203,7 +203,7 @@ read_wide(const QString &path, const ThumbnailSource &source, int tier,
hit.width = image->width;
hit.height = image->height;
hit.pixels.resize(size_t(hit.width) * hit.height * 4);
for (uint32_t y = 0; y < hit.height; ++y)
for (uint32_t y = 0; y < hit.height; y++)
memcpy(hit.pixels.data() + size_t(y) * hit.width * 4,
row_u16(*image, y), size_t(hit.width) * dawn::kBytesPerPixel);
hit.tier = tier;
@@ -238,7 +238,7 @@ read_png(const QString &path, const ThumbnailSource &source, int tier,
if (!valid_metadata(meta, source))
return {};
shared_ptr<dawn::Profile> srgb = cmm->get_profile_sRGB();
shared_ptr<dawn::Profile> srgb = cmm->get_profile_sRGB(false);
if (!cmm->transform_bgra16(image->data.data(), image->width, image->height,
srgb.get(), screen, true, true))
return {};
@@ -246,7 +246,7 @@ read_png(const QString &path, const ThumbnailSource &source, int tier,
hit.width = image->width;
hit.height = image->height;
hit.pixels.resize(size_t(hit.width) * hit.height * 4);
for (uint32_t y = 0; y < hit.height; ++y)
for (uint32_t y = 0; y < hit.height; y++)
memcpy(hit.pixels.data() + size_t(y) * hit.width * 4,
row_u16(*image, y), size_t(hit.width) * dawn::kBytesPerPixel);
hit.tier = tier;
@@ -414,7 +414,7 @@ thumbnail_cache_write(const ThumbnailSource &source, int tier,
for (size_t i = 0, n = size_t(width) * height; i < n; i++) {
const uint32_t a = pixels[i * 4 + 3];
bgra[i * 4 + 3] = uint8_t((a + 128) / 257);
for (int c = 0; c < 3; ++c) {
for (int c = 0; c < 3; c++) {
const uint32_t straight = a
? min(65535u,
uint32_t(
+1 -1
View File
@@ -52,7 +52,7 @@ ThumbnailHit thumbnail_cache_lookup(const ThumbnailSource &source,
bool thumbnail_cache_write(const ThumbnailSource &source, int tier,
const uint16_t *pixels, uint32_t width, uint32_t height,
uint32_t image_width, uint32_t image_height, QString *error = nullptr);
uint32_t image_width, uint32_t image_height, QString *error);
void thumbnail_cache_invalidate();
+22 -19
View File
@@ -168,16 +168,16 @@ Thumbnailer::Impl::Impl(Thumbnailer *thumbnailer, unsigned worker_count)
[thumbnailer] { thumbnailer->pump(); });
unsigned count =
worker_count ? worker_count : std::thread::hardware_concurrency();
worker_count ? worker_count : thread::hardware_concurrency();
if (!count)
count = 1;
this->worker_count = count;
background_max = min<size_t>(4, max<size_t>(1, count / 4));
workers.reserve(count);
for (unsigned i = 0; i < count; ++i)
for (unsigned i = 0; i < count; i++)
workers.emplace_back([this] { worker_loop(); });
encoders.reserve(count);
for (unsigned i = 0; i < count; ++i)
for (unsigned i = 0; i < count; i++)
encoders.emplace_back([this] { encoder_loop(); });
}
@@ -222,7 +222,7 @@ bool
Thumbnailer::Impl::have_cpu() const
{
const bool reserve = worker_count > 1 && cpu_running >= worker_count - 1;
for (size_t priority = 0; priority < cpu.size(); ++priority) {
for (size_t priority = 0; priority < cpu.size(); priority++) {
if (priority == priority_index(Priority::Prefetch) && reserve)
continue;
if (priority >= priority_index(Priority::Dimensions) &&
@@ -238,7 +238,7 @@ Thumbnailer::Impl::have_cpu() const
bool
Thumbnailer::Impl::pop_cpu(shared_ptr<CpuTask> *task)
{
for (size_t priority = 0; priority < cpu.size(); ++priority) {
for (size_t priority = 0; priority < cpu.size(); priority++) {
const bool reserve =
worker_count > 1 && cpu_running >= worker_count - 1;
if (priority == priority_index(Priority::Prefetch) && reserve)
@@ -308,8 +308,8 @@ Thumbnailer::Impl::worker_loop()
if (client != clients.end() && completion &&
client->second.epoch == task->epoch) {
client->second.gui++;
gui.push_back({task->client, task->epoch, task->running_priority,
std::move(completion)});
gui.push_back({task->client, task->epoch,
task->running_priority, std::move(completion)});
}
}
task->gate->store(true, memory_order_release);
@@ -363,7 +363,7 @@ Thumbnailer::Impl::erase_unpublished(Client id)
{
for (auto it = bundles.begin(); it != bundles.end();) {
if (it->second.client != id || it->second.bundle) {
++it;
it++;
continue;
}
bundle_bytes -= it->second.reserved_bytes;
@@ -388,7 +388,7 @@ Thumbnailer::Impl::erase_gui(Client id, ClientState &state)
state.gui--;
it = gui.erase(it);
} else {
++it;
it++;
}
}
}
@@ -403,7 +403,7 @@ Thumbnailer::Impl::erase_gpu(Client id, ClientState &state)
state.gpu--;
it = gpu_tasks.erase(it);
} else {
++it;
it++;
}
}
}
@@ -649,7 +649,8 @@ Thumbnailer::submit_gpu(Client id, uint64_t epoch, Priority priority,
impl_->fail_gpu(gpu_id, std::move(path));
}
return Completion{};
})) {
},
{})) {
lock_guard lock(impl_->mu);
impl_->drop_gpu(gpu_id);
return false;
@@ -683,8 +684,8 @@ Thumbnailer::reserve_bundle(Client id, uint64_t epoch,
if (!reservation)
reservation = impl_->next_reservation++;
impl_->bundles.emplace(reservation,
Impl::BundleSlot{reservation, id, epoch, source, top_tier, bytes,
priority, {}});
Impl::BundleSlot{
reservation, id, epoch, source, top_tier, bytes, priority, {}});
impl_->bundle_bytes += bytes;
return reservation;
}
@@ -787,13 +788,15 @@ Thumbnailer::foreground_busy(Client id) const
}
for (const auto &[gpu_id, task] : impl_->gpu_tasks) {
(void) gpu_id;
if (task.client == id && priority_index(task.priority) <
priority_index(Priority::Dimensions))
if (task.client == id &&
priority_index(task.priority) <
priority_index(Priority::Dimensions))
return true;
}
for (const Impl::GuiTask &task : impl_->gui)
if (task.client == id && priority_index(task.priority) <
priority_index(Priority::Dimensions))
if (task.client == id &&
priority_index(task.priority) <
priority_index(Priority::Dimensions))
return true;
return false;
}
@@ -836,7 +839,7 @@ Thumbnailer::pump()
// CPU completions establish browser state needed by any GPU job they
// queued. Always apply them before polling those jobs.
size_t gui_count = 0;
for (; gui_count < kGuiBatch; ++gui_count) {
for (; gui_count < kGuiBatch; gui_count++) {
Completion completion;
{
lock_guard lock(impl_->mu);
@@ -874,7 +877,7 @@ Thumbnailer::pump()
Impl::GpuTask &task = it->second;
if (!task.result ||
(task.gate && !task.gate->load(memory_order_acquire))) {
++it;
it++;
continue;
}
auto client = impl_->clients.find(task.client);
+4 -5
View File
@@ -80,25 +80,24 @@ public:
Maintenance,
};
explicit Thumbnailer(QObject *parent = nullptr, unsigned workers = 0);
explicit Thumbnailer(QObject *parent, unsigned workers);
~Thumbnailer() override;
Thumbnailer(const Thumbnailer &) = delete;
Thumbnailer &operator=(const Thumbnailer &) = delete;
bool init(const GpuContext &gpu);
Client add_client(uint64_t epoch = 0, Completion activity = {});
Client add_client(uint64_t epoch, Completion activity);
void remove_client(Client client);
void set_epoch(Client client, uint64_t epoch);
bool submit(Client client, uint64_t epoch, Priority priority, Work work,
std::string key = {});
std::string key);
bool reprioritize(Client client, uint64_t epoch, Priority priority,
const std::string &key);
/// Copies owned job pixels on a worker. Safe on the GUI thread.
bool submit_gpu(Client client, uint64_t epoch, Priority priority,
dawn::ThumbScaler::Job job, GpuCompletion completion,
std::string key = {});
dawn::ThumbScaler::Job job, GpuCompletion completion, std::string key);
Reservation reserve_bundle(Client client, uint64_t epoch,
const ThumbnailSource &source, int top_tier, size_t bytes,
Priority priority);
+1 -2
View File
@@ -38,8 +38,7 @@ url_normalized(const QUrl &url)
QUrl
url_from_user_input(const QString &input, const QString &working_dir)
{
auto url =
QUrl::fromUserInput(input, working_dir, QUrl::AssumeLocalFile);
auto url = QUrl::fromUserInput(input, working_dir, QUrl::AssumeLocalFile);
if (!url.isValid())
url = path_to_url(QDir(working_dir).absoluteFilePath(input));
return url_normalized(url);
+3 -2
View File
@@ -200,8 +200,9 @@ WaylandColorBridge::attach(QWindow *window)
// (winId changes meaning across Qt versions.)
auto *iface = QGuiApplication::platformNativeInterface();
if (iface) {
this->surface_ = static_cast<wl_surface *>(
iface->nativeResourceForWindow(QByteArrayLiteral("surface"), window));
this->surface_ =
static_cast<wl_surface *>(iface->nativeResourceForWindow(
QByteArrayLiteral("surface"), window));
}
if (!this->display_ || !this->surface_)
return;
+1 -2
View File
@@ -54,8 +54,7 @@ public:
explicit WaylandWindow(App *app);
~WaylandWindow() override;
bool initialize(
const QUrl &url, BrowseSetup setup = {}, bool browse = false);
bool initialize(const QUrl &url, BrowseSetup setup, bool browse);
};
// What Qt's own CSD does on titlebar right-click, in shell-local coordinates.
+21 -21
View File
@@ -174,8 +174,8 @@ Window::Window(App *app, QWindow *parent) : QWindow(parent), app_(app)
// Wants shell-local logical coordinates, while the kit passes
// device pixels; we may also hang off the shell by the glow.
const qreal dpr = qreal(host_dpr(*this));
const QPoint p = position() +
QPoint(int(qreal(x) / dpr), int(qreal(y) / dpr));
const QPoint p =
position() + QPoint(int(qreal(x) / dpr), int(qreal(y) / dpr));
wayland_show_window_menu(shell(), p.x(), p.y());
};
#endif
@@ -237,8 +237,7 @@ Window::initialize(const QUrl &url, BrowseSetup setup, bool browse)
// TODO: Pass an explicit presentation policy from WaylandWindow instead of
// using parenthood as this platform/role proxy.
this->renderer_.set_prefer_premultiplied(this->csd_);
this->renderer_.set_dither_enabled(
!this->app_->settings.disable_dithering);
this->renderer_.set_dither_enabled(!this->app_->settings.disable_dithering);
if (!this->renderer_.init(
this->app_->gpu, this->surface_, pixel_size(),
parent() ? VK_PRESENT_MODE_MAILBOX_KHR : VK_PRESENT_MODE_FIFO_KHR,
@@ -343,10 +342,10 @@ Window::bind_host()
if (!ui || !ui->dialog)
break;
dialog_location(this->kit_, *ui->dialog,
[this](const QString &location) {
open_any(url_from_user_input(
location, QDir::currentPath()));
dialog_location(
this->kit_, *ui->dialog, [this](const QString &location) {
open_any(url_from_user_input(location, QDir::currentPath()),
false);
});
request_render();
break;
@@ -387,8 +386,8 @@ Window::bind_host()
SettingsDraft draft;
draft.thumbnail_size = settings.browser_thumbnail_size;
draft.show_filenames = settings.browser_show_filenames;
draft.icc_profile_path = QString::fromStdString(
settings.icc_profile_override_path);
draft.icc_profile_path =
QString::fromStdString(settings.icc_profile_override_path);
draft.disable_dithering = settings.disable_dithering;
draft.loaders = settings.loaders;
dialog_settings(this->kit_, *ui->dialog, std::move(draft),
@@ -437,7 +436,7 @@ Window::bind_host()
BrowseSetup setup;
if (this->browser_)
setup = this->browser_->browse_setup();
this->app_->open(url, {}, setup);
this->app_->open(url, {}, setup, false);
};
this->host_.launch_exiftool = [this](QUrl url) { launch_exiftool(url); };
this->host_.trash = [this](QUrl url) { trash_url(url); };
@@ -681,7 +680,8 @@ Window::refresh_screen_profile(QScreen *target_screen)
label = this->app_->settings.icc_profile_override_path;
source = "configuration";
} else {
qWarning("configuration dn/ICCProfileOverride: invalid ICC profile");
qWarning(
"configuration dn/ICCProfileOverride: invalid ICC profile");
}
}
if (!next) {
@@ -697,7 +697,7 @@ Window::refresh_screen_profile(QScreen *target_screen)
}
}
if (!next)
next = this->cmm_->get_profile_sRGB();
next = this->cmm_->get_profile_sRGB(false);
this->screen_profile_fallback_ = source == "srgb";
const bool changed =
@@ -816,7 +816,7 @@ Window::viewer_file_index(const QUrl &url) const
{
if (!this->browser_ || url.isEmpty())
return -1;
for (int n = 0; n < int(this->browser_->files_.size()); ++n) {
for (int n = 0; n < int(this->browser_->files_.size()); n++) {
if (this->browser_->file_url(n) == url)
return n;
}
@@ -1121,7 +1121,7 @@ Window::event(QEvent *event)
event->ignore();
return true;
}
open_any(url);
open_any(url, false);
drop->acceptProposedAction();
return true;
}
@@ -1257,14 +1257,14 @@ Window::open_any(const QUrl &url, bool browse)
const QFileInfo info(path);
if (info.isDir()) {
if (this->browser_)
this->browser_->open_dir(url);
this->browser_->open_dir(url, true);
cancel_viewer_loads();
set_mode(Mode::Browser);
} else if (browse) {
// A file with --browse is a request to point at it, not to view it:
// browse the parent and put the cursor on the file.
if (this->browser_) {
this->browser_->open_dir(path_to_url(info.absolutePath()));
this->browser_->open_dir(path_to_url(info.absolutePath()), true);
this->browser_->select_file(url);
}
cancel_viewer_loads();
@@ -1277,7 +1277,7 @@ Window::open_any(const QUrl &url, bool browse)
const QFileInfo parent(info.absolutePath());
if (parent.exists() && parent.isDir() && parent.isReadable())
this->browser_->open_dir(
path_to_url(parent.absoluteFilePath()));
path_to_url(parent.absoluteFilePath()), true);
}
sync_viewer_preloads();
}
@@ -1553,8 +1553,8 @@ Window::wheelEvent(QWheelEvent *event)
// those should pan, while a real wheel falls through to discrete zooming.
if (event->device()->type() == QInputDevice::DeviceType::TouchPad &&
(pix.x() || pix.y())) {
if (kit_.pan(x, y, float(pix.x()) / kit_.dpr_,
float(pix.y()) / kit_.dpr_)) {
if (kit_.pan(
x, y, float(pix.x()) / kit_.dpr_, float(pix.y()) / kit_.dpr_)) {
request_render();
event->accept();
return;
@@ -1655,7 +1655,7 @@ Window::handle_touch(QTouchEvent *event)
x1 = float(p.position().x());
y1 = float(p.position().y());
}
++n;
n++;
}
if (event->type() == QEvent::TouchCancel || n < 2) {
this->touch_pinch_ = false;
+4 -5
View File
@@ -22,8 +22,8 @@
#include <libdn.h>
#include <memory>
#include <string>
#include <span>
#include <string>
class QCloseEvent;
class QExposeEvent;
@@ -142,13 +142,12 @@ protected:
void wheelEvent(QWheelEvent *event) override;
public:
explicit Window(App *app, QWindow *parent = nullptr);
explicit Window(App *app, QWindow *parent);
~Window() override;
bool initialize(
const QUrl &url, BrowseSetup setup = {}, bool browse = false);
bool initialize(const QUrl &url, BrowseSetup setup, bool browse);
void shutdown();
void open_any(const QUrl &url, bool browse = false);
void open_any(const QUrl &url, bool browse);
[[nodiscard]] QUrl current_url() const;
[[nodiscard]] HostActions &host() { return this->host_; }
[[nodiscard]] Page *active_page() { return active_ui(); }
+7 -5
View File
@@ -14,9 +14,11 @@
using namespace std;
namespace dnthumbd {
namespace dnthumbd
{
bool encode_webp_rgba8(uint32_t w, uint32_t h, const uint8_t *rgba8,
bool
encode_webp_rgba8(uint32_t w, uint32_t h, const uint8_t *rgba8,
vector<uint8_t> *out, string *error)
{
if (!out || !rgba8 || w == 0 || h == 0) {
@@ -61,7 +63,7 @@ bool encode_webp_rgba8(uint32_t w, uint32_t h, const uint8_t *rgba8,
for (uint32_t x = 0; x < w; x++) {
const uint8_t *p = src + x * 4;
dst[x] = (uint32_t(p[3]) << 24) | (uint32_t(p[0]) << 16) |
(uint32_t(p[1]) << 8) | uint32_t(p[2]);
(uint32_t(p[1]) << 8) | uint32_t(p[2]);
}
}
@@ -73,7 +75,7 @@ bool encode_webp_rgba8(uint32_t w, uint32_t h, const uint8_t *rgba8,
if (!WebPEncode(&config, &picture)) {
if (error)
*error = string("WebPEncode failed (code ") +
to_string(int(picture.error_code)) + ")";
to_string(int(picture.error_code)) + ")";
WebPPictureFree(&picture);
WebPMemoryWriterClear(&writer);
return false;
@@ -94,4 +96,4 @@ bool encode_webp_rgba8(uint32_t w, uint32_t h, const uint8_t *rgba8,
return true;
}
} // namespace dnthumbd
} // namespace dnthumbd
+3 -2
View File
@@ -11,9 +11,10 @@
#include <string>
#include <vector>
namespace dnthumbd {
namespace dnthumbd
{
bool encode_webp_rgba8(uint32_t w, uint32_t h, const uint8_t *rgba8,
std::vector<uint8_t> *out, std::string *error);
} // namespace dnthumbd
} // namespace dnthumbd
+1 -1
View File
@@ -59,7 +59,7 @@ process_one(const string &path, dawn::ScaleScaler *scaler)
ctx.uri = path;
// One Cmm per job — do not share get_default() across worker threads.
ctx.cmm = make_shared<dawn::Cmm>();
ctx.screen_profile = ctx.cmm->get_profile_sRGB();
ctx.screen_profile = ctx.cmm->get_profile_sRGB(false);
ctx.first_frame_only = true;
dawn::Error error;
+2 -1
View File
@@ -13,7 +13,8 @@
using namespace std;
namespace dnthumbd {
namespace dnthumbd
{
static bool
invert_matrix(const dawn::Matrix &m, dawn::Matrix *out)
+5 -3
View File
@@ -9,9 +9,11 @@
#include "libdn.h"
namespace dnthumbd {
namespace dnthumbd
{
/// Bake EXIF orientation into image.data (BGRA16 premul); set orientation Rotate0.
/// Bake EXIF orientation into image.data (BGRA16 premul); set orientation
/// Rotate0.
bool bake_orientation(dawn::Image &image);
} // namespace dnthumbd
} // namespace dnthumbd
+40 -20
View File
@@ -41,17 +41,27 @@ desktop_unescape(string_view value)
{
string out;
out.reserve(value.size());
for (size_t i = 0; i < value.size(); ++i) {
for (size_t i = 0; i < value.size(); i++) {
if (value[i] != '\\' || i + 1 == value.size()) {
out += value[i];
continue;
}
switch (value[++i]) {
case 'n': out += '\n'; break;
case 'r': out += '\r'; break;
case 't': out += '\t'; break;
case 's': out += ' '; break;
default: out += value[i]; break;
case 'n':
out += '\n';
break;
case 'r':
out += '\r';
break;
case 't':
out += '\t';
break;
case 's':
out += ' ';
break;
default:
out += value[i];
break;
}
}
return out;
@@ -64,11 +74,21 @@ desktop_escape(string_view value)
out.reserve(value.size());
for (const char c : value) {
switch (c) {
case '\\': out += "\\\\"; break;
case '\n': out += "\\n"; break;
case '\r': out += "\\r"; break;
case '\t': out += "\\t"; break;
default: out += c; break;
case '\\':
out += "\\\\";
break;
case '\n':
out += "\\n";
break;
case '\r':
out += "\\r";
break;
case '\t':
out += "\\t";
break;
default:
out += c;
break;
}
}
return out;
@@ -81,16 +101,15 @@ ini_parse(string_view text)
IniGroup *group = nullptr;
for (size_t offset = 0; offset <= text.size();) {
const size_t end = text.find_first_of("\r\n", offset);
string line(text.substr(offset,
end == string::npos ? string::npos : end - offset));
string line(text.substr(
offset, end == string::npos ? string::npos : end - offset));
const string stripped = trim(line);
if (stripped.empty() || stripped[0] == '#') {
if (!group)
ini.preamble.push_back(line);
} else if (stripped.size() >= 2 && stripped.front() == '[' &&
stripped.back() == ']' && stripped.find('=') == string::npos) {
ini.groups.push_back(
{stripped.substr(1, stripped.size() - 2), {}});
ini.groups.push_back({stripped.substr(1, stripped.size() - 2), {}});
group = &ini.groups.back();
} else if (group) {
const size_t equals = line.find('=');
@@ -103,8 +122,8 @@ ini_parse(string_view text)
break;
offset = end +
(text[end] == '\r' && end + 1 < text.size() && text[end + 1] == '\n'
? 2
: 1);
? 2
: 1);
}
return ini;
}
@@ -161,8 +180,8 @@ split_key(string_view key)
const size_t slash = key.rfind('/');
if (slash == string_view::npos || slash == 0 || slash + 1 == key.size())
return nullopt;
return pair<string, string>{string(key.substr(0, slash)),
string(key.substr(slash + 1))};
return pair<string, string>{
string(key.substr(0, slash)), string(key.substr(slash + 1))};
}
static fs::path
@@ -195,7 +214,8 @@ load_ini(const fs::path &path, Error *error)
fail(error, "cannot open configuration file");
return nullopt;
}
string text((istreambuf_iterator<char>(input)), istreambuf_iterator<char>());
string text(
(istreambuf_iterator<char>(input)), istreambuf_iterator<char>());
if (input.bad()) {
fail(error, "cannot read configuration file");
return nullopt;
+5 -5
View File
@@ -134,7 +134,7 @@ Decoder::take_be(uint64_t &v, size_t width)
if (remaining() < width)
return fail(DecodeError::Truncated);
uint64_t x = 0;
for (size_t i = 0; i < width; ++i)
for (size_t i = 0; i < width; i++)
x = (x << 8) | uint8_t(in_[off_ + i]);
off_ += width;
v = x;
@@ -290,7 +290,7 @@ utf8_validate(string_view s)
while (p < end) {
const uint8_t c = *p;
if (c <= 0x7F) {
++p;
p++;
continue;
}
int extra = 0;
@@ -313,12 +313,12 @@ utf8_validate(string_view s)
}
if (end - p < extra + 1)
return false;
++p;
for (int i = 0; i < extra; ++i) {
p++;
for (int i = 0; i < extra; i++) {
if ((*p & 0xC0) != 0x80)
return false;
cp = (cp << 6) | (*p & 0x3F);
++p;
p++;
}
if (cp < min_cp || cp > 0x10FFFF || (cp >= 0xD800 && cp <= 0xDFFF))
return false;
+1 -2
View File
@@ -19,8 +19,7 @@ inline thread_local OpenTiming *open_timing = nullptr;
struct OpenTimingGuard {
OpenTiming *prev;
explicit OpenTimingGuard(OpenTiming *t)
: prev(open_timing)
explicit OpenTimingGuard(OpenTiming *t) : prev(open_timing)
{
open_timing = t;
}
+13 -11
View File
@@ -515,7 +515,8 @@ ensure_working_premul(
if (owned)
image.effective_profile = owned;
else if (!source) {
image.effective_profile = cmm_or_default(ctx)->get_profile_sRGB();
image.effective_profile =
cmm_or_default(ctx)->get_profile_sRGB(false);
image.profile_assumed = true;
}
}
@@ -543,7 +544,8 @@ ensure_working_premul_pages(
if (owned)
page.effective_profile = owned;
else if (!source) {
page.effective_profile = cmm_or_default(ctx)->get_profile_sRGB();
page.effective_profile =
cmm_or_default(ctx)->get_profile_sRGB(false);
page.profile_assumed = true;
}
}
@@ -689,7 +691,7 @@ constexpr float kTransferMaxErr = 1.5f / 65535.f;
static bool
curve_matches(const cmsToneCurve *curve, Transfer transfer)
{
for (int i = 0; i < kTransferSamples; ++i) {
for (int i = 0; i < kTransferSamples; i++) {
const float x = float(i) / float(kTransferSamples - 1);
const float y = cmsEvalToneCurveFloat(curve, x);
if (fabsf(y - transfer_decode(x, transfer)) > kTransferMaxErr)
@@ -794,7 +796,7 @@ profile_chromaticities(const Profile *profile)
};
const uint8_t paper[4] = {0, 0, 0, 0};
c.have_white = xf_xy(xf, paper, &c.wx, &c.wy);
for (int i = 0; i < 6; ++i) {
for (int i = 0; i < 6; i++) {
if (!xf_xy(xf, corners[i], &c.x[i], &c.y[i])) {
cmsDeleteTransform(xf);
return c;
@@ -818,7 +820,7 @@ profile_chromaticities(const Profile *profile)
};
const uint8_t white[3] = {255, 255, 255};
c.have_white = xf_xy(xf, white, &c.wx, &c.wy);
for (int i = 0; i < 3; ++i) {
for (int i = 0; i < 3; i++) {
if (!xf_xy(xf, corners[i], &c.x[i], &c.y[i])) {
cmsDeleteTransform(xf);
return c;
@@ -930,7 +932,7 @@ Cmm::get_profile_display_p3(bool cache)
constexpr size_t samples = 4096;
vector<cmsUInt16Number> transfer(samples);
for (size_t i = 0; i < samples; ++i) {
for (size_t i = 0; i < samples; i++) {
const double encoded = double(i) / double(samples - 1);
const double linear = encoded <= 0.04045
? encoded / 12.92
@@ -1119,7 +1121,7 @@ Cmm::transform_bgra16(uint8_t *data, uint32_t width, uint32_t height,
{
shared_ptr<Profile> src_fallback;
if (target && !source) {
src_fallback = get_profile_sRGB();
src_fallback = get_profile_sRGB(false);
source = src_fallback.get();
}
if (!source || !target)
@@ -1140,7 +1142,7 @@ Cmm::transform_bgra8_to_bgra16(const uint8_t *src, uint8_t *dst, uint32_t width,
{
shared_ptr<Profile> src_fallback;
if (target && !source) {
src_fallback = get_profile_sRGB();
src_fallback = get_profile_sRGB(false);
source = src_fallback.get();
}
if (!src || !dst || !source || !target)
@@ -1216,7 +1218,7 @@ Cmm::finish_page(Image &page, Profile *target)
if (source)
page.effective_profile = source;
else {
page.effective_profile = get_profile_sRGB();
page.effective_profile = get_profile_sRGB(false);
page.profile_assumed = true;
}
}
@@ -1696,7 +1698,7 @@ constexpr Loader kLoaders[] = {
// A subset of shared-mime-info, chiefly motivated by the suckiness of raw
// photo formats: someone else will maintain the list of file extensions for us.
std::vector<std::string>
vector<string>
supported_media_types()
{
vector<string> types;
@@ -1717,7 +1719,7 @@ supported_media_types()
return types;
}
std::span<const Loader>
span<const Loader>
loaders()
{
return kLoaders;
+7 -20
View File
@@ -78,18 +78,13 @@ struct Error {
Code code = Code::Ok;
std::string message;
explicit
operator bool() const
{
return code != Code::Ok;
}
explicit operator bool() const { return code != Code::Ok; }
};
/// Read and write an opaque application configuration value.
/// A missing value is not an error and returns std::nullopt.
std::optional<std::string> config_get(std::string_view key, Error *error = nullptr);
bool config_set(
std::string_view key, std::string_view value, Error *error = nullptr);
std::optional<std::string> config_get(std::string_view key, Error *error);
bool config_set(std::string_view key, std::string_view value, Error *error);
// TODO(p): Why in Hell is this called detail, and what should it be called?
namespace detail
@@ -269,8 +264,8 @@ public:
std::shared_ptr<Profile> get_profile(const void *data, size_t len);
std::shared_ptr<Profile> get_profile(std::span<const uint8_t> bytes);
std::shared_ptr<Profile> get_profile_sRGB(bool cache = false);
std::shared_ptr<Profile> get_profile_display_p3(bool cache = false);
std::shared_ptr<Profile> get_profile_sRGB(bool cache);
std::shared_ptr<Profile> get_profile_display_p3(bool cache);
std::shared_ptr<Profile> get_profile_sRGB_gamma(double gamma);
std::shared_ptr<Profile> get_profile_parametric(
double gamma, double whitepoint[2], double primaries[6]);
@@ -306,16 +301,8 @@ public:
void finish_page(Image &page, Profile *target);
ImagePtr finish(ImagePtr image, Profile *target);
bool
broken_premul() const
{
return broken_premul_;
}
void *
context()
{
return context_;
}
bool broken_premul() const { return broken_premul_; }
void *context() { return context_; }
};
struct OpenContext {
+10 -7
View File
@@ -12,17 +12,19 @@
#include <string>
#include <vector>
namespace dawn {
namespace dawn
{
/// Soft cap on device-local bytes for one scale() (tiles + mid + dest).
/// Tweak in source; no CLI yet.
inline constexpr uint64_t kMaxDeviceBytes = 4ull << 30;
} // namespace dawn
} // namespace dawn
#include "scale-engine.hpp"
namespace dawn {
namespace dawn
{
struct ScaleOutput {
uint32_t width = 0;
@@ -32,7 +34,8 @@ struct ScaleOutput {
};
/// Headless Vulkan H→V scaler. `scale()` is internally mutex-serialized.
class ScaleScaler {
class ScaleScaler
{
struct Impl;
Impl *impl_ = nullptr;
@@ -43,14 +46,14 @@ public:
ScaleScaler(const ScaleScaler &) = delete;
ScaleScaler &operator=(const ScaleScaler &) = delete;
bool init(std::string *error = nullptr);
bool init(std::string *error);
void destroy();
/// `pixels` is BGRA_PREMUL_4X16LE; `stride` bytes per row.
/// Scales to exactly `out_w`×`out_h` with sRGB-aware filtering.
bool scale(uint32_t src_w, uint32_t src_h, const uint8_t *pixels,
size_t stride, uint32_t out_w, uint32_t out_h, ScaleOutput *out,
std::string *error = nullptr);
std::string *error);
};
} // namespace dawn
} // namespace dawn
+2 -2
View File
@@ -204,7 +204,7 @@ parse_exif_profile(Cmm &cmm, span<const uint8_t> exif)
// If sRGB is claimed, assume all parameters are standard.
if (params.colorspace == Exif_ColorSpace_sRGB)
return cmm.get_profile_sRGB();
return cmm.get_profile_sRGB(false);
// AdobeRGB Nikon JPEGs provide all of these.
if (params.colorspace != Exif_ColorSpace_Uncalibrated ||
@@ -555,7 +555,7 @@ load_jpeg_finalize(ImagePtr &image, bool cmyk, bool argb, int bits,
if (source)
image->effective_profile = source;
else if (!cmyk) {
image->effective_profile = cmm->get_profile_sRGB();
image->effective_profile = cmm->get_profile_sRGB(false);
image->profile_assumed = true;
}
+10 -10
View File
@@ -704,8 +704,8 @@ ScaleEngine::Impl::upload_tiles(const uint8_t *pixels, size_t stride,
VkMemoryRequirements mr{};
vkGetImageMemoryRequirements(device, tile_image, &mr);
uint32_t mem_type = vk_memory_type(
phys, mr.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, error);
uint32_t mem_type = vk_memory_type(phys, mr.memoryTypeBits,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, error, nullptr);
if (mem_type == UINT32_MAX)
return false;
VkMemoryAllocateInfo mai{
@@ -763,7 +763,7 @@ ScaleEngine::Impl::upload_tiles(const uint8_t *pixels, size_t stride,
mem_type = vk_memory_type(phys, smr.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
error);
error, nullptr);
if (mem_type == UINT32_MAX) {
vkDestroyBuffer(device, staging, nullptr);
return false;
@@ -983,8 +983,8 @@ ScaleEngine::Impl::ensure_mid(uint32_t vp_w, uint32_t src_h, string *error)
VkMemoryRequirements mr{};
vkGetImageMemoryRequirements(device, mid_image, &mr);
uint32_t mem_type = vk_memory_type(
phys, mr.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, error);
uint32_t mem_type = vk_memory_type(phys, mr.memoryTypeBits,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, error, nullptr);
if (mem_type == UINT32_MAX)
return false;
VkMemoryAllocateInfo mai{
@@ -1170,7 +1170,7 @@ ScaleEngine::Impl::cmd_h_pass(
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout_tiles, 0, 1, &dset_tiles, 0, nullptr);
vkCmdPushConstants(cmd, pipeline_layout_tiles, VK_SHADER_STAGE_FRAGMENT_BIT,
0, sizeof(pc), &pc);
0, sizeof pc, &pc);
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdEndRenderPass(cmd);
}
@@ -1246,7 +1246,7 @@ ScaleEngine::Impl::cmd_v_pass(VkCommandBuffer cmd, const PushConstants &pc,
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout_horiz, 0, 1, &dset_horiz, 0, nullptr);
vkCmdPushConstants(cmd, pipeline_layout_horiz, VK_SHADER_STAGE_FRAGMENT_BIT,
0, sizeof(pc), &pc);
0, sizeof pc, &pc);
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdEndRenderPass(cmd);
}
@@ -1284,7 +1284,7 @@ ScaleEngine::Impl::cmd_2d_pass(VkCommandBuffer cmd, const PushConstants &pc,
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout_tiles, 0, 1, &dset_tiles, 0, nullptr);
vkCmdPushConstants(cmd, pipeline_layout_tiles, VK_SHADER_STAGE_FRAGMENT_BIT,
0, sizeof(pc), &pc);
0, sizeof pc, &pc);
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdEndRenderPass(cmd);
}
@@ -1706,8 +1706,8 @@ ScaleEngine::create_offscreen(uint32_t w, uint32_t h, VkImage *image,
VkMemoryRequirements mr{};
vkGetImageMemoryRequirements(e.device, *image, &mr);
uint32_t mem_type = vk_memory_type(
e.phys, mr.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, error);
uint32_t mem_type = vk_memory_type(e.phys, mr.memoryTypeBits,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, error, nullptr);
if (mem_type == UINT32_MAX) {
destroy_offscreen(image, mem, view, fb);
return false;
+6 -6
View File
@@ -65,11 +65,11 @@ public:
/// readback.
bool init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
uint32_t queue_family, VkFormat dest_format,
VkImageLayout dest_final_layout, std::string *error = nullptr);
VkImageLayout dest_final_layout, std::string *error);
void destroy();
bool set_image(uint32_t w, uint32_t h, const uint8_t *pixels, size_t stride,
std::string *error = nullptr);
std::string *error);
void clear_image();
[[nodiscard]] uint32_t image_width() const;
@@ -77,21 +77,21 @@ public:
[[nodiscard]] bool has_image() const;
bool ensure_viewport(
uint32_t viewport_w, uint32_t viewport_h, std::string *error = nullptr);
uint32_t viewport_w, uint32_t viewport_h, std::string *error);
void set_dest_inset(
uint32_t left, uint32_t top, uint32_t right, uint32_t bottom);
bool record(VkCommandBuffer cmd, VkFramebuffer dest_fb, uint32_t viewport_w,
uint32_t viewport_h, const ScaleView &view, const float clear_rgba[4],
std::string *error = nullptr);
std::string *error);
/// Dest-pass CLEAR only (no H/V). For presenting the well with no pixmap.
bool record_clear(VkCommandBuffer cmd, VkFramebuffer dest_fb,
uint32_t viewport_w, uint32_t viewport_h, const float clear_rgba[4],
std::string *error = nullptr);
std::string *error);
bool create_offscreen(uint32_t w, uint32_t h, VkImage *image,
VkDeviceMemory *mem, VkImageView *view, VkFramebuffer *fb,
std::string *error = nullptr);
std::string *error);
void destroy_offscreen(VkImage *image, VkDeviceMemory *mem,
VkImageView *view, VkFramebuffer *fb);
+1 -1
View File
@@ -154,7 +154,7 @@ ScaleScaler::Impl::readback_dest(VkImage image, uint32_t out_w, uint32_t out_h,
uint32_t mem_type = vk_memory_type(phys, mr.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
error);
error, nullptr);
if (mem_type == UINT32_MAX) {
vkDestroyBuffer(device, staging, nullptr);
return false;
+15 -15
View File
@@ -91,7 +91,7 @@ pick_memory(VkPhysicalDevice phys, uint32_t bits,
vkGetPhysicalDeviceMemoryProperties(phys, &props);
MemoryType best;
int best_score = -1;
for (uint32_t i = 0; i < props.memoryTypeCount; ++i) {
for (uint32_t i = 0; i < props.memoryTypeCount; i++) {
if (!(bits & (1u << i)))
continue;
const auto flags = props.memoryTypes[i].propertyFlags;
@@ -471,7 +471,7 @@ bool
ThumbScaler::Impl::alloc_range(uint64_t bytes, Slot *slot)
{
bytes = align_up(bytes, alignment);
for (size_t i = 0; i < free_ranges.size(); ++i) {
for (size_t i = 0; i < free_ranges.size(); i++) {
Range &r = free_ranges[i];
if (r.size < bytes)
continue;
@@ -548,7 +548,7 @@ ThumbScaler::Impl::choose_k_impl(uint32_t w, uint32_t h, uint32_t *out) const
{
if (!w || !h || !out || !max_image_dim)
return false;
for (uint32_t k = 0; k < 32; ++k) {
for (uint32_t k = 0; k < 32; k++) {
const uint32_t rw = reduced_dim(w, k), rh = reduced_dim(h, k);
const uint64_t bytes = uint64_t(rw) * rh * kBytesPerPixel;
if (rw <= max_image_dim && rh <= max_image_dim &&
@@ -645,7 +645,7 @@ ThumbScaler::Impl::descriptor(Batch &b, const Buffer &in, VkDeviceSize in_off,
VkDescriptorBufferInfo info[2] = {
{in.handle, in_off, in_size}, {out.handle, out_off, out_size}};
VkWriteDescriptorSet writes[2]{};
for (uint32_t i = 0; i < 2; ++i) {
for (uint32_t i = 0; i < 2; i++) {
writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[i].dstSet = set;
writes[i].dstBinding = i;
@@ -690,7 +690,7 @@ ThumbScaler::Impl::record_reduce(
const Buffer *input = &b.source;
VkDeviceSize input_off = item.source_off;
bool linear = false;
for (uint32_t level = 0; level < s.info.k; ++level) {
for (uint32_t level = 0; level < s.info.k; level++) {
const uint32_t dw = ceil_div(sw, 2), dh = ceil_div(sh, 2);
const bool last = level + 1 == s.info.k;
Buffer *output = last ? &s.reduced : ((level & 1u) ? &b.pong : &b.ping);
@@ -706,7 +706,7 @@ ThumbScaler::Impl::record_reduce(
last ? item.req.tile_ox >> s.info.k : 0,
last ? item.req.tile_oy >> s.info.k : 0, uint32_t(s.info.transfer),
s.info.opaque ? 1u : 0u, linear ? 1u : 0u};
dispatch(b.cmd, reduce, set, &push, sizeof(push), dw, dh);
dispatch(b.cmd, reduce, set, &push, sizeof push, dw, dh);
barrier(b.cmd, VK_ACCESS_SHADER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
@@ -749,7 +749,7 @@ ThumbScaler::Impl::record_h(Batch &b, Item &item, string *error)
uint32_t(orientation_or_0(item.req.orientation)),
uint32_t(item.req.transfer), item.req.opaque ? 1u : 0u,
linear ? 1u : 0u};
dispatch(b.cmd, scale_h, set, &push, sizeof(push), item.req.out_w,
dispatch(b.cmd, scale_h, set, &push, sizeof push, item.req.out_w,
item.display_h);
return true;
}
@@ -770,7 +770,7 @@ ThumbScaler::Impl::record_v(Batch &b, Item &item, string *error)
item.req.out_h, item.req.out_w, item.req.out_w,
uint32_t(orientation_or_0(item.req.orientation)),
uint32_t(item.req.transfer), item.req.opaque ? 1u : 0u, 0};
dispatch(b.cmd, scale_v, set, &push, sizeof(push), item.req.out_w,
dispatch(b.cmd, scale_v, set, &push, sizeof push, item.req.out_w,
item.req.out_h);
return true;
}
@@ -1070,7 +1070,7 @@ ThumbScaler::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
e.destroy_all();
return false;
}
for (uint32_t i = 0; i < kBatchSlots; ++i) {
for (uint32_t i = 0; i < kBatchSlots; i++) {
e.batches[i].cmd = commands[i];
VkFenceCreateInfo fi{.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
if (!check_vk(vkCreateFence(device, &fi, nullptr, &e.batches[i].fence),
@@ -1081,7 +1081,7 @@ ThumbScaler::init(VkPhysicalDevice phys, VkDevice device, VkQueue queue,
}
}
VkDescriptorSetLayoutBinding bindings[2]{};
for (uint32_t i = 0; i < 2; ++i) {
for (uint32_t i = 0; i < 2; i++) {
bindings[i].binding = i;
bindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
bindings[i].descriptorCount = 1;
@@ -1261,12 +1261,12 @@ ThumbScaler::Impl::queue_full(const Job &job)
bool opaque = true;
auto *dst = static_cast<uint8_t *>(slot.mapped);
const auto *src = reinterpret_cast<const uint8_t *>(job.pixels->data());
for (uint32_t y = 0; y < job.src_h; ++y) {
for (uint32_t y = 0; y < job.src_h; y++) {
const auto *row =
reinterpret_cast<const uint16_t *>(src + y * job.stride);
memcpy(dst, row, size_t(row_bytes));
if (opaque) {
for (uint32_t x = 0; x < job.src_w; ++x) {
for (uint32_t x = 0; x < job.src_w; x++) {
if (row[x * 4 + 3] != 65535) {
opaque = false;
break;
@@ -1341,7 +1341,7 @@ ThumbScaler::queue(const Job &job)
if (!e.claim(tile_row * tile.h, job.user, job.priority, &slot))
break;
auto *dst = static_cast<uint8_t *>(slot.mapped);
for (uint32_t y = 0; y < tile.h; ++y) {
for (uint32_t y = 0; y < tile.h; y++) {
const uint8_t *src = base + size_t(tile.oy + y) * job.stride +
size_t(tile.ox) * kBytesPerPixel;
memcpy(dst, src, tile_row);
@@ -1412,7 +1412,7 @@ ThumbScaler::cancel(uint64_t user)
e.canceled.insert(user);
for (auto it = e.pending.begin(); it != e.pending.end();) {
if (it->req.user != user) {
++it;
it++;
continue;
}
found = true;
@@ -1474,7 +1474,7 @@ ThumbScaler::flush()
it = e.pending.erase(it);
item_room -= cost;
} else {
++it;
it++;
}
}
for (auto &entry : e.sessions) {
+1 -1
View File
@@ -74,7 +74,7 @@ vk_memory_type(VkPhysicalDevice phys, uint32_t bits,
VkPhysicalDeviceMemoryProperties properties{};
vkGetPhysicalDeviceMemoryProperties(phys, &properties);
uint32_t best = UINT32_MAX;
for (uint32_t i = 0; i < properties.memoryTypeCount; ++i) {
for (uint32_t i = 0; i < properties.memoryTypeCount; i++) {
if (!(bits & (1u << i)) ||
(properties.memoryTypes[i].propertyFlags & flags) != flags)
continue;
+1 -2
View File
@@ -26,8 +26,7 @@ namespace dawn
void vk_add_bundled_driver_files();
uint32_t vk_memory_type(VkPhysicalDevice phys, uint32_t bits,
VkMemoryPropertyFlags flags, std::string *error = nullptr,
VkDeviceSize *heap_size = nullptr);
VkMemoryPropertyFlags flags, std::string *error, VkDeviceSize *heap_size);
bool vk_create_graphics_device(VkInstance instance, VkSurfaceKHR surface,
std::function<bool(VkPhysicalDevice, uint32_t)> present,
+7 -10
View File
@@ -33,8 +33,7 @@ usage(const char *argv0)
static void
fit_size(uint32_t w, uint32_t h, uint32_t *out_w, uint32_t *out_h)
{
const float scale =
min(1.0f, min(512.0f / float(w), 256.0f / float(h)));
const float scale = min(1.0f, min(512.0f / float(w), 256.0f / float(h)));
*out_w = max(1u, uint32_t(float(w) * scale + 0.5f));
*out_h = max(1u, uint32_t(float(h) * scale + 0.5f));
}
@@ -48,7 +47,7 @@ bench_one(const char *path, bool cms, int repeats, dawn::ScaleScaler *scaler)
ctx.first_frame_only = true;
ctx.uri = path;
if (cms) {
auto srgb = cmm->get_profile_sRGB();
auto srgb = cmm->get_profile_sRGB(false);
if (!srgb) {
fprintf(stderr, "%s: get_profile_sRGB failed\n", path);
return 1;
@@ -70,15 +69,13 @@ bench_one(const char *path, bool cms, int repeats, dawn::ScaleScaler *scaler)
rc = 1;
continue;
}
const double open_ms =
chrono::duration<double, milli>(t1 - t0).count();
const double open_ms = chrono::duration<double, milli>(t1 - t0).count();
const double rest_ms = open_ms - st.file_ms - st.decode_ms -
st.alloc_ms - st.cms_ms - st.widen_ms;
if (repeats > 1)
printf("%d ", i + 1);
printf(
"file %.1f decode %.1f alloc %.1f cms %.1f widen %.1f "
"rest %.1f open %.1f %ux%u %s",
printf("file %.1f decode %.1f alloc %.1f cms %.1f widen %.1f "
"rest %.1f open %.1f %ux%u %s",
st.file_ms, st.decode_ms, st.alloc_ms, st.cms_ms, st.widen_ms,
rest_ms, open_ms, img->width, img->height, path);
if (scaler) {
@@ -97,8 +94,8 @@ bench_one(const char *path, bool cms, int repeats, dawn::ScaleScaler *scaler)
rc = 1;
continue;
}
printf(" scale %.1f %ux%u\n", scale_ms, scaled.width,
scaled.height);
printf(
" scale %.1f %ux%u\n", scale_ms, scaled.width, scaled.height);
} else {
printf("\n");
}
+4 -4
View File
@@ -114,7 +114,7 @@ create_display_p3_profile()
{
constexpr size_t samples = 4096;
vector<cmsUInt16Number> transfer(samples);
for (size_t i = 0; i < samples; ++i) {
for (size_t i = 0; i < samples; i++) {
const double encoded = double(i) / double(samples - 1);
const double linear = encoded <= 0.04045
? encoded / 12.92
@@ -179,9 +179,9 @@ write_display_p3_vs_srgb_red(const fs::path &path)
vector<uint8_t> raw;
raw.reserve(100 * (1 + 200 * 3));
for (int y = 0; y < 100; ++y) {
for (int y = 0; y < 100; y++) {
raw.push_back(0);
for (int x = 0; x < 200; ++x) {
for (int x = 0; x < 200; x++) {
const uint8_t *color = x < 100 ? p3_red : srgb_red_in_p3;
raw.insert(raw.end(), color, color + 3);
}
@@ -386,7 +386,7 @@ write_cmyk_lab_icc(const fs::path &path)
cmsWriteTag(h, cmsSigMediaWhitePointTag, &d50);
cmsUInt16Number tab[16 * 3];
for (int i = 0; i < 16; ++i) {
for (int i = 0; i < 16; i++) {
tab[i * 3 + 0] = 0xFFFF;
tab[i * 3 + 1] = 0x8080;
tab[i * 3 + 2] = 0x8080;
+1 -1
View File
@@ -32,7 +32,7 @@ class Application
}
public:
Application(int &argc, char **argv, const char *name = nullptr)
Application(int &argc, char **argv, const char *name)
: app_(prepare(argc, cache_, inputs_), argv)
{
if (name)
+7 -7
View File
@@ -117,7 +117,7 @@ test_pack_helpers()
{
// Host-endian 0xAARRGGBB: opaque red
const uint32_t word = 0xFFFF0000u;
dawn::pack_argb32_words_to_bgra16(*img, &word, sizeof(word));
dawn::pack_argb32_words_to_bgra16(*img, &word, sizeof word);
expect_bgra("pack_argb32 red", pixel0(*img), 0, 0, 65535, 65535, 0);
}
@@ -194,7 +194,7 @@ static void
test_jpeg_cms_8_to_16()
{
auto cmm = dawn::Cmm::get_default();
auto srgb = cmm->get_profile_sRGB();
auto srgb = cmm->get_profile_sRGB(false);
CHECK(srgb != nullptr);
const uint8_t src[4] = {0, 0, 255, 255};
@@ -254,7 +254,7 @@ static void
test_cmyk_cms_opaque()
{
auto cmm = dawn::Cmm::get_default();
auto srgb = cmm->get_profile_sRGB();
auto srgb = cmm->get_profile_sRGB(false);
CHECK(srgb != nullptr);
const fs::path icc = fs::path(DAWN_TEST_FIXTURES_DIR) / "cmyk-lab.icc";
@@ -281,7 +281,7 @@ static void
test_cms_tiled()
{
auto cmm = dawn::Cmm::get_default();
auto srgb = cmm->get_profile_sRGB();
auto srgb = cmm->get_profile_sRGB(false);
CHECK(srgb != nullptr);
// Above the serial threshold so row bands run on more than one worker.
@@ -451,7 +451,7 @@ test_chromaticities()
dawn::ColorModel::Unknown);
auto cmm = dawn::Cmm::get_default();
auto srgb = cmm->get_profile_sRGB();
auto srgb = cmm->get_profile_sRGB(false);
CHECK(srgb != nullptr);
dawn::Chromaticities s = dawn::profile_chromaticities(srgb.get());
CHECK(s.model == dawn::ColorModel::Rgb);
@@ -463,7 +463,7 @@ test_chromaticities()
CHECK(s.have_white);
near_xy("sRGB W", s.wx, s.wy, 0.3127, 0.3290, 0.002);
auto display_p3 = cmm->get_profile_display_p3();
auto display_p3 = cmm->get_profile_display_p3(false);
CHECK(display_p3 != nullptr);
CHECK(dawn::profile_transfer(display_p3.get()) == dawn::Transfer::Srgb);
dawn::Chromaticities d = dawn::profile_chromaticities(display_p3.get());
@@ -547,7 +547,7 @@ test_profile_transfer()
CHECK(dawn::profile_transfer(nullptr) == dawn::Transfer::Srgb);
auto cmm = dawn::Cmm::get_default();
auto srgb = cmm->get_profile_sRGB();
auto srgb = cmm->get_profile_sRGB(false);
CHECK(srgb != nullptr);
CHECK(dawn::profile_transfer(srgb.get()) == dawn::Transfer::Srgb);
+18 -18
View File
@@ -90,7 +90,7 @@ payload_eq(const vector<byte> &got, span<const uint8_t> want)
{
if (got.size() != want.size())
return false;
for (size_t i = 0; i < got.size(); ++i) {
for (size_t i = 0; i < got.size(); i++) {
if (uint8_t(got[i]) != want[i])
return false;
}
@@ -109,14 +109,14 @@ test_fragmented()
CHECK(conn.ok());
static constexpr uint8_t kPayload[] = {1, 2, 3, 4, 5};
uint8_t wire[4 + sizeof(kPayload)];
put_u32be(wire, uint32_t(sizeof(kPayload)));
memcpy(wire + 4, kPayload, sizeof(kPayload));
uint8_t wire[4 + sizeof kPayload];
put_u32be(wire, uint32_t(sizeof kPayload));
memcpy(wire + 4, kPayload, sizeof kPayload);
for (size_t i = 0; i < sizeof(wire); ++i) {
for (size_t i = 0; i < sizeof wire; i++) {
CHECK(write_all(peer, &wire[i], 1));
const auto st = conn.read();
if (i + 1 < sizeof(wire))
if (i + 1 < sizeof wire)
CHECK(st == dawn::ipc::Connection::Status::NeedMore);
else
CHECK(st == dawn::ipc::Connection::Status::Frame);
@@ -144,7 +144,7 @@ test_two_frames_one_write()
memcpy(wire + 4, kA, 5);
put_u32be(wire + 9, 5);
memcpy(wire + 13, kB, 5);
CHECK(write_all(peer, wire, sizeof(wire)));
CHECK(write_all(peer, wire, sizeof wire));
CHECK(conn.read() == dawn::ipc::Connection::Status::Frame);
vector<byte> first;
@@ -169,7 +169,7 @@ test_empty_payload()
uint8_t len[4];
put_u32be(len, 0);
CHECK(write_all(peer, len, sizeof(len)));
CHECK(write_all(peer, len, sizeof len));
CHECK(conn.read() == dawn::ipc::Connection::Status::Error);
}
@@ -185,7 +185,7 @@ test_oversize_length()
uint8_t len[4];
put_u32be(len, dawn::ipc::Connection::kMaxPayload + 1);
CHECK(write_all(peer, len, sizeof(len)));
CHECK(write_all(peer, len, sizeof len));
CHECK(conn.read() == dawn::ipc::Connection::Status::Error);
}
@@ -247,7 +247,7 @@ test_endpoint_roundtrip()
// The connect completion may not have been posted yet; an event loop
// would be woken by the listener instead of spinning like this.
dawn::ipc::Connection server;
for (int i = 0; i < 100 && !server.ok(); ++i)
for (int i = 0; i < 100 && !server.ok(); i++)
server = listen.listener.accept();
CHECK(server.ok());
if (!server.ok())
@@ -377,7 +377,7 @@ Fixture::start()
this->conn_id = id;
};
cfg.on_request = [this](inst::Call call, const inst::RequestView &req) {
++this->requests;
this->requests++;
if (this->handler)
this->handler(std::move(call), req);
else
@@ -392,7 +392,7 @@ Fixture::start()
return false;
this->peer = std::move(connect.conn);
for (int i = 0; i < 100 && !this->conn_id; ++i)
for (int i = 0; i < 100 && !this->conn_id; i++)
this->poll();
CHECK(this->conn_id != 0);
return this->conn_id != 0;
@@ -408,7 +408,7 @@ Fixture::send(const inst::Frame &frame)
bool
Fixture::recv(inst::FrameView &view, vector<byte> &storage)
{
for (int i = 0; i < 200; ++i) {
for (int i = 0; i < 200; i++) {
this->poll();
const auto st = this->peer.read();
if (st == dawn::ipc::Connection::Status::Frame) {
@@ -428,7 +428,7 @@ Fixture::recv(inst::FrameView &view, vector<byte> &storage)
bool
Fixture::closed()
{
for (int i = 0; i < 200; ++i) {
for (int i = 0; i < 200; i++) {
this->poll();
const auto st = this->peer.read();
if (st == dawn::ipc::Connection::Status::Eof ||
@@ -613,7 +613,7 @@ test_instance_out_of_order()
CHECK(handshake(f, limit));
CHECK(f.send(open_frame(11)));
CHECK(f.send(open_frame(12)));
for (int i = 0; i < 100 && f.requests < 2; ++i)
for (int i = 0; i < 100 && f.requests < 2; i++)
f.poll();
CHECK(f.requests == 2);
CHECK(held.size() == 2);
@@ -663,14 +663,14 @@ test_instance_cancel()
vector<inst::Call> held;
int cancels = 0;
f.handler = [&held, &cancels](inst::Call call, const inst::RequestView &) {
call.on_cancel([&cancels] { ++cancels; });
call.on_cancel([&cancels] { cancels++; });
held.push_back(std::move(call));
};
uint32_t limit = 0;
CHECK(handshake(f, limit));
CHECK(f.send(open_frame(3)));
for (int i = 0; i < 100 && f.requests < 1; ++i)
for (int i = 0; i < 100 && f.requests < 1; i++)
f.poll();
CHECK(held.size() == 1);
if (held.size() != 1)
@@ -678,7 +678,7 @@ test_instance_cancel()
CHECK(!held[0].cancelled());
CHECK(f.send(cancel_frame(3)));
for (int i = 0; i < 100 && cancels == 0; ++i)
for (int i = 0; i < 100 && cancels == 0; i++)
f.poll();
CHECK(cancels == 1);
CHECK(held[0].cancelled());
+3 -3
View File
@@ -38,7 +38,7 @@ bytes_eq(span<const byte> got, span<const uint8_t> want)
{
if (got.size() != want.size())
return false;
for (size_t i = 0; i < got.size(); ++i) {
for (size_t i = 0; i < got.size(); i++) {
if (uint8_t(got[i]) != want[i])
return false;
}
@@ -53,7 +53,7 @@ check_golden(
return;
test::fail(
"golden %s: got %zu bytes, want %zu", label, got.size(), want.size());
for (size_t i = 0; i < got.size(); ++i)
for (size_t i = 0; i < got.size(); i++)
fprintf(stderr, " %02x", uint8_t(got[i]));
fprintf(stderr, "\n");
}
@@ -287,7 +287,7 @@ test_truncation()
{
const vector<byte> full = encoded(inst::Hello{1, "b"});
CHECK(!full.empty());
for (size_t n = 0; n < full.size(); ++n) {
for (size_t n = 0; n < full.size(); n++) {
dawn::ipc::Decoder dec(span<const byte>(full.data(), n));
inst::HelloView view{};
const bool ok = decode(dec, view);
+1 -1
View File
@@ -112,7 +112,7 @@ test_cache_entries(const QTemporaryDir &inputs)
fprintf(stderr, "%s\n", qUtf8Printable(error));
auto cmm = make_shared<dawn::Cmm>();
auto p3 = cmm->get_profile_display_p3();
auto p3 = cmm->get_profile_display_p3(false);
dn::ThumbnailHit hit = dn::thumbnail_cache_lookup(source, 0, cmm, p3.get());
CHECK(!hit.pixels.empty());
CHECK(hit.width == 2 && hit.height == 1);
+44 -36
View File
@@ -19,7 +19,7 @@
#include <vector>
using namespace std;
using namespace std::chrono_literals;
using namespace chrono_literals;
namespace
{
@@ -56,7 +56,7 @@ test_background_reserve()
thumbnailer.background_limit());
return false;
}
const auto client = thumbnailer.add_client();
const auto client = thumbnailer.add_client(0, {});
WorkGate gate;
int background_started = 0;
bool visible_started = false;
@@ -67,9 +67,9 @@ test_background_reserve()
gate.changed.wait(lock, [&] { return gate.released; });
return dn::Thumbnailer::Completion{};
};
for (int i = 0; i < 2; ++i) {
if (!thumbnailer.submit(
client, 0, dn::Thumbnailer::Priority::Dimensions, background)) {
for (int i = 0; i < 2; i++) {
if (!thumbnailer.submit(client, 0,
dn::Thumbnailer::Priority::Dimensions, background, {})) {
gate.unblock();
return false;
}
@@ -81,12 +81,14 @@ test_background_reserve()
return false;
}
}
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible, [&] {
lock_guard lock(gate.mu);
visible_started = true;
gate.changed.notify_all();
return dn::Thumbnailer::Completion{};
}))
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible,
[&] {
lock_guard lock(gate.mu);
visible_started = true;
gate.changed.notify_all();
return dn::Thumbnailer::Completion{};
},
{}))
return false;
{
unique_lock lock(gate.mu);
@@ -108,7 +110,7 @@ static bool
test_visible_reserve()
{
dn::Thumbnailer thumbnailer(nullptr, 4);
const auto client = thumbnailer.add_client();
const auto client = thumbnailer.add_client(0, {});
WorkGate gate;
int prefetch_started = 0;
bool visible_started = false;
@@ -119,9 +121,9 @@ test_visible_reserve()
gate.changed.wait(lock, [&] { return gate.released; });
return dn::Thumbnailer::Completion{};
};
for (int i = 0; i < 4; ++i) {
for (int i = 0; i < 4; i++) {
if (!thumbnailer.submit(
client, 0, dn::Thumbnailer::Priority::Prefetch, prefetch)) {
client, 0, dn::Thumbnailer::Priority::Prefetch, prefetch, {})) {
gate.unblock();
return false;
}
@@ -133,12 +135,14 @@ test_visible_reserve()
return false;
}
}
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible, [&] {
lock_guard lock(gate.mu);
visible_started = true;
gate.changed.notify_all();
return dn::Thumbnailer::Completion{};
})) {
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible,
[&] {
lock_guard lock(gate.mu);
visible_started = true;
gate.changed.notify_all();
return dn::Thumbnailer::Completion{};
},
{})) {
gate.unblock();
return false;
}
@@ -159,17 +163,19 @@ static bool
test_reprioritization_order()
{
dn::Thumbnailer thumbnailer(nullptr, 1);
const auto client = thumbnailer.add_client();
const auto client = thumbnailer.add_client(0, {});
WorkGate gate;
bool blocker_started = false;
vector<int> order;
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible, [&] {
unique_lock lock(gate.mu);
blocker_started = true;
gate.changed.notify_all();
gate.changed.wait(lock, [&] { return gate.released; });
return dn::Thumbnailer::Completion{};
}))
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible,
[&] {
unique_lock lock(gate.mu);
blocker_started = true;
gate.changed.notify_all();
gate.changed.wait(lock, [&] { return gate.released; });
return dn::Thumbnailer::Completion{};
},
{}))
return false;
{
unique_lock lock(gate.mu);
@@ -218,7 +224,7 @@ static bool
test_bundle_reservations()
{
dn::Thumbnailer thumbnailer(nullptr, 2);
const auto client = thumbnailer.add_client(7);
const auto client = thumbnailer.add_client(7, {});
dn::ThumbnailSource a;
a.uri = QByteArrayLiteral("file:///a");
a.mtime = 1;
@@ -251,7 +257,7 @@ test_bundle_reservations()
static void
test_activity_transitions(QCoreApplication &app)
{
dn::Thumbnailer thumbnailer;
dn::Thumbnailer thumbnailer(nullptr, 0);
WorkGate gate;
bool saw_busy = false;
bool saw_idle = false;
@@ -265,11 +271,13 @@ test_activity_transitions(QCoreApplication &app)
app.quit();
}
});
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible, [&] {
unique_lock lock(gate.mu);
gate.changed.wait(lock, [&] { return gate.released; });
return dn::Thumbnailer::Completion{};
})) {
if (!thumbnailer.submit(client, 0, dn::Thumbnailer::Priority::Visible,
[&] {
unique_lock lock(gate.mu);
gate.changed.wait(lock, [&] { return gate.released; });
return dn::Thumbnailer::Completion{};
},
{})) {
test::fail("could not submit thumbnail work");
return;
}
@@ -287,7 +295,7 @@ test_activity_transitions(QCoreApplication &app)
int
main(int argc, char **argv)
{
test::Application application(argc, argv);
test::Application application(argc, argv, nullptr);
return test::run({
{"background worker reserve", [] { CHECK(test_background_reserve()); }},
{"visible worker reserve", [] { CHECK(test_visible_reserve()); }},
+1 -1
View File
@@ -27,7 +27,7 @@ fail(const char *format, ...)
vfprintf(stderr, format, args);
va_end(args);
fputc('\n', stderr);
++failures;
failures++;
}
inline void