On Mon, 16 Dec 2002, Rodolphe Ortalo wrote:
> once again, I think I hit the problem of synchronizing the accelerator
> drawings and the drawings made directly in the framebuffer by
> (unaccelerated) drawing operations.
>  It seems there is a provision for such synchro in ggi_visual (especially
> with the fields needidleaccel and accelactive).

Yes, but there's some improvements needed as well IMO.  Actually
you're right to be confused.  I think this was, well, not necessarily
"hacked up" when originally implemented, but not though entirely to its
logical conclusion.

>  I'm looking for more information on this topic, and possibly pointers to
> example code inside libggi where this is used. (How is it supposed to
> operate? Is there a function that should be provided by the
> accelerator-specific sub lib to allow the sync?)

vis->opdisplay->idleaccel should be loaded with your target's 
accelerator idling funtion.

When a mode is set, the target is supposed to set vis->needidleaccel
if it wants the stubs renderer to provide accelerator-friendly pixel
functions.  When the stubs renderer is opened, it checks the field and
loads the pixel routines from pixel.c if there is no need for
accelerator idling (needidleaccel == 0), or from pixela.c if there is
a need (needidleaccel != 0).

A sublib that has the need for idling the accelerator should provide
at least hline, vline, box; e.g. it should not leave solid-fill
primitives to the generic renderers, because the generic libs only
contain "accelerator aware" versions of the single-pixel functions.

The pixela functions call PREPARE_FB(vis) before altering the
framebuffer.

PREPARE_FB(vis) in ggi-dl.h checks to see if accelactive is true, and
if it is, then it calls LIBGGIIdleAccel(vis) (a macro) which calls
vis->opdisplay->idleaccel.  Note it does not check that there is
actually a function pointer hooked there, so it is important that
accelactive never be raised unless this pointer has been initialized.

(Note for some reason the stubs target uses the non-macro function
form _ggiIdleAccel.  I don't know why it is this way and perhaps that
is just leftovers from before the macro was defined.)

Now, that's the way it's *supposed* to work.  The xf86dga target code
still in CVS is a good example of this.

In reality, and the reason why the fbdev target is currently hacked to
always load pixela functions, is that some targets *do*not*know*
whether they have accelleration until they have tried to load an
accelerated sublib.  If for one of many reasons the sublib cannot be
loaded, then the pixel functions should be reverted to non-accelerated
versions.  Unfortunately by the time this is known, it is too late:
the generic renderer is loaded before the accelarated sublibs are tried,
and once it chooses between the pixel or pixela drawops, the function
pointers to the other set are lost for good.  Early targets just assumed 
that the sublib was available based on a simplistic check.

The generic renderers have to be loaded before the accelerated
renderers so that the accelerated renderers can overload selected
pointers.  Re-loading the generic renderers a second time to get the 
pixela functions back would cause the generic renderer to stomp on the 
accelerated renderer's function pointers.

IMO what needs to be done is to have renderers included in the 
ggiIndicateChange() callback facility, and when an accelerator is
loaded, the generic renderers will be able to swap the function
pointers appropriately.

(BTW, This is just one of many symptoms of the dl system needing to be
taken one step further than it already goes.  See the "dummyfunc"
hacks and such used in most extensions for another.)

--
Brian

Reply via email to