2015-06-29 2 views
2

Я пытаюсь использовать один поток, чтобы отобразить три отдельных объекта 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); 
} 
+0

У меня есть подозрение, что в драйвере или в TextureView есть ошибка, которая препятствует выбору правильной текстуры. Это может быть та же проблема, что и здесь: http://stackoverflow.com/questions/31057293/android-textureview-drawing-painting-performance/ - OP удалось обойти проблему с кучей вызовов Invalidate (). Я бы хотел сначала исключить ошибки приложений, хотя ... проблема все еще возникает, если вы запускаете все в одном потоке? – fadden

+0

Спасибо за совет. К сожалению, я не смог решить проблему с использованием этого решения. Я немного смущен относительно того, как работать с invalidate() на текстуре (таким образом, как он это сделал), учитывая, что я уже использую отдельный поток рендеринга и вообще избегаю onDraw (Canvas c); Насколько мне известно, onDraw() называется следующим invalidate? Кроме того, я выполнял вышеупомянутый скрипт в одном потоке, отдельно от потока пользовательского интерфейса, поэтому проблема возникла из одного потока. –

+0

Мое лучшее предположение заключается в том, что обратные вызовы View invalidate имеют побочный эффект, который работает с ошибкой. Как, может быть, неправильный контекст EGL используется, но каким-то образом использование какого-либо кода View приводит к его сбросу, или TextureViews непреднамеренно используют одну текстуру. Другой вопрос также сообщил о проблемах с коррупцией при однопоточности (почему у вас есть «многопоточность»?), что для меня делает менее вероятным проблему с приложением и, скорее всего, будет проблемой структуры. К сожалению, я не в состоянии их отлаживать. – fadden

ответ

0

я смог найти обходной путь для этого. (я не наблюдаю это на Android 5.0 и выше).

Добавьте прозрачный вид, как ниже псевдо

  <View 
       android:id="@+id/flicker_hack_view" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_alignParentBottom="true" 
       android:layout_centerHorizontal="true" 
       android:alpha="0.01" 
       android:background="@color/black_12" /> 

, которая охватывает всю деятельность везде, где есть textureView. альфа должна быть установлена ​​равной 0,01 или меньшее значение, чтобы сделать ее невидимой.

Это обходное решение было основано на моем наблюдении, что, когда два изображения рендеринга изображений текстур перекрываются, мерцание не наблюдается.

+0

Согласно http://b.android.com/178525, ошибка была исправлена ​​в 'L'. Подробности об ошибке, включая обходные пути (дополнительные недействительные, с использованием пользовательского вида), можно найти в трекере ошибок. – fadden

Смежные вопросы