Possibly a low level graphic bug? Using a non-simp...
# compose-android
r
Possibly a low level graphic bug? Using a non-simple round corner rectangle shape creates a glitchy shadow Check attached image, note how bad shapes near the screen bottom have a horizontal bar in their shadow. Some observations: • Only repro in portrait mode (I have no idea why) • Only repro when shape is showing near the bottom of screen • Only repro when RoundedCornerShape have at least one corner size is different than others (that is, a non-simple rounded corner rectangle) • Does't repro when shadow elevation is very large (usually > 16.dp), or when corner size is very large (usually > 24.dp) • Doesn't repro if the path in the Shape is built with addRoundRect(..., direction = Clockwise) (the default value is CCW) (again, no idea why) • Repros on various API levels • I'm using Jetpack compose 1.7.2, upgrading to newest version doesn't change anything
Copy code
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun ShadowDemo() {
    LazyColumn (
        modifier = Modifier
            .fillMaxSize()
            .background(color = Color.Yellow),
        verticalArrangement = Arrangement.spacedBy(16.dp),
        contentPadding = PaddingValues(16.dp)
    ) {
        items(100) { index ->
            val density = LocalDensity.current
            val elevation = index.dp
            val corner = index.dp
            val goodShape = RoundedCornerShape(corner)
            val badShape = RoundedCornerShape(bottomStart = corner, bottomEnd = corner)
            // val badShapeClockwise = badShape.clockwise()

            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceAround
            ) {
                val odd = index % 2 == 0
                val leftShape = if (odd) goodShape else badShape
                val rightShape = if (odd) badShape else goodShape
                Box(
                    modifier = Modifier
                        .shadow(
                            elevation = elevation,
                            shape = leftShape,
                            clip = true
                        )
                        .clip(leftShape)
                        .background(color = Color.Blue)
                        .heightIn(min = 64.dp)
                        .padding(8.dp)
                        .weight(1f)
                ) {
                    Text("$index ${if (odd) "good" else "bad"}")
                }

                Spacer(modifier = Modifier.width(4.dp))

                Box(
                    modifier = Modifier
                        .graphicsLayer {
                            shadowElevation = with(density) { elevation.toPx() }
                            shape = rightShape
                            clip = false
                        }
                        .clip(rightShape)
                        .background(color = Color.Blue)
                        .heightIn(min = 64.dp)
                        .padding(8.dp)
                        .weight(1f)
                ) {
                    Text("$index ${if (odd) "bad" else "good"}")
                }
            }
        }
    }
r
Compose uses the platform’s rendering pipeline so the version of Compose most likely won’t matter. Seems indeed like a Skia bug since the winding of the shape changes the result. Shadows generate a mesh and it seems like there’s a problem in that process. It’s visible at the bottom of the screen because of the position of the light source. @Nader Jawad have you ever seen this issue?
a
Not quite the same, but https://issuetracker.google.com/356726103 is another weird shadow bug where behavior depends on orientation
n
Did you try Compose 1.7.5? Also which device is this running on? Pixel devices leverage a vulkan based rendered internally but other oems leverage the GL based pipeline as well. There has been quite a bit of effort standardizing elevation shadows in scenarios where outlined provided exceed the bounds of the layer itself. Would be good to share a sample repro application as well
r
• I tried upgrade to 1.7.5 and 1.8.0 alpha06, it didn't change anything • It repros on most of my physical devices, which are SONY Xperia 5V API 34, SONY Xperia 5III API 33, Some Samsung tablet with API 29, but not on my Samsung tablet S8 Ultra API 34. It repros on emulators like Galaxy NOTE 10 API 28, Pixel C API 28, and Pixel 8 Pro API 34, but not on Pixel 5 API 31. Among them Pixel C and Samsung tablet with API 29 have most obvious issues like the image I attached, other devices shows a 1px or 1dp bar. • For repro app could you check the 1st comment above?
n
Thanks for the information. I will take a look
❤️ 1