fyne-io / fyne

Cross platform GUI toolkit in Go inspired by Material Design
https://fyne.io/
Other
25.12k stars 1.4k forks source link

Driver: Web - "fyne serve" GOOS = Windows #3161

Closed renlite closed 2 years ago

renlite commented 2 years ago

Checklist

Describe the bug

I tried to execute the fyne_demo with "fyne serve" but got following message: GOOS is not supported, the supported GOOS values are linux and darwin. The GopherJS is falling back to GOOS=linux panic: open c:\go\src\runtime/fastrand.go: open /\src\runtime/fastrand.go: file does not exist

Does this mean that development of a web version is only possible on Linux and MacOS?

How to reproduce

on Windows

cd \fyne\cmd\fyne_demo fyne serve see the error

Screenshots

No response

Example code

...

Fyne version

2.2.2

Go compiler version

1.17

Operating system

Windows

Operating system version

Windows 10

Additional Information

--

Bluebugs commented 2 years ago

Hum, indeed, gopherks does not support Windows for building. You can work around this by disabling gopherjs and use fyne serve --target wasm, but in that case only firefox and safary are supposed to work with the generated web site (If it is just for development purpose, you can maybe get chrome to work by maintaining open the developer console in chrome as that disable chrome buggy optimization). Maybe fyne serve on Windows should disable gopherjs and display an error message.

You could also use fyne-cross new web target to build the web site which include gopherjs by using docker/podman.

renlite commented 2 years ago

With 'fyne serve --target wasm' I get these errors on firefox: image

Bluebugs commented 2 years ago

The only error that matter here is the getAttribLocation. I hadn't seen that before using your branch for rounded corner. I will have to dig further to understand what is going on, but is it possible that a shader compilation failed or something given to that getAttribLocation call that actually come from a failed call.

renlite commented 2 years ago

Thank you for the information! I will try to find the issue too.

renlite commented 2 years ago

I forgot the initialization of p.rectangleProgram = p.createProgram("rectangle_es") in gl_goxjs.go. After implementation: image The error happens after the compilation of the shaders. Could you please test the GL_ES on a mobile device or with gopherjs.

Bluebugs commented 2 years ago

I will try testing your PR tomorrow afternoon and let you know. Cool work!

Bluebugs commented 2 years ago

Sorry it took me time to come back to your PR. I am still having trouble with it after fixing the crash you got above. I have created a PR that solve this problem : https://github.com/fyne-io/gl-js/pull/9 . Weirdness of JS...

After this I get a lot of:

WebGL error gl.INVALID_OPERATION in drawArrays(gl.TRIANGLES, 0, 10) [webgl-debug.js:44:20](http://localhost:8080/webgl-debug.js)
Bluebugs commented 2 years ago

(you will need to do a go mod edit -replace until that PR land along with go mod vendor until that PR land)

renlite commented 2 years ago

image I found the issue why drawArrays(...) did not work. It seems that GL ES is stricter than GL. My calculation of triangle points was not correct. I changed it in the PR, now on web (wasm) rectangles are rendered. But when an other canvas is rendered in combination with rectangle then the error appears again. Maybe the VBO is not freed correctly or too late (async problem) after switch to other shader. I saw there is a different implementation of DeleteBuffer depending on the gl context. This is something I don't understand because on desktop there is no problem. For easier testing I enclodes the flexrect.go file in the PR. After solution this file could be deleted.

renlite commented 2 years ago

Rendering on WebGL (GL ES) works now. There is an error or a difference between GL and GL ES in handling the different number of VertexAttribArray index. https://stackoverflow.com/questions/9705771/conflict-when-using-two-or-more-shaders-with-different-number-of-attributes?rq=1 The VertexAttribArrays are not bound to the VBO of eg. Line or Rectangle but it is in the global memory of a GL program. An index of VertexAttribArray can be overwritten from the following VBO/shader. If the previous VBO has more VertexAttribArrays enabled than the actual VBO then some VertexAttribArrays are not used by the actual schader and an error occurs. drawLine and drawTextureWithDetails use 2 VertexArrays while drawRectangle has 5.

func (p *painter) drawTextureWithDetails(o fyne.CanvasObject, creator func(canvasObject fyne.CanvasObject) Texture,
    pos fyne.Position, size, frame fyne.Size, fill canvas.ImageFill, alpha float32, pad float32) {
       (...)
    p.defineVertexArray(p.program, "vert", 3, 5, 0)
    p.defineVertexArray(p.program, "vertTexCoord", 2, 5, 3)
}

func (p *painter) drawLine(line *canvas.Line, pos fyne.Position, frame fyne.Size) {
    (...)
    p.defineVertexArray(p.lineProgram, "vert", 2, 4, 0)
    p.defineVertexArray(p.lineProgram, "normal", 2, 4, 2)
}

func (p *painter) drawRectangle(rect *canvas.Rectangle, pos fyne.Position, frame fyne.Size) {
    points := p.flexRectCoords(pos, rect, 0.5, frame)
    p.ctx.UseProgram(p.rectangleProgram)
    vbo := p.createBuffer(points)
    p.defineVertexArray(p.rectangleProgram, "vert", 2, 7, 0)
    p.defineVertexArray(p.rectangleProgram, "normal", 2, 7, 2)
    p.defineVertexArray(p.rectangleProgram, "colorSwitch", 1, 7, 4)
    p.defineVertexArray(p.rectangleProgram, "lineWidth", 1, 7, 5)
    p.defineVertexArray(p.rectangleProgram, "feather", 1, 7, 6)
}

Solution: After p.ctx.DrawArrays(triangles, 0, triangleXYPoints) the VertexAttrib 3 - 5 are disabled.

    p.ctx.DrawArrays(triangles, 0, triangleXYPoints)

    p.ctx.DisableVertexAttribArray(p.ctx.GetAttribLocation(p.rectangleProgram, "colorSwitch"))
    p.ctx.DisableVertexAttribArray(p.ctx.GetAttribLocation(p.rectangleProgram, "lineWidth"))
    p.ctx.DisableVertexAttribArray(p.ctx.GetAttribLocation(p.rectangleProgram, "feather"))

image

2803

As you can see on the screenshot the rendering of all canvas objects (gl/draw.go) is done after the event of a button. (Mouse over or click). Except "Button" all the othe objects are unchanged. The unnecessary calculations seem to be responsible for the slow performance on the Web/wasm too.

Bluebugs commented 2 years ago

Thanks for all this work. Your point about performance is interesting and likely not just affecting the web driver. Would you mind opening a separate issue to track it?

renlite commented 2 years ago

Yes, I will open a separate issue. Could you please tell me, what is the difference between gopherjs and wasm when developing wiht fyne? As far as I understand with gopherjs go code is compiled to js and with wasm to webassembly and js as bootstrap and for DOM communication. Is there a difference in size and performance between these technologie? I think this issue could be closed because as you mentioned there is an "work around by disabling gopherjs and use fyne serve --target wasm" on Windows and it is not direct a fyne issue.

Bluebugs commented 2 years ago

The main reason we are supporting gopherjs is that it is the only solution for Chrome based browser at this point as they do exhibit a bug with their optimizer and webassembly. In term of performance, I have only felt marginal difference between the two solutions (We do not have a benchmark at the moment that would be useful for this case). So in production, you would need to deploy both wasm and gopherjs, but during testing you could just use wasm and rely on firefox.

Bluebugs commented 2 years ago

I still need to add a proper warning for the case where the host platform is windows.

andydotxyz commented 2 years ago

@Bluebugs is the warning added already? This would be a good time as we plan for the next release.

Bluebugs commented 2 years ago

This is now covered in develop.