Android应用上的GPU工件

时间:2015-09-07 14:10:58

标签: android gpu

我的应用程序有一个非常奇怪的问题。有时在启动应用程序时,所有碎片都会遇到此问题。看起来GPU正在做一些奇特的事情。 在下面的动画Gif中,您可以清楚地看到具有上述伪像的PreferenceFragment。

修改1 。看起来我有一个特定的片段,一旦在屏幕上“绘制”,就会出现错误。使用.replace切换片段实际上不会“清除”问题。

我该怎么调试呢?

gpu-artifacts android

2 个答案:

答案 0 :(得分:0)

它看起来像来自GPU的垃圾 您需要关注的第一件事是窗口背景(之后是各种全屏布局背景) 它可能被定义为null或其他类似问题。

答案 1 :(得分:0)

好吧我的问题是因为我的主题是

<item name="android:windowBackground">@color/dark</color>

其中dark是设置为#313131

的颜色项

然后我有一个观点,我用它作为其他一些内容的封面,以使基础观点变暗如下:

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/mydrawable"
            />

        <View
            android:id="@+id/coverview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/dark"/>
    </FrameLayout>

以编程方式我必须使用coverView.getBackground().setAlpha((int)(0.6f*255));

设置封面视图的alpha

令人惊讶的是,这个新的alpha值也应用于窗口背景并生成了许多你在我的问题中看到的工件(即使在切换片段后,封面视图不再出现在视图树中) < / p>

默认情况下,从同一资源加载的所有drawables实例都共享一个公共状态。因此我的代码错了,我需要在应用新的alpha值之前在背景上调用.mutate

除了我错了@在不调用.setAlpha的情况下调用.mutate(),GPU闪烁对我来说仍然是一个谜。

为什么GPU闪烁呢?正如Christophe here指出的那样:

  GPU闪烁导致背景现在是半透明的   系统尝试将其与当前在空缓冲区中的内容混合   (主要是垃圾)。

为了展示 bug 问题,我创建了一个github repo,其中包含一个展示此问题的示例项目:https://github.com/vekexasia/gpuflickering-background-alpha

变通办法:好几个。如果您想使用相同的方法(也会导致过度绘制),您应该以编程方式设置颜色,然后将alpha值设置为它。像这样: coverView.setBackground(new ColorDrawable(getResources().getColor(R.color.dark)));

更好的方法是将ColorFilter应用于ImageView,或者如果您使用Picasso使用Transformation

另一种方法是在.mutate()

之前致电.setAlpha()