Я пытаюсь использовать один поток, чтобы отобразить три отдельных объекта TextureView вне потока пользовательского интерфейса, используя блокировку/разблокировку холста. Наблюдаемая проблема заключается в постоянном мерцании каждого из рисунков Текстуры, которые вырисовываются, с мерцанием, состоящим из кадра TextureView DIFFERENT. Так, например, я рисую кадры A, B и C в этом порядке. Кадр C будет казаться точным, однако кадры A и B будут мерцать со случайными экземплярами кадра C, а кадр A будет иногда мерцать с экземплярами кадра B.Android-поток, управляющий несколькими видами текстур, вызывает странное мерцание
Я прочитал документацию, описывающую графическую карту Android Core, и довольно хорошее понимание того, как работает система буферизации кадров Android. Вкратце, мое подозрение в том, что я выполняю вызов lockCanvas/unlockCanvasAndPost слишком быстро подряд и что фреймбуфер не может выполнить мой запрос и просто рисует предыдущий (неправильный) фрейм.
Я пробовал несколько вещей, чтобы решить эту проблему. Попытка использовать хореографа для ожидания VSYNC до продолжения вызова холста помогла, но, как ожидалось, снизила частоту кадров, однако проблема все еще была там. Я также попробовал альтернативный цикл рендеринга без команды сна, без различия наблюдаемого явления.
По существу, я не в курсе, как решить эту проблему, и надеялся получить на ней какой-то внешний вход. Спасибо заранее, фрагмент кода ниже:
Основной цикл визуализации: метод
while (running) {
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
float delta = updateLength/((float)OPTIMAL_TIME.get());
lastFpsTime += updateLength;
fps++;
if (lastFpsTime >= 1000000000)
{
Log.e(TAG, "(FPS Target: " + TARGET_FPS+ " ,FPS Actual: " + fps + ")");
lastFpsTime = 0;
fps = 0;
}
for (MyTextureView mtv : mItemList){
if (!mtv.isLocked()) {
mtv.doUpdate(delta);
mtv.doRender();
}
}
long sleepTime = (lastLoopTime-System.nanoTime() + OPTIMAL_TIME.get())/1000000;
sleepTime = sleepTime < 0 ? 0 : sleepTime;
try{
Thread.sleep(sleepTime);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
MyTextureView doRender():
public void doRender() {
doubleBufferCanvas.drawPaint(Colors.BLACK);
doDraw(doubleBufferCanvas); //draws content onto secondary canvas
Canvas c = lockCanvas();
c.drawPaint(Colors.BLACK);
c.save();
c.drawBitmap(dbbmp, 0, 0, null);
c.restore();
unlockCanvasAndPost(c);
}
У меня есть подозрение, что в драйвере или в TextureView есть ошибка, которая препятствует выбору правильной текстуры. Это может быть та же проблема, что и здесь: http://stackoverflow.com/questions/31057293/android-textureview-drawing-painting-performance/ - OP удалось обойти проблему с кучей вызовов Invalidate (). Я бы хотел сначала исключить ошибки приложений, хотя ... проблема все еще возникает, если вы запускаете все в одном потоке? – fadden
Спасибо за совет. К сожалению, я не смог решить проблему с использованием этого решения. Я немного смущен относительно того, как работать с invalidate() на текстуре (таким образом, как он это сделал), учитывая, что я уже использую отдельный поток рендеринга и вообще избегаю onDraw (Canvas c); Насколько мне известно, onDraw() называется следующим invalidate? Кроме того, я выполнял вышеупомянутый скрипт в одном потоке, отдельно от потока пользовательского интерфейса, поэтому проблема возникла из одного потока. –
Мое лучшее предположение заключается в том, что обратные вызовы View invalidate имеют побочный эффект, который работает с ошибкой. Как, может быть, неправильный контекст EGL используется, но каким-то образом использование какого-либо кода View приводит к его сбросу, или TextureViews непреднамеренно используют одну текстуру. Другой вопрос также сообщил о проблемах с коррупцией при однопоточности (почему у вас есть «многопоточность»?), что для меня делает менее вероятным проблему с приложением и, скорее всего, будет проблемой структуры. К сожалению, я не в состоянии их отлаживать. – fadden