Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Draw Optimizations  (Read 6017 times)

0 Members and 1 Guest are viewing this topic.

vidjogamer

  • Jr. Member
  • **
  • Posts: 67
    • View Profile
Draw Optimizations
« on: February 06, 2011, 06:31:34 pm »
Hi. I am running on a macbook pro with these specs:

Hardware Overview:

  Model Name:   MacBook Pro
  Model Identifier:   MacBookPro5,5
  Processor Name:   Intel Core 2 Duo
  Processor Speed:   2.26 GHz
  Number Of Processors:   1
  Total Number Of Cores:   2
  L2 Cache:   3 MB
  Memory:   2 GB
  Bus Speed:   1.07 GHz
 
NVIDIA GeForce 9400M:

  Chipset Model:   NVIDIA GeForce 9400M
  Type:   GPU
  Bus:   PCI
  VRAM (Total):   256 MB
  Vendor:   NVIDIA (0x10de)
  Device ID:   0x0863
  Revision ID:   0x00b1
  ROM Revision:   3427
  Displays:
Color LCD:
  Resolution:   1280 x 800
  Pixel Depth:   32-Bit Color (ARGB8888)
  Main Display:   Yes
  Mirror:   Off
  Online:   Yes
  Built-In:   Yes
Display Connector:
  Status:   No Display Connected



I am experiencing slow down after drawing about 2300 16x16 pixel tiles to the screen. I wanted to know if this is normal. Is there anything I can do to speed this up?

This is the code im using right now. Im looping through all the tiles that need drawn and doing this for each one.

Quote
Image *src = tileLayers->image;

int left = tile->tx;
int right = left + 16;
int top = tile->ty;
int bottom = tile->ty + 16;

Sprite sprite;
sprite.SetImage(*src);

sprite.SetSubRect(IntRect( left, top, right, bottom));
sprite.SetX(tile->x*PTM_RATIO);
sprite.SetY(tile->y*PTM_RATIO);

renderWindow->Draw(sprite);



Is there a better way to do this? Would it be faster to draw everything to an image and then just call RenderWindow::Draw() once?

My time profiler tells me im spending
15.4% of my time in glrCompExecuteKernel
10.1% in gldCopyTexSubImage
6.2% in gleUpdateDeferredState
3.4% in gleUpdateFragmentStateProgram

Any help is very appreciated. Thx =)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Draw Optimizations
« Reply #1 on: February 06, 2011, 06:41:22 pm »
First, why don't you store sprites directly? Here you store tile info, and then you translate it to a sprite every time you want to draw the tile. Sprites are meant to be prepared at init, then stored and drawn. Otherwise I would have made a function such as Draw(position, image, subrect, ...) ;)

Doing this will help a little bit but probably not enough. Switching to SFML 2 will help much more. It will be even better in the final version.
Laurent Gomila - SFML developer

vidjogamer

  • Jr. Member
  • **
  • Posts: 67
    • View Profile
Draw Optimizations
« Reply #2 on: February 06, 2011, 07:26:01 pm »
Thanks for the speedy reply. You're completely right. I should be storing sprites directly.

Im curious what the bottleneck for drawing is. Would using bigger tiles make any improvement? Is there anything I can do on my part to optimize?

How stable is SFML 2.0? I need to be able to run on windows/linux/mac. Do you have benchmarks for how much faster it is?

Also when drawing zoomed tiles, SFML blurs the pixels. Is there a way to zoom without blur?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Draw Optimizations
« Reply #3 on: February 06, 2011, 07:39:17 pm »
Quote
Im curious what the bottleneck for drawing is

The number of driver calls, much more than all other possible bottlenecks. SFML makes a lot of them, because everything is fully dynamic. SFML 2 reduces the number of OpenGL calls by using an internal state cache.

Quote
Would using bigger tiles make any improvement?

According to what I said first, no.

Quote
Is there anything I can do on my part to optimize?

Not much, SFML is designed so that there's only one (good) way to do things.

Quote
How stable is SFML 2.0? I need to be able to run on windows/linux/mac

Everything that is implemented works pretty well. The only thing that is not stable is the graphics API (I mean the public classes and functions, not the implementation), which will probably change before the public release.

Quote
Do you have benchmarks for how much faster it is?

It depends on too many things. But basically, if you're storing all your tiles in a single sf::Image, you'll get a pretty good improvement.

Quote
Also when drawing zoomed tiles, SFML blurs the pixels. Is there a way to zoom without blur?

Code: [Select]
tileImage.SetSmooth(false);
Laurent Gomila - SFML developer

Spodi

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • http://www.netgore.com/
Draw Optimizations
« Reply #4 on: February 07, 2011, 03:38:07 pm »
When porting directly from SFML 1.6 to 2.0, I don't remember there being much of a speed increase (though I wasn't exactly looking for it). The important performance considerations from 2.0 come from a design aspect. For instance, 2.0 lets you render directly to textures, which for me meant both huge performance increases and a lot more options.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Draw Optimizations
« Reply #5 on: February 07, 2011, 04:07:09 pm »
Quote
When porting directly from SFML 1.6 to 2.0, I don't remember there being much of a speed increase (though I wasn't exactly looking for it)

Yeah, it depends on what you draw. You have maximum improvement if you draw a lot of consecutive sprites from the same image (tileset, particle system, GUI, etc.). But you won't see much difference if you have several different images
Laurent Gomila - SFML developer

vidjogamer

  • Jr. Member
  • **
  • Posts: 67
    • View Profile
Draw Optimizations
« Reply #6 on: February 20, 2011, 01:12:55 am »
So I guess I was under the impression that it was the number of pixels drawn that would be the bottleneck.

So I tried drawing a screen sized image over top of itself a dozen times and i dont see any decrease in framerate but when i just draw enough 16x16 pixel tiles to fill the screen my framerate really starts to take a hit. Why is this? I feel like I must be doing something wrong. All my tiles are on the same image.

Gibgezr

  • Newbie
  • *
  • Posts: 33
    • View Profile
Draw Optimizations
« Reply #7 on: March 07, 2011, 08:17:29 pm »
See this thread:
http://www.sfml-dev.org/forum/viewtopic.php?t=3173

My answer at the bottom is the way to draw thousands of tiles at high frame rates.

And yes, drawing less sprites at larger resolution is way faster than drawing many small sprites, even if the area covered by the sum total of all draws is somewhat less with the small sprite case. SFML 2 helps get rid of state changes when drawing from the same image repeatedly, but draw less polys is almost always faster than drawing more. It's not fill rate you need to worry about, it's the overhead inherent in drawing any size poly.

vidjogamer

  • Jr. Member
  • **
  • Posts: 67
    • View Profile
Draw Optimizations
« Reply #8 on: March 12, 2011, 07:56:12 am »
Any hints on how to implement this in sfml =p

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
Draw Optimizations
« Reply #9 on: March 12, 2011, 08:31:28 am »
The biggest performance hit in OpenGL is caused by texture binding, I noticed that pretty often. The more sprites you have using different textures (sf::Image), the more texture bindings will be required each frame and things will slow down.

The best solution is to use as little different images as possible. This is best achieved by using sprite sheets and tilesets that have as many frames as possible in one single image. It's better to have a few LARGE images that many many small ones. Ultimately you also should code your application to render sprites with the same image in direct sequence to avoid texture binding as much as possible. The CPU time required to sort them accordingly will pay off when rendering. If you work with linked lists intelligently even that CPU use will be minimal.
JSFML - The Java binding to SFML.