TextureView
sınıfı, bir görünümü SurfaceTexture ile birleştiren bir görünüm nesnesidir.
OpenGL ES ile oluşturma
TextureView nesnesi, geri çağırmalara yanıt verip yeni arabellekler edinerek bir SurfaceTexture'ı sarmalar. Bir TextureView nesnesi yeni arabellekler edindiğinde TextureView
görünüm geçersiz kılma isteği gönderir ve en yeni arabelleğin içeriğini veri kaynağı olarak kullanarak çizim yapar. Böylece, görünüm durumunun belirtildiği her yerde ve şekilde oluşturma işlemi gerçekleştirilir.
OpenGL ES (GLES), TextureView nesnesinde render edebilir. Bunun için SurfaceTexture'ı EGL oluşturma çağrısına iletmek gerekir ancak bu durum sorun yaratır. GLES, TextureView üzerinde oluşturulduğunda BufferQueue üreticileri ve tüketicileri aynı iş parçacığında yer alır. Bu durum, arabellek değişimi çağrısının durmasına veya başarısız olmasına neden olabilir. Örneğin, bir üretici kullanıcı arayüzü iş parçacığından hızlı bir şekilde art arda birkaç arabellek gönderirse EGL arabellek değişimi çağrısının BufferQueue'dan bir arabellek çıkarması gerekir. Ancak tüketici ve üretici aynı iş parçacığında olduğundan arabellek kullanılamaz ve takas çağrısı askıya alınır veya başarısız olur.
Arabellek değişimi duraklamalarını önlemek için BufferQueue'da her zaman kuyruktan çıkarma için kullanılabilir bir arabellek olması gerekir. Bunu yapmak için BufferQueue, yeni bir arabellek sıraya alındığında daha önce edinilmiş arabelleğin içeriğini atar. Ayrıca, tüketicilerin tüm arabellekleri aynı anda tüketmesini önlemek için minimum ve maksimum arabellek sayılarıyla ilgili kısıtlamalar da getirir.
SurfaceView veya TextureView'ı seçme
SurfaceView ve TextureView benzer rolleri doldurur ve her ikisi de görünüm hiyerarşisinin vatandaşlarıdır. Ancak SurfaceView ve TextureView farklı uygulamalara sahiptir. Bir SurfaceView nesnesi, diğer görünümlerle aynı parametreleri alır ancak SurfaceView içerikleri oluşturulduğunda şeffaftır.
TextureView, SurfaceView öğesine kıyasla daha iyi alfa ve döndürme işleme özelliğine sahiptir ancak SurfaceView, videoların üzerine yerleştirilmiş kullanıcı arayüzü öğelerini birleştirirken performans avantajları sunar. Bir istemci SurfaceView nesnesiyle oluşturma yaptığında SurfaceView, istemciye ayrı bir kompozisyon katmanı sağlar. SurfaceFlinger, cihaz tarafından destekleniyorsa ayrı katmanı donanım yerleşimi olarak oluşturur. Bir istemci TextureView ile oluşturduğunda, kullanıcı arayüzü araç seti TextureView nesnesinin içeriğini GPU ile görünüm hiyerarşisine birleştirir. İçerikte yapılan güncellemeler, diğer görünüm öğelerinin yeniden çizilmesine neden olabilir. Örneğin, diğer görünümler TextureView öğesinin üzerinde konumlandırılmışsa. Görünüm oluşturma işlemi tamamlandıktan sonra SurfaceFlinger, uygulama kullanıcı arayüzü katmanını ve diğer tüm katmanları birleştirir. Böylece, görünür her piksel iki kez birleştirilir.
Örnek Olay: Grafika's Play Video
Grafika's Play Video, biri TextureView ile, diğeri SurfaceView ile uygulanmış bir çift video oynatıcı içerir. Etkinliğin video kodu çözme kısmı, hem TextureView hem de SurfaceView için MediaCodec'ten bir yüzeye kare gönderir. Uygulamalar arasındaki en büyük fark, doğru en boy oranını sunmak için gereken adımlardır.
Ölçeklendirme SurfaceView için FrameLayout'un özel olarak uygulanması gerekir.
WindowManager, SurfaceFlinger'a yeni pencere konumu ve yeni boyut değerleri göndermelidir. TextureView nesnesinin SurfaceTexture'ını ölçeklendirmek için TextureView#setTransform() ile bir dönüşüm matrisi yapılandırmanız gerekir.
Doğru en boy oranı sunulduktan sonra her iki uygulama da aynı deseni izler. SurfaceView veya TextureView yüzeyi oluşturduğunda uygulama kodu, oynatmayı etkinleştirir. Kullanıcı oynat'a dokunduğunda, yüzeyin çıkış hedefi olarak kullanıldığı bir video kod çözme iş parçacığı başlatılır. Bundan sonra uygulama kodu herhangi bir işlem yapmaz. Bileşen ve ekran, SurfaceFlinger (SurfaceView için) veya TextureView tarafından işlenir.
Örnek olay: Grafika'nın Çift Kod Çözme
Grafika's Double Decode, TextureView içindeki SurfaceTexture'ın işlenmesini gösterir.
Grafika'nın Double Decode'u, video konferans uygulaması simülasyonu yaparak yan yana oynatılan iki videoyu göstermek için bir çift TextureView nesnesi kullanır. Ekranın yönü değiştiğinde ve etkinlik yeniden başladığında MediaCodec kod çözücüleri durmaz ve gerçek zamanlı bir video akışının oynatılması simüle edilir. Verimliliği artırmak için istemci, yüzeyi etkin tutmalıdır. Yüzey, SurfaceTexture'ın BufferQueue'sindeki üretici arayüzünün tutma yeridir. TextureView nesnesi SurfaceTexture'ı yönettiğinden, istemcinin yüzeyin canlı kalması için SurfaceTexture'ı canlı tutması gerekir.
Grafika'nın Double Decode işlevi, SurfaceTexture'ı canlı tutmak için TextureView nesnelerinden SurfaceTexture referansları alır ve bunları statik bir alana kaydeder.
Ardından, Grafika's Double Decode, SurfaceTexture'ın yok edilmesini önlemek için false değerini TextureView.SurfaceTextureListener#onSurfaceTextureDestroyed() olarak döndürür. TextureView, daha sonra onSurfaceTextureDestroyed() öğesine bir SurfaceTexture iletir. Bu SurfaceTexture, etkinlik yapılandırması değişikliği boyunca korunabilir. İstemci, setSurfaceTexture() aracılığıyla yeni TextureView nesnesine iletir.
Her video kod çözücüyü ayrı iş parçacıkları çalıştırır. Mediaserver, çözülmüş çıkış içeren arabellekleri BufferQueue tüketicileri olan SurfaceTexture'lara gönderir. TextureView nesneleri oluşturma işlemini gerçekleştirir ve kullanıcı arayüzü iş parçacığında yürütülür.
Grafika'nın Double Decode özelliğini SurfaceView ile uygulamak, TextureView ile uygulamaktan daha zordur. Bunun nedeni, SurfaceView nesnelerinin yön değişiklikleri sırasında yüzeyleri kaldırmasıdır. Ayrıca, SurfaceView nesnelerinin kullanılması iki katman ekler. Bu da donanımda kullanılabilen yer paylaşımlarının sayısıyla ilgili sınırlamalar nedeniyle ideal değildir.