Chapter 7: Graphics: Module: Application Development and Emerging Technologies-Cc05

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

MODULE: APPLICATION DEVELOPMENT AND EMERGING

TECHNOLOGIES- CC05

CHAPTER 7: GRAPHICS

LESSON 1: PERFORMANCE AND MULTI-THREADING


 Working on multiple tasks at the same time is Multitasking. In the same way,
multiple threads running at the same time in a machine is called Multi-Threading.
Technically, a thread is a unit of a process. Multiple such threads combine to form a
process. This means when a process is broken, the equivalent number of threads are
available.
For example, Autocorrect is the process where the software looks for the mistakes
in the current word being typed. Endlessly checking for the mistake and providing
suggestions at the same time is an example of a Multi-Threaded process.
 Let’s try to visualize Multi-Threading with the help of an Android App. In the below
example, 3 Threads start at the same time on a button click and work concurrently.
 Step 1: Add the below code in activity_main.xml. Here we add three TextViews and
a button.

XML
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

<TextView

[Type text] Page 1


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05

android:id="@+id/tv1"

android:layout_width="75sp"

android:layout_height="75sp"

android:background="@color/colorPrimary"

android:textColor="@color/colorAccent"

android:gravity="center"

android:textSize="10sp"

android:layout_centerVertical="true"

android:layout_toLeftOf="@id/tv2"

/>

<TextView

android:id="@+id/tv2"

android:layout_width="75sp"

android:layout_height="75sp"

android:background="@color/colorPrimary"

android:textColor="@color/colorAccent"

android:gravity="center"

android:textSize="10sp"

android:layout_centerInParent="true"

/>

<TextView

[Type text] Page 2


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05

android:id="@+id/tv3"

android:layout_width="75sp"

android:layout_height="75sp"

android:background="@color/colorPrimary"

android:textColor="@color/colorAccent"

android:gravity="center"

android:textSize="10sp"

android:layout_centerVertical="true"

android:layout_toRightOf="@id/tv2"

/>

<Button

android:id="@+id/btnStart"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Start"

android:layout_centerHorizontal="true"

android:layout_below="@id/tv2"

/>

</RelativeLayout>

[Type text] Page 3


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05

Step 2: Add the below code in MainActivity. Here, three threads are made, each thread keeps
updating the respective TextView every second (declared in the code) when the button is
clicked. These Threads keep running until the button is clicked again (i.e.”Stop”).

JAVA
class MainActivity : AppCompatActivity() {

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Assigning Layout elements


val tv1
= findViewById<TextView>(R.id.tv1)
val tv2
= findViewById<TextView>(R.id.tv2)
val tv3
= findViewById<TextView>(R.id.tv3)
val btn
= findViewById<Button>(R.id.btnStart)

// Boolean for Button (initially False)


var boolbtn
= false
// Button onClick action
btn.setOnClickListener
{
// Button (True)
boolbtn = !boolbtn
// Case where Button is False
if (!boolbtn)
{
tv1.text = "Stopped1"
tv2.text = "Stopped2"
tv3.text = "Stopped3"
btn.text = "Start"
}
// Case where Threads are running
else
{
// Setting the button text as "Stop"
btn.text = "Stop"

// Thread 1
Thread(Runnable {

// Runs only when Button is True

[Type text] Page 4


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05
while (boolbtn) {

runOnUiThread
{
tv1.text = "Started1"
}
Thread.sleep(1000)
runOnUiThread
{
tv1.text = "Activity1"
}
Thread.sleep(1000)
}
}).start()

// Thread 2
Thread(Runnable {

// Runs only when Button is


// True
while (boolbtn) {
runOnUiThread
{
tv2.text = "Started2"
}
Thread.sleep(1000)
runOnUiThread
{
tv2.text = "Activity2"
}
Thread.sleep(1000)
}
}).start()

// Thread 3
Thread(Runnable {

// Runs only when Button is


// True
while (boolbtn) {
runOnUiThread
{
tv3.text = "Started3"
}
Thread.sleep(1000)
runOnUiThread
{
tv3.text = "Activity3"
}
Thread.sleep(1000)
}
})
.start()
}

[Type text] Page 5


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05
}
}
}
For more knowledge about this topic, please check the link provided.
https://www.geeksforgeeks.org/multithreading-in-android-with-examples/

LESSON 2: Graphics and UI Performance


 Test UI performance
o User interface (UI) performance testing ensures that your app not only meets its
functional requirements, but that user interactions with your app are buttery
smooth, running at a consistent 60 frames per second (why 60fps?), without any
dropped or delayed frames, or as we like to call it, jank. This document explains
tools available to measure UI performance, and lays out an approach to
integrate UI performance measurements into your testing practices.
 Measure UI Performance
o In order to improve performance you first need the ability to measure the
performance of your system, and then diagnose and identify problems that may
arrive from various parts of your pipeline.
o dumpsys is an Android tool that runs on the device and dumps interesting
information about the status of system services. Passing the gfxinfo command to
dumpsys provides an output in logcat with performance information relating to
frames of animation that are occurring during the recording phase.

This command can produce multiple different variants of frame timing data.

 AGGREGATE FRAME STATS

o With Android 6.0 (API level 23) the command prints out aggregated analysis of
frame data to logcat, collected across the entire lifetime of the process. For
example:

[Type text] Page 6


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05

 FRAMESTATS DATA FORMAT

o Since the block of data is output in CSV format, it's very straightforward to paste
it to your spreadsheet tool of choice, or collect and parse with a script. The
following table explains the format of the output data columns. All timestamps
are in nanoseconds.

o Rows with a ‘0’ for the FLAGS column can have their total frame time computed
by subtracting the INTENDED_VSYNC column from the FRAME_COMPLETED
column.

o If this is non-zero the row should be ignored, as the frame has been determined
as being an outlier from normal performance, where it is expected that layout &
draw take longer than 16ms. Here are a few reasons this could occur:

 The window layout changed (such as the first frame of the application
or after a rotation)

 It is also possible the frame was skipped in which case some of the
values will have garbage timestamps. A frame can be skipped if for
example it is out-running 60fps or if nothing on-screen ended up being
dirty, this is not necessarily a sign of a problem in the app.

o INTENDED_VSYNC
o The intended start point for the frame. If this value is different from VSYNC,
there was work occurring on the UI thread that prevented it from responding to
the vsync signal in a timely fashion.

o VSYNC

[Type text] Page 7


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05

o The time value that was used in all the vsync listeners and drawing for the frame
(Choreographer frame callbacks, animations, View.getDrawingTime(), etc…)

o To understand more about VSYNC and how it influences your application, check
out the Understanding VSYNC video.

o OLDEST_INPUT_EVENT
o The timestamp of the oldest input event in the input queue, or
Long.MAX_VALUE if there were no input events for the frame.

o This value is primarily intended for platform work and has limited usefulness to
app developers.

o NEWEST_INPUT_EVENT
o The timestamp of the newest input event in the input queue, or 0 if there were
no input events for the frame.

o This value is primarily intended for platform work and has limited usefulness to
app developers.

o However it’s possible to get a rough idea of how much latency the app is adding
by looking at (FRAME_COMPLETED - NEWEST_INPUT_EVENT).

o HANDLE_INPUT_START
o The timestamp at which input events were dispatched to the application.

o By looking at the time between this and ANIMATION_START it is possible to


measure how long the application spent handling input events.

o If this number is high (>2ms), this indicates the app is spending an unusually
long time processing input events, such as View.onTouchEvent(), which may
indicate this work needs to be optimized, or offloaded to a different thread.
Note that there are some scenarios, such as click events that launch new
activities or similar, where it is expected and acceptable that this number is
large.

o ANIMATION_START
o The timestamp at which animations registered with Choreographer were run.

o By looking at the time between this and PERFORM_TRANVERSALS_START it is


possible to determine how long it took to evaluate all the animators
(ObjectAnimator, ViewPropertyAnimator, and Transitions being the common
ones) that are running.

[Type text] Page 8


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05

o If this number is high (>2ms), check to see if your app has written any custom
animators or what fields ObjectAnimators are animating and ensure they are
appropriate for an animation.

o To learn more about Choreographer, check out the For Butter or Worse video.

o PERFORM_TRAVERSALS_START
o If you subtract out DRAW_START from this value, you can extract how long the
layout & measure phases took to complete. (note, during a scroll, or animation,
you would hope this should be close to zero..)

o To learn more about the measure & layout phases of the rendering pipeline,
check out the Invalidations, Layouts and Performance video

o DRAW_START
o The time at which the draw phase of performTraversals started. This is the start
point of recording the display lists of any views that were invalidated.

o The time between this and SYNC_START is how long it took to call View.draw()
on all the invalidated views in the tree.

o For more information on the drawing model, see Hardware Acceleration or


the Invalidations, Layouts and Performance video

o SYNC_QUEUED
o The time at which a sync request was sent to the RenderThread.

o This marks the point at which a message to start the sync phase was sent to the
RenderThread. If the time between this and SYNC_START is substantial (>0.1ms
or so), it means that the RenderThread was busy working on a different frame.
Internally this is used to differentiate between the frame doing too much work
and exceeding the 16ms budget and the frame being stalled due to the previous
frame exceeding the 16ms budget.

o SYNC_START
o The time at which the sync phase of the drawing started.

o If the time between this and ISSUE_DRAW_COMMANDS_START is substantial


(>0.4ms or so), it typically indicates a lot of new Bitmaps were drawn which
must be uploaded to the GPU.

o To understand more about the sync phase, check out the Profile GPU
Rendering video

o ISSUE_DRAW_COMMANDS_START

[Type text] Page 9


MODULE: APPLICATION DEVELOPMENT AND EMERGING
TECHNOLOGIES- CC05

o The time at which the hardware renderer started issuing drawing commands to
the GPU.

o The time between this and FRAME_COMPLETED gives a rough idea of how much
GPU work the app is producing. Problems like too much overdraw or inefficient
rendering effects show up here.

o SWAP_BUFFERS
o The time at which eglSwapBuffers was called, relatively uninteresting outside of
platform work.

o FRAME_COMPLETED
o All done! The total time spent working on this frame can be computed by doing
FRAME_COMPLETED - INTENDED_VSYNC.

You can use this data in different ways. One simple but useful visualization is a histogram
showing the distribution of frames times (FRAME_COMPLETED - INTENDED_VSYNC) in different
latency buckets, see figure below. This graph tells us at a glance that most frames were very
good - well below the 16ms deadline (depicted in red), but a few frames were significantly over
the deadline. We can look at changes in this histogram over time to see wholesale shifts or new
outliers being created. You can also graph input latency, time spent in layout, or other similar
interesting metrics based on the many timestamps in the data.

For more knowledge about this topic, please check the link provided
https://www.youtube.com/watch?v=zdQRIYOST64

[Type text] Page 10

You might also like