generated from saji/ecp5-template
add gamma module
This commit is contained in:
parent
29464f91b4
commit
75d6e15b42
52
src/groovylight/gamma.py
Normal file
52
src/groovylight/gamma.py
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
# Gamma correction by adjusting the display OE/Expose timings.
|
||||||
|
|
||||||
|
|
||||||
|
# Most gamma correction is done on the values being displayed.
|
||||||
|
# i.e gammacorrect (RGB) -> RGB (adjusted). However this adds
|
||||||
|
# a complex look-up step which adds complexity and cycles.
|
||||||
|
# There is a simpler solution which uses some properties of the
|
||||||
|
# gamma function as well as the fact that we are manually doing
|
||||||
|
# color depth using BCM/PWM.
|
||||||
|
#
|
||||||
|
# Consider the default BCM timing layout:
|
||||||
|
# MSB MSB-1 MSB-2 MSB-3
|
||||||
|
# P*8 P*4 P*2 P
|
||||||
|
# that is, we have a baseline display, measured in clocks/us/whatever
|
||||||
|
# and then the next most significant bit is displayed for twice that,
|
||||||
|
# four times that, and so on.
|
||||||
|
# But, we can adjust the individual bit timings to adjust the brightness
|
||||||
|
# curve as we see fit. This has numerous advantages:
|
||||||
|
# 1. It's free, we don't have to do any math on the board, just adjusting
|
||||||
|
# an existing process.
|
||||||
|
# 2. We can go more granular that n-bits of color. This means that the gamma
|
||||||
|
# curve will be effective and accurate regardless of the color depth.
|
||||||
|
#
|
||||||
|
# This file contains code to generate these timing adjustments and
|
||||||
|
# control/quantify them.
|
||||||
|
|
||||||
|
from math import pow
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _gammavec(vals: [float], g: float) -> [float]:
|
||||||
|
return [pow(x,g) for x in vals]
|
||||||
|
|
||||||
|
def _nbit_scale(f, nbits:int) -> [float]:
|
||||||
|
"""Computes the equivalent linear value for each bit of n_bits.
|
||||||
|
That is, the list contains scalar values that are doubling as they progress,
|
||||||
|
[ x, 2x, 4x ] such that the sum(list) = 7x = f
|
||||||
|
"""
|
||||||
|
base = float(f) / (pow(2.0, nbits) - 1.0)
|
||||||
|
return [base * pow(2.0, x) for x in range(nbits)]
|
||||||
|
|
||||||
|
|
||||||
|
def gamma_timings(gamma:float = 2.2, nbits:int = 8, max_clocks: int = 4096):
|
||||||
|
"""Computes the clock cycle timings for a given gamma correction.
|
||||||
|
"""
|
||||||
|
linear_values = _nbit_scale(1.0, nbits)
|
||||||
|
gamma_values = _gammavec(linear_values, gamma)
|
||||||
|
|
||||||
|
bclk_ratio = max_clocks / gamma_values[-1]
|
||||||
|
result = [round(bclk_ratio * x) for x in gamma_values]
|
||||||
|
return result
|
||||||
|
|
Loading…
Reference in a new issue