On Monday, June 11, 2007 11:36:10 Keith Packard wrote:
> On Mon, 2007-06-11 at 10:59 -0700, Jesse Barnes wrote:
> > The patch doesn't yet deal with two obvious cases (and probably more
> > that I'm missing, it's untested yet):
> >   - the hardware counter resets on mode switch, we need to rebase
> >     the appropriate last_counter at that point so it's not treated as
> >     a counter wrap
>
> I think this should be handled in the core by having an offset that
> relates the hardware counter to the software visible value. Mode setting
> would then 'rebase' the offset to make the user-visible value change
> smoothly:
>
>       pre_mode_set
>               old = current raw hardware counter
>       post_mode_set
>               new = current raw hardware counter
>               offset += old - new
>
> now create a 'cooked' hardware counter:
>
>       cooked hardware counter = offset + raw hardware counter

Yep, sounds reasonable.

>
> >   - a client interested in signals but also blocked on a vblank event
> >     may cause vblanks to be disabled if it received signal at the wrong
> >     time
>
> the core should track a per-crtc enable/disable count and call the
> driver when it transitions through zero.

Yeah, I think there's even a 'vbl_pending' counter I can use for this, though 
I'll have to make it atomic.

> > +   unsigned long last_vblank_count[2];
> > +   atomic_t vblank_count[2];
>
> For a first implementation, I suggest that the driver never store this
> value and just read from the registers every time it fetches the frame
> counter. You could 'optimize' reading when the interrupt was running by
> caching the last value, but this will be race-prone.

I'm using last_vblank_count to deal with wrapping (as you see below), and 
vblank_count is the total vblank value (including all wraps).

>
> > +   /*
> > +    * Now update the appropriate counter.
> > +    * Assume we haven't missed a full 24 bits of vblank
> > +    * events, or that it won't matter if they're not accounted
> > +    * for when we adjust for wrapping.
> > +    * FIXME: if count was zero'd due to modeset, need to rebase
> > +    */
> > +   spin_lock_irqsave(&dev->vbl_lock, irqflags);
> > +   if (count < dev_priv->last_vblank_count[crtc]) {
> > +           diff = 0xffffff - dev_priv->last_vblank_count[crtc];
> > +           diff += count;
> > +   } else {
> > +           diff = count - dev_priv->last_vblank_count[crtc];
> > +   }
> > +   dev_priv->last_vblank_count[crtc] = count;
> > +   spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> > +   atomic_add(diff, &dev_priv->vblank_count[crtc]);
> > +   return atomic_read(&dev_priv->vblank_count[crtc]);
>
> ick. just read the registers and return the value here. We should place
> wrap-detection in the core code by reporting the range of the register
> values; with the offset suggested above, that would result in a single
> addition to convert from raw to cooked frame counts.

Hm, yeah I guess it might be nicer in the core.  I was thinking that this 
would give the driver maximum flexibility and avoid the need for a 'max 
value' callback or field, but that may be a net win.

Thanks,
Jesse



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to