Xojo Conferences
XDCMay2019MiamiUSA

[RB List] More speed (Real Studio getting started Mailinglist archive)

Back to the thread list
Previous thread: Tab Panels .... was Compile Error:-> There is no class with this name
Next thread: Array with alphanumeric key


RE: [RB List] MouseRightButton ?   -   RBNUBE
  [RB List] More speed   -   Eirik Karlsen
    Re: [RB List] More speed   -   Joseph J. Strout
    Re: [RB List] More speed   -   Eirik Karlsen
    Re: [RB List] More speed   -   GAmoore aol.com
     Re: [RB List] More speed   -   Seth Willits
     Re: [RB List] More speed   -   Phil M
    Re: [RB List] More speed   -   Joseph J. Strout
    Re: [RB List] More speed   -   Eirik Karlsen
    Re: [RB List] More speed   -   Joseph J. Strout
    [RB List] More speed   -   Eirik Karlsen

[RB List] More speed
Date: 24.01.05 21:17 (Mon, 24 Jan 2005 21:17:22 +0100)
From: Eirik Karlsen
Anyone had experience with something like this:

In a canvas MouseMove event I'm using this code to draw a Y-cursor
(vertical line)
at the mouse X position.
The cursor line is drawn ontop of the completed picture with graphs and
stuff.

'******************************'
'GraphCursor.graphics.DrawPicture GraphFront,0,0 'draw complete
graphs picture to cursor picture
'GraphCursor.graphics.ForeColor=RGB(0,0,0) 'Black
cursorline
'GraphCursor.graphics.DrawLine x,0,x,CanvasGraph.height 'Draw
cursorline
'CanvasGraph.graphics.DrawPicture GraphCursor,0,0 'Draw cursor
picture to Graphcanvas
'******************************

The problem is that most of this code is slow, especially the DrawPicture.

The 4 lines above slows down the performance by at least 500%...
annoyingly slow.

Is there a significantly faster way of doing this cursor?
Maybe a custom mouse cursor is faster??
Anyone know this?

Re: [RB List] More speed
Date: 24.01.05 21:51 (Mon, 24 Jan 2005 14:51:16 -0600)
From: Joseph J. Strout
At 9:17 PM +0100 1/24/05, Eirik Karlsen wrote:

>'******************************'
> 'GraphCursor.graphics.DrawPicture GraphFront,0,0 'draw complete
>graphs picture to cursor picture
> 'GraphCursor.graphics.ForeColor=RGB(0,0,0) 'Black
>cursorline
> 'GraphCursor.graphics.DrawLine x,0,x,CanvasGraph.height 'Draw
>cursorline
> 'CanvasGraph.graphics.DrawPicture GraphCursor,0,0 'Draw cursor
>picture to Graphcanvas
>'******************************
>
>The problem is that most of this code is slow, especially the DrawPicture.

I wouldn't expect it to be too slow, if GraphCursor is just the size
of the cursor -- but from the parameters, I'm guessing it's as big as
the entire graph? So you're drawing a full-sized picture twice per
frame. That's a lot of work.

The easy things you can do to make this faster are (1) stop accessing
the Graphics property on every line, using a local variable instead,
and (2) set UseOldRenderer = True on that local variable, which if
you happen to be running on OS X with RB 5.5.4 or earlier, will make
DrawPicture go faster.

But that's just a band-aid; the real fix is to stop drawing the
entire graph twice per frame. Instead, you should only be drawing as
many pixels as needed to cover the cursor. GraphCursor, in short,
should be 1 pixel wide, by however many pixels high your graph is.

No, actually, scratch that -- there's no need for GraphCursor at all,
since it will contain nothing but solid black. So ditch GraphCursor
entirely; draw your cursor by calling DrawLine directly on
CanvasGraph.

Now, how to erase the cursor? Don't do it by redrawing the entire
graph! Use DrawPicture, but use all nine parameters so that you're
only redrawing a single column of pixels.

Best,
- Joe

Re: [RB List] More speed
Date: 25.01.05 00:22 (Tue, 25 Jan 2005 00:22:06 +0100)
From: Eirik Karlsen
Joseph,
yes as you can see I'm making a picture copy of the entire canvas, then drawing
the cursor to that picture,
and finally drawing this new picture to the canvas.
I found this necessary to erase the cursor.

Your idea of narrowing some of the pictures down to one pixel wide should help
alot, will look into it.

..... So ditch GraphCursor
entirely; draw your cursor by calling DrawLine directly on
CanvasGraph.......

The main problem here is to erase the cursor
What do you mean...what nine parameters?

"Joseph J. Strout" wrote:

> At 9:17 PM +0100 1/24/05, Eirik Karlsen wrote:
>
> >'******************************'
> > 'GraphCursor.graphics.DrawPicture GraphFront,0,0 'draw complete
> >graphs picture to cursor picture
> > 'GraphCursor.graphics.ForeColor=RGB(0,0,0) 'Black
> >cursorline
> > 'GraphCursor.graphics.DrawLine x,0,x,CanvasGraph.height 'Draw
> >cursorline
> > 'CanvasGraph.graphics.DrawPicture GraphCursor,0,0 'Draw cursor
> >picture to Graphcanvas
> >'******************************
> >
> >The problem is that most of this code is slow, especially the DrawPicture.
>
> I wouldn't expect it to be too slow, if GraphCursor is just the size
> of the cursor -- but from the parameters, I'm guessing it's as big as
> the entire graph? So you're drawing a full-sized picture twice per
> frame. That's a lot of work.
>
> The easy things you can do to make this faster are (1) stop accessing
> the Graphics property on every line, using a local variable instead,
> and (2) set UseOldRenderer = True on that local variable, which if
> you happen to be running on OS X with RB 5.5.4 or earlier, will make
> DrawPicture go faster.
>
> But that's just a band-aid; the real fix is to stop drawing the
> entire graph twice per frame. Instead, you should only be drawing as
> many pixels as needed to cover the cursor. GraphCursor, in short,
> should be 1 pixel wide, by however many pixels high your graph is.
>
> No, actually, scratch that -- there's no need for GraphCursor at all,
> since it will contain nothing but solid black. So ditch GraphCursor
> entirely; draw your cursor by calling DrawLine directly on
> CanvasGraph.
>
> Now, how to erase the cursor? Don't do it by redrawing the entire
> graph! So ditch GraphCursor
> entirely; draw your cursor by calling DrawLine directly on
> CanvasGraph.
>
> Best,
> - Joe
>
> --
> REAL World 2005 - The REALbasic User Conference
> March 23-25, 2005, Austin, Texas
> <http://www.realsoftware.com/realworld>
> _______________________________________________
> Unsubscribe or switch delivery mode:
> <http://www.realsoftware.com/support/listmanager/>
> Search the archives of this list here:
> <http://www.realsoftware.com/listarchives/lists.html>

Re: [RB List] More speed
Date: 24.01.05 20:12 (Mon, 24 Jan 2005 19:12:58 EST)
From: GAmoore aol.com
In a message dated 1/24/05 12:58:37 PM, <email address removed> writes:
> The easy things you can do to make this faster are (1) stop accessing
> the Graphics property on every line, using a local variable instead,
>

How do you do that?
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://www.realsoftware.com/listarchives/lists.html>

Re: [RB List] More speed
Date: 25.01.05 01:25 (Mon, 24 Jan 2005 16:25:44 -0800)
From: Seth Willits
On Jan 24, 2005, at 4:12 PM, <email address removed> wrote:

>> The easy things you can do to make this faster are (1) stop accessing
>> the Graphics property on every line, using a local variable instead,
>
> How do you do that?

dim g as graphics
g = me/picture.graphics

proceed to use g instead of me/picture.graphics


Seth Willits
------------------------------------------------------------------------
---
President and Head Developer of Freak Software - http://www.freaksw.com
REALbasic Guru at ResExcellence - http://www.resexcellence.com/realbasic

"More praise of peace is easy but ineffective. What is needed is active
participation in the fight against war and everything that leads to it."
-- Albert Einstein
------------------------------------------------------------------------
---

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://www.realsoftware.com/listarchives/lists.html>

Re: [RB List] More speed
Date: 25.01.05 01:30 (Mon, 24 Jan 2005 16:30:06 -0800)
From: Phil M
On Jan 24, 2005, at 4:12 PM, <email address removed> wrote:

>> The easy things you can do to make this faster are (1) stop accessing
>> the Graphics property on every line, using a local variable instead,
>
> How do you do that?

Think of it like this:

My friend has a CD and I really want to listen to one particular song.
So I go over to the friends house, but he tells me that he let his
ex-girlfriend borrow it. So I go over to her house and ask her if I
could listen to the CD. She tells me that she let her new boyfriend
borrow it, and so I go over to his house which happens to be right next
door to where I live. I knock on the door and finally get to listen to
the CD.

The next day I want to listen to the song again. Do I go through the
entire process again, or do I just go next door?

The same is true for following object references... if you do not store
a direct reference, then you have to traverse the link every time you
want access the data.

Instead of:

GraphCursor.graphics.DrawPicture GraphFront,0,0
GraphCursor.graphics.ForeColor=RGB(0,0,0)
GraphCursor.graphics.DrawLine x,0,x,CanvasGraph.height

You write:

Dim g As Graphics
g = GraphCursor.graphics // here is where you set the direct
reference

g.DrawPicture GraphFront,0,0
g.ForeColor=RGB(0,0,0)
g.DrawLine x,0,x,CanvasGraph.height

If there are only two lines which use the direct reference, I figure
(and I could be wrong) that it would be about break even on the
performance benefits. But with three and more, you will start to see
better performance.

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://www.realsoftware.com/listarchives/lists.html>

Re: [RB List] More speed
Date: 25.01.05 03:44 (Mon, 24 Jan 2005 20:44:42 -0600)
From: Joseph J. Strout
At 12:22 AM +0100 1/25/05, Eirik Karlsen wrote:

>The main problem here is to erase the cursor
>What do you mean...what nine parameters?

The nine parameters to DrawPicture. You're only using the first
three, which means that you can only draw a picture in its entirety.
DrawPicture can do much more (er, less) than that: it can draw any
subsection of the source picture, into any subsection of the
destination. With this, you can erase the cursor by just drawing the
column of pixels where the cursor was previously drawn.

See Graphics.DrawPicture in the language reference for the details.

Best,
- Joe

Re: [RB List] More speed
Date: 26.01.05 00:25 (Wed, 26 Jan 2005 00:25:59 +0100)
From: Eirik Karlsen
Joseph,
Tonight I tested your suggestion of using smaller pictures. And it sort
of works, the speed is greatly increased.
But an unforeseen problem came up: the cursor is not properly erased if
the mouse is moving fast.
At first I thought that the reason was that I was using the real-time
MouseX at various places in the code...
(thereby using slightly different x values because the mouse would be
moving between calculations).
So I took a snapshot of the x value and used that instead. This actually
didn't help much, or at all.

However it did help quite a bit if I made cursorpicture wider, now using
40 pixels. But its still not good enough.
I suspect I'd have to use half the canvas width for the cursor picture to
get reliable cursor erase....
haven't even tried it as I know it would just be way too slow.

I can't really see whats causing the cursor erase problem...I assume that
the MouseMove sub is finished before it
is re-called (as new event), and not called recursively ??

I'm running this on winXP
Any suggestions?

See the code below:

'******************************************
'DrawPicture
-------,DestX,DestY,DestWidth,DestHeight,SourceX,SourceY,SourceWidth,SourceHeight

'
Dim CursorX As Double
CursorX=X 'Store the mouse's momentary position because it may be
moving while processing the pictures!
'----------- Create Graphs cursor -----------------------
'GraphCursor.graphics.DrawPicture GraphFront,0,0 'draw complete
graphs picture to cursor picture
'GraphCursor.graphics.ForeColor=RGB(0,0,0) 'Black
cursorline
'GraphCursor.graphics.DrawLine x,0,x,CanvasGraph.height 'Draw
cursorline
'CanvasGraph.graphics.DrawPicture GraphCursor,0,0 'Draw cursor
picture to Graphcanvas

'****************
'Copy the small part of the graphimage that will be covered by the
cursor:
GraphCursor.graphics.DrawPicture
GraphFront,0,0,40,370,CursorX-20,0,40,370
'Draw the cursor into that part of the graphimage:
GraphCursor.graphics.ForeColor=RGB(0,0,0)
'Black cursorline
GraphCursor.graphics.DrawLine 20,0,20,CanvasGraph.height 'Draw
cursorline into the middle of the 40 pix wide picture
'Draw the new image including cursor to the graphimage:
CanvasGraph.graphics.DrawPicture GraphCursor,CursorX-20,0
'**************************************

Re: [RB List] More speed
Date: 26.01.05 04:43 (Tue, 25 Jan 2005 21:43:45 -0600)
From: Joseph J. Strout
At 12:25 AM +0100 1/26/05, Eirik Karlsen wrote:

>But an unforeseen problem came up: the cursor is not properly erased if
>the mouse is moving fast....
>
>However it did help quite a bit if I made cursorpicture wider, now using
>40 pixels. But its still not good enough.

Yes, there's clearly a logic problem here; erasing more only hides
the problem, but you couldn't hide it completely unless you go back
to redrawing the entire canvas.

The right solution is to store the X position at which the cursor was
drawn, and use that to erase. You said you tried this and it didn't
help, but I can only guess that there was a bug in there somewhere,
because that should work fine.

>I can't really see whats causing the cursor erase problem...I assume that
>the MouseMove sub is finished before it
>is re-called (as new event), and not called recursively ??

Right.

>Any suggestions?

Well, you're still doing way more work than you need to. Delete the
code you pasted into your email entirely, and replace it with:

Dim g as Graphics = CanvasGraph.graphics
g.UseOldRenderer = true
g.DrawLine x, 0, x, g.height

No need to involve any picture-drawing here; simply draw a line.
That draws the cursor. Now, you still need to erase the cursor --
you didn't show any code for doing that. But the whole thing should
look *something* like this:

Dim g as Graphics = CanvasGraph.graphics
g.UseOldRenderer = true

// erase old cursor, if any
if mOldCursorX >= 0 then
g.DrawPicture GraphCursor, X,0,1,g.height, X,0,1,g.height
end if

// draw new cursor (and remember where we drew it)
g.DrawLine x, 0, x, g.height
mOldCursorX = x

where mOldCursorX is a property of the window or canvas.

HTH,
- Joe

[RB List] More speed
Date: 27.01.05 22:15 (Thu, 27 Jan 2005 22:15:42 +0100)
From: Eirik Karlsen
Joseph,
have you had a chance to look at the code?