Overdraw — је прекомерно прецртавање истих пиксела више пута у једном кадру. Када се на екрану приказује сложен интерфејс са много преклапајућих елемената, GPU је приморан да више пута обрађује сваки пиксел, што директно утиче на број кадрова у секунди и потрошњу енергије. Према Google Android Developer Documentation, 2025, смањење overdraw-а за 50% може повећати перформансе рендеровања до 30%. Оптимизација overdraw-а — обавезна фаза при развоју апликација са глатким анимацијама и одзивним интерфејсом.
Главне идеје
Overdraw — је ситуација у којој се исти пиксел екрана прецртава више пута током једног кадра рендеровања. У идеалном сценарију, сваки пиксел треба да се запише тачно једном, али у стварним интерфејсима због угњеждених View-ова, позадинских слика и провидних слојева, GPU врши поновљене записе.
Свако додатно прецртавање повећава време рендеровања кадра. При стандардној фреквенцији од 60 FPS, за обраду једног кадра предвиђено је око 16.6 ms. Ако overdraw доводи до прекорачења овог лимита, број кадрова пада на 30 FPS или ниже, што приметно погоршава глаткоћу интерфејса.
Према Android Performance Patterns од Google-а, апликација са коефицијентом overdraw-а 3x троши три пута више времена на фрагмент шејдер од апликације са overdraw 1x. На уређајима са ниским перформансама GPU-а, то доводи до приметних застоја при скроловању и анимацији.
За мобилне програмере, разумевање overdraw-а је критично важно: управо овај фактор најчешће изазива трзаво скроловање и низак број кадрова у наизглед једноставним екранима са великим бројем угњеждених елемената.
GPU конвејер се састоји из неколико фаза: вертекс шејдер, растеризација и фрагмент шејдер. Фрагмент шејдер — најскупљи део, јер се извршава за сваки пиксел сваког примитива. При overdraw x2, фрагмент шејдер обрађује двоструко више пиксела, што директно повећава време кадра.
Савремени мобилни GPU-и, као што су Qualcomm Adreno и Apple GPU, имају механизме Early-Z Test и Hidden Surface Removal који делимично компензују overdraw. Међутим, ове оптимизације раде само под одређеним условима и не треба се ослањати искључиво на хардверско убрзање.
На пример, при рендеровању полупровидних елемената, хардверски Early-Z је неефикасан и сваки пиксел се обрађује у потпуности — overdraw у таквим сценаријима може достићи 5x и више.
Вишеслојне позадине — један од главних узрока overdraw-а у мобилним апликацијама. Када Activity или ViewController поставља боју позадине, сваки угњеждени View може додати сопствену позадину, а пиксел се прецртава на сваком нивоу хијерархије.
Истраживање Uber Engineering показало је да је уклањање сувишних позадина у њиховој Android апликацији смањило overdraw за 32%, а време рендеровања екрана — за 25%. Слична ситуација у iOS-у: постављање opaque = true за непрозирне View-ове елиминише алфа мешање и спречава вишеструки запис пиксела.
На платформи iOS, overdraw често настаје због коришћења провидних UIStackView, CALayer са shouldRasterize и преклапајућих UIBlurEffect. Apple препоручује проверу overdraw-а путем Core Animation алата у XCode-у — он приказује зоне прецртавања као нанос црвене боје.
Debug GPU Overdraw — уграђени Android алат који боји екран у различите боје у зависности од вишеструкости overdraw-а. Љубичаста боја означава 1x, плава — 2x, зелена — 3x, розе — 4x, црвена — 5x и више. Идеалан екран треба да буде претежно љубичаст.
У iOS-у сличну дијагностику обавља алат Core Animation у саставу XCode Instruments. Он визуализује зоне прецртавања и показује тачан број уписивања по пикселу у режиму Color Blended Layers. Зелени слојеви — непрозирни (оптимално), црвени — садрже провидност и изазивају overdraw.
Након дијагностике, важно је измерити FPS пре и после оптимизације. Разлика од 10–15 FPS при исправљању overdraw-а је нормалан резултат за сложен екран са листама и анимацијом.
Уклањање сувишних позадина — најједноставнији и најефикаснији метод. У Android-у је довољно поставити android:windowBackground само за Activity или тему, а не за сваки View. У iOS-у, opaque = true за све непрозирне UIView-ове смањује overdraw практично на нулу за те елементе.
Према Google I/O 2019, оптимизација overdraw-а у Google Maps-у омогућила је смањење времена рендеровања кадра за 40% спајањем слојева и коришћењем ClipRect-а за ограничавање области цртања. Google препоручује Android програмерима следеће праксе:
У iOS-у, оптимизација се постиже конфигурацијом CALayer-а: постављање masksToBounds = true обрезује садржај изван граница слоја, а shouldRasterize укључује кеширање растерске репрезентације за статичке слојеве.
Размотримо практичне примере на Kotlin и Swift који демонстрирају типичне сценарије уклањања overdraw-а. Први пример приказује оптимизацију путем ClipRect-а у Android-у:
class OptimizedView@JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : View(context, attrs) {
override fun onDraw(canvas: Canvas) {
canvas.clipRect(
paddingLeft.toFloat(), paddingTop.toFloat(),
width - paddingRight.toFloat(), height - paddingBottom.toFloat()
)
// Цртај садржај само у исеченом подручју
super.onDraw(canvas)
}
}
Други пример — на Swift-у, приказује искључивање провидности за слој ако елемент не треба да буде полупровидан:
class OpaqueLabel: UILabel {
override var isOpaque: Bool {
get { true }
set { }
}
override func draw(_ rect: CGRect) {
backgroundColor?.setFill()
UIRectFill(rect)
super.draw(rect)
}
}
Трећи пример — коришћење ViewStub за одложено учитавање мапе у Android-у. ViewStub се не рендерује док не постане видљив, што елиминише overdraw у фази иницијализације екрана:
<!-- layout/activity_main.xml -->
<ViewStub
android:id="@+id/map_stub"
android:layout_width="match_parent"
android:layout_height="200dp"
android:inflatedId="@+id/map_container"
android:layout="@layout/map_fragment" />
// Прошири на захтев
ViewStub stub = findViewById(R.id.map_stub)
stub?.inflate()
Често постављана питања
Overdraw — је када се пиксел на екрану прецртава више пута у једном кадру. Замислите да бојите лист папира, а на њега лепите неколико провидних фолија са цртежима — доњи слојеви се морају прецртавати сваки пут када се горњи слој промени.
Укључите Debug GPU Overdraw у подешавањима програмера. Елементи са overdraw 1x се боје љубичасто, 2x — плаво, 3x — зелено, 4x — розе, 5x+ — црвено. Оптималан екран — претежно љубичаст без црвених зона.
Свако додатно прецртавање пиксела захтева позив фрагмент шејдера, који обрађује боју, текстуру и осветљење. При 60 FPS, за кадар је предвиђено 16.6 ms — ако overdraw приморава GPU да обрађује 2–3 пута више пиксела, лимит се прекорачује и FPS пада на 30.
Да, директно. GPU који обавља прекомерни рад троши више енергије. Према Google истраживању, смањење overdraw-а са 4x на 1x смањује потрошњу енергије GPU-а за 35–50%, што је посебно приметно на уређајима са екранима високе резолуције.
За једноставне екране — 1x–1.5x (љубичаст са малом количином плаве). За богате интерфејсе — до 2x. Ниво 3x и више (розе, црвено) захтева оптимизацију. Google препоручује да не прелазите overdraw 2.5x у просеку по екрану.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође