Improve my own performance hack
This commit is contained in:
+9
-5
@@ -319,7 +319,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(false);
|
||||
return cmm.get_profile_sRGB();
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -590,7 +590,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(false);
|
||||
shared_ptr<dawn::Profile> p3 = cmm->get_profile_display_p3();
|
||||
if (p3 && screen && !result.ram.empty() &&
|
||||
cmm->transform_bgra16(
|
||||
reinterpret_cast<uint8_t *>(result.ram.data()),
|
||||
@@ -639,8 +639,7 @@ 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(false) : screen;
|
||||
ctx.screen_profile = job.cacheable ? cmm->get_profile_display_p3() : screen;
|
||||
ctx.first_frame_only = true;
|
||||
ctx.screen_dpi = 96;
|
||||
|
||||
@@ -699,6 +698,11 @@ static shared_ptr<dawn::Cmm>
|
||||
worker_cmm()
|
||||
{
|
||||
thread_local auto cmm = make_shared<dawn::Cmm>();
|
||||
|
||||
// Cmm memoizes these only for as long as somebody holds one, and
|
||||
// every cache read and every display transform asks for them again.
|
||||
thread_local auto srgb = cmm->get_profile_sRGB();
|
||||
thread_local auto display_p3 = cmm->get_profile_display_p3();
|
||||
return cmm;
|
||||
}
|
||||
|
||||
@@ -728,7 +732,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(false);
|
||||
shared_ptr<dawn::Profile> p3 = cmm->get_profile_display_p3();
|
||||
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() &&
|
||||
|
||||
+2
-2
@@ -376,7 +376,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(false);
|
||||
return cmm.get_profile_sRGB();
|
||||
}
|
||||
|
||||
static bool apply_action(Viewer &v, Action action);
|
||||
@@ -797,7 +797,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(false);
|
||||
srgb = cmm->get_profile_sRGB();
|
||||
img = profile_chromaticities(srgb.get());
|
||||
image_dashed = true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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(false);
|
||||
auto srgb = cmm->get_profile_sRGB();
|
||||
if (!srgb)
|
||||
return colour;
|
||||
if (!cmm->transform_bgra16(
|
||||
|
||||
@@ -194,7 +194,7 @@ read_wide(const QString &path, const ThumbnailSource &source, int tier,
|
||||
const string *tag = value(meta, kColorSpace);
|
||||
const bool p3 = tag && *tag == "Display P3";
|
||||
shared_ptr<dawn::Profile> src =
|
||||
p3 ? cmm->get_profile_display_p3(true) : cmm->get_profile_sRGB(true);
|
||||
p3 ? cmm->get_profile_display_p3() : cmm->get_profile_sRGB();
|
||||
dawn::ImagePtr image = decode_webp(bytes, *cmm, src.get(), screen);
|
||||
if (!image)
|
||||
return hit;
|
||||
@@ -237,7 +237,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(false);
|
||||
shared_ptr<dawn::Profile> srgb = cmm->get_profile_sRGB();
|
||||
if (!cmm->transform_bgra16(image->data.data(), image->width, image->height,
|
||||
srgb.get(), screen, true, true))
|
||||
return {};
|
||||
|
||||
+1
-1
@@ -697,7 +697,7 @@ Window::refresh_screen_profile(QScreen *target_screen)
|
||||
}
|
||||
}
|
||||
if (!next)
|
||||
next = this->cmm_->get_profile_sRGB(false);
|
||||
next = this->cmm_->get_profile_sRGB();
|
||||
this->screen_profile_fallback_ = source == "srgb";
|
||||
|
||||
const bool changed =
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ decode_job(const Job &job)
|
||||
context.cmm = cmm;
|
||||
context.first_frame_only = job.first_frame_only;
|
||||
context.screen_profile = job.target_icc.empty()
|
||||
? cmm->get_profile_sRGB(false)
|
||||
? cmm->get_profile_sRGB()
|
||||
: cmm->get_profile(span<const uint8_t>(
|
||||
reinterpret_cast<const uint8_t *>(job.target_icc.data()),
|
||||
job.target_icc.size()));
|
||||
|
||||
+25
-18
@@ -515,8 +515,7 @@ ensure_working_premul(
|
||||
if (owned)
|
||||
image.effective_profile = owned;
|
||||
else if (!source) {
|
||||
image.effective_profile =
|
||||
cmm_or_default(ctx)->get_profile_sRGB(false);
|
||||
image.effective_profile = cmm_or_default(ctx)->get_profile_sRGB();
|
||||
image.profile_assumed = true;
|
||||
}
|
||||
}
|
||||
@@ -544,8 +543,7 @@ ensure_working_premul_pages(
|
||||
if (owned)
|
||||
page.effective_profile = owned;
|
||||
else if (!source) {
|
||||
page.effective_profile =
|
||||
cmm_or_default(ctx)->get_profile_sRGB(false);
|
||||
page.effective_profile = cmm_or_default(ctx)->get_profile_sRGB();
|
||||
page.profile_assumed = true;
|
||||
}
|
||||
}
|
||||
@@ -649,7 +647,18 @@ profiles_equal(const Profile *a, const Profile *b)
|
||||
return true;
|
||||
if (!a || !b)
|
||||
return false;
|
||||
return a->to_bytes() == b->to_bytes();
|
||||
|
||||
// ICC.1 lays the header out identically in every version: 128 bytes,
|
||||
// with the creation dateTimeNumber at 24. It says when the profile
|
||||
// was made, never what it does.
|
||||
constexpr size_t header = 128, created = 24, created_size = 12;
|
||||
vector<uint8_t> x = a->to_bytes(), y = b->to_bytes();
|
||||
if (x.size() != y.size() || x.size() < header)
|
||||
return x == y;
|
||||
|
||||
memset(x.data() + created, 0, created_size);
|
||||
memset(y.data() + created, 0, created_size);
|
||||
return x == y;
|
||||
}
|
||||
|
||||
float
|
||||
@@ -907,28 +916,27 @@ Cmm::get_profile(span<const uint8_t> bytes)
|
||||
}
|
||||
|
||||
shared_ptr<Profile>
|
||||
Cmm::get_profile_sRGB(bool cache)
|
||||
Cmm::get_profile_sRGB()
|
||||
{
|
||||
// We may use these a lot, no need to recreate each time.
|
||||
if (this->cached_sRGB)
|
||||
return this->cached_sRGB;
|
||||
if (auto cached = this->cached_sRGB.lock())
|
||||
return cached;
|
||||
|
||||
cmsHPROFILE p = cmsCreate_sRGBProfileTHR(cmsContext(context_));
|
||||
if (!p)
|
||||
return nullptr;
|
||||
|
||||
shared_ptr<Profile> result(new Profile(shared_from_this(), p));
|
||||
if (cache)
|
||||
this->cached_sRGB = result;
|
||||
this->cached_sRGB = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
shared_ptr<Profile>
|
||||
Cmm::get_profile_display_p3(bool cache)
|
||||
Cmm::get_profile_display_p3()
|
||||
{
|
||||
// We may use these a lot, no need to recreate each time.
|
||||
if (this->cached_display_p3)
|
||||
return this->cached_display_p3;
|
||||
if (auto cached = this->cached_display_p3.lock())
|
||||
return cached;
|
||||
|
||||
constexpr size_t samples = 4096;
|
||||
vector<cmsUInt16Number> transfer(samples);
|
||||
@@ -958,8 +966,7 @@ Cmm::get_profile_display_p3(bool cache)
|
||||
cmsSetProfileVersion(p, 4.3);
|
||||
|
||||
shared_ptr<Profile> result(new Profile(shared_from_this(), p));
|
||||
if (cache)
|
||||
this->cached_display_p3 = result;
|
||||
this->cached_display_p3 = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1121,7 +1128,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(false);
|
||||
src_fallback = get_profile_sRGB();
|
||||
source = src_fallback.get();
|
||||
}
|
||||
if (!source || !target)
|
||||
@@ -1142,7 +1149,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(false);
|
||||
src_fallback = get_profile_sRGB();
|
||||
source = src_fallback.get();
|
||||
}
|
||||
if (!src || !dst || !source || !target)
|
||||
@@ -1218,7 +1225,7 @@ Cmm::finish_page(Image &page, Profile *target)
|
||||
if (source)
|
||||
page.effective_profile = source;
|
||||
else {
|
||||
page.effective_profile = get_profile_sRGB(false);
|
||||
page.effective_profile = get_profile_sRGB();
|
||||
page.profile_assumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -254,6 +254,7 @@ public:
|
||||
};
|
||||
|
||||
/// Serialized ICC equality. Null equals null; lcms has no compare API.
|
||||
/// The header's creation date/time is excluded.
|
||||
bool profiles_equal(const Profile *a, const Profile *b);
|
||||
|
||||
class Cmm : public std::enable_shared_from_this<Cmm>
|
||||
@@ -262,8 +263,10 @@ class Cmm : public std::enable_shared_from_this<Cmm>
|
||||
void *context_ = nullptr; ///< cmsContext
|
||||
bool broken_premul_ = false;
|
||||
|
||||
std::shared_ptr<Profile> cached_sRGB;
|
||||
std::shared_ptr<Profile> cached_display_p3;
|
||||
// Weak, because a Profile owns its Cmm: we don't want a cycle.
|
||||
// Deduplicating profiles for as long as somebody else wants them.
|
||||
std::weak_ptr<Profile> cached_sRGB;
|
||||
std::weak_ptr<Profile> cached_display_p3;
|
||||
|
||||
public:
|
||||
Cmm();
|
||||
@@ -275,8 +278,8 @@ public:
|
||||
|
||||
std::shared_ptr<Profile> get_profile_data(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);
|
||||
std::shared_ptr<Profile> get_profile_display_p3(bool cache);
|
||||
std::shared_ptr<Profile> get_profile_sRGB();
|
||||
std::shared_ptr<Profile> get_profile_display_p3();
|
||||
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]);
|
||||
|
||||
+2
-2
@@ -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(false);
|
||||
return cmm.get_profile_sRGB();
|
||||
|
||||
// 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(false);
|
||||
image->effective_profile = cmm->get_profile_sRGB();
|
||||
image->profile_assumed = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,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(false);
|
||||
auto srgb = cmm->get_profile_sRGB();
|
||||
if (!srgb) {
|
||||
fprintf(stderr, "%s: get_profile_sRGB failed\n", path);
|
||||
return 1;
|
||||
|
||||
@@ -194,7 +194,7 @@ static void
|
||||
test_jpeg_cms_8_to_16()
|
||||
{
|
||||
auto cmm = dawn::Cmm::get_default();
|
||||
auto srgb = cmm->get_profile_sRGB(false);
|
||||
auto srgb = cmm->get_profile_sRGB();
|
||||
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(false);
|
||||
auto srgb = cmm->get_profile_sRGB();
|
||||
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(false);
|
||||
auto srgb = cmm->get_profile_sRGB();
|
||||
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(false);
|
||||
auto srgb = cmm->get_profile_sRGB();
|
||||
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(false);
|
||||
auto display_p3 = cmm->get_profile_display_p3();
|
||||
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(false);
|
||||
auto srgb = cmm->get_profile_sRGB();
|
||||
CHECK(srgb != nullptr);
|
||||
CHECK(dawn::profile_transfer(srgb.get()) == dawn::Transfer::Srgb);
|
||||
|
||||
|
||||
@@ -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(false);
|
||||
auto p3 = cmm->get_profile_display_p3();
|
||||
dn::ThumbnailHit hit = dn::thumbnail_cache_lookup(source, 0, cmm, p3.get());
|
||||
CHECK(!hit.pixels.empty());
|
||||
CHECK(hit.width == 2 && hit.height == 1);
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ main()
|
||||
const auto *pixels = reinterpret_cast<const uint8_t *>(bytes.data());
|
||||
|
||||
auto cmm = make_shared<dawn::Cmm>();
|
||||
auto icc = cmm->get_profile_sRGB(false)->to_bytes();
|
||||
auto icc = cmm->get_profile_sRGB()->to_bytes();
|
||||
string error;
|
||||
if (!write_png16(stdout, pixmap.width, pixmap.height, pixmap.stride, pixels,
|
||||
icc, pixmap.orientation, &error)) {
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ main(int argc, char **argv)
|
||||
auto cmm = make_shared<dawn::Cmm>();
|
||||
dawn::OpenContext context;
|
||||
context.cmm = cmm;
|
||||
context.screen_profile = cmm->get_profile_sRGB(false);
|
||||
context.screen_profile = cmm->get_profile_sRGB();
|
||||
context.first_frame_only = true;
|
||||
dawn::Error open_error;
|
||||
auto image = dawn::open_from_data(input, context, &open_error);
|
||||
|
||||
Reference in New Issue
Block a user