Class TextureView
adalah objek tampilan yang menggabungkan tampilan dengan SurfaceTexture.
Merender dengan OpenGL ES
Objek TextureView membungkus SurfaceTexture, merespons callback, dan
mendapatkan buffer baru. Saat objek TextureView mendapatkan buffer baru, TextureView
mengirimkan permintaan pembatalan validasi tampilan dan menggambar menggunakan konten buffer
terbaru sebagai sumber datanya, merender di mana pun dan bagaimana pun status tampilan
menunjukkan bahwa ia harus dirender.
OpenGL ES (GLES) dapat merender pada objek TextureView dengan meneruskan SurfaceTexture ke panggilan pembuatan EGL, tetapi hal ini menimbulkan masalah. Saat GLES
merender di TextureView, produsen dan konsumen BufferQueue berada di thread yang sama, yang dapat menyebabkan panggilan pertukaran buffer terhenti atau gagal. Misalnya, jika produser mengirimkan beberapa buffer secara berurutan dengan cepat dari UI thread, panggilan pertukaran buffer EGL perlu mengeluarkan buffer dari BufferQueue. Namun,
karena konsumen dan produsen berada di thread yang sama, tidak akan ada
buffer yang tersedia dan panggilan swap akan terhenti atau gagal.
Untuk mencegah jeda pertukaran buffer, BufferQueue selalu memerlukan buffer yang tersedia untuk penghapusan dari antrean. Untuk melakukannya, BufferQueue akan membuang konten buffer yang sebelumnya diperoleh saat buffer baru dimasukkan dalam antrean. Hal ini juga memberikan batasan pada jumlah buffer minimum dan maksimum untuk mencegah konsumen menggunakan semua buffer sekaligus.
Pilih SurfaceView atau TextureView
SurfaceView dan TextureView memiliki peran serupa dan keduanya adalah elemen
hierarki tampilan. Namun, SurfaceView dan TextureView memiliki
penerapan yang berbeda. Objek SurfaceView menggunakan parameter yang sama dengan tampilan lainnya, tetapi
konten SurfaceView transparan saat dirender.
TextureView memiliki penanganan alfa dan rotasi yang lebih baik daripada SurfaceView, tetapi
SurfaceView memiliki keunggulan performa saat menggabungkan elemen UI yang disusun
di atas video. Saat dirender dengan objek SurfaceView, SurfaceView menyediakan
lapisan komposisi terpisah untuk klien. SurfaceFlinger menyusun
lapisan terpisah sebagai overlay hardware jika didukung oleh perangkat. Saat merender dengan TextureView, toolkit UI menggabungkan konten objek TextureView ke dalam hierarki tampilan dengan GPU. Pembaruan pada konten dapat menyebabkan elemen tampilan lain digambar ulang, misalnya, jika tampilan lain diposisikan di atas TextureView. Setelah rendering tampilan selesai, SurfaceFlinger menggabungkan lapisan UI aplikasi dan semua lapisan lainnya, sehingga setiap piksel yang terlihat digabungkan dua kali.
Studi Kasus: Putar Video Grafika
Grafika's Play Video menyertakan sepasang pemutar video, satu
diimplementasikan dengan TextureView dan satu lagi diimplementasikan dengan SurfaceView. Bagian decoding video dari aktivitas mengirimkan frame dari MediaCodec ke permukaan untuk TextureView dan SurfaceView. Perbedaan terbesar antara
implementasi adalah langkah-langkah yang diperlukan untuk menampilkan rasio aspek yang benar.
Penskalaan SurfaceView memerlukan implementasi FrameLayout kustom.
WindowManager perlu mengirimkan nilai posisi jendela baru dan ukuran baru ke
SurfaceFlinger. Menskalakan SurfaceTexture objek TextureView memerlukan konfigurasi matriks transformasi dengan TextureView#setTransform().
Setelah menampilkan rasio aspek yang benar, kedua penerapan mengikuti pola yang sama. Saat SurfaceView atau TextureView membuat platform, kode aplikasi mengaktifkan pemutaran. Saat pengguna mengetuk putar, thread decoding video akan dimulai, dengan permukaan sebagai target output. Setelah itu, kode aplikasi tidak melakukan apa pun—komposisi dan tampilan ditangani oleh SurfaceFlinger (untuk SurfaceView) atau oleh TextureView.
Studi Kasus: Double Decode Grafika
Grafika's Double Decode menunjukkan manipulasi
SurfaceTexture di dalam TextureView.
Double Decode Grafika menggunakan sepasang objek TextureView untuk menampilkan dua video yang diputar berdampingan, yang menyimulasikan aplikasi konferensi video. Saat orientasi layar berubah dan aktivitas dimulai ulang, decoder MediaCodec tidak berhenti, yang menyimulasikan pemutaran streaming video real-time. Untuk meningkatkan efisiensi, klien harus menjaga agar platform tetap aktif. Permukaan adalah handle ke antarmuka
produsen di BufferQueue SurfaceTexture. Karena objek TextureView mengelola
SurfaceTexture, klien harus menjaga SurfaceTexture tetap aktif agar
permukaan tetap aktif.
Untuk menjaga SurfaceTexture tetap aktif, Decode Ganda Grafika mendapatkan referensi
ke SurfaceTexture dari objek TextureView dan menyimpannya di kolom statis.
Kemudian, Double Decode Grafika menampilkan false dari
TextureView.SurfaceTextureListener#onSurfaceTextureDestroyed() untuk
mencegah penghancuran SurfaceTexture. TextureView kemudian meneruskan
SurfaceTexture ke onSurfaceTextureDestroyed() yang dapat
dipertahankan di seluruh perubahan konfigurasi aktivitas, yang diteruskan klien ke
objek TextureView baru melalui setSurfaceTexture().
Setiap dekoder video didorong oleh thread terpisah. Mediaserver mengirim buffer dengan output yang didekode ke SurfaceTexture, konsumen BufferQueue. Objek TextureView melakukan rendering dan dieksekusi di UI thread.
Menerapkan Dekode Ganda Grafika dengan SurfaceView lebih sulit daripada
menerapkan dengan TextureView karena objek SurfaceView menghancurkan permukaan
selama perubahan orientasi. Selain itu, penggunaan objek SurfaceView menambahkan dua
lapisan, yang tidak ideal karena batasan jumlah overlay yang tersedia di hardware.