# Drawing thread not getting enough time from scheduler?

**URL:** <https://www.ruby-forum.com/t/drawing-thread-not-getting-enough-time-from-scheduler/124542>\
**Category:** wxRuby\
**Created:** [December 30, 2007, 1:46am UTC](https://www.ruby-forum.com/t/drawing-thread-not-getting-enough-time-from-scheduler/124542 "2007-12-30T01:46:56Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jay\_McGavren](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e79b87/32.png) [@Jay\_McGavren](https://www.ruby-forum.com/u/Jay_McGavren)\
**Post date:** [December 30, 2007, 1:46am UTC](https://www.ruby-forum.com/t/drawing-thread-not-getting-enough-time-from-scheduler/124542/1 "2007-12-30T01:46:56Z")

</div>

Need some assistance with animation again… When I run the drawing  
code in a separate thread, it’s slow as heck. I think it may be  
because the drawing thread isn’t getting enough time from the thread  
scheduler.

I was able to reproduce the problem in my little sample program simply  
by increasing the number of lines it draws per update. I’m lucky to  
get one frame every three seconds with this. If I “thread.join” or  
“thread.priority += 1” the speed greatly increases, but then the GUI  
becomes unresponsive. (Similar problems with threads have been  
discussed previously on the wxRuby mailing list.)

require ‘rubygems’  
require ‘wx’

class MyApp \< Wx::App

```
def on_init

#Animate every 33 milliseconds.
  t = Wx::Timer.new(self, 55)
  evt_timer(55) { Thread.pass }
  t.start(33)

  #Containing frame.
  frame = Wx::Frame.new(nil, :size => [300, 300])
  frame.show

  #Offscreen drawing buffer.
  buffer = Wx::Bitmap.new(300, 300)

  #Displays drawing.
  window = Wx::Window.new(frame, :size => [300, 300])

  #Animate.
  thread = Thread.new do
    300.times do |i|
      #Clear screen.
      buffer.draw do |surface|
        surface.pen = Wx::Pen.new(Wx::Colour.new(0, 0, 0), 0)
        surface.brush = Wx::BLACK_BRUSH
        surface.draw_rectangle(0, 0, 300, 300)
      end
      #Draw lines.
      30.times do |j|
        x = i + j
        buffer.draw do |surface|
          surface.pen = Wx::Pen.new(
            Wx::Colour.new(128, 255, 128),
            3
          )
          surface.pen.cap = Wx::CAP_ROUND
          surface.draw_line(x, 0, x+100, 100)
        end
      end
      #Update screen.
      update_window(window, buffer)
    end
  end

end

def update_window(window, buffer)
  window.paint do |dc|
    #Copy the buffer to the viewable window.
    dc.draw_bitmap(buffer, 0, 0, false)
  end
end

```

end

app = MyApp.new  
app.main\_loop

I ran it through ruby-prof… Am I right in thinking these results  
mean the drawing thread is getting a fraction of the time that the  
main loop is?

Thread ID: 59174940  
Total: 0.01

%self total self wait child calls name  
1250.00 30.45 0.13 2.02 28.31 11 Integer#times-1  
160.00 2.86 0.02 2.84 0.00 3391  
Wxruby2::Colour#initialize  
160.00 0.02 0.02 0.00 0.00 3378  
Wxruby2::DC#draw\_line  
0.00 0.05 0.00 0.05 0.00 11  
Wxruby2::Window#paint  
…

Thread ID: 42518340  
Total: 32.594

%self total self wait child calls name  
96.59 31.72 31.48 0.00 0.24 1  
Wxruby2::App#main\_loop  
2.01 0.77 0.66 0.00 0.11 42  
Kernel#gem\_original\_require-1  
0.19 0.06 0.06 0.00 0.00 28 Class::Dir#[]  
…

My actual program (a game) is going to be doing even more drawing  
operations than this, so I need to boost the speed wherever I can.  
Any advice would be most appreciated!

-Jay McGavren  
[http://jay.mcgavren.com/zyps](http://jay.mcgavren.com/zyps)

---

<div class="post-metadata">

**Author:** ![Jay\_McGavren](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e79b87/32.png) [@Jay\_McGavren](https://www.ruby-forum.com/u/Jay_McGavren)\
**Post date:** [December 30, 2007, 3:22am UTC](https://www.ruby-forum.com/t/drawing-thread-not-getting-enough-time-from-scheduler/124542/2 "2007-12-30T03:22:42Z")

</div>

Hello Jay,

Well, one optimization that I can see just by skimming the code, is that  
your creating a DC Buffer each time you loop to draw a line. The  
grabbing  
of a DC weither it’s an On-Screen Control, or an Off Screen Bitmap.

The better way to do this, is to go this route here:

–Code–  
buffer.draw do |surface|  
surface.pen = Wx::Pen.new(  
Wx::Colour.new(128, 255, 128),  
3  
)  
30.times do |j|  
x = i + j  
surface.pen.cap = Wx::CAP\_ROUND  
surface.draw\_line(x, 0, x+100, 100)  
end  
end  
–end code–

If you would also notice, I’m not constantly re-creating the Wx::Pen  
either. Since it’s created once, and your using the same colour, and  
size  
for the Pen, there’s no reason to be re-creating it for each and every  
line  
you draw.

Whenever it comes to drawing, the main things you need to keep in mind,  
as  
far as performance is concerned, is that everytime you create a DC, it  
takes  
the Underlying OS a bit to load up the DC, the same to release the DC.  
Also, you will want to create your primary pens first, that your going  
to  
use most often, and avoid trying to create them everytime an iteration  
of a  
loop occurs, as this also takes time away from which you can do stuff  
with.

I believe, that with these simple modifications, you would easily get up  
to  
50~ FPS on the game.

Let me know how it goes,

Mario S.
