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