Поворот холста и представление растрового изображения - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь создать игру, в которой планета была бы в центре экрана пользователя и очень медленно вращалась, как планета .. Итак, сначала я решил проверить это, если все будет работать нормально, а это не так ...Я получаю простое изображение "планета", как это:

Bitmap image = BitmapFactory.decodeResource(getResources(),R.mipmap.totone);

У меня также есть переменная, которая хранит угол.Затем в функции рисования я просто вращаю холст, рисую свою планету (теперь повернутую) и поворачиваю холст обратно.вот так:

//the planet's image is 512x512px
canvas.rotate(ang,256,256); //256, 256 is the center of rotation
canvas.drawBitmap(image, 0,0, null);
canvas.rotate(-ang,256,256); //rotate back

Понятия не имею почему, но похоже, что когда изображение поворачивается на 90 и 270 градусов, скорость игры немного замедляется?Я сделал небольшой подарок, чтобы показать проблему.Частота кадров идеально 60, но затем она падает на 50ish в течение пары миллисекунд без причины?Чем это вызвано?Я попытался изменить целевую частоту кадров моего потока на 30, и похоже, что никаких падений частоты кадров в секунду не происходило ... Так что, вероятно, это проблема производительности.Обратите внимание, что я пытался вращать растровое изображение, используя несколько различных методов, эффект падения fps остается тем же.

Gif

1 Ответ

0 голосов
/ 23 февраля 2019

Скорее всего, это взаимодействие между фиксированной частотой обновления экрана устройства и небольшим изменением времени рисования растрового изображения под определенными углами.

Я предполагаю, что вы увеличиваете angна постоянную сумму в onDraw().Этот факт можно использовать для объяснения резкого изменения частоты вращения.

ОБЪЯСНЕНИЕ

Ваше устройство обновляет свой экран с частотой 60 Гц.Это означает, что onDraw() вызывается при максимальной частоте 60 Гц при идеальных условиях: примерно раз в 16,7 мс.

Предположим, что для выполнения onDraw() требуется около 15 мс.Осталось 1,7 мс;все в порядке!Вы получите хороший, плавный поворот на 60 Гц.

Затем предположите, что при определенных значениях ang, onDraw() занимает немного больше времени;скажем, 18 мс.(Я буду размышлять о том, почему время выполнения drawBitmap() изменяется в зависимости от угла в данный момент. А сейчас давайте посмотрим, что происходит с этим временем рисования 18 мс.)

В идеале, onDraw() вызываетсяна 60 Гц.Но теперь ты слишком долго;более 1 цикла. compositor теперь должен удалить фрейм из вашего приложения, потому что вы не могли предоставить его достаточно быстро!Таким образом, вместо onDraw() выполнения каждые 16,7 мс, теперь он может вызываться только каждые 33,4 мс.

Другими словами, аппаратное обеспечение экрана обновляется с постоянной скоростью, и когда ваш onDraw() пересекает этот 16,7порог мс, ваша частота обновлений уменьшается ровно вдвое.

На это намекает ваш GIF.Отображаемая частота смены кадров составляет от 60 до 51, но мне кажется довольно ясным, что фактическая частота вращения падает почти точно на 50%.Я подозреваю, что расхождение просто из-за того, как вы рассчитали отображаемую частоту кадров.

СПЕКУЛЯЦИЯ НА ИЗМЕНЕНИЕ В drawBitmap () ВРЕМЯ ИСПОЛНЕНИЯ

Может быть производительность кэшированияпроцессор.При определенных углах поворота графическая логика могла бы получать доступ к битовой памяти способом, который не идеален для логики кэша / предварительного просмотра L1.Другими словами, вы можете получить много ошибок в кэше на этих углах.

РЕКОМЕНДУЕМЫЕ ИСПРАВЛЕНИЯ ДЛЯ ВОСПРОИЗВОДИТЕЛЬНОСТИ

  1. Используйте более быстрый графический конвейер, такой какOpenGL и / или:
  2. База ang на временном хаке (uptimeMillis()) вместо приращения.Вы по-прежнему будете отбрасывать кадры, но кажущаяся скорость вращения будет исправлена.
  3. Если вы хотите по-настоящему сойти с ума, вы можете предоставить второй битовый массив, предварительно повернутый на 90 градусов к первому, и использовать этот битовый массивдля розыгрышей, которые происходят под углами ближе к 90/270 градусов.Если я прав насчет промахов кэша, это уменьшит проблему.
...