#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 () прямо перед обновлением моего растрового изображения, но это не возымело никакого эффекта. Есть еще идеи?