PtTrend question & bug report

bridged with qdn.public.qnxrtp.photon
Bill Caroselli

Re: New Question

Post by Bill Caroselli » Mon Sep 22, 2003 7:24 pm

Duah!

It makes sense. OK. Thanks.


Steve, you might want to document that!


Wojtek Lerch <wojtek_l@yahoo.ca> wrote:
WL > Bill Caroselli <qtps@earthlink.net> wrote:
Can someone at QSSL take a stab at this?
WL > PtBlit() damages the portion of the source rectangle that doesn't
WL > overlap with the destination rectangle. For instance, if you're
WL > blitting by one pixel to the right, it'll damage a one-pixel strip along
WL > the left adge of the rectangle.

WL > It also will damage any portions of the destination area where the
WL > corresponding source area is invisible (i.e. outside of the canvas; I
WL > don't think we handle cases where there's another widget on top of the
WL > one you're blitting). For instance, if you take a huge rectangle and
WL > blit it by one pixel to the left, it'll damage a one-pixel strip along
WL > the right edge of the canvas.

Dave Rempel

Re: New Question

Post by Dave Rempel » Tue Sep 23, 2003 1:00 pm

Bill Caroselli wrote:
I'm still waiting to find out why PtBlit() is damaging my widget
(I.E. forcing my draw_f() function ot be called.
Wojtek got that one...
I have a new problem.

In my draw function I call:
PhRect_t my_rect;
PtCalcCanvas( widget, &my_rect );
PgSetTranslation( &my_rect.ul, PgRELATIVE );
/* draw stuff */
my_rect.ul.x *= -1;
my_rect.ul.y *= -1;
PgSetTranslation( &my_rect.ul, PgRELATIVE );
where 'widget' is from the draw callback, and this works. Everything I
draw is where I expect it to be.

Later in the program some external event occurs and I try to display a
new object on the PtRaw widget. I call:
PhRect_t my_rect;
PtCalcCanvas( ABW_my_widget, &my_rect );
PgSetTranslation( &my_rect.ul, PgRELATIVE );
/* draw stuff */
my_rect.ul.x *= -1;
my_rect.ul.y *= -1;
PgSetTranslation( &my_rect.ul, PgRELATIVE );
but the translation is off. I.E. it draws too high. Above my PtRaw
widget actually. Note: I left the clipping off just so I could see
where it was drawing.

Why is my translation wrong?

In th PgSetTranslation(), PgRELATIVE is relative to what?
Note: there is no telling what widget had focus when the additional
draw was attempted.
The Translation is relative to the translation in the current GC. What
I think you really want to do is set some state on your PtRaw widget
(see "Storing arbitrary user data" in the doc's for PtWidget) that means
that you want to draw this new object. Then call PtDamageWidget on your
PtRaw so it get's drawn in the proper order (the current translation
should be what you expect it to be, as will be the clipping).
Bill Caroselli <qtps@earthlink.net> wrote:
BC > Bill Caroselli <qtps@earthlink.net> wrote:
BC > BC > Dave Rempel <drempel@qnx.com> wrote:
BC > BC > DR > Bill Caroselli wrote:

My thoughts were this:

2) Use a PtRaw and draw what I need as I need it. But can I blit my
PtRaw image?



BC > BC > DR > Yes, using PtBlit()

BC > BC > I'm using a PtRaw inside of a PtOSContainer inside of a PtPanelGroup
BC > BC > inside of my main window.

BC > BC > Also on my main window I have a PtButton I've added for diagnostic
BC > BC > purposes. It calls the routine that PtBlit()s my PtRaw by one pixel
BC > BC > row.

BC > BC > The blitting is working, *BUT* the draw function for my PtRaw is also
BC > BC > being called. Nothing should be damaging the widget.

BC > BC > Why is the draw function being called?

BC > BC > I'm using blitting because I don't want to redraw the whole thing!
BC > BC > The button that I'm clicking does not over lap PtPanelGrou in any way.

BC > I did a little more research. It is the call to PtBlit that is
BC > damaging the widget. If I comment out the PtBlit() call then my draw
BC > function does not get called.

BC > What am I doing wrong?

Bill Caroselli

Re: New Question

Post by Bill Caroselli » Tue Sep 23, 2003 1:12 pm

Dave Rempel <drempel@qnx.com> wrote:
DR > Bill Caroselli wrote:
I have a new problem.


Why is my translation wrong?
DR > The Translation is relative to the translation in the current GC. What
DR > I think you really want to do is set some state on your PtRaw widget
DR > (see "Storing arbitrary user data" in the doc's for PtWidget) that means
DR > that you want to draw this new object. Then call PtDamageWidget on your
DR > PtRaw so it get's drawn in the proper order (the current translation
DR > should be what you expect it to be, as will be the clipping).

Ouch!

My PtRaw is very complicated (i.e. many graphical objects). When some
external event occurs I merely want to draw one more dot on the screen,
and possibly erase one (draw it with background color and then draw the
adjacent dots).

If I damage the widget then I have to redraw *all* the dots. There can
be as many as 10,000 (more likely 3000 to 5000). And I want to do this
10 times a second. I can't draw the whole PtRaw 10 times a second.
The system isn't fast enough.

So, can I know the correct graphics context to draw my dots into?

Or, can my non-photon code somehow call a user defined callback for my
PtRaw widget? (That would force the correct GC right?)

Dave Rempel

Re: New Question

Post by Dave Rempel » Tue Sep 23, 2003 1:54 pm

Bill Caroselli wrote:
Dave Rempel <drempel@qnx.com> wrote:
DR > Bill Caroselli wrote:

I have a new problem.


Why is my translation wrong?



DR > The Translation is relative to the translation in the current GC. What
DR > I think you really want to do is set some state on your PtRaw widget
DR > (see "Storing arbitrary user data" in the doc's for PtWidget) that means
DR > that you want to draw this new object. Then call PtDamageWidget on your
DR > PtRaw so it get's drawn in the proper order (the current translation
DR > should be what you expect it to be, as will be the clipping).

Ouch!

My PtRaw is very complicated (i.e. many graphical objects). When some
external event occurs I merely want to draw one more dot on the screen,
and possibly erase one (draw it with background color and then draw the
adjacent dots).

If I damage the widget then I have to redraw *all* the dots. There can
be as many as 10,000 (more likely 3000 to 5000). And I want to do this
10 times a second. I can't draw the whole PtRaw 10 times a second.
The system isn't fast enough.
Generally a widget's draw function shouldn't do a lot of work (this
includes PtRaw's). Given that, then what I think you want to do is
create an offscreen context to hold what your PtRaw should currently
look like (PdCreateOffscreenContext()). You can then update the
offscreen context to look like what ever you want, when ever you want.
In your PtRaw's draw function you call PgContextBlit or
PgContextBlitArea to copy the contents of the offscreen context to the
location of your PtRaw widget's canvas. You can be even smarter about
it and look at the damage rects (remember to look starting at the second
one, since the first damage rect is always the entire canvas) and copy
just the portions you need. Offscreen Contexts are hardware
accelerated, so they are better than PhImage_t's and Memory Context's
generally. The other change you would have to do is instead of using
PtBlit you'd have to use PgContextBlit with the offscreen context as the
source and destination contexts. IIRC you are also using a
PtOSContainer already, you probably won't need it if you are using this
method to reduce flicker, but if you still need it for other reasons,
make sure that in your widget draw function that you call
PhDCGetCurrent() for the destination context parameter of
PgContextBlit(), since you will be wanting to blit to the OSContainers's
offscreen context, not the actual display (OS Container's offscreen
context needs to kept up to date so that it can handle exposes
correctly). It's generally good practice to use PhDCGetCurrent() for
blitting to the "screen" instead of NULL anyways.

Look at "Raw Drawing and Animation: Video Memory Offscreen" for
examples of using an offscreen context.
So, can I know the correct graphics context to draw my dots into?

Or, can my non-photon code somehow call a user defined callback for my
PtRaw widget? (That would force the correct GC right?)
No, there is only (generally) one GC that gets used by the widget
engine, and it's translation and clipping is constantly changing, so the
only way for it to be gaurunteed to be correct is in the widgets draw
function when the widget engine calls it.

Dave Rempel

Re: New Question

Post by Dave Rempel » Tue Sep 23, 2003 4:07 pm

Oops, this part came out completely wrong....
"(remember to look starting at the second one, since the first damage
rect is always the entire canvas)"

I meant to start walking the list using the second rect if it's there,
otherwise use the first....

Dave

Steve Reid

Re: New Question

Post by Steve Reid » Wed Sep 24, 2003 2:01 pm

Bill Caroselli <qtps@earthlink.net> wrote:
: Duah!

: It makes sense. OK. Thanks.


: Steve, you might want to document that!

I don't work on the Photon docs anymore; done enough damage there -- time
for new victims. :-)

I've told the writer about this thread.

------------------------------------------
Steve Reid stever@qnx.com
TechPubs (Technical Publications)
QNX Software Systems
------------------------------------------

Bill Caroselli

Re: New Question

Post by Bill Caroselli » Wed Sep 24, 2003 5:30 pm

I'm now trying to draw text into my PtRaw.

The Text down't show up on the widget. The code looks something like
this:

void my_fraw_f( PtWidget_t * widget, PhTile_t * damage )
{
PhRect_t canvas;
PhPoint_t p;
char helv [ MAX_FONT_TAG ];
char text [] = "text";
PtCalcCanvas( widget, &canvas );
if( PfGenerateFontName( "Helvetica, 0, 8, helv ) == 0 )
// error
PgSetFont( helv );
PgSetTextColor( Pg_BLACK );
p.x = canvas.ul.x + 100; // the size of my PtRaw is 500 x 500
p.y = canvas.ul.y + 100;
if( PgDrawText( text, strlen( text ), &p, Pg_TEXT_BOTTOM ) == -1 )
// error
}

This is a very stripped down version of what I'm using. Hopefully I'm
not leaving out anything important.

I am NOT getting an error from either call that I'm checking.

What am I missing?

Bill Caroselli

Re: New Question

Post by Bill Caroselli » Wed Sep 24, 2003 5:45 pm

Bill Caroselli <qtps@earthlink.net> wrote:
BC > I'm now trying to draw text into my PtRaw.

BC > The Text down't show up on the widget. The code looks something like
BC > this:

BC > void my_fraw_f( PtWidget_t * widget, PhTile_t * damage )
^^^^
draw

BC > {
BC > PhRect_t canvas;
BC > PhPoint_t p;
BC > char helv [ MAX_FONT_TAG ];
BC > char text [] = "text";
BC > PtCalcCanvas( widget, &canvas );
BC > if( PfGenerateFontName( "Helvetica, 0, 8, helv ) == 0 )
BC > // error
BC > PgSetFont( helv );
BC > PgSetTextColor( Pg_BLACK );
BC > p.x = canvas.ul.x + 100; // the size of my PtRaw is 500 x 500
BC > p.y = canvas.ul.y + 100;
BC > if( PgDrawText( text, strlen( text ), &p, Pg_TEXT_BOTTOM ) == -1 )
BC > // error
BC > }

BC > This is a very stripped down version of what I'm using. Hopefully I'm
BC > not leaving out anything important.

BC > I am NOT getting an error from either call that I'm checking.

BC > What am I missing?

--
Bill Caroselli -- Q-TPS Consulting
1-(708) 308-4956 <== Note: New Number
qtps@earthlink.net

Misha Nefedov

Re: New Question

Post by Misha Nefedov » Wed Sep 24, 2003 6:19 pm

"Bill Caroselli" <qtps@earthlink.net> wrote in message
news:bksl7p$9sn$3@inn.qnx.com...
Bill Caroselli <qtps@earthlink.net> wrote:
BC > I'm now trying to draw text into my PtRaw.

BC > The Text down't show up on the widget. The code looks something like
BC > this:

BC > void my_fraw_f( PtWidget_t * widget, PhTile_t * damage )
^^^^
draw

BC > {
BC > PhRect_t canvas;
BC > PhPoint_t p;
BC > char helv [ MAX_FONT_TAG ];
BC > char text [] = "text";
BC > PtCalcCanvas( widget, &canvas );
BC > if( PfGenerateFontName( "Helvetica, 0, 8, helv ) == 0 )
BC > // error
; //error
BC > PgSetFont( helv );
BC > PgSetTextColor( Pg_BLACK );
BC > p.x = canvas.ul.x + 100; // the size of my PtRaw is 500 x 500
BC > p.y = canvas.ul.y + 100;
BC > if( PgDrawText( text, strlen( text ), &p, Pg_TEXT_BOTTOM ) == -1 )
BC > // error
BC > }

BC > This is a very stripped down version of what I'm using. Hopefully
I'm
BC > not leaving out anything important.

BC > I am NOT getting an error from either call that I'm checking.

BC > What am I missing?

--
Bill Caroselli -- Q-TPS Consulting
1-(708) 308-4956 <== Note: New Number
qtps@earthlink.net

Bill Caroselli

Re: New Question

Post by Bill Caroselli » Wed Sep 24, 2003 6:50 pm

Misha Nefedov <mnefedov@qnx.com> wrote:

MN > "Bill Caroselli" <qtps@earthlink.net> wrote in message
MN > news:bksl7p$9sn$3@inn.qnx.com...
Bill Caroselli <qtps@earthlink.net> wrote:
BC > I'm now trying to draw text into my PtRaw.

BC > The Text down't show up on the widget. The code looks something like
BC > this:

BC > void my_draw_f( PtWidget_t * widget, PhTile_t * damage )
BC > {
BC > PhRect_t canvas;
BC > PhPoint_t p;
BC > char helv [ MAX_FONT_TAG ];
BC > char text [] = "text";
BC > PtCalcCanvas( widget, &canvas );
BC > if( PfGenerateFontName( "Helvetica, 0, 8, helv ) == 0 )
BC > // error
MN > ; //error

My error comment is actually a statement block with about 5 lines.

That wasn't the problem.

The only other issue is that this PtRaw is being PtBlit()'ed.
But the draw occurs after th blit.

Martin Tilsted

Re: New Question

Post by Martin Tilsted » Mon Sep 29, 2003 10:09 pm

The problem might be that you try to draw in an area that is not
damaged. You can't do that.

Just a guess/hint for the problem. I don't have any connection with qnx.

Martin Tilsted

Bill Caroselli wrote:
Misha Nefedov <mnefedov@qnx.com> wrote:

MN > "Bill Caroselli" <qtps@earthlink.net> wrote in message
MN > news:bksl7p$9sn$3@inn.qnx.com...

Bill Caroselli <qtps@earthlink.net> wrote:
BC > I'm now trying to draw text into my PtRaw.

BC > The Text down't show up on the widget. The code looks something like
BC > this: [Cut of code]

Bill Caroselli

Re: New Question

Post by Bill Caroselli » Tue Sep 30, 2003 1:11 pm

Martin Tilsted <tiller@daimi.au.dk> wrote:
MT > The problem might be that you try to draw in an area that is not
MT > damaged. You can't do that.

MT > Just a guess/hint for the problem. I don't have any connection with qnx.


By Jingles! I think you've got it!

Actually, I've completely changed the design of the Window and I think
I have it working now. BUT . . . I do believe that that was part of the
problem.

Is it docuemnted anywhere that I can't do subsequent draws into a part
of a PtRaw that isn't damaged?

Martin Tilsted

Can't draw in non damaged widget. [Doc people: look here]

Post by Martin Tilsted » Tue Sep 30, 2003 6:13 pm

Bill Caroselli wrote:
Martin Tilsted <tiller@daimi.au.dk> wrote:
MT > The problem might be that you try to draw in an area that is not
MT > damaged. You can't do that.

Is it docuemnted anywhere that I can't do subsequent draws into a part
of a PtRaw that isn't damaged?
I don't think so. I had the same problem once. I think the problem is
that someone(Photon I think) setup clipping which normaly is a good
thing. But it should be in the docs :}

Maybe we should ask the doc people to add it :}

Martin

Wojtek Lerch

Re: New Question

Post by Wojtek Lerch » Tue Sep 30, 2003 6:22 pm

Bill Caroselli <qtps@earthlink.net> wrote:
Is it docuemnted anywhere that I can't do subsequent draws into a part
of a PtRaw that isn't damaged?
No, because that wouldn't be true.

In principle, you can draw anywhere you want. Trouble is, there are a
lot of details that affect where your draw commands will draw (and
whether they'll draw anything at all) -- the current region,
translation, several kinds of clipping, and so on. If you damage a
portion of your raw widget, the library sets everything up for you and
then calls your draw function, and all you need to do is the actual
drawing. But if you skip the part where you damage the widget, you're
skipping the part where the library sets things up for you, too, and
you'll have to set them up yourself -- and since it's quite a few things
that you need to set up, it's easy to screw one or two of them up.

Wojtek Lerch

Re: New Question

Post by Wojtek Lerch » Tue Sep 30, 2003 6:45 pm

Bill Caroselli <qtps@earthlink.net> wrote:
The only other issue is that this PtRaw is being PtBlit()'ed.
But the draw occurs after th blit.
PtBlit() can be tricky.

Currently, PtBlit() calls PtFlush() before blitting anything. This is
how PtBlit() is trying to avoid blitting garbage to places that are
undamaged and aren't going to be redrawn.

This means that if your widget is damaged, your draw function will be
called from *inside* of PtBlit, and it'll be expected to draw the *old*
state (pre-blit) of the widget. You shouldn't modify any variables
that your draw function depends on until after the PtBlit(): otherwise,
you'll end up drawing the post-blit state of the widget (or maybe even
some inconsistent mixture of states) before the blit happens -- and as a
result, some portions of your widget may look like they've been blitted
twice. Or worse.

Does this possibly explain what you're seeing?

BTW In QNX 6.3, PtBlit() will not call PtFlush(). Instead, it'll play
with damage lists and only blit the portion that's not damaged, and
damage any remaining portions appropriately.

Post Reply

Return to “qdn.public.qnxrtp.photon”