2016-03-21 12 views
0

Android uygulamamın ekran görüntüsünü Render'imin onDrawFrame işlevinden yakalamaya çalışıyorum. Ancak, çerçeve tamamlanana ve işlem tamamlanana kadar uygulamayı donduruyor. Bunu farklı bir konu üzerinde yapmaya çalışıyorum ama başarı yok. Ekran görüntüsünü farklı bir iş parçacığına almak mümkün mü?GLSurfaceView'in ekran görüntüsünü Android'deki başka bir diziden almak mümkün müdür?

+0

Mesaj bazı kod, çoklu iş parçacığı bu durumu mümkün olmalıdır, sadece sen nasıl yapıyorlar bağlıdır. – zgc7009

cevap

1

glReadPixels()'u başka bir iş parçacığından gerçekleştiremezsiniz, çünkü EGL içeriği her seferinde yalnızca bir iş parçacığında geçerli olabilir ve GLSurfaceView ile herhangi bir denetiminiz yoktur.

Ancak gles bir ekran resmi kapma harcanan zamanın 95 +% PNG/JPEG sıkıştırma ve disk g/Ç harcanmaktadır. Bu nedenle, onDrawFrame() numaralı telefondan glReadPixels() aramasını yaparsanız ve verileri yeni bir iş parçacığına aktarırsanız, ekran görüntüsü arka planda işlenirken çalışmaya devam edebilmeniz gerekir.

1

Daha önce direk okumalı başka bir iş parçacığı imkansız olabilir söz ama başka yolları da vardır. Bunun yerine yüzeye doğrudan sahne çizim

ekli bir dokuya sahip bir çerçeve tampon nesnesi (fbo) için çizmek ve daha sonra ana tampon doku yeniden çizmek olabilir görüntülemek. Bu, post processing ve benzeri için oldukça standart bir prosedürdür ve yüksek bir performans etkisine sahip değildir. Bunu gerçekleştirmek için aslında FBO'nun nasıl oluşturulacağına bakmanız, çizimi başlamadan önce bağlamanız ve kodunuzun geri kalanının olduğu gibi kalması gerekir. Ardından, ana tamponu (indeks 0 yapmalı) bağlayarak ekranda FBO yapısını yeniden çizmek için kodu da ekleyin. şimdi yeni bir iş parçacığı ve bu iş parçacığı üzerinde ayarlanmış yeni bir bağlam oluşturmak için gereken ayrı bir iş parçacığı üzerinde ekran görüntüsü için

. Yeni içerik ana ile paylaşılmalı (bunun için ana çerçeveyi kabul eden bir kurucu var), böylece dokuyu paylaşabilirsiniz. Şimdi eğlenceli bölüm: Ekran görüntüsünü almak istediğinizde yeni bir doku oluşturmalısınız, yeni dokuyu FBO'ya bağlayın, eski dokuyu çıkarın. Böylece, içeriğin çizildiği dokuyu çalabilirsiniz ve istediğiniz herhangi bir şeyi ve istediğiniz herhangi bir parçayı yapabilirsiniz. Bu yüzden ikincil parçanıza koyun ve bu bağlamda başka bir FBO oluşturabilir, bağlayabilir ve bu konudaki pikselleri okuyabilirsiniz. Temizlemeyi unutmayın.

Yine de bazı dikkat edilmesi önerilir. Göreceli olarak az miktarda ekran görüntüsü aldığınızda bu tür prosedürler iyi olabilir. Bir ekran görüntüsü diğeri başlamadan tamamen bitmezse, bellek kullanımında şişirilirsiniz ve uygulamanız büyük olasılıkla kilitlenir. Bu nedenle, bir tür kilitleme mekanizması oluşturmaya veya devam eden ekran görüntüsü işleme sayısını sınırlamaya dikkat edin. Ve bu sadece openGL için değil, görüntü verisini basitçe kodlarken aynı sorun ortaya çıkabilir.

Ve orijinal fikri üzerine sadece bir not

: Eğer ayrı iş parçacığı üzerinde yüzey görünümünü kullanın ve ana tampon pikselleri okuyabilir bile size iyi bir sonuç almak bekliyoruz olmayabilir. Tampon okunurken çizilebilir, böylece farklı karelerden gelen veri parçalarını elde edersiniz. Yine de bu sadece teoride. Çünkü gerçek şu ki, tampon kilitlenecek ve uygulamanıza erişmeye çalışırken uygulama çökecektir. Yani bu hiçbir şekilde mümkün değildir ve sonuçta tahmin edilemez olsa bile.

+0

Dikkatli olun - farklı konulardaki bağlamlar arasındaki dokuları yarış koşullarına sahip olabilirsiniz. Grafika'da yanlış anladım; https://github.com/google/grafika/issues/36 adresine bakın. – fadden

+0

Ve bu yüzden dokuyu "çalmak" gerektiğini söylüyorum. Çizdiğiniz mevcut dokuyu yenisiyle değiştirmeniz gerekir. 2 doku kullanarak çift tamponlama yapabilirsiniz. –

İlgili konular