Skip to content

Setting dispmanx resource palette when using VC_IMAGE_8BPP pixel format #95

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

Closed
vanfanel opened this issue Oct 3, 2013 · 15 comments
Closed

Comments

@vanfanel
Copy link

vanfanel commented Oct 3, 2013

Hi there,

I really need help with this.
I made a "hacky" but working dispmanx backend for libSDL 1.2.x (wich is available on my github, of course), but I recently discovered 8bpp games/apps wouldn't display correctly.
In particular, 8bpp games wich set custom palettes seem to show all kind of strange colors.

I use VC_IMAGE_8BPP as pixel format when I create a resource with vc_dispmanx_resource_create() in case the game/app is requesting a 8bpp video mode, so when I do vc_dispmanx_resource_write_data() (because I dump SDL video surface to one of my two resources for double buffering by doing this), the pixel format parameter is the same.
Pixels appear with the expected size, etc, but wrong colors.
How can I modify a VC_IMAGE_8BPP resource's palette, then? Is there any other way to archieve this?

Thanks

@popcornmix
Copy link
Contributor

Can I confirm if you need a single 256 entry colour palette with an 8bpp framebuffer, and all resources should use this palette. Or
You need multiple 256 entry colour palettes, one for each resource and the framebuffer is 16, 24 or 32 bit?

@vanfanel
Copy link
Author

vanfanel commented Oct 4, 2013

Hi popcornmix! Thanks for answering :)

I already have two 8bpp resources (since my backend uses double buffer to avoid tearing), wich I created with

pix_format = VC_IMAGE_8BPP;

dispvars->resources[0] = vc_dispmanx_resource_create(
dispvars->pix_format, width, height,
&(dispvars->vc_image_ptr) );

dispvars->resources[1] = vc_dispmanx_resource_create(
dispvars->pix_format, width, height,
&(dispvars->vc_image_ptr) );

The programs using SDL1.2.x must be able to set the palette on the video SDL_Surface using SDL_SetPalette().
The SDL_Surface in wich I draw, has it's screen->pixels = pixmem, where pixmem is a void*, and wich I upload to the VC RAM using this:

vc_dispmanx_resource_write_data( dispvars->resources[flip_page],
dispvars->pix_format, dispvars->pitch, dispvars->pixmem,
&(dispvars->bmp_rect) );

Now, the problem is that colors are totally messed up with 8BPP resources, so I guess these resources should have a way to have their palettes changed, accoring to the palette in the SDL_Surface whose pixels field is used to draw the final frame.
SDL_Surface is an structured data type wich contains a SDL_PixelFormat structure wich has a palette SDL_Palette structure, containing a SDL_Color*. Each SDL_Color in a palette has 3 Uint8 fields: r, g and b.

SO I believe what I need is an 256 colors palette, just one for both resources, wich can be updated (changed) anytime before I call vc_dispmanx_resource_write_data(): An SDL_Color is 8x8x8, yes, but the values it can take inside a palette are limited to a given 256 set of combinations in a given moment for a given surface.

@popcornmix
Copy link
Contributor

What I need to know is what is the maximum number of different palettes you need in total for a given instance in time?
The HVS (which composites resources) has a block of context memory which describes the state of the current display. A palette takes a significant part of the context memory, and currently we only allow a maximum of one palette (256 entries of 32bpp colour).
So if you just want to change the single palette in the system, that should be possible.
If you want to composite a scene consisting of a number of surfaces with different palettes then that won't be possible.

@vanfanel
Copy link
Author

vanfanel commented Oct 4, 2013

I should need only a palette at a given time for every resource, and a way (a function call) to change that palette.
And yes, every of the 256 entries on that palette is 32bpp, with 3 components (r,g,b) as the "incoming" palette (wich is unique for each completed frame in a givem moment) is an SDL_Color* array.

@popcornmix
Copy link
Contributor

But how many resources are on screen?
There can only be a single palette for the whole screen. Is that sufficient?

@vanfanel
Copy link
Author

vanfanel commented Oct 4, 2013

There's only one resource on screen at a given time, since I simply alternate between two resources to create the "double buffer". So, one resource on screen at a time. One or the other.

This is how I swap bewteen them, in case there's any doubt:

dispvars->update = vc_dispmanx_update_start( 0 );

vc_dispmanx_element_change_source(dispvars->update,
dispvars->element, dispvars->resources[flip_page]);
vc_dispmanx_update_submit_sync( dispvars->update );

flip_page = !flip_page;

If you know about a better (more optimal) way to implement double buffer using dispmanx, please tell me for the good of libSDL 1.2.x on the Pi. :)

@popcornmix
Copy link
Contributor

Double buffering like that seems fine.
What you want should be possible, but there may not be an easily exposed was of doing it.
You may be able to use:
https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
See "Set palette".
It may also work if you are in an 8bpp framebuffer mode (i.e. fbset -depth 8) and you use the FBIOPUTCMAP ioctl.

I'll try and get a hello_dispmanx type test working with a palette and see if this works. It may be best to add a new dispmanx_ function to set the palette for a resource.

@vanfanel
Copy link
Author

vanfanel commented Oct 9, 2013

But I can't guarantee an user is on an 8bpp framebuffer when using an SDL 1.2.x program, so that ioctl isn't a solution.
I guess I'll wait for your example before getting down to arm assembler mailbox techniques.

@vanfanel
Copy link
Author

I've been making further experiments with the FBIOPUTCMAP ioctl:
I'm setting the fbcon successfully in 8bpp mode with FBIOPUT_VSCREENINFO ioctl.
I'm taking a working fbcon backend, where the FBIOPUTCMAP ioctl works as expected, I went and modified it to use dispmanx instead, but palette changes don't seem to propagate to the dispmanx part.
In other words, the FBIOPUTCMAP ioctl does work, but changes don't propagate to the resources, wich show the same wrong colors.

I know you must be busy, but I'd love to see that "hello world" palette change example.

@vanfanel
Copy link
Author

I'm not in a hurry because 8bpp support isn't that important to me, but after implementing my own software paletted-8bpp to 32bpp conversion and finding how much CPU it eats on the PI (it's ok for 320x200 buffers, but it's a complete hog in bigger video buffers) , I'd like to know it there's a chance to be able of setting resource palettes.
Maybe I should forget about it, popcornmix? It would be nice if you gave me some word on this ;)

@popcornmix
Copy link
Contributor

If you just need a single active palette, then yes, I will implement that.
I can't say exactly when, as it feels like something few people will care about and so it seems less urgent than most other work on my list.
Although it should be straightforward (an hour or two) so I'll try to fit it in soon.

@popcornmix
Copy link
Contributor

I've had a bash at this, and this test program seems to be working:
http://pastebin.com/sBxpu184

check that looks okay, and I'll push out an updated firmware tomorrow.

@popcornmix
Copy link
Contributor

This is now pushed out. rpi-update to get.

popcornmix pushed a commit to raspberrypi/firmware that referenced this issue Nov 7, 2013
…ERSPACE and crypto options

See: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=29&t=55711

bootcode: fix noobs boot issue when booting from alternate partition

firmware: Support for multichannel audio (from next tree). Improvements to force_audio option.
firmware: Improvements to spdif formatting of HDMI PCM data during start/stop/pause/underrun.
firmware: Add pause_burst_frames config option to avoid noise when pausing ac3 passthrough
firmware: Add dispmanx api to set resource's palette
See: raspberrypi/userland#95
popcornmix pushed a commit to Hexxeh/rpi-firmware that referenced this issue Nov 7, 2013
…ERSPACE and crypto options

See: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=29&t=55711

bootcode: fix noobs boot issue when booting from alternate partition

firmware: Support for multichannel audio (from next tree). Improvements to force_audio option.
firmware: Improvements to spdif formatting of HDMI PCM data during start/stop/pause/underrun.
firmware: Add pause_burst_frames config option to avoid noise when pausing ac3 passthrough
firmware: Add dispmanx api to set resource's palette
See: raspberrypi/userland#95
@vanfanel
Copy link
Author

Thanks a lot for this, popcornmix!

I've already incorporated native 8bpp to my DispmanX libSDL 1.2.x backend here:
https://github.com/vanfanel/SDL12-kms-dispmanx

Many SDL apps/games using 8bpp modes now work great, without slow color conversions.
Should I press the "Close & Comment" button?

@popcornmix
Copy link
Contributor

Glad it worked for you. Feel free to close this.

neuschaefer pushed a commit to neuschaefer/raspi-binary-firmware that referenced this issue Feb 27, 2017
…ERSPACE and crypto options

See: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=29&t=55711

bootcode: fix noobs boot issue when booting from alternate partition

firmware: Support for multichannel audio (from next tree). Improvements to force_audio option.
firmware: Improvements to spdif formatting of HDMI PCM data during start/stop/pause/underrun.
firmware: Add pause_burst_frames config option to avoid noise when pausing ac3 passthrough
firmware: Add dispmanx api to set resource's palette
See: raspberrypi/userland#95
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

No branches or pull requests

2 participants