When should I *NOT* release a DrawingSurface?

Started by Monsieur OUXX, Wed 28/10/2015 13:23:19

Previous topic - Next topic

Monsieur OUXX

Hello,
I've been using DrawingSurfaces for quite a long time, doing sometimes complex stuff, without asking myself too many questions: Just get the surface, draw onto it, then release it!

But I'm actually curious about scenarios where the surface has been released too early or too late. Do such scenarios exist? Is there such a thing as "releasing a surface too early" or "too late"?
For example, I've successfully managed to do this: 1. Get the drawingSurface of a sprite, 2. Draw things, 3. Draw that sprite into another DrawingSurface before releasing its surface. It works, apparently.

2. Also, out of curiosity: when you get the surface, does it copy stuff or does it just create a pointer to its data? Is GetDrawingSurface resources intensive?
 

Crimson Wizard

#1
Quote from: Monsieur OUXX on Wed 28/10/2015 13:23:19
For example, I've successfully managed to do this: 1. Get the drawingSurface of a sprite, 2. Draw things, 3. Draw that sprite into another DrawingSurface before releasing its surface. It works, apparently.
Of course it does. Multuple drawing surfaces can be created at the same time (there is some limit but it is arbitrary, I think).
The sprite is in no way connected to drawing surface (except if you create one of it), so it can be drawn anywhere, it does not make any difference.


Quote from: Monsieur OUXX on Wed 28/10/2015 13:23:19
2. Also, out of curiosity: when you get the surface, does it copy stuff or does it just create a pointer to its data? Is GetDrawingSurface resources intensive?
Drawing surface has a pointer to data and makes no copies itself. This is simply a reference to something you can draw upon.
However, AGS internally may need to convert raw bitmaps into Direct3D textures. It does so after DrawingSurface is released. That is why you won't see any changes in Direct3D mode until you call Release.


EDIT: There is DrawingSurface.CreateCopy() function that actually creates a copy of original bitmap.

Monsieur OUXX

I'm still a bit confused.

Quote from: Crimson Wizard on Wed 28/10/2015 14:37:46
The sprite is in no way connected to drawing surface (except if you create one of it)
Except if I create a what of what? If I create a DrawingSurface of the Sprite, or a Sprite of the Drawing Surface?

Quote from: Crimson Wizard on Wed 28/10/2015 14:37:46
AGS internally may need to convert raw bitmaps into Direct3D textures. It does so after DrawingSurface is released. That is why you won't see any changes in Direct3D mode until you call Release.
What you're saying is that for its internal workings AGS will ignore any Surface modification until rendering time because it needs to convert it to texture before displaying it, right? But I can still copy and paste and draw DrawingSurfaces as much as I want before the end of the cycle, without worrying about texture conversions, right?

 

Crimson Wizard

#3
Quote from: Monsieur OUXX on Wed 28/10/2015 16:19:27
Quote from: Crimson Wizard on Wed 28/10/2015 14:37:46
The sprite is in no way connected to drawing surface (except if you create one of it)
Except if I create a what of what? If I create a DrawingSurface of the Sprite, or a Sprite of the Drawing Surface?
Except if you create DrawingSurface from sprite, of course, because in this way you will be drawing over sprite, and DrawingSurface will be connected to sprite...
And you cannot create Sprite of DrawingSurface.
Anyway, this is unrelated to original question.



Quote from: Monsieur OUXX on Wed 28/10/2015 16:19:27
Quote from: Crimson Wizard on Wed 28/10/2015 14:37:46
AGS internally may need to convert raw bitmaps into Direct3D textures. It does so after DrawingSurface is released. That is why you won't see any changes in Direct3D mode until you call Release.
What you're saying is that for its internal workings AGS will ignore any Surface modification until rendering time because it needs to convert it to texture before displaying it, right? But I can still copy and paste and draw DrawingSurfaces as much as I want before the end of the cycle, without worrying about texture conversions, right?
AGS won't "ignore modification until rendering time". It will ignore modifications until you release drawing surface. It may render many times in between, but your modifications are not guaranteed to be included in render until you call Release.

Monsieur OUXX

Quote from: Crimson Wizard on Wed 28/10/2015 16:33:33
It will ignore modifications until you release drawing surface. It may render many times in between, but your modifications are not guaranteed to be included in render until you call Release.
OK that's what I was worried about. So that means the scenario I described before (which I'm doing in my script) is hazardous:
1. Get the drawingSurface of a sprite "mySprite", 2. Draw things onto that surface, 3. Draw "MySprite" into something else (for example, onto another drawing surface: ds.DrawImage(0,0,mySprite.Graphic)) before releasing its surface.
You're saying that this might work but not always. OK.
To be honest I'm just afraid to release the DrawingSurface as often as I should just because of performance concerns.

 

Crimson Wizard

#5
Quote from: Monsieur OUXX on Thu 29/10/2015 08:57:51
OK that's what I was worried about. So that means the scenario I described before (which I'm doing in my script) is hazardous:
1. Get the drawingSurface of a sprite "mySprite", 2. Draw things onto that surface, 3. Draw "MySprite" into something else (for example, onto another drawing surface: ds.DrawImage(0,0,mySprite.Graphic)) before releasing its surface.
You're saying that this might work but not always.
Well, in theory it is not guaranteed to work, in practice this should work, because the sprite is a raw bitmap, and updated instantly as you draw on it. So when you copy the sprite on something else, it will copy modified version of sprite.
However, this is strongly relied on internal implementation of the engine. I would say you should not do that simply in sake of correctness. If something changes in the engine regarding internal work of drawing surfaces, your game is screwed...

Quote from: Monsieur OUXX on Thu 29/10/2015 08:57:51
To be honest I'm just afraid to release the DrawingSurface as often as I should just because of performance concerns.
Mmmm... this is not a proper way of thinking. If some function has to be called in time, then it should be called in time. If you have perfomance concerns, you might try changing the overall algorythm, but you should not use hacks that work simply because of coincidence.
Regarding perfomance, DrawingSurface.Release cause texture to be updated only if the image is currently a part of the visible object on screen. If it is just a dynamic sprite you use as intermediate buffer (as seems by your example), then it will never be created into 3d texture.

Textures are created only for bitmaps that has to be displayed on screen (room backgrounds, view frames, overlays, gui gfx).

Monsieur OUXX

Quote from: Crimson Wizard on Thu 29/10/2015 09:45:54
DrawingSurface.Release cause texture to be updated only if the image is currently a part of the visible object on screen. If it is just a dynamic sprite you use as intermediate buffer (as seems by your example), then it will never be created into 3d texture. Textures are created only for bitmaps that has to be displayed on screen (room backgrounds, view frames, overlays, gui gfx).

Well then it's all god because it is indeed a temporary buffer.
Hurray! Thanks for your answers.
 

SMF spam blocked by CleanTalk