首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Bitmap.Config.HARDWARE对Bitmap.Config.RGB_565

Bitmap.Config.HARDWARE对Bitmap.Config.RGB_565
EN

Stack Overflow用户
提问于 2017-08-04 15:53:54
回答 1查看 9.5K关注 0票数 39

API 26 添加新选项 Bitmap.Config.HARDWARE

特殊配置,当位图仅存储在图形内存中时。此配置中的位图总是不可变的。当使用位图的唯一操作是在屏幕上绘制它时,这是最优的情况。

没有在文档中解释的问题:

  1. 如果速度是第一位的,而且质量和易变性不是很好(例如缩略图等等),我们现在应该总是更喜欢Bitmap.Config.HARDWARE而不是Bitmap.Config.RGB_565吗?
  2. 使用此选项解码后的像素数据实际上不消耗任何堆内存,只驻留在GPU内存中吗?如果是这样的话,这似乎最终缓解了OutOfMemoryException在处理图像时的担忧。
  3. 与RGB_565、RGBA_F16或ARGB_8888相比,我们应该期望从这个选项中获得什么质量?
  4. 与使用RGB_565解码相比,解码本身的速度是否相同/更好/值得?
  5. (谢谢@CommonsWare在注释中指向它)如果我们在使用此选项解码图像时超过GPU内存,会发生什么情况?会抛出一些异常(可能是同一个OutOfMemoryException :)?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-13 13:02:51

文档和公共源代码尚未推送到谷歌的git。因此,我的研究只基于部分信息,一些实验,以及我自己将JVM移植到各种设备上的经验。

我的测试创建了大型可变位图,并在单击按钮后将其复制到一个新的硬件位图中,并将其添加到位图列表中。在大型位图崩溃之前,我设法创建了几个实例。

我在android-o预览-4 git推送中找到了这一点:

代码语言:javascript
运行
复制
+struct AHardwareBuffer;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer);
+#else
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const struct AHardwareBuffer *buffer);

为了寻找AHardwareBuffer文档,它正在安卓共享内存("ashmem")中创建一个由ANativeWindowBuffer (原生图形缓冲区)支持的EGLClientBuffer。但是实际的实现可能因硬件而异。

因此,有关问题:

  1. 我们应该永远喜欢Bitmap.Config.HARDWARE而不是Bitmap.Config.RGB_565.?

对于SDK >= 26,HARDWARE配置可以通过防止每次相同位图返回屏幕时将像素数据复制到GPU来改进低级别位图绘制。我想,当位图添加到屏幕上时,它可以防止丢失一些帧。

内存是不计算在你的应用程序,我的测试证实了这一点。

本机库文档表示,如果内存分配失败,它将返回null。如果没有源代码,就不清楚在这种情况下Java实现( API实现者)将做什么--它可能决定抛出OutOfMemoryException或回退到另一种类型的分配。

更新:实验显示没有抛出OutOfMemoryException。虽然分配是成功的,但一切都很顺利。分配失败时,仿真器崩溃(刚刚结束)。在其他情况下,我在应用程序内存中分配位图时得到了一个奇怪的NullPointerException

由于无法预测的稳定性,我不建议在目前的生产中使用这个新API。至少没有经过广泛的测试。

  1. 使用此选项解码后的像素数据实际上不消耗任何堆内存,只驻留在GPU内存中吗?如果是这样的话,这似乎最终缓解了OutOfMemoryException在处理图像时的担忧。

像素数据将在共享内存中(可能是纹理内存),但在Java中仍然有一个小的Bitmap对象引用它(因此“任何”都是不准确的)。

每个供应商都可以决定以不同的方式实现实际分配,这不是他们所绑定的公共API。因此,OutOfMemoryException可能仍然是一个问题。我不知道怎么才能正确处理。

  1. 与RGB_565/ARGB_8888相比有什么质量?

HARDWARE标志不是关于质量,而是关于像素存储位置。由于配置标志不能是OR-ed,所以我认为默认(ARGB_8888)用于解码。

(实际上,在我看来,HARDWARE枚举就像是一个黑客)。

  1. 解码本身的速度是否相同/更好/更糟.?

HARDWARE标志似乎与解码无关,因此与ARGB_8888相同。

  1. 如果我们超过GPU内存会发生什么?

当记忆耗尽时,我的测试结果是非常糟糕的事情。仿真器有时会严重崩溃,在其他情况下,我得到了意想不到的无关NPE。没有发生OutOfMemoryException,也无法判断GPU内存何时耗尽,因此无法预见这一点。

票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45511017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档