RSS Amplifier

Blog

Litherum

litherum.blogspot.comRSS feed ↗25 posts

Latest posts

C++ Concepts as GADTs

I'm learning about GADTs in OCaml, and thinking about how one might be able to achieve the same kind of thing in C++. With C++ concepts, I think you can actually get pretty much all the way there. GADTs The canonical example of GADTs seems to be implementing a little embedded DSL, such that the embedded language's typechecking rules are checked by the embedding language's typechecker. Real World…

Vulkan Synchronization: Why it sucks (Part 2)

There are a variety of reasons why I don't think the Vulkan committee designed synchronization very well. Let's get one thing out of the way first: State/Hazard Tracking is a Thing that People Need to Do At GDC 2016 (the year that Vulkan came out), Matthaeus Chajdas presented making the point that you shouldn't need to do state tracking in Vulkan. He says that, instead of tracking state at…

Vulkan Synchronization: What it is (Part 1)

Synchronization in Vulkan is actually somewhat tricky to grok. And you have to grok it, because it isn't done automatically for you - you have to explicitly synchronize between every data hazards that might arise. (This is in contrast to APIs like Metal which do most, or even all, of the synchronization for you.) Hazards So let's start out with: What's a data hazard? A data hazard is when two…

Avoiding Seemingly-Necessary Retain Cycles

I was recently implementing an API that seemed like it required a retain cycle. Object A has a property of object B, and object B has a property of object A. Customer code is allowed to retain either object A or object B and must be able to access the other one via the property. It seems like this requires a retain cycle to implement, doesn't it! Specifically, I'm implementing reflection for a…

So I wrote a double delete...

I wrote a double delete. Actually, it was a double autorelease. Here's a fun story describing the path it took to figure out the problem. I'm essentially writing a plugin to a different app, and the app I'm plugging-in-to is closed-source. So, I'm making a dylib which gets loaded at runtime. I'm doing this on macOS. The Symptom When running my code, I'm seeing this: Let's see what we can learn…

Nvidia SLI from Vulkan's Point of View

SLI is an Nvidia technology, which (is supposed to) allow multiple GPUs to act as one. The use case is supposed to be simple: you turn it on, and everything gets faster. However, that's not how it works in Vulkan (because of course it isn't - nothing is simple in Vulkan). So let's dig in and see exactly how it works and what's exposed in Vulkan. Logical Device Creation SLI is exposed in Vulkan…

My First Qt App

Just for fun, I wanted to try to make a Qt app that graphs some data. For contrast, I'm aware of Swift Charts , and I thought using Qt to graph some stuff would be a fun little project, now that I'm using FreeBSD full time, rather than macOS. The latest version of Qt is version 6, so that's what I'll be using. Basics When you use Qt Creator to create a new Qt project, it only creates 4 files:…

ReSTIR Part 2: Characterizing Sample Reuse

After enumerating all the building blocks of ReSTIR , there isn't actually that much more. The rendering equation is an integral, and our job is to approximate the value of the integral by sampling it in the most intelligent way possible. Importance sampling tells us that we want to generate samples with a density that's proportional to the contribution of those samples to the value of the final…

ReSTIR Part 1: Building Blocks

ReSTIR is built on a bunch of other technologies. Let's discuss them one-by-one. Rejection Sampling Rejection sampling isn't actually used in ReSTIR, but it's useful to cover it anyway. It is a technique to convert samples from one PDF (probability density function) to another PDF. So, you start with the fact that you have 2 PDFs: a source PDF and a destination PDF. The first thing you do is you…

Implementing a GPU's Programming Model on a CPU

SIMT The programming model of a GPU uses what has been coined "single instruction multiple thread." The idea is that the programmer writes their program from the perspective of a single thread, using normal regular variables. So, for example, a programmer might write something like: int x = threadID; int y = 6; int z = x + y; Straightforward, right? Then, they ask the system to run this program a…

Video Splitter

I record ~all the games I play. Not for any particular reason, but really just because sometimes it's fun to go back and re-watch them, to repeat a positive experience. Usually, I just upload the raw footage directly to YouTube , but this time I wanted to see if I could do a little better. Problem Statement I just finished playing Cyberpunk 2077 , and recorded 77 hours of footage. This footage is…

Understanding CVDisplayLink

I found it actually somewhat difficult to understand how to use CVDisplayLink . But, after a while of playing around with it, I think I've got a pretty good handle on it. It's not too complicated. The main use of a CVDisplayLink is to have a callback that runs once per vsync of a screen. It's also stateful, so you can stop and start the callback stream. Creation When you create one of these…

Addition Font

Shaping When laying out text using a font file, the code points in the string are mapped one-to-one to glyphs inside the file. A glyph is a little picture inside the font file, and is identified by ID, which is a number from 0 - 65535. However, there’s a step after character mapping but before rasterization: shaping. For example, one application of shaping is seen in Arabic text. In Arabic, each…

Wide color vs HDR

Over the past few years, there’s been something of a renaissance in display technology. It started with retina displays and now is extending to wide color and HDR . Wide color has been added to Apple’s devices, and HDR support has arrived in Windows. These are similar technologies, but they aren’t the same. HDR allows you to display the same colors you could display with out, but at a higher…

Texture Sampling

Textures are one of the fundamental data types in 3D graphics. Any time you want to show an image on a 3D surface, you use a texture. Texture Types First of all, there are many kinds of textures. The simplest kind of texture to understand is a 2D texture, whose purpose is to act like a rectangular image. Each element in the image is configurable; you can specify that it’s a float, or an int, or 4…

Comparison of Entity Framework to Core Data

Object Relational Mapping libraries connect in-memory object graphs to relational databases. Object-oriented programming is built upon the idea that there is an in-memory object graph, where each object is an instance of a class. An ORM is the software that can save that object graph to a database, either on-disk or using a service across the network. Entity Framework is Microsoft’s premier ORM…

Development Analogy

iOS Windows Swift C# Metal Direct3D 12 Core Animation DirectComposition Core Graphics Direct2D WebKit EdgeHTML WKWebView Windows.UI.Xaml.Controls.WebView JavaScriptCore Chakra Core Text DirectWrite Core Data EntityFramework XMLParser Windows.Data.Xml.Dom JSONSerialization Windows.Data.Json .xib .xaml .dylib .dll dlopen/dlsym LoadLibrary/GetProcAddress UISplitViewController…

Wide and Deep Color in Metal and OpenGL

“Wide Color” and “Deep Color” refer to different things. A color space can be “wide” if it has a gamut that is bigger than sRGB. “Gamut” roughly corresponds to how saturated it is possible to represent a color. The wider the color space is, it is possible to represent more and more saturated colors. “Deep color” refers to the number of representable values in a particular encoding of a color…

Chromaticity Diagrams

Humans can see light of the wavelengths between around 380 nm and 780 nm. We see many photons at a time, and we recognize the collection of photons as a particular color. Each photon has a frequency, which means that a particular color is the effect of how much power the photons have at each particular frequency. Put another way, a color is a distribution of power throughout the visible…

Relationship Between Glyphs and Code Points

Recently, there have been some discussions about various Unicode concepts like surrogate pairs, variation selectors, and combining clusters, but I thought I could shed some light into how these pieces all fit together and their relationship with the things we actually see on screen. tl;dr: The relationship between what you see on the screen and the unicode string behind it is completely arbitrary.…

Single Screen GPU Handoff

Over the past few years, a collection of laptops have been released with two graphics cards. The idea is that one is low-power and one is high power. When you want long battery life, you can use the low-power GPU, but when you want high performance, you can use the high-power GPU. However, there is a wrinkle: the laptop only has one screen. The screen’s contents have to come from somewhere. One…

Variation Fonts Demo

Try opening this in a recent Safari nightly build . The first line shows the text with no variations. The second line animates the weight. The third line animations the width. The fourth line animates both. hamburgefonstiv hamburgefonstiv hamburgefonstiv hamburgefonstiv

Variable Fonts in CSS Draft

Recently, the CSS Working Group in the W3C resolved to pursue adding support for variable fonts within CSS. A draft has been added to the CSS Fonts Level 4 spec . Your questions and comments are extremely appreciated, and will help shape the future of variation fonts support in CSS! Please add them to either a new CSS GitHub issue , tweet at @Litherum , email to mmaxfield@apple.com , or use any…

Font Taxonomy

OpenGL on iOS

The model of OpenGL on iOS is much simpler than that on macOS. In particular, the context creation routine on macOS is older than the concept of OpenGL frame buffers, which is why it is structured the way that it is. Back then, the model was much simpler: the OS gave you a buffer, and you drew stuff into it. If you wanted to render offscreen, you had to ask the OS to give you an offscreen buffer.…