Android: segfault rendering mouse cursor

Lucas Stach l.stach at pengutronix.de
Mon Jul 23 15:12:12 UTC 2018


Hi Martin,

Am Montag, den 23.07.2018, 16:42 +0200 schrieb Martin Fuzzey:
> Hi,
> 
> on Android 8.1, etnaviv, gbm-gralloc, i.MX6 I get a segfault in input 
> flinger when using a mouse.
> 
> This is because input flinger uses software rendering to draw the mouse 
> pointer like this [frameworks/base/libs/input/SpriteController.cpp]
> 
>                  sp<Surface> surface = 
> update.state.surfaceControl->getSurface();
>                  ANativeWindow_Buffer outBuffer;
>                  status_t status = surface->lock(&outBuffer, NULL);
> 
>                  SkBitmap surfaceBitmap;
>                  ssize_t bpr = outBuffer.stride * 
> bytesPerPixel(outBuffer.format);
> #if 0
>                  int hacked_stride = 32;
>                  ALOGI("@MF@ hacking stride %d=>%d", outBuffer.stride, 
> hacked_stride);
>                  bpr = hacked_stride * bytesPerPixel(outBuffer.format);
> #endif
> 
> surfaceBitmap.installPixels(SkImageInfo::MakeN32Premul(outBuffer.width, 
> outBuffer.height),
>                                              outBuffer.bits, bpr);
>                  SkCanvas surfaceCanvas(surfaceBitmap);
> 
>                  ... (drawing code omitted)
> 
>                  status = surface->unlockAndPost();
> 
> 
> Where surface is 29x37 pixels
> 
> The problem is that etnaviv allocates a tiled buffer with a stride of 
> 256 bytes (64 pixels).
> 
> This stride is obtained from gralloc.
> 
> 
> However when the buffer is mapped for software rendering a linear mapped 
> transfer buffer of a stride of 128 bytes (32 pixels) is allocated and 
> mapped.
> 
> So, when the software renderer uses the stride obtained from gralloc to 
> write into the locked buffer an overflow occurs, usually resulting in a 
> segfault.
> 
> 
> Activating the hack in #ifdef above (which changes the stride from 64 to 
> 32 pixels) makes it work but is obviously not the right solution.
> 
> 
> The fundemental problem here seems to be that Android requires the 
> stride to be returned during the buffer *allocation* whereas, when the 
> internal and transfer buffers can have different geometries as for 
> etnaviv, we really want to get the stride from the lock / map operation. 
> Unfortunately we can't change the Android API here...
> 
> 
> I also tried modifying gralloc to "lie" about the stride (just for 
> buffers the size of the mouse pointer as a test).
> 
> But that causes "BO stride 128 is too small for RS engine width padding 
> (256, format PIPE_FORMAT_R8G8B8A8_UNORM)"
> 
> 
> The only way I can think of fixing this would be to artificially 
> increase the stride of the transfer buffer to match that of the tiled 
> buffer.
> 
> Of course that would waste some memory.

This is the same issue as was hit by the AMD guys when dealing with
gralloc. See thread
"[PATCH 00/10] DRI interface, gallium: User-specified transfer stride"
on the Mesa-dev list and related discussions. Unfortunately I don't
think this has been resolved yet. Maybe you can get the ball rolling on
this one again.

Regards,
Lucas


More information about the etnaviv mailing list