Strange slowness using canvas texture

About Monkey 2 Forums Monkey 2 Programming Help Strange slowness using canvas texture

This topic contains 6 replies, has 3 voices, and was last updated by  Mark Sibly 2 years, 10 months ago.

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #1044

    Ethernaut
    Participant

    Not the most compact example code, but here it goes: https://github.com/DoctorWhoof/GridShooter

    If you run it as it is, you’ll notice that “debug” graphics is on by default. This works well as a stress test, since it draws text and lines all over the place, like this:

    The render time at the top line of text is under 1 millisecond (in release mode). Not bad at all! Now if you hit the “T” key, it will switch the rendering to a canvas texture, and then draw that texture into the Window canvas. You can really see the difference between the two modes if you run fullscreen or maximized.

    Holy smokes! That’s 15 times slower! I know the code is probably a pain to look at (If I have time later tonight I’ll try to create a small test that reproduces this), but is there a good reason for that to happen?

    All the render to texture magic happens in the RenderWindow class. The ‘canvas’ field redirects any drawing operation to the appropriate canvas, _textureCanvas or _windowCanvas.

    Thanks!

    P.S. I figured how to post images (they have to be URLs), but they stretch all over. Is there a way to prevent this?

    #1045

    Mark Sibly
    Keymaster

    Ok, 2 main problems:

    • Use the TextureFlags.Dynamic flag for frequently modified textures. By default, texture contents are ‘backed up’ to system memory (so they can survive a graphics device reset) after texture target changes, but this is not necessary if you’re constantly updating the texture.
    • The ‘render to texture’ code path executes a ‘canvas.flush’ where-as the ‘render to window’ path doesn’t, so it’s not a fair comparison! Flush() will cause all the ‘draw commands’ you’ve submitted to execute as GL code which will still partly execute in parallel but will still have some overhead.

    No idea about the image problem – how did you add the image? Can you see an ‘Add Media’ button? Testing here…

    monkey2-logo-63

    #1052

    Anonymous

    Ok, found a plugin that offers attachments that seems to work – be nice to add stuff inline but that seems to be tricky for non-admin users so this’ll do for now.

    Anyway, you should see an ‘Attachments’ thing at the end of the topic/reply form now.

    #1058

    Ethernaut
    Participant

    Use the TextureFlags.Dynamic flag for frequently modified textures

    That improved a lot, about 2ms instead of 14ms!

    The ‘render to texture’ code path executes a ‘canvas.flush’ where-as the ‘render to window’ path doesn’t

    So, wait, is there a way to not call Flush() when drawing to a texture? Turning it off renders an empty texture, as I expected.

    As for the attachments, let me try it…

    Attachments:
    #1061

    Mark Sibly
    Keymaster

    So, wait, is there a way to not call Flush() when drawing to a texture?

    No, but all rendering needs to be flushed eventually anyway, whether it’s to a canvas or to the render window. Window does a canvas.flush internally, so render to window will be ‘slower’ than you think because you’re not measuring this flush.

    Try this just before calcing _renderDuration:

    This should flush all drawing on the mx2 side, followed by all GL drawing.

    Render to image will probably be a little slower, because there’s the extra ‘blit’ to update the window canvas, but it should be pretty much the same.

    Also, you can probably optimize the blit a bit – get rid of _windowCanvas.Clear and use BlendMode.Opaque.

    #1062

    Ethernaut
    Participant

    Yes! That pretty much equalizes the rendering speed in both modes and gives a more accurate reading as well. But if I actually include gles20.glFinish() the render duration becomes the vSync interval, about 16ms.

    Thanks Mark, this is great information!

    P.S. Just for the record, when I turn off all the graphic visual aids and just render the sprites and 3 background layers, the rendering speed in both modes is about 0.35ms on my laptop, which is great. I’m really happy with M2’s performance so far!

    #1064

    Mark Sibly
    Keymaster

    >  But if I actually include gles20.glFinish() the render duration becomes the vSync interval, about 16ms.

    Weird, I don’t get that here – yours must be waiting for the last ‘flip’ to finish whereas mine isn’t. Quite likely a driver thing, but it does mean you can’t reliably measure render time.

    Perhaps try with SwapInterval=0?

Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.