Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ev3: fix display fb handling for new kernel #3

Merged
merged 2 commits into from
Apr 29, 2018
Merged

Conversation

kortschak
Copy link
Member

@dlech Please take a look.

This was even easier than I had guessed.

Fixes #2.

@dlech
Copy link

dlech commented Apr 25, 2018

Your image is RGBA, but the framebuffer is XRGB, so if you are writing the image directly to the framebuffer, it won't work exactly right.

@kortschak
Copy link
Member Author

I was operating on the basis that the fb packing is big endian, which I got from the fbset source (in the absence of any real documentation to that effect - so certainly possible wrong). This means that the A will get put in the last slot and be ignored. If it is actually little endian, then I'll either have to wrap image.RGBA or probably more likely just reimplement the type with the order reversed and dropping A.

@dlech
Copy link

dlech commented Apr 25, 2018

You could very well be right, but then wouldn't R and B would be swapped.

If you go to the route of re-implementing, you might consider using an 8-bit grayscale image (the EV3 screen is actually only 2-bit grayscale, but 8-bit is the closest "standard" format). Then when you push the image to the screen, use the same 8-bit pixel value for each of RGB.

@kortschak
Copy link
Member Author

I'll do the experiments to see if what is going on. As far as making the image type handle an 8 bit greyscale, that's handled by the stdlib image/color code; an image copy of a greyscale to the fb will just work. Do we have a gamut mapping of colour values to the grey scale bits, or it just linear?

@dlech
Copy link

dlech commented Apr 25, 2018

The kernel driver does the mapping from RGB to grayscale.

/**
 * tinydrm_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale
 * @dst: 8-bit grayscale destination buffer
 * @vaddr: XRGB8888 source buffer
 * @fb: DRM framebuffer
 * @clip: Clip rectangle area to copy
 *
 * Drm doesn't have native monochrome or grayscale support.
 * Such drivers can announce the commonly supported XR24 format to userspace
 * and use this function to convert to the native format.
 *
 * Monochrome drivers will use the most significant bit,
 * where 1 means foreground color and 0 background color.
 *
 * ITU BT.601 is used for the RGB -> luma (brightness) conversion.
 */

@kortschak
Copy link
Member Author

The code for that is very helpful.

It looks like the endianism is machine-endian and (as the name suggests) 00rrggbb. The conversion is straightforward, but we still need to take a color.Color; the good thing is that the grey colours provided in color already implement the ITU BT.601.

In the kernel:

			/* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */

In color:

func grayModel(c Color) Color {
	if _, ok := c.(Gray); ok {
		return c
	}
	r, g, b, _ := c.RGBA()


	// These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
	// as those given by the JFIF specification and used by func RGBToYCbCr in
	// ycbcr.go.
	//
	// Note that 19595 + 38470 + 7471 equals 65536.
	//
	// The 24 is 16 + 8. The 16 is the same as used in RGBToYCbCr. The 8 is
	// because the return value is 8 bit color, not 16 bit color.
	y := (19595*r + 38470*g + 7471*b + 1<<15) >> 24


	return Gray{uint8(y)}
}


func gray16Model(c Color) Color {
	if _, ok := c.(Gray16); ok {
		return c
	}
	r, g, b, _ := c.RGBA()


	// These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
	// as those given by the JFIF specification and used by func RGBToYCbCr in
	// ycbcr.go.
	//
	// Note that 19595 + 38470 + 7471 equals 65536.
	y := (19595*r + 38470*g + 7471*b + 1<<15) >> 16


	return Gray16{uint16(y)}
}

This means that all that's needed is the correct byte order to be written to the byte buffer that reflects the fb.

@kortschak
Copy link
Member Author

This will fail since it will try to build against master. I'll ping after having done successful tests on actual hardware over the weekend.

@kortschak
Copy link
Member Author

Tested and working (failure here is due to the dependency on the ev3dev-stretch branch).

@kortschak
Copy link
Member Author

PTAL

Copy link

@dlech dlech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not much to see 😄

@kortschak kortschak merged commit 66dad0f into ev3dev-stretch Apr 29, 2018
@kortschak kortschak deleted the display branch April 29, 2018 22:02
@kortschak
Copy link
Member Author

Indeed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants