Skip to main content

News

Topic: Sphere SFML v0.90 (Read 108200 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere SFML v0.80
Reply #225
The image is created from an existing surface, so it's probably just reusing the surface for the image bitmap, perhaps with some copy-on-write magic to prevent disasters.  Not quite the same as doing a LoadImage() every frame.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: Sphere SFML v0.80
Reply #226
I hate to say it, but very simple C++ will usually be faster than very simple C#. I do not believe that is the whole story, but it could account for, perhaps, 10% in this case.

And it really isn't the whole story, Sphere-GL iterates through every pixel of a surface on CreateImage, and once it finds one that has an alpha that isn't 0, it considers the texture not transparent. Not that much overhead, but some.

I would expect that it isn't super slow because Sphere is CPU-limited, mainly due to using ancient SpiderMonkey. I've done a lot of testing with FJ-GL, and there is really only about 10% performance to be gained over Sphere-GL no matter what. At that point, you are taking hardly any cycles in the video driver, and all the time is being spent in jsapi calls. FJ-GL can never, never double speed over Sphere-GL. The biggest performance gain I could get was with image.clone(), since I can do that fully in hardware, and Sphere-GL has a GPU download, a full pixel copy and analysis, and then a full upload. FJ-GL is about 80% faster at it, depending on the image size.

Re replace blend mode: If you could set the GL blend mode, you could do that all with only a single call to OpenGL: glDisable(GL_BLEND). If you really want full performance, I would recommend using a toolkit that gives you more OpenGL control. OpenGL has a lot to offer, if you can use at least most of what it exposes to C/C++.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #227
No, yeah, this was just me not doing the hardware-stuff yet. I was just trying to get close to the speed of the C++ version of the software driver's ability to perform fast surface edits. I have it good now, but yeah, part of the problem is I'm contending with a software driver. I should get started moving things straight to hardware. :P

In fact it's going to be fairly easy since my primitives class wraps a render target. So technically I should just set the render target to the texture of the surface and have at it, easy as pie. The sprite batcher was made with the same concept in mind, so that means you get full sprite batching benefits on surfaces as well. This is nice if you want to make your own map engine in Sphere and decide to draw lots of textures straight to a surface.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #228
Alright, I moved over to hardware and now it draws at 120fps, but accurately. I have no idea how to make this faster. It should be blinding fast, and well, I think it is. It's just that tung's startup game redraws surfaces each frame. In the way I'm doing it, the render target is updated each time that happens. Then there is a further slowdown since he is only using 3 surfaces. Yep. So that means when he draws a list of names he keeps clearing and moving the surface as well. This should not make a huge difference in fact it's not that bad since he is only using 3 surfaces. But it slows my HW draws way, way down.

I know you think this can go faster, but I just don't see how. My  (naive) intuition on HW draw calls says I should be lucky to get more than 30 fps on tung's startup game. I have no idea where to optimize. Technically he isn't really using HW surfaces right. Every resource on them say to keep a hardware target floating around - never keep creating and destroying them - and scarcely update them. That's the damn definition of them.

Now here's why I'm going nuts. When I properly use them my fps is even greater than the software version. The fill rates are faster and I can draw them at 10000 fps.

See this: http://www.sfml-dev.org/tutorials/2.1/graphics-draw.php

Quote

This clear/draw/display cycle is the only good way to draw things. Don't try other strategies, such as keeping pixels from the previous frame, "erasing" pixels, or drawing once and calling display multiple times. You'll get strange results due to double-buffering.
Modern graphics chipsets and APIs are really made for repeated clear/draw/display cycles where everything is completely refreshed at each iteration of the main loop. Don't be scared to draw 1000 sprites 60 times per second, you're far below the millions of triangles that your computer can handle.


Tung was not doing the above in his code; to emulate Sphere's legacy pixel-buffer strategy to surfaces means not adhering to the modern design principle of using such features. I think it's the double-buffering that's killing my performance. Laurent did not design SSFML with older API's in mind.  So in order to emulate Sphere I keep my old way of doing things which is slower, or I switch to a toolkit and abuse features to make things work.

But I am indeed perplexed. The trade-off is odd, my HW surfaces are really not that bad when used right, but really bad when used like how tung treated them. :/
  • Last Edit: January 24, 2014, 06:25:19 am by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #229
But, not all is lost. See, while the performance is horrendous on Tung's demo, it's outstanding on other surface demos. See screenshot for an image of what's produced.

So, I was thinking Tung's demo is seriously flawed for HW acceleration. So I decided to make a different "thrash test" to see how robust my changes are. Turns out I get quite good results for "misusing" the surfaces like I do, below:

Code: (javascript) [Select]

var surf = CreateSurface(48, 48, white);
surf.rectangle(12, 12, 24, 24, green);
surf.gradientRectangle(0, 0, 48, 48, green, green, white, white);
surf.line(0, 0, 48, 48, red);
surf.setPixel(8, 2, red);
surf.drawText(sys_font, 0, 0, "Hi");

while (!done) {

            // draw surfaces:
    for (var i = 0; i < 5; ++i) {
        for (var j = 0; j < 5; ++j) {
            surf.blit(0 + i * 48, 16 + j * 48);
        }
    }
    // now, try to "thrash" the GPU (for Sphere GL/SSFML):
    surf.rectangle(12, 12, 24, 24, green);
    surf.gradientRectangle(0, 0, 48, 48, green, green, white, white);
    surf.line(0, 0, 48, 48, red);
    surf.setPixel(8, 2, red);
    surf.drawText(sys_font, 0, 0, "Hi");


SSFML: 2700 fps
Sphere 1.5 GL: 1200 fps (pictured)
Sphere 1.5 32: 1700 fps
Sphere 1.6 32: 2100 fps

Sphere 1.6 really is a very fast Sphere version. But at least it shows my HW surfaces are really very fast. Tung's example is just bad for HW acceleration I guess, even though you will see better performance in other more cryptic methods of drawing textures. I will never arrest my case, his code is an anomaly, I am still shocked SphereGL's method is any good, considering I still win in the above thrash test over Sphere-GL.
  • Last Edit: January 24, 2014, 06:19:11 pm by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #230
Well, well, it turns out I get 6100 fps moving back to my software surface code. So Tung's code is really bad, but if the surfaces are used right not only did my HW solution skyrocket, so did the SW solution.

Again to do the test:
SSFML HW: 2700
SSFML SW: 6100
Sphere 1.5 GL: 1200
Sphere 1.5 32: 1700
Sphere 1.6 32: 2100

That means I have a very fast solution. :) The colors are not that accurate though, I think the color blending needs some rework but that's ok.

Edit: On full color replace (not blend) the fps of SSFML is at 6600, and in Sphere1.6 32 it's still at 2100. BTW all of my tests were on 2x screen size.
  • Last Edit: January 24, 2014, 06:20:53 pm by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #231
I found out the solution. Color objects are expensive to create in SSFML. I'll have to think up a better color strategy.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Sphere SFML v0.80
Reply #232
You can't put colors directly in the state on a per-vertex basis?

That's how I've been doing it (originally glColorPointer, but that's deprecated, so I switched to using Shaders and a vertex attribute). I actually considered making calls to new Color/CreateColor allocate their own vertex buffers that hold the color (theoretically quite fast, although on-the-fly color uploads are also pretty quick). I already do that with a single buffer of full color, just for non-color masked operations. So I suppose in the case of direct blits and plain old image blits, that probably speeds up FJ-GL (and TurboSphere) compared to Sphere-GL, which uploads the whole color every call--although only once per draw, in ancient immediate-mode fashion, through glColorub().

I considered creating a pool of vertex buffers that hold colors, and ref-counting them. Theoretically it could be quite expensive memory-wise, since V8 is extremely lazy about freeing handles, but I could probably certainly get away with making the colors 24 bit on the GPU (r6g6b6a6, for example). Technically, colors only need to be 30 bit, since if alpha is all zero I can just put a zeroed-out buffer on the state (I can even share that data source with primitive texture mapping buffers which also should be cache friendly), and I can put full alpha on the state using only any buffer that is equal in RGB and use blend modes (sometimes, wouldn't work for gradient primitives). I haven't done that because TurboSphere mostly isn't bus-limited, and color uploads are not a huge consumer of bandwidth.

There is no equivalent to glColor() in SFML? It's beginning to sound like SFML works a bit differently than OpenGL.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #233
SFML colors are fast to make. Yes, I can put them in on a per-vertex basis. It's just that the Jurassic wrapper around them was god-awful slow and I have no way around that. So, to circumvent that altogether I make the engine make a color object like this:

Code: (javascript) [Select]

function CreateColor(r, g, b, a) {
    if (a === undefined) a = 255;
    return { red: r, green: g, blue: b, alpha: a };
}


Yep, colors are just objects, which is near instantaneous to create. Then the rgba is 'parsed' out of it only when needed. It helps in Tung's demo since I realized he always created new colors when modifying things rather than set the rgba properties.

This made the SW surfaces blit at 750fps, which is now the fastest among all Sphere versions on my computer. The HW surfaces are still slow, and I'm still wondering why since technically I see nothing obvious to cause the slowdown. The color object fix just makes those HW surfaces run from 120fps to 200fps.

I made a fill-rate test where I constantly fill a surface in a loop, (on a 320*240, 2x screen):
Code: (javascript) [Select]

function TestSurfaceFillRate() {
    var w = GetScreenWidth(),
        h = GetScreenHeight(),
        surf = CreateSurface(w, h, CreateColor(255, 255, 255)),
        green = CreateColor(0, 255, 0),
        done = false;
   
    while (!done) {
        surf.rectangle(0, 0, w, h, green);
        surf.blit(0, 0);
        FlipScreen();

        while (AreKeysLeft()) {
            if (GetKey() == KEY_ENTER) done = true;
        }
    }
}


SSFML SW: 650fps
SSFML HW: 2900fps
Sphere 1.5 GL: 910fps
Sphere 1.5 32: 780fps
Sphere 1.6 32: 780fps

So I *know* my HW approach is the fastest, so again I'm still befuddled on why Tung's code is performing so slow.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #234
Ok, I think a lot of slowdown is really the JS side of things, not Jurassic's compiled stuff it's actually pretty fast. But the CLR handlers and wrappers are slow. So I was thinking of moving over to an environment that implements .NET in JS, there are a few libraries that do this, but this one got my eye since it may be built to use V8, which is a heck of a lot faster than Jurassic: https://clearscript.codeplex.com/

So not only might I get really fast performance script wise, modern Sphere games can use the C# Runtime in their JS code:
Code: (javascript) [Select]

System.Console.WriteLine("Hello World!");

System.Linq. //... usage of Linq in your game

System.XML. // ...

SFML. // ... use sfml features in your code, includes shaders, textures, everything really!


And I can pass wrapped SFML objects directly into the environment.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Sphere SFML v0.80
Reply #235
Is it any faster to unwrap integers? You could try having colors be JS numbers behind the scenes. Primitive types are faster to deal with in V8 than full objects (although not by much).

If we are exposing console writing, I would recommend it at least be wrapped to also look like Web-JS console writing.

The XML exposition would be an excellent addition, though.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #236
Currently it turns out ClearScript is very slow. Doing this:

Code: (javascript) [Select]

while (true) {
    CreateColor(255, 255, 255, 255);
    CreateColor(255, 255, 255, 255);
    CreateColor(255, 255, 255, 255);
    CreateColor(255, 255, 255, 255);
    CreateColor(255, 255, 255, 255);
    CreateColor(255, 255, 255, 255);
    FlipScreen();
}


Brings the framerate way down. In Vanilla Sphere and my Jurassic branch, the above code had little slowdown. It seems exposing CLR to JS is very slow.

In ClearScript I got a 3 to 4 times performance boost by switching from this:
Code: (javascript) [Select]

var image = LoadImage("test.png");

while (true) {
    image.blit(0, 0);
    FlipScreen();
}


To this:
Code: (javascript) [Select]

var image = LoadImage("test.png");
var blit = image.blit;

while (true) {
    blit(0, 0);
    FlipScreen();
}


And that's running in a V8 context! Despite that, ClearScript is faster at RAW JS computations and computation speeds. About 2x slower than Chrome, which is damn fast since Jurassic is like 38 times slower than Chrome, even though it is 67 times faster than Sphere 1.5.

Argh! I hate this. I hate how going from C# to JS is so damn slow. How the hell can Sphere get away with fast Host-to-JS support? WTF is it doing differently?
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Sphere SFML v0.80
Reply #237
How direct is the JS to CLI connection in Jurassic?

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #238

How direct is the JS to CLI connection in Jurassic?


Very intimate, you must tell it precisely what methods and members to "cast" to JS.

Jurassic Definition:
Code: (csharp) [Select]

public class MyClass : ObjectInstance
{
    private Texture _tex;

    public MyClass(ScriptEngine parent) : base(parent) {
        PopulateFunctions();
    }

    [JSFunction(Name = "blit")] // needed
    public void Blit(double x, double y, [DefaultValue(0)] int state = 0)
    {
        Program.window.draw(x, y, _tex);
    }
}


ClearScript Definition:
Code: (csharp) [Select]

public class MyClass
{
    private Texture _tex;

    public MyClass() { }

    [ScriptMember("blit")] // optional
    public void Blit(double x, double y, int state = 0)
    {
        Program.window.draw(x, y, _tex);
    }
}


There's far more annotated C# code for Jurassic. I"m not sure that is it's secret or not. You always take a hit going between Host-to-JS, I've even read a post in the ClearScript discussion board claiming that. I'm just baffled that Jurassic and Vanilla Sphere do it without much overhead. I mean, I should be able to blit hundreds of items before the JS-to-CLR overhead creeps up, not just 2 to 5 items.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere SFML v0.80
Reply #239
Alright, with some tweaks to the Jurassic-wrapped color object (thanks to Jurassic's creator) I finally have fast color creation. :)

I can't get ClearScript to run fast, so I'll stick with Jurassic for now, it's superior in every way to ClearScript for one reason: CLR to JS performace is slow and a game that uses JS in Sphere needs fast performance in precisely that area. Jurassic is fast since it compiles everything to the same bytecode C# uses so there is 0 performance hit going between them.

I noticed under Sphere 1.5 color creation is not as fast as under SSFML. Interestingly,
Creating Colors in a loop:
SSFML: 10600 fps
Sphere 1.5 GL: 8600fps
Sphere 1.5 32: 2500fps // holy cow!!

I really think that the color creation in the 1.5/1.6 Standard32 drivers are to blame for slow performance in Tung's startup game.
  • Last Edit: January 27, 2014, 10:49:36 pm by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here