Re: ScreenSaverView/NSQuickDrawView/Opaque issue [solved]
Re: ScreenSaverView/NSQuickDrawView/Opaque issue [solved]
- Subject: Re: ScreenSaverView/NSQuickDrawView/Opaque issue [solved]
- From: "Andy O'Meara" <email@hidden>
- Date: Sat, 04 Jun 2005 00:14:01 -0400
I wanted to post that I found a solution for two of the problems described
in my previous post (also copied below), so that other folks don't have to
burn the time that I did on this crazy issue...
The secret is to call QDFlushPortBuffer() right before your
NSQuickDrawView's unlock() is called. This signals to the mysterious Quartz
netherworld that a the port's rect has been drawn to and should be flushed
to screen. The other implied step here is the NSQuickDrawView isOpaque is
overriden to return YES (as well as its host view, depending on how you have
your views set up). Enjoy!
Andy
P.S. Now that we're all going to be one happy little endian family, I move
that we rename Cocoa-dev maillist to "ocoCed-a\0\0\0v". Excuse me while I
go cry/vomit/gag.
On 6/3/05 9:17 AM, "Andy O'Meara" <email@hidden> wrote:
>
> I was hoping to get some bites on my help request from a few days ago
> (appended below), but nothing thus far. After several additional hours of
> experimentation, guessing, and checking I've made some progress (I thought I
> left this kind of workflow behind with Windows programming, but I guess
> not).
>
> So that folks like me may benefit, I wanted to share my root
> issues/mysteries (and this doesn't just apply to screen savers--if you use
> NSQuickDrawView, this is also for you). I apologize in advance if some of
> there are novice Cocoa comments/mysteries... If anyone can shed some light
> on the following issues, I'd be very grateful.
>
> - Is there anyway to have an NSQuickDrawView *not* erase the entire pane
> rect each drawRect? My child class of NSQuickDrawView overrides drawRect()
> and I do a CopyBits to the view's qdPort during that. Apparently, unless I
> CopyBits over the entire pane rect, the part I don't copy over is black (vs.
> going unchanged from whatever was there). For example, my visual engine
> blts a splash frame and then does no drawing for the following couple frames
> while it bootstraps, so what's seen is an initial flash of my splash
> followed by a couple seconds of blackness, followed by normal output. So,
> again, is there any way to have an NSQuickDrawView *not* erase the entire
> pane rect each draw? I don't think it's very impressive that the
> documentation page for NSQuickDrawView consists of a total of three
> sentences.
>
> - Suppose you put your child class of NSQuickDrawView inside a NSView (or
> ScreenSaverView in my case). If you override your NSQuickDrawView's
> isOpaque to return YES, drawRect() never gets called (in my case, triggered
> from calling setNeedsDisplay from my ScreenSaverView's animateOneFrame()).
> Sure, the NSQuickDrawView will get drawRect() following window layer changes
> and obscures, but setNeedsDisplay won't cause a redraw weather I send it to
> the parent view of my NSQuickDrawView or the NSQuickDrawView itself. This
> one baffles me.
>
> - Overriding my ScreenSaverView's drawRect() proc, surprisingly causes the
> setNeedsDisplay calls (made from animateOneFrame) to no longer trigger
> drawRect() calls to my NSQuickDrawView. In other words, NSView's drawRect()
> appears do more than just draw a black rect--it appears to draw its subviews
> as well. However, since there's no NSView implementation to look at, I'm
> all of sudden a little helpless to mimic NSView's drawRect (but without a
> black rect). So, it would be nice to have access Apple's implementation of
> NSView to see what goes in certain NSView calls by default. Back when
> Metrowerks CodeWarrior was the big kid on the block for serious Mac OS app
> development, there was no better way to learn Classic/Carbon Mac OS *and*
> PowerPlant than by looking at how PowerPlant implemented its core classes.
> That said, can the the core AppKit implementations be found anywhere? -- I'd
> take that over the one-sentence descriptions found in Apple's Reference any
> day of the week...
>
>
> Thanks in advance for any assistance...
>
>
> Andy
>
>
> ------ Previous Message ------
>
> From: Andy O'Meara <email@hidden>
> Date: Tue, 31 May 2005 21:12:06 -0400
> To: Cocoa-Dev Mail <email@hidden>
> Subject: ScreenSaverView/Opaque/Update issue
>
>
> I've already searched the archives and spent a long time on this, so I'm
> really hoping someone has some insight on this seemingly simple
> ScreenSaverView issue...
>
> I currently create each output frame in an off-screen GWorld, and when tone
> is done, I call CopyBits() to a NSQuickDrawView that's inside my
> ScreenSaverView. This is very similar to the method used in Apple's
> "MungSaver".
>
> So everything is working well with my ScreenSaverView, with the exception of
> a nasty flicker that happens after the first frame is drawn... After
> investigating, it seems that that since NSView::isOpaque returns NO by
> default, the "Desktop & Screen Saver" window went to draw the superview
> before drawing the frame (accounting for the nasty initial flicker). No
> problem, I say, I'll just override isOpaque to return YES... The good news
> is that the initial flicker is of course gone, but the baffling issue is
> that now new frames only seem to appear when the host window changes layers
> or needs to get refreshed. Otherwise, the frame is never updated. My logs
> clearly show that *both* animateOneFrame and drawRect are firing, yet the
> the ScreenSaverView rect is only ever visibly updated when I activate any
> window in the OS. It's as if the window store wasn't getting flushed to
> screen despite the fact setNeedsDisplay is set to YES (keep in mind:
> changing isOpaque() to always return NO makes this problem go away with no
> other changes to the code).
>
> I've already tried things like putting a shotgun of lockFocus and
> unlockFocus calls everywhere, and sticking in flush and update calls, but no
> go. Below are the relevant snippets...
>
> Thanks in advance,
> Andy
>
>
>
>
> - (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
> {
> ...
> // Make the NSQuickDrawView
> mQDView = [[NSQuickDrawView alloc] initWithFrame:NSZeroRect];
>
> // make sure the subview resizes
> [ self setAutoresizesSubviews:YES ];
> [ self addSubview:mQDView ];
> [ mQDView release ];
> ...
> }
>
>
>
> - (void)startAnimation
> {
> [super startAnimation];
> ...
>
> // the first time lockFocus is called on the NSQuickDrawView
> // it creates a valid qdPort - we need this to draw into and
> // before this is done, qdPort is NULL
> if ( [mQDView qdPort] == NULL ) {
> [mQDView lockFocus];
> [mQDView unlockFocus];
> }
> ...
> }
>
>
>
> - (void)animateOneFrame
> {
> [self setNeedsDisplay: YES];
> }
>
>
> - (void)drawRect:(NSRect)rect
> {
> ...
> CopyBits( ... , [mQDView qdPort], ... );
> ...
> }
>
>
> // end snippets
>
>
>
> ------ End of Forwarded Message
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden