How much of your phone’s screen resolution can you actually see? I’ve created an Android app called Resolution. It has two goals:
- collect some statistics to better understand what users of their phones can and can’t see in relation to their screen resolution/density.
- give you a better understanding of what you can see. So that you can make more informed purchasing decisions.
This is part of the larger series of deep-dives into whether a 4k display on a phone is useful.
Here’s a very brief video summarising the app:
Table of contents
Assumptions
Pixels vs shapes
Due to how the majority of modern phone displays work, an individual pixel is hard to make out, regardless of resolution, and is inconsistent at best. (Here’s a deep dive into what’s being displayed.)
Coming from the other side; think about the use-cases when we need clarity, and what it is that we need. While there might be some obscure use-cases that benefit from what exactly one pixel is doing; in most cases a single pixel is used as part of a team to produce a shape.
Fonts are a prime example of this. Clear communication of the shapes is essential to easy reading. Fuzzy, and jagged edges are counter-productive to that communication. Meanwhile, very few characters only contain vertical or Horizontal lines. The diagonal lines and curves need to be displayed clearly as well.
Diagonals
Diagonals present an interesting problem: While horizontal and vertical steps can be conveyed as one pixel width, diagonals can not.
Above: A diagram showing a 1 pixel width step in both the vertical, and horizontal orientations.
These fit naturally within the characteristics of a grid array of pixels.
Above: A diagram showing a diagonal solution for a 1 pixel width step. Effectively 0.7 pixels wide, and perpendicular to the original diagonal line.
The green pixel shows where the last cyan pixel would have come from if it was still part of the original line, and had not stepped out. By the time you take into account the spacing, it’s movement along that line is 0.5 pixels offset on both the x axis and the y axis. You can see that to step out of the original line, it has had to move by 0.5 pixels on both the x axis and y axis.
The effective movement is 0.7 pixels diagonally away from the original line. (A^2 + B^2 = C^2)
This presents two problems:
- The edge is not perpendicular to the original diagonal line. Ie it’s not representing the shape that we are setting out to represent. It also makes it harder to see.
- Most modern displays do not display 1 pixel well. So 1 pixel width is already pushing what the user will be able to see regardless of the resolution. (Deep dive on this is coming.) So to off-set the line by effectively less than 1 pixel is going to make it even harder to see.
Above: A diagram showing 2 diagonal solutions for a 1 pixel width step. Effectively 1.4 pixels wide.
These two solutions move by 1 whole pixel in both the x axis, and the y axis. Doing the same A^2 + B^2 = C^2 calculation, this gives us a step pixel width of 1.4 pixels.
The left solution is a natural evolution of the previous attempt, where each final pixel is horizontally inline with the same pixel from the original line. This continues the problem of not having a perpendicular step.
The solution on the right fixes this by continuing the outer line by one more pixel. Now the step is perpendicular.
Both of these solutions have the problem that the effective 1.4 pixel width is greater than the 1 pixel width that we are aiming for.
I ended up choosing the solution on the right, because it honestly represents the shape that I’m trying to show. Since it is very slightly easier to see, we therefore need to give more weight to the horizontal and vertical orientations when judging how well we can see the resolution of a display.
How it works
It works by getting you to tap in the corner of a step, and measuring how close you got to the corner, and how long it took you. For each test; the first one has an arrow showing you what to look for:
Above: A screenshot of the first vertical test, with an arrow showing the user what they need to look for.
Each time you succeed, the size of the step is halved and put in a new location of the screen:
Above: A screenshot showing the same vertical test, but at half the previous width, and in a new location. The arrow is no longer present now that the user knows what to look for.
This continues until it gets down to 1 pixel width:
Above: A screenshot of a 1 pixel width step.
1 pixel width will be hard on most devices, regardless of the resolution. I’ve touched on why this is in the video, but am planning on a deeper dive blog post into it. If you’d like to see that, please leave a comment on the video, asking for it.
How the app behaves
Some other notes:
- Every test/attempt will be put in a different location on the screen. This is to:
- reduce the influence of any quirks of the display. Eg many pentile displays will display either even columns, or odd columns clearly, and the other columns only light up 1 of the 3 sub-pixels.
- make it harder for the user to predict where the step is, so if they find it, there’s a high chance that they actually saw it.
- You get 3 attempts per level.
- For each failure a new location will be chosen.
- After 3 failures, that type of test will end, and your last success will be recorded.
- For each success:
- Your distance from the step, and time it took you to find it, will be recorded.
- The number of attempts will be recorded.
- For each failure a new location will be chosen.
- The full test includes every combination of:
- Left, right / top, bottom.
- Vertical, diagonal, horizontal.
- The quick test only includes:
- Vertical.
- Diagonal.
- Horizontal.
The homescreen
Here’s the homescreen of the app:
Above: A screenshot of the homescreen.
The current version, as of this writing, has 3 buttons:
- “Show test patterns” - The test patterns that I used to test the different types of displays.
- “Quick” - 1 Vertical test. 1 Diagonal test. And 1 Horizontal test.
- “Full” - All tests.
The test pattern page
The test pattern page looks like this:
Above: A screenshot of the test pattern page.
There is an “Increment” button at the bottom page, which increments each of the various on-screen tests.
Text at the top-left of the page
There are currently 4 lines of “iilloo lllll ooooo”.
The increment button moves each of these lines in a different direction by one pixel per increment. This was interesting to observe how the sub-pixel anti-aliasing would change on different display types. The results of this were not as obvious as I had hoped. However they were really helpful for testing observations.
The repeating characters is really interesting. What I was trying to achieve was to offset each repeating character by a different amount so that it would give different sub-pixel anti-aliasing solutions for each character. But that’s not what happened. Almost always, the repeating characters repeated nicely with the same offsets. It was only when other characters were mixed in that these different distortions happened. See the fonts deep-dive for more understanding of that, but here’s a sneak peak:
Above: A screenshot showing the anti-aliasing solutions on a 1080p display.
Look at
- The “t”s:
- Notice how some vertical edges are clean. Some are not.
- None of the horizontal edges are clean.
- The “i”s:
- None of the edges are clean.
- 1 is 3 pixels wide.
- 1 is 4 pixels wide, but one of the columns is very dark.
- The other 4 pixel wide “i” has it’s 4th column more moderately lit up.
- The second “i” looses its dot into the “f”.
- Letters of the same type are noticeably not consistent with each other. (eg “t” vs “t”, “i” vs “i”)
Test patterns at the center of the page
The test patterns are where the magic really happens. This is where almost all of the insight came from.
Above: A macro photo of a 1080p display with a ‘Traditional RGB’ layout.
This is a good moment to show the effect of incrementing the patterns:
Above: An animation showing the increment in progress.
The pattern that I gained the most insight from was the squares of varying sizes, and colours, dancing around each other. It gave really interesting insights into what sub-pixel optimisations each type of display was doing. More on that in another deep-dive soon.
The right-angle patterns that begin in the top-left hand corner were also really interesting. This showed how 1 more pixel, or a block of pixels influences the sub-pixels around the change. It was also really interesting to see how this changed for different colours based on the sub-pixel layout of the display.
Just below the right-angle patterns, and also down the right hand side of the whole area, are the lines at different intervals. The purpose of this was to reveal if a display was doing interpolation on different rows and columns.
At the very bottom, there are some blocks of varying colours beside each other. Each row is a different pixel-width (1, 2, and 3 pixels wide.) The purpose of this was to show how different sub-pixels behaved when different combinations of colours were neighbouring each other. Every time I had a theory about how the display was behaving in this regard; this confirmed it. But I didn’t find it particularly interesting to discuss further.