Android 2D oluşturma ardışık düzeni, donanım hızlandırmayı destekler. Bu nedenle, tuval üzerinde gerçekleştirilen tüm çizim işlemleri GPU'yu kullanır. Donanım hızlandırmayı etkinleştirmek için gereken kaynaklar arttığından uygulamanız daha fazla RAM kullanır.
Donanım hızlandırma varsayılan olarak etkindir. Uygulamanız yalnızca standart composable'lar kullanıyorsa bu ayarı genel olarak etkinleştirmek olumsuz çizim efektlerine neden olmaz. Ancak donanım hızlandırma, 2D çizim işlemlerinin tümünde desteklenmediğinden bu özelliği etkinleştirmek bazı özel çizim çağrılarınızı etkileyebilir. Sorunlar genellikle görünmez öğeler, istisnalar veya yanlış oluşturulmuş pikseller olarak ortaya çıkar. Android, bu sorunu gidermek için donanım hızlandırmayı birden fazla düzeyde etkinleştirme veya devre dışı bırakma seçeneği sunar. Donanım hızlandırmayı kontrol etme başlıklı makaleyi inceleyin.
Uygulamanız özel çizim yapıyorsa sorunları bulmak için donanım hızlandırma özelliği açık olan gerçek donanım cihazlarda uygulamanızı test edin. Çizim işlemleri desteği bölümünde, donanım hızlandırmayla ilgili bilinen sorunlar ve bu sorunları giderme yöntemleri açıklanmaktadır.
Ayrıca OpenGL with the Framework APIs (Çerçeve API'leriyle OpenGL) başlıklı makaleyi de inceleyin.
Donanım hızlandırmayı kontrol etme
Donanım hızlandırmayı aşağıdaki düzeylerde kontrol edebilirsiniz:
- Uygulama
- Etkinlik
- Pencere
- Oluşturulabilir
Uygulama düzeyi
Android manifest dosyanızda, uygulamanızın tamamında donanım hızlandırmayı etkinleştirmek için <application> etiketine aşağıdaki özelliği ekleyin:
<application android:hardwareAccelerated="true" ...>
Etkinlik düzeyi
Uygulamanız, donanım hızlandırma özelliği genel olarak etkinleştirildiğinde düzgün çalışmıyorsa bu özelliği tek tek etkinlikler için de kontrol edebilirsiniz. Donanım hızlandırmayı etkinlik düzeyinde etkinleştirmek veya devre dışı bırakmak için <activity> öğesinde android:hardwareAccelerated özelliğini kullanabilirsiniz. Aşağıdaki örnek, uygulamanın tamamında donanım hızlandırmayı etkinleştirir ancak bir etkinlikte devre dışı bırakır:
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
Pencere seviyesi
Daha da hassas bir denetime ihtiyacınız varsa aşağıdaki kodu kullanarak belirli bir pencere için donanım hızlandırmayı etkinleştirebilirsiniz:
window.setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
)
Birleştirilebilir düzey
Compose'da donanım hızlandırmayı devre dışı bırakmak için composable başına bir anahtar yoktur.
Bir composable'ı kendi katmanında oluşturmak için Modifier.graphicsLayer kullanın. Bu, birleştirilebilir öğenin çizim kodu yeniden çalıştırılmadan dönüştürme özelliklerinin (ör. alpha, scaleX, scaleY, translationX, translationY, rotationX, rotationY, rotationZ ve transformOrigin) değiştirilmesine olanak tanır. En iyi performans için bu özellikleri ayarlarken her zaman değiştiricinin lambda biçimini kullanın.
Katman içinde özel karıştırma gibi gelişmiş çizim işlemleri için ekran dışı arabelleği açıkça zorlamak üzere CompositingStrategy.Offscreen kullanın.
Daha fazla bilgi için Grafik değiştiriciler konusuna bakın.
Kesinlikle yazılım oluşturma gerektiren özel bir çizim işleminiz varsa AndroidView kullanarak eski bir görünümü barındırabilir ve bu görünümde setLayerType(View.LAYER_TYPE_SOFTWARE, null) çağrısı yapabilirsiniz.
Çizim işlemleri için destek
Donanım hızlandırmalı olduğunda 2D oluşturma ardışık düzeni, en sık kullanılan Canvas çizim işlemlerinin yanı sıra daha az kullanılan birçok işlemi de destekler. Android ile birlikte gelen uygulamaları, standart composable'ları ve yansımalar ile döşenmiş dokular gibi yaygın gelişmiş görsel efektleri oluşturmak için kullanılan tüm çizim işlemleri desteklenir.
Aşağıdaki tabloda, API düzeylerindeki çeşitli işlemlerin destek düzeyi açıklanmaktadır:
| Desteklenen ilk API düzeyi | ||||
| Tuval | ||||
| drawBitmapMesh() (renkler dizisi) | 18 | |||
| drawPicture() | 23 | |||
| drawPosText() | 16 | |||
| drawTextOnPath() | 16 | |||
| drawVertices() | 29 | |||
| setDrawFilter() | 16 | |||
| clipPath() | 18 | |||
| clipRegion() | 18 | |||
| clipRect(Region.Op.XOR) | 18 | |||
| clipRect(Region.Op.Difference) | 18 | |||
| clipRect(Region.Op.ReverseDifference) | 18 | |||
| Döndürme/perspektif ile clipRect() | 18 | |||
| Boyama yapın | ||||
| setAntiAlias() (metin için) | 18 | |||
| setAntiAlias() (çizgiler için) | 16 | |||
| setFilterBitmap() | 17 | |||
| setLinearText() | ✗ | |||
| setMaskFilter() | ✗ | |||
| setPathEffect() (çizgiler için) | 28 | |||
| setShadowLayer() (metin dışında) | 28 | |||
| setStrokeCap() (çizgiler için) | 18 | |||
| setStrokeCap() (noktalar için) | 19 | |||
| setSubpixelText() | 28 | |||
| Xfermode | ||||
| PorterDuff.Mode.DARKEN (framebuffer) | 28 | |||
| PorterDuff.Mode.LIGHTEN (framebuffer) | 28 | |||
| PorterDuff.Mode.OVERLAY (framebuffer) | 28 | |||
| Shader | ||||
| ComposeShader içinde ComposeShader | 28 | |||
| ComposeShader içinde aynı türdeki gölgelendiriciler | 28 | |||
| ComposeShader'da yerel matris | 18 | |||
Tuval ölçeklendirme
Donanımla hızlandırılmış 2D oluşturma ardışık düzeni, ölçeklenmemiş çizimi desteklemek için ilk olarak oluşturuldu. Bazı çizim işlemleri, daha yüksek ölçek değerlerinde kaliteyi önemli ölçüde düşürüyordu. Bu işlemler, GPU tarafından dönüştürülen 1.0 ölçeğinde çizilmiş dokular olarak uygulanır. API düzeyi 28'den itibaren tüm çizim işlemleri sorunsuz bir şekilde ölçeklendirilebilir.
Aşağıdaki tabloda, büyük ölçekleri doğru şekilde işlemek için uygulamanın ne zaman değiştirildiği gösterilmektedir:
| Ölçeklendirilecek çizim işlemi | Desteklenen ilk API düzeyi |
| drawText() | 18 |
| drawPosText() | 28 |
| drawTextOnPath() | 28 |
| Basit Şekiller | 17 |
| Karmaşık Şekiller | 28 |
| drawPath() | 28 |
| Gölge katmanı | 28 |
Bağlı olduğunuz bir çizim işlemi donanım hızlandırmalı değilse etkilenen çizimi ekran dışı bir yazılım Bitmap (veya ImageBitmap) olarak oluşturun ve sonucu çizin. Kullanıcı arayüzünüzün geri kalanı donanım hızlandırmalı yolu kullanmaya devam eder.
İpuçları ve püf noktaları
Donanım hızlandırmalı 2D grafiklere geçiş performansı anında artırabilir ancak yine de aşağıdaki önerileri uygulayarak uygulamanızı GPU'yu etkili bir şekilde kullanacak şekilde tasarlamanız gerekir:
- Düzen karmaşıklığını ve yeniden oluşturmayı en aza indirme
- Düzen ağacını sığ tutun ve yeniden oluşturma miktarını sınırlayın. Durum okumalarını en dar kapsamda erteleyin. Böylece bir değişiklik, mümkün olan en küçük bölgeyi yeniden çizer. Örneğin, animasyonlu durumu composable'ın gövdesinde değil,
Modifier.graphicsLayer { }içinde okuyun. Daha fazla bilgi için Jetpack Compose performansı başlıklı makaleyi inceleyin. - Fazla çizimden kaçının
- Üst üste çok fazla katman çizmeyin. Üzerlerindeki diğer opak öğeler tarafından tamamen gizlenen tüm kullanıcı arayüzü öğelerini kaldırın. Birbiriyle harmanlanmış birkaç katman çizmeniz gerekiyorsa bunları tek bir katmanda birleştirebilirsiniz. Mevcut donanımlarda genel bir kural olarak, kare başına ekranda piksel sayısının 2,5 katından fazla piksel çizilmemesi gerekir (bit eşlemdeki şeffaf pikseller sayılır).
- Çizim yöntemlerinde oluşturma nesneleri oluşturmayın
- Sık yapılan bir hata, her oluşturma yöntemi çağrıldığında yeni bir
Paintveya yeni birPatholuşturmaktır. Bu, çöp toplayıcının daha sık çalışmasına neden olur ve donanım işlem hattındaki önbellekleri ve optimizasyonları atlar. Bunu önlemek için nesnelerinizi yeniden kullanın ve değiştirin:- Standart yöntemleri kullanın: Standart
DrawScopeyöntemleri (ör.drawRectvedrawCircle), geliştirici ayırması gerektirmedenPaintnesnelerini dahili olarak yeniden kullanır. - Yeniden ayırmak yerine değiştirin: Özel mantık yazarken yeni bir
Patholuşturmak yerine mevcut birPath'ı temizlemek içinpath.rewindkullanın. - Durumu verimli bir şekilde tutma: Birleştirilebilir bir öğenin içinde,
remember { Path() }kullanarak nesneleri bir kez ayırın. Yeniden kullanılabilir özel değiştirici uzantıları oluşturuyorsanız nesneleri yeni yığın ayırmalarına neden olmadan ayırmak ve yeniden kullanmak içinDrawModifierNodekullanarak özel birModifier.Nodeuygulayın.
- Standart yöntemleri kullanın: Standart
- Şekilleri çok sık değiştirmeyin
- Örneğin, karmaşık şekiller, yollar ve daireler doku maskeleri kullanılarak oluşturulur. Her yol oluşturduğunuzda veya değiştirdiğinizde donanım ardışık düzeni yeni bir maske oluşturur. Bu işlem maliyetli olabilir.
- Bit eşlemleri çok sık değiştirmeyin
- Bir bit eşlemin içeriğini her değiştirdiğinizde, bir sonraki çiziminizde GPU dokusu olarak tekrar yüklenir.
- Alfa sürümünü dikkatli kullanma
Modifier.alphaveya Compose animasyon API'lerini kullanarak birleştirilebilir yarı saydam öğe oluşturduğunuzda, bu öğe genellikle ekran dışı bir arabellekte oluşturulur. Bu durum, gereken doldurma hızını iki katına çıkarır. Çakışmayan içeriklerde ekran dışı arabellek ek yükünü önlemek içinCompositingStrategy.ModulateAlphadeğerini ayarlayın. Tek tek çizim çağrıları için katman oluşturmadan alfa değerini doğrudan çizim komutuna (ör.color = Color.Red.copy(alpha = 0.5f)ile olduğu gibi) uygulayın.