Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Redraw / main loop / task issues #437

Open
ghost opened this issue Aug 19, 2019 · 1 comment
Open

Redraw / main loop / task issues #437

ghost opened this issue Aug 19, 2019 · 1 comment

Comments

@ghost
Copy link

ghost commented Aug 19, 2019

I first posted this at JuliaImages/ImageView.jl#178, but maybe here is more appropriate:

The issue is that ImageView will not refresh the displayed images in a tight computational loop displaying intermediate results. At first it seemed that a sleep is needed after every redraw, to somehow pass control to Gtk. A simple yield will not do. But the main difference between those is that sleep will call system pause if there are no Julia internal Tasks to run. So that would indicate troubles with trying to embed the Gtk main loop (in a separate system thread or not, how can it even work otherwise?) into the Julia Tasks system.

After some further hunting through the sources of ImageView/Gtk/GtkReactive, my hunch is that something is preventing notify_realize within cairo.jl from being called. It turns out that one only needs to sleep once in the beginning after the widgets and canvases have been created. It is not necessary to sleep after each animation frame, they are redrawn just fine, as long as that initial sleep is performed.

Additionally, the sleep does not help (neither in the beginning nor after every redraw) if I put the drawing process in a Distributed.Thread to run on another core.

@LilithHafner
Copy link
Contributor

It turns out that one only needs to sleep once in the beginning after the widgets and canvases have been created. It is not necessary to sleep after each animation frame, they are redrawn just fine, as long as that initial sleep is performed.

I find that using yield() instead of sleep(.001) causes most rendering to take place fine, but commands like width(canvas) continue to report out of date results until a sleep call happens.

I drew this conclusion from the fact that when I run this code with `yield()` instead of `sleep(.001)` and enlarge the window, the ball keeps bouncing in the original region.
using Gtk, Graphics
c = @GtkCanvas()
win = GtkWindow(c, "Canvas")

x = 100rand()
y = 100rand()
xv = 50randn()
yv = 50randn()
t = time()
function update_ball(w, h)
    global t, x, y, xv, yv
    dt = time()-t
    x += xv*dt
    y += yv*dt
    t += dt
    x = mod(x, 2w)
    if x > w
        x = 2w - x
        xv = -xv
    end
    y = mod(y, 2h)
    if y > h
        y = 2h - y
        yv = -yv
    end
end

@guarded draw(c) do widget
    ctx = getgc(c)
    h = height(c)
    w = width(c)

    # Paint background
    rectangle(ctx, 0, 0, w, h)
    set_source_rgb(ctx, 0, 0, 0)
    fill(ctx)

    update_ball(w, h)

    # Paint ball
    set_source_rgb(ctx, .69, .58, .96)
    arc(ctx, x, y, 5, 0, 2pi)
    stroke(ctx)
end

c.mouse.button1press = @guarded (widget, event) -> begin
    global xv = event.x - x
    global yv = event.y - y
end

show(c)

sleep(1)

while true
    sleep(.001) # or yield()
    c.draw(true)
    reveal(c)
end

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant