Page MenuHomeFreeBSD

stand: Bulk operations on each gfxfb_blt if shadow buffer enabled
AcceptedPublic

Authored by aokblast on Sun, May 31, 3:24 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Jun 8, 8:32 AM
Unknown Object (File)
Mon, Jun 8, 7:45 AM
Unknown Object (File)
Mon, Jun 8, 2:53 AM
Unknown Object (File)
Fri, Jun 5, 11:44 PM
Unknown Object (File)
Fri, Jun 5, 10:14 PM
Unknown Object (File)
Fri, Jun 5, 7:00 PM
Unknown Object (File)
Thu, Jun 4, 12:30 PM
Unknown Object (File)
Thu, Jun 4, 7:47 AM

Details

Summary

Previously, gfxfb_blt flushed the framebuffer on every call. Since a
single drawing operation may invoke gfxfb_blt multiple times, this can
result in unnecessary flushes.

Instead, write updates to the shadow buffer (when present) and mark the
affected area as dirty. Flushing is deferred so multiple gfxfb_blt calls
can be coalesced into a single update. As before, only the dirty region
is flushed.

This fixes the slow bootloader problem in some platforms.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 73590
Build 70473: arc lint + arc unit

Event Timeline

Flush and read from the framebuffer directly while doning framebuffer -> buffer

hi! Oh, so this is to flush a partial region of the shadow frame buffer rather than the whole framebuffer? How does this accelerate things given the current framebuffer API in stand/ doesn't have an explicit flush() ? (ie, i think every putchar() is an individual rectangle blit, no?)

stand/common/gfx_fb.c
937

Maybe refactor this into a separate routine (gfxfb_blt_shadow() ?) and call that if needed?

(ie, can you list some of the drawing done by the bootloader that's being accelerated by this?)

(ie, can you list some of the drawing done by the bootloader that's being accelerated by this?)

This works not because of partially flushing. It is because we aggregate multiple flush into one single operation. For example, gfx_fb_drawrect flushes four times as we call gfxfb_blt four times. Now, gfxfb_blt does not flush the buffer and waiting for gfx_fb_flush call. It just writes to the shadow buffer. Then there is a explicit flush operation to flush the buffer.

I like this. I haven't delved into the fine details though, but it looks like adrian is, so my acceptance is conditional on making him happy.

This revision is now accepted and ready to land.Sun, May 31, 4:39 PM

ok, i see where the multiple flushing is happening now. and yeah this makes drawing a single pixel have even more overhead! But that's not specifically your problem, its the API that's exposed.

stand/common/gfx_fb.c
943

Note - reads can be really really slow; if you're not using the shadow buffer then (a) the flush may occur extra overhead if someone's doing some read/modify/write operations, and (b) one of the reasons for having the shadow buffer /is/ to accelerate reads.

If we're concerned about reading the existing firmware screen and it being inconsistent then we should consider just doing a full screen blank first (which i thought we were doing), or reading the framebuffer into the shadow buffer.

(ie, can you list some of the drawing done by the bootloader that's being accelerated by this?)

stand/common/gfx_fb.c
943

The only place uses read is in gfx_fb_cons_display. And it has gfx_state.tg_shadow_fb != NULL with early returns without calling read. We never read from framebuffer if shadow_fb is available.

Also, we still need to flush the shadow buffer before writing to shadow buffer as it might be dirty.

And if we are not using shadow buffer, tg_dirty will be false and thus it is just a if statement in gfx_fb_flush.

adrian added inline comments.
stand/common/gfx_fb.c
943

ok, if this stuff needs to get faster for some other weird usecase then we can do that. Thanks!