veandco / go-sdl2

SDL2 binding for Go
https://godoc.org/github.com/veandco/go-sdl2
BSD 3-Clause "New" or "Revised" License
2.2k stars 218 forks source link

RenderUTF8BBlended Out of memory when loaded from RWops #357

Closed ghost closed 5 years ago

ghost commented 6 years ago

The title kinda says it all, here's the code I'm working with:

package main

import (
    "fmt"
    "io/ioutil"

    "github.com/veandco/go-sdl2/img"
    "github.com/veandco/go-sdl2/sdl"
    "github.com/veandco/go-sdl2/ttf"
)

func main() {
    if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
        panic(err)
    }
    defer sdl.Quit()

    if err := ttf.Init(); err != nil {
        panic(err)
    }
    defer ttf.Quit()

    // rubik, err := ttf.OpenFont("/home/rucuriousyet/code/go/src/gitlab.com/rucuriousyet/carbon/assets/fonts/Roboto Mono/RobotoMono-Regular.ttf", int(20))
    // if err != nil {
    //  panic(err)
    // }

    rbt, err := ioutil.ReadFile("/home/rucuriousyet/code/go/src/gitlab.com/rucuriousyet/carbon/assets/fonts/Roboto Mono/RobotoMono-Regular.ttf")
    if err != nil {
        panic(err)
    }

    // also tried RWFromFile
    rw, err := sdl.RWFromMem(rbt)
    if err != nil {
        panic(err)
    }
    defer rw.Free()

    rubik, err := ttf.OpenFontRW(rw, 1, len(rbt))
    if err != nil {
        panic(err)
    }

    slideInx := 0
    slides := []string{
        "What do you want?! A helicopter to cuba? Anything!",
        "Let's lie down and practice kicking him in our sleep",
        "My wife has instituted this open-door policy",
        "If one of our kids has a nightmare they're welcome to",
        "Come in our room and pee in our bed.",
    }

    window, err := sdl.CreateWindow("Sublight", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
        800, 600, sdl.WINDOW_ALLOW_HIGHDPI)
    if err != nil {
        panic(err)
    }
    defer window.Destroy()

    icon, err := img.Load("/usr/share/icons/macOS/apps/128/atom.png")
    if err != nil {
        panic(err)
    }

    window.SetResizable(true)
    window.SetTitle("Sublight")
    window.SetIcon(icon)
    window.Show()

    renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
    if err != nil {
        panic(err)
    }
    defer renderer.Destroy()

    X := int32(0)
    Y := int32(0)

eventloop:
    for {
        for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
            switch e := event.(type) {
            case *sdl.QuitEvent:
                break eventloop

            case *sdl.RenderEvent:
                println(event)
                break

            case *sdl.MouseMotionEvent:
                X = e.X
                Y = e.Y
                break

            case *sdl.MouseButtonEvent:
                if e.Button == sdl.BUTTON_LEFT && e.State == sdl.RELEASED {
                    if slideInx >= len(slides)-1 {
                        slideInx = 0
                    } else {
                        slideInx++
                    }

                    fmt.Println(slideInx)
                }
                break

            }
        }

        renderer.Clear()
        width, height, err := rubik.SizeUTF8("text")
        if err != nil {
            panic(err)
        }

        // this is where to panic occurs
        textSurf, err := rubik.RenderUTF8Blended("text", sdl.Color{R: 255, G: 255, B: 255, A: 255})
        if err != nil {
            panic(err)
        }

        textTexture, err := renderer.CreateTextureFromSurface(textSurf)
        if err != nil {
            panic(err)
        }

        renderer.Copy(textTexture, &sdl.Rect{0, 0, int32(width), int32(height)}, &sdl.Rect{X, Y, int32(width), int32(height)})

        renderer.Present()
        window.UpdateSurface()
        textSurf.Free()
        textTexture.Destroy()

        sdl.Delay(16)
    }
}

just note that everything works perfectly when I call OpenFont (with a file). The end goal here is to embed fonts as constants and load them using rwops in order to have a completely standalone binary.

And yes, I totally wrote this while watching comedy skit from Jim Gaffigan... which is where those slides sentences are coming from LOL.

ghost commented 6 years ago

On linux this program only uses about 15mb of memory before the program panics, and the font file I'm loading is only about 120kb in size.... My laptop has 16gb of memory with atleast 10gb free while running. This laptop is running Arch Linux with Gnome and uses embedded graphics, So I wonder if maybe the program is running out of VRAM or something? I don't know what parts of SDL are loading surfaces/textures into VRAM but I assume my integrated intel GPU can handle a font file.

veeableful commented 5 years ago

Hi @rucuriousyet, I'm really sorry for taking so long to respond! It seems you supplied too big of a point size to ttf.OpenFontRW(). Once you put a reasonable value, it should work!