Почему обновленные NDK растровые изображения отображаются черным цветом при включении hardwareAccelerated в Honeycomb?

#android #opengl-es #android-ndk

#Android #opengl-es #android-ndk

Вопрос:

У меня есть приложение для создания изображений для Android, и я использую машинный код для рисования непосредственно в растровых изображениях Java; все работает нормально. Я только что приобрел планшет Acer A500 и решил попробовать использовать новый атрибут Honeycomb android: hardwareAccelerated. Все растровые изображения отображаются черным цветом, когда это включено. Я использую простой полноэкранный режим с рисованием на холсте. У кого-нибудь есть идея, как заставить его обновлять текстуру OpenGL, когда я рисую в своих растровых изображениях?

Ответ №1:

Как сказано в этой статье, пиксельные данные для растровых объектов хранятся в массивах байтов на Android 3.0 (Honeycomb). Ранее они хранились не в куче Dalvik, а во внешней куче, которая не управляется виртуальной машиной Dalvik.

Итак, это большая разница между Android 2.x и 3.x. И, возможно, небезопасно рисовать в bitmap из собственного кода, потому что NDK не предоставляет собственный API для уровней выше 9. В целом API должен быть обратно совместим, но атрибут hardwareAccelerated изменяет поведение нескольких методов и может нарушить совместимость.

Например, следующие операции ведут себя по-разному при включенном аппаратном ускорении:

  • Холст
    • clipRect: режимы клипа XOR, Difference и ReverseDifference игнорируются; 3D-преобразования не применяются к прямоугольнику клипа
    • drawBitmapMesh: массив цветов игнорируется
    • Линии рисования: сглаживание не поддерживается
    • setDrawFilter: может быть установлен, но игнорируется
  • Краски
    • setDither: игнорируется
    • setFilterBitmap: фильтрация всегда включена
    • setShadowLayer: работает только с текстом
  • ComposeShader
    • ComposeShader может содержать только шейдеры разных типов (например, BitmapShader и LinearGradientShader, но не два экземпляра BitmapShader)
    • ComposeShader не может содержать ComposeShader

Вот более подробная информация об аппаратном ускорении: http://android-developers.blogspot.com/2011/03/android-30-hardware-acceleration.html

Комментарии:

1. Я уже нашел эту информацию — я ищу решение для отображения растровых изображений с аппаратным ускорением в Honeycomb. Сказать мне, что это может быть невозможно, — это не ответ.

Ответ №2:

Проблема, похоже, в том, что Android не обновляет «номер поколения» текстуры, которую он использует за кулисами для растрового изображения, поэтому он не использует новые пиксельные данные. У меня была похожая проблема (в моей библиотеке рисования карт CartoType, которая работает как собственный код на Android), и я решил ее, записав значение 0 в верхний левый пиксель перед получением свежих данных. Вот мой Java-код с поясняющим комментарием:

 private void getMap()
    {
    NativeInterface.getMap(iDemoFrameworkRef,iBitmapData);
    iBuffer.rewind();

    /*
    Hack: we have to change the bitmap because the Android hardware-accelerated canvas will not
    re-upload the bitmap unless it has a different generation number,
    and copyPixelsFromBuffer doesn't change the generation number.
    See http://osdir.com/ml/Android-Developers/2011-10/msg02215.html.
    */
    iBitmap.setPixel(0,0,0);

    iBitmap.copyPixelsFromBuffer(iBuffer);  
    }
  

Эта проблема возникла на Galaxy Nexus, использующем Android 4.0. Код отлично работал на симуляторе, но не на оборудовании, пока я не добавил хак. Тогда все было в порядке.

Комментарии:

1. Спасибо, Грэм, я думаю, вы ближе к решению, но это не сработало в Honeycomb 3.2. Я модифицирую свои растровые изображения из собственного кода и добавил SetPixel () прямо перед обновлением моего растрового изображения, но это не возымело никакого эффекта. Есть еще идеи?