Development

Zmiany w dystrybucji pakietów Ansel

Development

Klony docelowe (target clones)

Kompilowanie oprogramowania natywnie na komputerze poprawiało czasy działania na CPU o około 30 % w porównaniu z gotowymi pakietami. Powodem jest to, że kompilator dokonuje specyficznych optymalizacji dla docelowego sprzętu, na którym jest kompilowany, podczas gdy gotowe pakiety muszą pozostać uniwersalne i uruchamiają bardziej zachowawcze optymalizacje ze względu na szerokie wsparcie. Zwróć uwagę, że jądra OpenCL i tak są kompilowane dla Twojego konkretnego GPU przy użyciu Twojego sterownika OpenCL, więc tam sytuacja wygląda inaczej.

Elementy sterujące kolorem wreszcie poprawne

Development Design

Wprowadzenie

Narzędzia kontra maszyny, rzemiosło kontra przemysł

W swojej książce Społeczeństwo technologiczne (1954) Jacques Ellul przedstawia różnicę między okresem przed- i porewolucji przemysłowej w następujący sposób:

Epoka przedindustrialna to panowanie narzędzia i rzemiosła. Najważniejszą cechą narzędzi jest to, że są ogólne, wszechstronne i łatwe do przystosowania. To rzemieślnik musi rozwijać swoje umiejętności, aby narzędzia podążały za jego intencją, tak by ręka nadrabiała ograniczenia instrumentu. Koncepcja ta jest wciąż dobrze znana dzisiejszym muzykom: musisz ćwiczyć, uczyć się, próbować, ponosić porażki, próbować ponownie… nie ma dróg na skróty. Ellul podkreśla ideę oszczędności, która towarzyszy narzędziom: zasoby są ograniczone, więc Twój zestaw narzędzi jest w zasadzie określony przez to, na co Cię stać, co możesz nosić, opanować i zbudować lokalnie. Trendy zmieniają się powoli i są lokalne, ponieważ wykorzystują lokalne zasoby i dostosowują się do lokalnych potrzeb, a narzędzia podążają za tym samym wzorcem. Narzędzia to dziedzictwo przekazywane od mistrza do ucznia, od rodzica do dziecka. Nie stają się niekompatybilne ani przestarzałe.

Przeprojektowanie stołu podświetlanego i pamięci podręcznej mipmap

Development Redesign Wydajność

Między styczniem 2022 a marcem 2026 do Ansela trafiło 297 commitów (nie licząc merge’y) dotyczących siatki stołu podświetlanego, jej miniatur oraz potoku (pipeline) ich renderowania i buforowania. Tak długo, jak się dało, próbowałem radzić sobie z niechlujnym kodem stołu podświetlanego z Darktable, jedynie odtłuszczonym, ale niestety był to czysty dług techniczny i działał boleśnie wolno.

Rzeczywiście, Darktable „radzi sobie" z kiepską jakością swojego stołu podświetlanego, zmniejszając jego rozmiar: lewy i prawy panel boczny zajmują dużą część powierzchni wyświetlania, przez co stołowi podświetlanemu zostaje jeszcze mniej obszaru do przemalowania. Ponieważ Ansel usunął prawy panel boczny, scalając jego zawartość z lewym panelem i menu globalnym, powierzchni do malowania było więcej, pracy dla procesora więcej, a fatalny projekt stołu podświetlanego stał się tym bardziej szkodliwy.

Całkowita przebudowa potoku (pipeline)

Development

Odkąd zacząłem używać Darktable, mniej więcej w 2012 roku, zawsze zaskakiwało mnie, jak mało pamięci RAM zużywa. Ludzie sądzą, że to dobrze, gdy aplikacja oszczędnie gospodaruje pamięcią — i to z pewnością prawda, gdy mowa o Twoim środowisku graficznym. Ale gdy mówimy o oprogramowaniu produkcyjnym, które wykonuje ciężkie renderowanie pikseli na obrazach od 12 do 54 Mpikseli, oznacza to, że te same ciężkie obliczenia wykonywane są w kółko, zamiast być zapisane do ponownego wykorzystania później. Właśnie od tego jest pamięć podręczna (cache): od unikania kosztownych obliczeń. I powinna używać do tego całej dostępnej pamięci RAM, ponieważ obliczanie to marnowanie energii, a to ma konkretny wpływ, jeśli pracujesz na baterii. Poza tym zapłaciłeś za tę pamięć RAM, a jej używanie nie rozładowuje baterii. Z kolei CPU/GPU…

Scalanie historii uczynione solidnym i przewidywalnym

Development

Wspomnienia gościa, który spędził zbyt wiele czasu na sprzątaniu cudzego gówna i płaceniu za cudze złe decyzje, odcinek #zbyt wiele.

Kopiowanie/wklejanie historii i stylów to kluczowe funkcje w Anselu i te, które sprawiają, że zasługuje on (lub nie) na miano „aplikacji do pracy”. Są to jednak zarazem jedne z najtrudniejszych do poprawnego zaimplementowania wewnętrznie. Użytkownicy widzą listę edycji, ale pod maską edycje te zależą od kolejności w potoku, instancji modułów i masek. Jeśli dwa zdjęcia mają różne topologie potoku, naiwne kopiowanie edycji może wywołać niespójności.

Witaj, dokumentacjo dla programistów !

Development

W grudniu 2019 roku poprosiłem, aby ktoś zajął się dostarczaniem pakietów AppImage  dla Darktable. Oczywistą korzyścią byłoby umożliwienie wczesnego testowania, przed wydaniem, przez osoby, które nie potrafią samodzielnie zbudować kodu źródłowego, tak by z nadzieją uzyskać wczesne opinie i pomóc w usuwaniu błędów przed wydaniem. Nigdy nie było to priorytetem, co oznacza, że można było mieć pośpiech z naprawą błędów zarówno przed wydaniem, jak i po nim.

Naprawianie pamięci podręcznej potoku i 10-letnich błędów

Development

Podsumowanie poprzednich odcinków

  1. W latach 2020–2022 Darktable przeszedł przez przedsięwzięcie masowej destrukcji, za sprawą garstki gości mających więcej wolnego czasu i dobrej woli niż faktycznych umiejętności,
  2. W 2022 roku zacząłem zauważać irytujące opóźnienie  między interakcjami w interfejsie z suwakami a informacją zwrotną/aktualizacją owych suwaków. Z braku informacji zwrotnej stwierdzającej, że zmiana wartości została zapisana, użytkownicy mogli zmienić ją ponownie, tym samym uruchamiając dodatkowe przeliczenia potoku i skutecznie zawieszając swój komputer, ponieważ głupi interfejs nigdy nie powiedział „mam cię, teraz chwilę poczekaj".
  3. Odkryłem, że rozkazy przeliczenia potoku były wydawane dwukrotnie na kliknięcie (raz przy zdarzeniu „przycisk wciśnięty", raz przy „przycisk zwolniony") oraz jeszcze raz przy każdym ruchu myszy, ale również, że stany interfejsu były pozornie aktualizowane po przeliczeniu potoku.
  4. Naprawiłem to, niemal przepisując od nowa niestandardowe kontrolki interfejsu (biblioteka Bauhaus). Sądziłem, że powstrzymanie lekkomyślnych rozkazów przeliczenia rozwiąże problem opóźnienia: tak się nie stało. Następnie odkryłem, że żądanie nowego przeliczenia potoku przed zakończeniem poprzedniego czekało na zakończenie poprzedniego, mimo mechanizmu wyłączania zaimplementowanego wiele lat temu, który powinien był działać.
  5. Naprawiłem to, implementując mechanizm wyłącznika awaryjnego (kill-switch) na potokach, kierując się komentarzami w kodzie z lat 2010. i wewnętrznymi narzędziami, które równie dobrze mogły nigdy nie działać. Nie zawsze to działało, ponieważ rozkaz zabicia przychodził często z zauważalnym opóźnieniem. Po raz kolejny opóźnienie interfejsu nie zostało naprawione.

Przepisywanie narzędzia importu

Development Redesign

Ansel dziedziczy po Darktable jego bazodanowy kręgosłup: nieniszczące historie edycji zapisywane są dla każdego zdjęcia w bazie danych SQLite, wraz z metadanymi i innymi danymi zdefiniowanymi przez użytkownika. Uświadomienie bazie danych istnienia nowych zdjęć odbywa się poprzez „importowanie" zdjęć z dysku lub karty pamięci. I tu pojawia się narzędzie importu.

Niestety, importer Darktable to kolejna rzecz, którą sknocono około 2020 roku i zamieniono w coś głęboko niepokojącego, ponieważ jest to przeglądarka plików, która nie przypomina żadnej wcześniej znanej przeglądarki plików, a przy tym udaje jej się nie mieć podstawowych funkcji (jak Ctrl+F czy podgląd EXIF), będąc jednocześnie napchaną bezużytecznymi (patrz niżej). To tutaj tracimy niejednego przyszłego użytkownika, a jest to dopiero krok 0 procesu pracy. Cóż za wspaniała wizytówka tego, co potrafi „aplikacja do pracy z procesem" (workflow app)!

Implementacja wyłącznika awaryjnego w potoku

Development

Przez bardzo długi czas myślałem, że w potoku pikseli istnieje jakiś mechanizm wyłącznika awaryjnego. Przypadek użycia jest następujący:

  1. zmieniasz parametr modułu,
  2. podglądy (centralny podgląd w ciemni oraz miniatura w lewym panelu, używana także dla histogramu i próbników koloru) przeliczają swój potok, aby uwzględnić tę zmianę,
  3. jeden z podglądów kończy renderowanie przed drugim, a wynik jest oczywiście nie tym, czego chciałeś,
  4. zmieniasz ponownie parametr modułu, nie czekając na zakończenie przeliczania.

W takim przypadku chcesz zabić wszystkie aktywne potoki, ponieważ ich wynik nie zostanie użyty, i natychmiast rozpocząć przeliczanie wszystkiego z nowymi parametrami. Tyle że Darktable tego nie robi — pozwala potokowi zakończyć się przed jego ponownym uruchomieniem, a patrząc na komentarze w kodzie źródłowym, wygląda na to, że jest to dość niedawna regresja, a nie pierwotnie zamierzone zachowanie.

Od-darktable-owienie kontrolek GUI

Development

Darktable ma własną bibliotekę widżetów GUI, dla suwaków i list rozwijanych (znanych też jako menu rozwijane lub pola wyboru), nazwaną Bauhaus (w kodzie źródłowym znajduje się ona w src/bauhaus/bauhaus.c). Choć jako backendu używają Gtk, obiekty Bauhaus są niestandardowe. A jak wiele rzeczy w Darktable, niestandardowe znaczy zepsute.

W 2022 roku ‍zauważyłem pasożytnicze przerysowania i opóźnienia  podczas ich używania, prowadzące do frustrującego doświadczenia użytkownika: przerysowanie widżetu zdawało się czekać na zakończenie ponownych obliczeń potoku (pipeline), co oznaczało, że użytkownicy nie byli do końca pewni, czy zmiana ich wartości została zapisana, co mogło skłaniać ich do ponawiania próby, uruchamiając kolejny cykl kosztownych ponownych obliczeń i skutecznie zawieszając ich komputer na kilka bardzo frustrujących minut bezużytecznych, pośrednich ponownych obliczeń potoku.

Nowe opcje kompilacji dla Linuksa

Development

Przypadkiem odkryłem, że skrypt kompilacji dla Linuksa używał kompilacji „pakietowej", co oznacza, że optymalizacje CPU są ograniczone do ogólnych, aby wytwarzać przenośne pliki binarne, które można zainstalować na dowolnej platformie x86-64. Przez „używał" mam na myśli, że kompilacja pakietowa nie była jawnie wyłączona, więc była domyślnie włączona.

W każdym razie jest to teraz domyślnie wyłączone, ponieważ właściwe pakiety (.exe i .appimage) nie są budowane przez ten skrypt, który jest przede wszystkim przeznaczony do pomocy użytkownikom końcowym. Aby przywrócić poprzednie zachowanie, musisz uruchomić:

Dziennik dewelopera #2: przedstawiamy Chantal

Development

Rok 2022 był tak fatalny pod względem śmieciowych e-maili i szumu, że rozpocząłem projekt Virtual Secretary , framework w Pythonie do pisania inteligentnych filtrów poczty, które krzyżują informacje z kilku źródeł, aby odgadnąć, czym są przychodzące e-maile i czy są ważne/pilne, czy nie. Kiedy mówię o śmieciowych e-mailach, chodzi też o powiadomienia z Githuba, pingi na pixls.us (dzięki Bogu zamknąłem konto na tym głupim forum), YouTube oraz bezpośrednie e-maile od ludzi liczących na uzyskanie prywatnej pomocy.

Dziennik dewelopera

Development

Minęły mniej więcej 3 miesiące, odkąd zmieniłem nazwę „R&Darktable" (której nikt zdawał się nie rozumieć poprawnie) na „Ansel", a następnie kupiłem domenę i stworzyłem stronę internetową od zera przy użyciu Hugo (nigdy wcześniej nie programowałem w Golangu, ale to głównie kod szablonów).

Potem spędziłem łącznie 70 h na tym, żeby nocne kompilacje pakietów dla Windowsa i Linuksa działały w ramach ciągłego dostarczania — coś, czego Darktable nigdy nie zrobił porządnie („możesz skompilować samodzielnie, to nietrudne") — tylko po to, by po wydaniu zobaczyć eksplozję w systemie zgłaszania błędów (nic tak nie skraca oczekiwanej długości życia jak połączenie sprintu przedwydaniowego ze sprintem powydaniowym).

Search

You can also ask Chantal, the AI search engine.