Locking surfaces

Hi,

I’d like to go without locking every software surface I need to access
directly. I know there’s an SDL_MUSTLOCK() macro, but checking it and then
locking/unlocking wouldn’t help much.

In short, would it be safe to not perform locking on non-RLE-compressed
software surfaces when I’m only reading from them?

Thanks
Drirr C.

“Drirr C.” wrote:

In short, would it be safe to not perform locking on non-RLE-compressed
software surfaces when I’m only reading from them?

Yes, as long as it’s not a screen surface where you use SDL_ASYNCBLIT.
But locking anyway doesn’t cost anything worth speaking about

…except when someone tries to lock/unlock very, very frequently… (As
in once per pixel, while rendering particle effects or lines.) Maybe
that’s the problem?

Simple solution:
* Implement higher level rendering calls.

* Implement array versions for SetPixel() and the like

* Perform only one lock/unlock cycle per function call.

* Make use of recursive locks! (Lock before performing
  a number of rendering calls, and then unlock.)

Sophisticated solution (OpenGL style):
* Make the rendering calls write “comands” into a buffer.

* Implement an "engine" that executes commands from the
  buffer, looping without unlocking or dropping temp
  variables until done.

* Add a "Flush()" call to the API, to make the engine
  render all buffered commands.

There. If you still have a problem with locking/unlocking overhead, I’m
afraid you have to explain it in more detail. :slight_smile:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Tuesday 20 November 2001 19:53, Mattias Engdeg?rd wrote:

“Drirr C.” wrote:

In short, would it be safe to not perform locking on
non-RLE-compressed software surfaces when I’m only reading from them?

Yes, as long as it’s not a screen surface where you use SDL_ASYNCBLIT.
But locking anyway doesn’t cost anything worth speaking about

David Olofson <david.olofson at reologica.se> escribi? en el mensaje de
noticias mailman.1006294867.379.sdl at libsdl.org

…except when someone tries to lock/unlock very, very frequently… (As
in once per pixel, while rendering particle effects or lines.) Maybe
that’s the problem?

[…]

There. If you still have a problem with locking/unlocking overhead, I’m
afraid you have to explain it in more detail. :slight_smile:

Ok, I’m doing a many-to-one blitting (directly accessing the pixel buffers).
I have a template with “indices” (well, kinda) into the surfaces I must
blit from. So for each pixel I copy I must check the index in the template.
There are some runs in the template which refer to the same surface, so I
exploit coherence there.

BTW, I cannot know beforehand which images the template makes reference to.
so I cannot lock all the surfaces at once. I could go through the template
to see which images I’d be blitting from, but getting the “indices” from the
template is not straightforward, so it wouldn’t help.

The source surfaces are software, non RLE encoded surfaces, and the
destination surface is whatever I get from SDL_SetVideoMode() with
SDL_DOUBLEBUF

So, if I could just lock the “screen” surface and assume there will be no
problems with reading from the source surfaces it would help much.

So far i’ve done it like this and it hasn’t given me problems, but I don’t
know how stable that could be.

Thanks again for the help =)
Drirr C.On Tuesday 20 November 2001 19:53, Mattias Engdeg?rd wrote:

David Olofson <david.olofson at reologica.se> escribi? en el mensaje de
noticias mailman.1006294867.379.sdl at libsdl.org

…except when someone tries to lock/unlock very, very frequently…
(As in once per pixel, while rendering particle effects or lines.)
Maybe that’s the problem?

[…]

There. If you still have a problem with locking/unlocking overhead,
I’m afraid you have to explain it in more detail. :slight_smile:

Ok, I’m doing a many-to-one blitting (directly accessing the pixel
buffers). I have a template with “indices” (well, kinda) into the
surfaces I must blit from. So for each pixel I copy I must check the
index in the template. There are some runs in the template which refer
to the same surface, so I exploit coherence there.

Ok… I suspect you may be getting a great deal of cache misses due to
all this dereferencing of pointers/indices, but maybe there’s no sensible
way around it. What are you doing? :slight_smile:

Anyway, yeah, as long as the source surfaces are fully under your control
(ie you create them as software surfaces, and make sure they don’t get
RLE encoded somewhere), it should be safe to drop the surface locking.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Wednesday 21 November 2001 01:25, Drirr C. wrote:

On Tuesday 20 November 2001 19:53, Mattias Engdeg?rd wrote:

I didn’t write that. Be careful with your attributions.>On Tuesday 20 November 2001 19:53, Mattias Engdeg?rd wrote:

…except when someone tries to lock/unlock very, very frequently… (As
in once per pixel, while rendering particle effects or lines.) Maybe
that’s the problem?

David Olofson <david.olofson at reologica.se> escribi? en el mensaje de
noticias mailman.1006303987.4466.sdl at libsdl.org

Ok… I suspect you may be getting a great deal of cache misses due to
all this dereferencing of pointers/indices, but maybe there’s no sensible
way around it. What are you doing? :slight_smile:

The first time I use painter’s algorithm to blit the surfaces, but also
create a template with the surface visibility at each point, so the next
time I have to blit on the same place I know what is visible and what isn’t.

I guess I must be getting lot’s of cache misses, but even then it’s way
faster than using painter’s algorithm, which in my case repaints each pixel
about three times.

yes… yes… I know there are other techniques like recursive blitting from
front to back, s-buffers, etc… :wink:

Anyway, yeah, as long as the source surfaces are fully under your control
(ie you create them as software surfaces, and make sure they don’t get
RLE encoded somewhere), it should be safe to drop the surface locking.

Ok, thanks

BTW, being rather new to posting in this newsgroup I wonder… is this post
off-topic enough so as not to have been posted in the first place?

Drirr C.

David Olofson <david.olofson at reologica.se> escribi? en el mensaje de
noticias mailman.1006303987.4466.sdl at libsdl.org

Ok… I suspect you may be getting a great deal of cache misses due to
all this dereferencing of pointers/indices, but maybe there’s no
sensible way around it. What are you doing? :slight_smile:

The first time I use painter’s algorithm to blit the surfaces, but also
create a template with the surface visibility at each point, so the
next time I have to blit on the same place I know what is visible and
what isn’t.

I guess I must be getting lot’s of cache misses, but even then it’s way
faster than using painter’s algorithm, which in my case repaints each
pixel about three times.

Probably - at least if you’re writing directly to VRAM.

yes… yes… I know there are other techniques like recursive blitting
from front to back, s-buffers, etc… :wink:

Anyway, yeah, as long as the source surfaces are fully under your
control (ie you create them as software surfaces, and make sure they
don’t get RLE encoded somewhere), it should be safe to drop the
surface locking.

Ok, thanks

BTW, being rather new to posting in this newsgroup I wonder… is this
post off-topic enough so as not to have been posted in the first place?

Don’t know about the rendering algorithms stuff, but the “To lock, or not
not to lock” question is definitely SDL related. Probably bordering to an
FAQ - but then again, I don’t know if there is a clear enough answer in
any FAQ. (The stardard “Always lock/unlock” or "check SDL_MUSTLOCK()"
methods are sufficient in most cases.)

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Wednesday 21 November 2001 18:20, Drirr C. wrote:

Just as a sidenote, something I found out that might be useful to someone.
(and which many must know already)

If the surface needs locking, (like a hardware double buffer), you not only
cannot read/write from surface->pixels, but the address of surface->pixels
might as well be invalid

say, if you have:

p = (Uint16*)(surface->pixels);
SDL_LockSurface( surface );
*p = 0x0000;

Chances are it not work, as “p” could have the wrong address of the real
buffer.

Internally SDL has an offset which gets added to surface->pixels when the
surface is locked and gets substracted again when unlocked, something one
normally doesn’t need to care about but is good to know.

I presume (read: I could be completelly wrong here) that’s used when
splitting the video memory in several screens.

Drirr C.

If the surface needs locking, (like a hardware double buffer), you not only
cannot read/write from surface->pixels, but the address of surface->pixels
might as well be invalid

say, if you have:

p = (Uint16*)(surface->pixels);
SDL_LockSurface( surface );
*p = 0x0000;

Chances are it not work, as “p” could have the wrong address of the real
buffer.

Internally SDL has an offset which gets added to surface->pixels when the
surface is locked and gets substracted again when unlocked, something one
normally doesn’t need to care about but is good to know.

I presume (read: I could be completelly wrong here) that’s used when
splitting the video memory in several screens.

It’s actually for centering video modes when the display driver can’t
set the real display mode as low as the one requested.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment