[PATCH and additional rambling] cache glyphs in the destination format requested to make sure the hardware can use the cached glyphs

Michael macallan at netbsd.org
Sat Jan 14 17:30:50 UTC 2017


Hello,

On Fri, 13 Jan 2017 11:14:47 +0900
Michel Dänzer <michel at daenzer.net> wrote:

> [ Re-adding the xorg-devel list to Cc ]
> 
> On 12/01/17 02:01 AM, Michael wrote:
> > On Tue, 10 Jan 2017 16:46:35 +0900
> > Michel Dänzer <michel at daenzer.net> wrote:  
> >> On 09/01/17 07:36 AM, Michael Lorenz wrote:  
> >>> From: Michael Lorenz <macallan at netbsd.org>
> >>>
> >>> Signed-off-by: Michael Lorenz <macallan at netbsd.org>
> >>> ---
> >>>  exa/exa_glyphs.c | 6 +-----
> >>>  1 file changed, 1 insertion(+), 5 deletions(-)
> >>>
> >>> diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
> >>> index 192a643cc..7386d05e9 100644
> >>> --- a/exa/exa_glyphs.c
> >>> +++ b/exa/exa_glyphs.c
> >>> @@ -544,7 +544,6 @@ exaBufferGlyph(ScreenPtr pScreen,
> >>>                 INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst)
> >>>  {
> >>>      ExaScreenPriv(pScreen);
> >>> -    unsigned int format = (GetGlyphPicture(pGlyph, pScreen))->format;
> >>>      int width = pGlyph->info.width;
> >>>      int height = pGlyph->info.height;
> >>>      ExaCompositeRectPtr rect;
> >>> @@ -554,13 +553,10 @@ exaBufferGlyph(ScreenPtr pScreen,
> >>>      if (buffer->count == GLYPH_BUFFER_SIZE)
> >>>          return ExaGlyphNeedFlush;
> >>>  
> >>> -    if (PICT_FORMAT_BPP(format) == 1)
> >>> -        format = PICT_a8;
> >>> -
> >>>      for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
> >>>          ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
> >>>  
> >>> -        if (format == cache->format &&
> >>> +        if (pDst->format == cache->format &&
> >>>              width <= cache->glyphWidth && height <= cache->glyphHeight) {
> >>>              ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen,
> >>>                                                                    &pExaScr->
> >>>     
> >>
> >> Unfortunately, testing reveals that this doesn't work correctly in
> >> general when exaGlyphs is called with maskFormat == NULL, I suspect
> >> because pDst->format may not have any alpha bits here in that case. This
> >> results e.g. in some missing text in xfce4-terminal for me.  
> > 
> > Hmm, I tested this with a whole lot of gtk2 applications and didn't see
> > this - I'll build xfce4 now.
> > That looks like the case in exaGlyphs() where exaBufferGlyphs() is
> > called to render directly to the destination, not into an intermediate
> > mask, which then may not find an appropriate glyph cache if the
> > destination is something like XRGB. Maybe it should fall back to A8
> > ( or the glyph's format ) in that case.  
> 
> I tried that quickly, but couldn't get it to work correctly. I might
> have missed something silly in my attempt though.

Stupid question - I can't seem to get xfce built right now - do you see
problems elsewhere? I tried things like mate-terminal, firefox,
bluefish, pidgin etc. without problems, with radeon or glint + exa.
Then again, exaGlyphs() ( or whatever calls it ) seems to behave
strangely in some cases anyway - my xrender code for suncg14/SX
( which, being a more or less freely programmable vector processor, can
support A8 textures ) doesn't even get the initial
CheckComposite(PictOpAdd,...) call, ends up using UploadToScreen on A8
glyphs and simple Copy() operations to assemble them into lines. 

> > Or maybe the check which format the driver likes its glyphs in
> > should be done early and exaBufferGlyphs() should use that instead
> > of pDst->format, that way all glyphs would be cacheable, we wouldn't
> > allocate an A8 pixmap in exaGlyphs() just to throw it away
> > immediately every time it's called etc.  
> 
> Something like that might be nice.

How about a driver flag which states that the driver does not support
A8 textures in any way, skips the check if set and goes straight for
ARGB?

Something more general - I've been (re-)adding support for hardware
acceleration on a bunch of older chips, and a few of them do not fit
EXA's expectations, to varying degrees.
The most common problem is no support for byte offsets, which can be
worked around by forcing all off-screen pixmaps to align to the visible
area's stride. Wastes some space but works.
Some of these chips ( like Sun's Creator series, or SGI's Crime engine
) can support xrender operations, and on those systems the CPUs tend to
be slow so they need any help they can get. The SGI case is easy enough
- we just lack byte offsets and the thing can accelerate all OpenGL
blending operations, at speeds roughly in line with early radeons. A8
Textures are tricky though.
The Creator is weirder - it's got what Sun calls '3dRAM' - little ALUs
built into the memory chips which can do things like ROPs and alpha
blending. So basically you can set up a few registers, then write a
texture into memory and have it PictOpOver-ed at more or less the speed
you can get it through the UPA bus. The 'blitter' has no copy
operation, and it can't handle A8 textures, so storing textures in video
RAM is useless. Also, its organization is weird and, for off-screen
areas, undocumented.
What would be a sane way to make EXA deal with these? I'm not asking
for EXA to change to accommodate old and weird hardware, but I bet
there are other cases where we'd want to do blending operations
directly from RAM to VRAM. What I'm thinking of doing in that case is
to just set aside some actual RAM and coax EXA into using that as
off-screen memory. Or have the driver replace exaGlyphs().

have fun
Michael


More information about the xorg-devel mailing list