In the function hline_clip(..) in gdisp.c, the following code is executed when GDISP_HARDWARE_FILLS is defined:
// This is an optimization for the point case. It is only worthwhile however if we
// have hardware fills or if we support both hardware pixel drawing and hardware streaming
#if GDISP_HARDWARE_FILLS || (GDISP_HARDWARE_DRAWPIXEL && GDISP_HARDWARE_STREAM_WRITE)
// Is this a point
if (g->p.x == g->p.x1) {
drawpixel(g);
return;
}
#endif
// Best is hardware accelerated area fill
#if GDISP_HARDWARE_FILLS
#if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
if (gvmt(g)->fill)
#endif
{
g->p.cx = g->p.x1 - g->p.x + 1;
g->p.cy = 1;
gdisp_lld_fill_area(g);
return;
}
#endif
I think the problem that I see is that drawpixel(..) is aware of the GDISP_FLG_SCRSTREAM flag, acquires the bus only if this flag is not set, and does not release the bus. However, the SSD2119 version of gdisp_lld_fill_area(..) (as well as many of the others that I checked) does not seem to be aware of this GDISP_FLG_SCRSTREAM flag, always acquires the bus and always releases the bus.
So if this hline_clip(..) function is being called in a loop, as it is when drawing text, then depending on the order of single pixels vs. areas drawn we can mismanage the bus ownership. For instance, if we draw a single pixel and then an area, we will try to acquire the bus twice in a row, then perform a single release. Then if we draw another single pixel the GDISP_FLG_SCRSTREAM flag is already set and we attempt to access the bus without a first acquiring it.
Have I misunderstood the intent of the acquire_bus(..) and release_bus(..) functions and they are supposed to implement reference counting?