Surface pitch

Hello to everyone on the mailing list :slight_smile: I’m happy it’s not dead :slight_smile:

My app creates an 8-bit surface. When surface->pitch is different than
surface->w in bytes?
I had that problem before - I was creating a Meritous port for Sony PSP, for
which SDL is fully ported, even with multitasking. The game had a very
strange way to show strings on a surface: it creates a pointer to
screen->pixels (or however it’s called) and moves it to drawing position,
but instead of moving screen->pitch for each line, it moved screen->w bytes
down. When app was in resolution 640x480, this method was working, but when
I changed to 480x272 (PSP native resolution) the strings were all shattered.
I spent 2 days finding out what was wrong.

So, my question is: When surface->pitch is different than
surface->w*surface->format->BytesPerPixel (it’s multiplying here)? And when
it is different, what data are stored between lines?
Don’t consider this an urgent question, why? because it’s not :slight_smile:

You can find Meritous PSP port almost stable on my website:
http://elementgame.boo.pl/

Marach

Le Sat, 6 Jun 2009 10:44:30 +0200
Hubert Maraszek a ?crit:

My app creates an 8-bit surface. When surface->pitch is different than
surface->w in bytes?

It is different if SDL can not create a video mode for the width you
asked for (for example if the underlying hardware does nto support it).

I had that problem before - I was creating a Meritous port for Sony PSP, for
which SDL is fully ported, even with multitasking. The game had a very
strange way to show strings on a surface: it creates a pointer to
screen->pixels (or however it’s called) and moves it to drawing position,
but instead of moving screen->pitch for each line, it moved screen->w bytes
down. When app was in resolution 640x480, this method was working, but when
I changed to 480x272 (PSP native resolution) the strings were all shattered.
I spent 2 days finding out what was wrong.

For example, if the target only provides a 640x480 resolution and you
want 480x272, SDL will give you 640 for pitch (for 8 bits/pixel), and
your 480x272 SDL_Surface screen in reality is only a part of the real
640x480 screen.

So, my question is: When surface->pitch is different than
surface->w*surface->format->BytesPerPixel (it’s multiplying here)? And when
it is different, what data are stored between lines?

When drawing, you should always use surface->pitch *
surface->format->BytesPerPixel.–
Patrice Mandin
WWW: http://pmandin.atari.org/
Programmeur Linux, Atari
Sp?cialit?: D?veloppement, jeux

For efficiency reasons, each line in a surface is memory-aligned.
The extra data is unused.

On a PSP:
32bit -> 2048
16bit -> 1024On Sat, Jun 06, 2009 at 10:44:30AM +0200, Hubert Maraszek wrote:

Hello to everyone on the mailing list :slight_smile: I’m happy it’s not dead :slight_smile:

My app creates an 8-bit surface. When surface->pitch is different than
surface->w in bytes?
I had that problem before - I was creating a Meritous port for Sony PSP, for
which SDL is fully ported, even with multitasking. The game had a very
strange way to show strings on a surface: it creates a pointer to
screen->pixels (or however it’s called) and moves it to drawing position,
but instead of moving screen->pitch for each line, it moved screen->w bytes
down. When app was in resolution 640x480, this method was working, but when
I changed to 480x272 (PSP native resolution) the strings were all shattered.
I spent 2 days finding out what was wrong.

So, my question is: When surface->pitch is different than
surface->w*surface->format->BytesPerPixel (it’s multiplying here)? And when
it is different, what data are stored between lines?
Don’t consider this an urgent question, why? because it’s not :slight_smile:

You can find Meritous PSP port almost stable on my website:
http://elementgame.boo.pl/


Sylvain

But 640x480 is NOT a native resolution! 480x272 is and it’s the only surface
hardware-supported on PSP, other resolutions are just scaled down/up to
480x272.
Maybe that difference is because of SDL trying to make a “bytes per
scanline” amount a “round” (in binary, of course) number? (in example: 1024,
640, 16, 65536 etc.)

2009/6/6 Patrice Mandin <mandin.patrice at orange.fr>> Le Sat, 6 Jun 2009 10:44:30 +0200

Hubert Maraszek <@Hubert_Maraszek> a ?crit:

My app creates an 8-bit surface. When surface->pitch is different than
surface->w in bytes?

It is different if SDL can not create a video mode for the width you
asked for (for example if the underlying hardware does nto support it).

I had that problem before - I was creating a Meritous port for Sony PSP,
for
which SDL is fully ported, even with multitasking. The game had a very
strange way to show strings on a surface: it creates a pointer to
screen->pixels (or however it’s called) and moves it to drawing position,
but instead of moving screen->pitch for each line, it moved screen->w
bytes
down. When app was in resolution 640x480, this method was working, but
when
I changed to 480x272 (PSP native resolution) the strings were all
shattered.
I spent 2 days finding out what was wrong.

For example, if the target only provides a 640x480 resolution and you
want 480x272, SDL will give you 640 for pitch (for 8 bits/pixel), and
your 480x272 SDL_Surface screen in reality is only a part of the real
640x480 screen.

So, my question is: When surface->pitch is different than
surface->w*surface->format->BytesPerPixel (it’s multiplying here)? And
when
it is different, what data are stored between lines?

When drawing, you should always use surface->pitch *
surface->format->BytesPerPixel.


Patrice Mandin
WWW: http://pmandin.atari.org/
Programmeur Linux, Atari
Sp?cialit?: D?veloppement, jeux


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Maybe that difference is because of SDL trying to make a
"bytes per scanline" amount a “round”
(in binary, of course) number? (in example: 1024, 640, 16,
65536 etc.)

You’re almost right. I can’t say if it’s identical for PSP (actually, looking at the numbers where 272/4=68, almost certainly not) but on PC the graphics hardware will only accept data that is 4 byte aligned, that is 32 Bit, so the data for every line must be a multiple of 4 bytes in size regardless of whether all that data is actually used. This can make memory transfers 4x faster than if individual bytes were accessed because it costs the same on PC architechture to move one byte as it does to move four as one 32 bit integer. Other colour depths will not automatically line up to a multiple of 4 and so need to be padded out on each line until they do.

What it comes down to is, sometimes to get graphics data aligned and displaying properly you have to pad each line out a bit and while the original width of an image needs to be recorded the padded width is also required to compensate for this padding when you want to access the correct pixel. So, while this does speed up things like blitting whole images you have to access individual pixels as:

(ypitchBytesPerPixel)+x

Or, if you wanted to access the rightmost pixel on a line it could be (someone correct me if I’m wrong):

(ypitchBytesPerPixel)+(width-BytesPerPixel)

hope this helps, Paul— On Sat, 6/6/09, Hubert Maraszek wrote:

Maybe that difference is because of SDL trying to make a
"bytes per scanline" amount a “round”
(in binary, of course) number? (in example: 1024, 640, 16,
65536 etc.)

You’re almost right. I can’t say if it’s identical for PSP (actually,
looking at the numbers where 272/4=68, almost certainly not) but on PC the
graphics hardware will only accept data that is 4 byte aligned, that is 32
Bit, so the data for every line must be a multiple of 4 bytes in size
regardless of whether all that data is actually used. This can make memory
transfers 4x faster than if individual bytes were accessed because it costs
the same on PC architechture to move one byte as it does to move four as
one 32 bit integer. Other colour depths will not automatically line up to a
multiple of 4 and so need to be padded out on each line until they do.

In fact some platforms need the lines to be 64 bit aligned and for cache and
SIMD reasons it is better to set the row alignment as 128 bits.

What it comes down to is, sometimes to get graphics data aligned and
displaying properly you have to pad each line out a bit and while the
original width of an image needs to be recorded the padded width is also
required to compensate for this padding when you want to access the correct
pixel. So, while this does speed up things like blitting whole images you
have to access individual pixels as:

(ypitchBytesPerPixel)+x

This is wrong.

The start of row y is y*pitch bytes from the begining of the pixel data as
pitch is equal to the amount of bytes between two rows of pixel data.

The correct one is ypitch+xbytesPerPixel

Or, if you wanted to access the rightmost pixel on a line it could be
(someone correct me if I’m wrong):

(ypitchBytesPerPixel)+(width-BytesPerPixel)

This would be
y*pitch+(w-1)*bytesPerPixelOn Saturday 06 June 2009 14:09:14 Paul Duffy wrote:

— On Sat, 6/6/09, Hubert Maraszek wrote:

You’re right that I’m wrong. That’s quite embarrasing. I’ve done this the right way before as well (not that I’ve had the time to work on that since last Nov). You’re forgetting operator precedence though, you’re going to get (ypitch)+(xbytesPerPixel).

So if I’m thinking properly I’d probably put ((y*pitch)+x)BytesPerPixel and ((ypitch)+(width-1))*BytesPerPixel.

Yes, I use a lot of brackets. I’ve seen more than one buggy compiler ‘optimise’ the operator precedence putting + before * and so on. Call me Mr. Paranoid if you like :o)

With our powers combined we could be an unstoppable force, we could even be… competent! Oh dear, I’ll go back to bed shall I?— On Sat, 6/6/09, Sami N??t?nen <sn.ml at keijukammari.fi> wrote:

(ypitchBytesPerPixel)+x

This is wrong.

The start of row y is y*pitch bytes from the begining of
the pixel data as
pitch is equal to the amount of bytes between two rows of
pixel data.

The correct one is ypitch+xbytesPerPixel

Or, if you wanted to access the rightmost pixel on a
line it could be
(someone correct me if I’m wrong):

(ypitchBytesPerPixel)+(width-BytesPerPixel)

This would be
y*pitch+(w-1)*bytesPerPixel


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

No, the exprsesion Sami gave is correct.
Don’t forget: pitch is in bytes, not pixels.

John BOn Sat, 2009-06-06 at 17:52 +0000, Paul Duffy wrote:

You’re right that I’m wrong. That’s quite embarrasing. I’ve done this the right way before as well (not that I’ve had the time to work on that since last Nov). You’re forgetting operator precedence though, you’re going to get (ypitch)+(xbytesPerPixel).

So if I’m thinking properly I’d probably put ((y*pitch)+x)BytesPerPixel and ((ypitch)+(width-1))*BytesPerPixel.

You’re right that I’m wrong. That’s quite embarrasing.
I’ve done this the right way before as well (not that I’ve
had the time to work on that since last Nov). You’re
forgetting operator precedence though, you’re going to get
(ypitch)+(xbytesPerPixel).

So if I’m thinking properly I’d probably put
((y*pitch)+x)BytesPerPixel and
((y
pitch)+(width-1))*BytesPerPixel.

No, the exprsesion Sami gave is correct.
Don’t forget: pitch is in bytes, not pixels.

Ah. I had quite forgotten that.

Something’s clear. It has been way too long since I did any of this and my heads too much in pattern matching. Apologies for any confusion.— On Sat, 6/6/09, John Bartholomew wrote:

From: John Bartholomew
Subject: Re: [SDL] surface pitch
To: “A list for developers using the SDL library. (includes SDL-announce)”
Date: Saturday, June 6, 2009, 6:03 PM
On Sat, 2009-06-06 at 17:52 +0000, Paul Duffy wrote: