# Patch for sub surfaces

**URL:** <https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300>\
**Category:** SDL Development\
**Created:** [June 22, 2005, 11:48pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300 "2005-06-22T23:48:24Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ben\_Campbell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/ben_campbell/32/102_2.png) [@Ben\_Campbell](https://discourse.libsdl.org/u/Ben_Campbell)\
**Post date:** [June 22, 2005, 11:48pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/1 "2005-06-22T23:48:24Z")

</div>

All the talk of implementing multiple windows got me thinking again  
about a feature of SDL I always thought would be cool - the ability to  
create surfaces which were really just sub-rectangles of other surfaces.  
Great for split-screen multiplayer support!

I think allegro has this feature - at least it did 10 years ago when I  
was using it on DOS, and I really liked it. Seemed lovely and elegant.

Anyway, I’ve attached a patch (against the latest from CVS) and a noddy  
little demo program.

The patch implements an extra surface flag (SDL\_SUBSURFACE), three extra  
fields in SDL\_Surface (uhoh!), and a new API call: SDL\_CreateSubSurface().

I _think_ it maintains binary compatibility. As long as apps use SDL to  
allocate and free surfaces, then the extra fields on SDL\_Surface  
shouldn’t be a problem. And even if an app _does_ alloc it’s own  
SDL\_Surface structs on the heap or stack, SDL wouldn’t ever attempt to  
read the (missing) extra fields unless the SDL\_SUBSURFACE flag is set…  
(actually I think my patch might need a slight tweak to ensure this).  
I don’t think adding a new API call to the library breaks binary  
compatibility, but I could be wrong about that…

Anyway, I don’t have any particular vested interest in this feature (not  
doing any split-screen games at the moment :-). I just thought it’d be  
fun to implement, so I’m not too worried or offended if it falls in the  
bit bucket.  
But hopefully someone might find it useful!

docs for the new API call:----------------------------------------------------  
Synopsis:

SDL\_Surface \*SDL\_CreateSubSurface( SDL\_Surface \*parent, const SDL\_Rect  
\*area );

Description:

Creates a surface which is really just an sub-area of a parent surface.  
The subsurface is like a window on to the parent. Drawing to the subsurface  
draws directly to the parent.

If a parent surface is the screen, then the subsurface can also be  
treated as  
a screen. That is, SDL\_UpdateRect() SDL\_UpdateRects() should work as  
expected  
on a subsurface of the screen (internally, the rectangles will be mapped to  
the screen).

## Subsurfaces have the internal flags SDL\_SUBSURFACE and SDL\_PREALLOC set. Relevant fields in SDL\_Surface: parent: points to the parent surface parent\_x: x position of subsurface on the parent parent\_y: y position of subsurface on the parent

## Ben.

[http://www.scumways.com](http://www.scumways.com)

-------------- next part --------------  
A non-text attachment was scrubbed…  
Name: subsurface.patch  
Type: text/x-patch  
Size: 5389 bytes  
Desc: not available  
URL: [http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050622/5e62b9f5/attachment.bin](http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050622/5e62b9f5/attachment.bin)  
-------------- next part --------------  
A non-text attachment was scrubbed…  
Name: subsurfacetest.c  
Type: text/x-csrc  
Size: 1410 bytes  
Desc: not available  
URL: [http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050622/5e62b9f5/attachment.c](http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050622/5e62b9f5/attachment.c)

---

<div class="post-metadata">

**Author:** ![Gabriel\_Gambetta](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/gabriel_gambetta/32/4004_2.png) [@Gabriel\_Gambetta](https://discourse.libsdl.org/u/Gabriel_Gambetta)\
**Post date:** [June 22, 2005, 11:52pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/2 "2005-06-22T23:52:03Z")

</div>

> All the talk of implementing multiple windows got me thinking again  
> about a feature of SDL I always thought would be cool - the ability to  
> create surfaces which were really just sub-rectangles of other surfaces.  
> Great for split-screen multiplayer support!

I’ve been using sub-surfaces for ages with plain SDL… I just use  
SDL\_CreateRGBSurfaceFrom() using a pointer to the parent surface data. I  
haven’t found a single problem… does your patch address any  
shortcoming I’m not aware of?

```
    --Gabriel

```

---

<div class="post-metadata">

**Author:** ![icculus](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/icculus/32/81_2.png) [@icculus](https://discourse.libsdl.org/u/icculus)\
**Post date:** [June 23, 2005, 12:31am UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/3 "2005-06-23T00:31:48Z")

</div>

> I’ve been using sub-surfaces for ages with plain SDL… I just use  
> SDL\_CreateRGBSurfaceFrom() using a pointer to the parent surface data. I  
> haven’t found a single problem… does your patch address any  
> shortcoming I’m not aware of?

It doesn’t accomplish anything that you can’t already do with SDL’s  
clipping rectangles, but it does make the subsurface look like it starts  
at coordinates (0,0), which can simplify some app logic.

I don’t know that it makes it something to add to the API, but it’s nice  
that the patch is out there for people that need it.

–ryan.

---

<div class="post-metadata">

**Author:** ![Gabriel\_Gambetta](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/gabriel_gambetta/32/4004_2.png) [@Gabriel\_Gambetta](https://discourse.libsdl.org/u/Gabriel_Gambetta)\
**Post date:** [June 23, 2005, 3:27am UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/4 "2005-06-23T03:27:11Z")

</div>

El mi?, 22-06-2005 a las 20:31 -0400, Ryan C. Gordon escribi?:

> > I’ve been using sub-surfaces for ages with plain SDL… I just use  
> > SDL\_CreateRGBSurfaceFrom() using a pointer to the parent surface data. I  
> > haven’t found a single problem… does your patch address any  
> > shortcoming I’m not aware of?
> 
> It doesn’t accomplish anything that you can’t already do with SDL’s  
> clipping rectangles, but it does make the subsurface look like it starts  
> at coordinates (0,0), which can simplify some app logic.

I’m not sure I understand what you mean… without the patch, and with  
just SDL\_CreateRGBSurfaceFrom(), I can use sub-surfaces that start at  
(0,0).

---

<div class="post-metadata">

**Author:** ![Ben\_Campbell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/ben_campbell/32/102_2.png) [@Ben\_Campbell](https://discourse.libsdl.org/u/Ben_Campbell)\
**Post date:** [June 23, 2005, 7:57am UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/5 "2005-06-23T07:57:36Z")

</div>

Gabriel wrote:

> El mi?, 22-06-2005 a las 20:31 -0400, Ryan C. Gordon escribi?:
> 
> > > I’ve been using sub-surfaces for ages with plain SDL… I just use  
> > > SDL\_CreateRGBSurfaceFrom() using a pointer to the parent surface data. I  
> > > haven’t found a single problem… does your patch address any  
> > > shortcoming I’m not aware of?
> > 
> > It doesn’t accomplish anything that you can’t already do with SDL’s  
> > clipping rectangles, but it does make the subsurface look like it starts  
> > at coordinates (0,0), which can simplify some app logic.
> 
> I’m not sure I understand what you mean… without the patch, and with  
> just SDL\_CreateRGBSurfaceFrom(), I can use sub-surfaces that start at  
> (0,0).

It means you can create subsurfaces which start at some offset within a  
larger parent surface, and can have a smaller width and height. With  
CreateRGBSurfaceFrom(), the new surface addresses the entire area of the  
parent.  
Also, if the parent is the screen, you can treat the subsurface as if it  
were a screen, and call the updaterect functions on it.

Like Ryan said, it’s nothing that can’t be achieved with clipping  
rectangles and offsets. But I like the idea that you can set up multiple  
viewports, and use the exact same drawing code for each one. The drawing  
code can assume it’s got the whole screen to itself.

Ben.

---

<div class="post-metadata">

**Author:** ![icculus](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/icculus/32/81_2.png) [@icculus](https://discourse.libsdl.org/u/icculus)\
**Post date:** [June 23, 2005, 2:39pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/6 "2005-06-23T14:39:19Z")

</div>

> I’m not sure I understand what you mean… without the patch, and with  
> just SDL\_CreateRGBSurfaceFrom(), I can use sub-surfaces that start at  
> (0,0).

Yes, but it’s a whole seperate block of memory that takes up seperate  
resources and would need to be blitted back to the original surface if  
you wanted to update the original.

–ryan.

---

<div class="post-metadata">

**Author:** ![Tyler\_Montbriand](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/t/7bcc69/32.png) [@Tyler\_Montbriand](https://discourse.libsdl.org/u/Tyler_Montbriand)\
**Post date:** [June 23, 2005, 4:25pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/7 "2005-06-23T16:25:42Z")

</div>

If it’s not in the API, people can’t really use it without custom-building  
their own SDL; which isn’t a barrier for you, but rules out lots of  
developers and _all_ commercial SDL programmers. Some of it could be done  
with a library, but not all of it, especially not the intelligent reference  
counting.

Could it at least be considered for SDL 1.3? Seldom have I seen an addition  
so simple and elegant.On June 22, 2005 06:31 pm, Ryan C. Gordon wrote:

> It doesn’t accomplish anything that you can’t already do with SDL’s  
> clipping rectangles, but it does make the subsurface look like it starts  
> at coordinates (0,0), which can simplify some app logic.
> 
> I don’t know that it makes it something to add to the API, but it’s nice  
> that the patch is out there for people that need it.

---

<div class="post-metadata">

**Author:** ![Drake\_Wilson](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/d/8e7dd6/32.png) [@Drake\_Wilson](https://discourse.libsdl.org/u/Drake_Wilson)\
**Post date:** [June 23, 2005, 4:33pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/8 "2005-06-23T16:33:21Z")

</div>

Quoth “Ryan C. Gordon” , on 2005-06-23 10:39:19 -0400:

> Yes, but it’s a whole seperate block of memory that takes up seperate  
> resources and would need to be blitted back to the original surface if  
> you wanted to update the original.

Firstly, from the manpage of SDL\_CreateRGBSurfaceFrom:

```
The data stored in pixels is assumed to be of the depth specified in
the parameter list. The pixel data is not copied into the SDL_Surface
structure so it should not be freed until the surface has been freed
with a called to SDL_FreeSurface. pitch is the length of each scanline
in bytes.

```

Secondly, wasn’t the reference to SDL\_CreateRGBSurfaceFrom a reference  
to using different widths, heights, pitches, and offsets into the  
original pixels array to create displaced subsurfaces that act like  
they’re ordinay surfaces but just happen to share the same block of  
memory?

Perhaps I’m just misunderstanding something…

—\> Drake Wilson

-------------- next part --------------  
A non-text attachment was scrubbed…  
Name: not available  
Type: application/pgp-signature  
Size: 189 bytes  
Desc: Digital signature  
URL: [http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050623/5b6dcca9/attachment.pgp](http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050623/5b6dcca9/attachment.pgp)

---

<div class="post-metadata">

**Author:** ![icculus](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/icculus/32/81_2.png) [@icculus](https://discourse.libsdl.org/u/icculus)\
**Post date:** [June 23, 2005, 5:31pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/9 "2005-06-23T17:31:24Z")

</div>

> Could it at least be considered for SDL 1.3? Seldom have I seen an addition  
> so simple and elegant.

Well, obviously this is Sam’s call…I didn’t mean to sound like the  
authority here.

–ryan.

---

<div class="post-metadata">

**Author:** ![Gabriel\_Gambetta](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/gabriel_gambetta/32/4004_2.png) [@Gabriel\_Gambetta](https://discourse.libsdl.org/u/Gabriel_Gambetta)\
**Post date:** [June 23, 2005, 5:45pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/10 "2005-06-23T17:45:18Z")

</div>

El jue, 23-06-2005 a las 07:57 +0000, Ben Campbell escribi?:

> It means you can create subsurfaces which start at some offset within a  
> larger parent surface, and can have a smaller width and height. With  
> CreateRGBSurfaceFrom(), the new surface addresses the entire area of the  
> parent.

El jue, 23-06-2005 a las 10:39 -0400, Ryan C. Gordon escribi?:

> Yes, but it’s a whole seperate block of memory that takes up seperate  
> resources and would need to be blitted back to the original surface if  
> you wanted to update the original.

No, no, believe me, I use SDL\_CreateRGBSurfaceFrom() to create surfaces  
that a) start at any offset within the parent surface, b) have any width  
and height (that fits inside the parent, of course), c) share memory  
with the parent… here’s the code :-----  
(the parameters are pParent, nTop, nLeft, nWidth, nHeight)

SDL\_LockSurface(pParent);

byte\* pPixels = (byte\*)pParent-\>pixels + pParent-\>pitch\*nTop + pParent-

> format-\>BytesPerPixel \* nLeft;

m\_pSurface = SDL\_CreateRGBSurfaceFrom(pPixels, nWidth, nHeight, pParent-

> format-\>BitsPerPixel, pParent-\>pitch, pParent-\>format-\>Rmask, pParent-  
> format-\>Gmask, pParent-\>format-\>Bmask, pParent-\>format-\>Amask);

if (pParent-\>format-\>palette)  
SDL\_SetColors(m\_pSurface, pParent-\>format-\>palette-\>colors, 0, pParent-

> format-\>palette-\>ncolors);

## SDL\_UnlockSurface(pParent);

---

<div class="post-metadata">

**Author:** ![Ben\_Campbell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/ben_campbell/32/102_2.png) [@Ben\_Campbell](https://discourse.libsdl.org/u/Ben_Campbell)\
**Post date:** [June 23, 2005, 6:02pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/11 "2005-06-23T18:02:52Z")

</div>

Drake Wilson wrote:

> Secondly, wasn’t the reference to SDL\_CreateRGBSurfaceFrom a reference  
> to using different widths, heights, pitches, and offsets into the  
> original pixels array to create displaced subsurfaces that act like  
> they’re ordinay surfaces but just happen to share the same block of  
> memory?

I hadn’t really thought of using CreateRGBSurfaceFrom() like that, but  
yeah I think you’re right.  
The benefits of my patch are:

1. more obvious interface (caller doesn’t need to calculate the pixel  
address, or pass in bitmasks)
2. you can call SDL\_UpdateRect[s] directly on a subsurface of the  
screen, whereas with CreateRGBSurfaceFrom() you have to map the  
rectangles back onto the screen yourself.
3. the subsurface stores it’s xy offset relative to the parent (in the  
new parent\_x and parent\_y fields) which is handy when, say, mapping  
mouse event positions from the screen to the subsurface. Minor benefit,  
but means the app doesn’t have to keep track of that kind of thing  
itself - all the info you need is in the surface.

Ben.

---

<div class="post-metadata">

**Author:** ![icculus](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/icculus/32/81_2.png) [@icculus](https://discourse.libsdl.org/u/icculus)\
**Post date:** [June 23, 2005, 7:12pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/12 "2005-06-23T19:12:40Z")

</div>

> No, no, believe me, I use SDL\_CreateRGBSurfaceFrom() to create surfaces  
> that a) start at any offset within the parent surface, b) have any width  
> and height (that fits inside the parent, of course), c) share memory  
> with the parent… here’s the code :

Oh, I see what you’re saying. Just a note:

SDL\_UnlockSurface(pParent);

The subsurface’s pixel data might be gone when you unlock the parent’s  
surface. This will work if you guarantee that SDL\_MUSTLOCK(pParent) is  
false (i.e. - it’s never a hardware surface)…but having to lock a  
surface means you’re temporarily copying it to memory for byte-level  
manipulation and ditching that memory block after the unlock is complete.

Without heavy examination of the Subsurface patch, I assume they’ll have  
the same issue, or they just fail to create if the parent has the  
SDL\_HWSURFACE flag.

–ryan.

---

<div class="post-metadata">

**Author:** ![icculus](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/icculus/32/81_2.png) [@icculus](https://discourse.libsdl.org/u/icculus)\
**Post date:** [June 23, 2005, 7:16pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/13 "2005-06-23T19:16:04Z")

</div>

> Secondly, wasn’t the reference to SDL\_CreateRGBSurfaceFrom a reference  
> to using different widths, heights, pitches, and offsets into the  
> original pixels array to create displaced subsurfaces that act like  
> they’re ordinay surfaces but just happen to share the same block of  
> memory?

I just figured it was for creating a surface when you’ve already  
allocated a memory buffer yourself (say, because some image library  
decompressed to a memory buffer and then you later want to create a  
surface around it).

> Perhaps I’m just misunderstanding something…

I misread the first mail. Most of the confusion is my fault. 🙂

–ryan.

---

<div class="post-metadata">

**Author:** ![Ben\_Campbell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/ben_campbell/32/102_2.png) [@Ben\_Campbell](https://discourse.libsdl.org/u/Ben_Campbell)\
**Post date:** [June 23, 2005, 7:58pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/14 "2005-06-23T19:58:08Z")

</div>

Ryan C. Gordon wrote:

> Oh, I see what you’re saying. Just a note:
> 
> SDL\_UnlockSurface(pParent);
> 
> The subsurface’s pixel data might be gone when you unlock the parent’s  
> surface. This will work if you guarantee that SDL\_MUSTLOCK(pParent) is  
> false (i.e. - it’s never a hardware surface)…but having to lock a  
> surface means you’re temporarily copying it to memory for byte-level  
> manipulation and ditching that memory block after the unlock is complete.
> 
> Without heavy examination of the Subsurface patch, I assume they’ll have  
> the same issue, or they just fail to create if the parent has the  
> SDL\_HWSURFACE flag.

I think you’re right. My patch does increment the refcount of the parent  
surface, but I guess refers only to the surface struct itself and not  
the pixeldata.

Ben.

---

<div class="post-metadata">

**Author:** ![Gabriel\_Gambetta](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/gabriel_gambetta/32/4004_2.png) [@Gabriel\_Gambetta](https://discourse.libsdl.org/u/Gabriel_Gambetta)\
**Post date:** [June 23, 2005, 8:23pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/15 "2005-06-23T20:23:28Z")

</div>

El jue, 23-06-2005 a las 15:12 -0400, Ryan C. Gordon escribi?:

> SDL\_UnlockSurface(pParent);
> 
> The subsurface’s pixel data might be gone when you unlock the parent’s  
> surface. This will work if you guarantee that SDL\_MUSTLOCK(pParent) is  
> false (i.e. - it’s never a hardware surface)…

You’re right. I guess it works in my case because I don’t use hardware  
surfaces. And I do the refcount management on a higher level (ie a  
parent is never deallocated before its children)

```
    --Gabriel

```

---

<div class="post-metadata">

**Author:** ![Bob\_Pendleton](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/b/9de053/32.png) [@Bob\_Pendleton](https://discourse.libsdl.org/u/Bob_Pendleton)\
**Post date:** [June 23, 2005, 8:28pm UTC](https://discourse.libsdl.org/t/patch-for-sub-surfaces/12300/16 "2005-06-23T20:28:15Z")

</div>

> > Could it at least be considered for SDL 1.3? Seldom have I seen an addition  
> > so simple and elegant.
> 
> Well, obviously this is Sam’s call…I didn’t mean to sound like the  
> authority here.

Ya’know… I personally would object to this one just because of the  
questions it would generate on the mailing list. How many times are we  
going to see questions about using sub-sufaces in OpenGL and so on. Not  
to mention how easy it is to do with clipping rectangles and the create  
surface from hack…

Ok, I know I am being a curmudgeon, but some features create more  
problems than they are worth.

```
	Bob PendletonOn Thu, 2005-06-23 at 13:31 -0400, Ryan C. Gordon wrote:

```

> –ryan.
> 
> * * *
> 
> SDL mailing list  
> SDL at [libsdl.org](http://libsdl.org)  
> [http://www.libsdl.org/mailman/listinfo/sdl](http://www.libsdl.org/mailman/listinfo/sdl)

–  
±-------------------------------------+

- Bob Pendleton: writer and programmer +
- email: Bob at [Pendleton.com](http://Pendleton.com) +
- web: [www.GameProgrammer.com](http://www.GameProgrammer.com) +
- [www.Wise2Food.com](http://www.Wise2Food.com) +
- nutrient info on 6,000+ common foods +  
±-------------------------------------+
