SlideShare a Scribd company logo
Tricks to Making a Realtime
SurfaceView Actually Perform in
Realtime
Maarten Edgar
Hello, my name is …
Hello, my name is …
Maarten Edgar
What we’ll cover
SurfaceViews:
• Why
• When
• What
• How
• Hard earned lessons
Why use a SurfaceView?
SurfaceView
GL_SurfaceView
TextureView
SurfaceTexture
View
What is a SurfaceView?
A View which gives you access to a
Surface using .getHolder(), which is
drawn on a seperate thread and is
double/triple buffered behind the
scenes.
It cuts holes and displays underneath
the window it is in.
How to use it:
• Setup
• Threads vs Runnables and other
control mechanisms
• Loops
• UI communication
• Tips
Setup
• Activity/View
• SurfaceView and its Thread
Setup: Activity and View
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set flags as needed
getWindow().setFormat(PixelFormat.RGBA_8888);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
setContentView(R.layout.activity_game);
// get handles to the View from XML, and its Thread
mCSurfaceView = (MySurfaceView) findViewById(R.id.surfaceview);
setSurfaceType(View.LAYER_TYPE_SOFTWARE);
mSurfaceViewThread = mSurfaceView.getThread();
createInputObjectPool();
Your SurfaceView class
public class ChiBlastSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
public ChiBlastSurfaceView(Context context) {
super(context);
mSurfaceCreated = false;
touchBool = true;
// register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
myHandler = new MyInnerHandler(this);
// create thread only; it's started in surfaceCreated()
thread = new ChiBlastSurfaceViewThread(holder, context, myHandler);
setFocusable(true); // make sure we get key events
}
Your SurfaceView callbacks 1/3
SurfaceHolder.Callback:
@Override
public void surfaceCreated(SurfaceHolder holder) {
// start the thread here so that we don't busy-wait
in run() waiting for the surface to be created
if (mSurfaceCreated == false)
{
createThread(holder);
mSurfaceCreated = true;
touchBool = true;
}
}
Your SurfaceView callbacks 2/3
SurfaceHolder.Callback:
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mSurfaceCreated = false;
cleanupResource();
terminateThread();
}
Your SurfaceView callbacks 3/3
SurfaceHolder.Callback:
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
thread.setSurfaceSize(width, height);
}
Setup: driving the SurfaceView
Runnables, thread and loops, oh my!
Setup: Thread
public class ChiBlastSurfaceViewThread extends Thread {
public ChiBlastSurfaceViewThread(SurfaceHolder surfaceHolder,
Context context, Handler handler) {
// get handles to some important objects
mSurfaceHolder = surfaceHolder;
mSurfaceHolder.setFormat(PixelFormat.RGBA_8888);
mContext = context;
res = context.getResources();
//any other initialization:
ops = new BitmapFactory.Options();
ops.inPurgeable = true;
ops.inDensity = 0;
ops.inDither = false;
ops.inScaled = false;
ops.inPreferredConfig = Bitmap.Config.ARGB_8888;
ops.inJustDecodeBounds = false;
}
@Override
public void run() {
while (mRun) {
Canvas c = null;
try {
// update game state
processInput();
//if (mMode == STATE_SCROLL_MAP)
if (mMode != STATE_PAUSE)
{
updatePhysics(timeDiff);
}
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
doDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
Setup: Thread
The Thread and your Activity
What does this now mean for your
Activity?
or
How do we make this fit into the
Android Lifecycle?
The Thread and your Activity
@Override
protected void onPause() {
super.onPause();
// pause game when Activity pauses
mSurfaceView.getThread().pause();
mSurfaceView.terminateThread();
System.gc();
}
The Thread and your Activity
@Override
protected void onResume()
{
super.onResume();
if (mSurfaceView.mSurfaceCreated)
{
mSurfaceView.createThread(mSurfaceView.getHolder());
setSurfaceType(View.LAYER_TYPE_SOFTWARE);
}
mSurfaceView.SetTouch(true);
}
The Thread and your Activity
@Override
protected void onRestoreInstanceState(Bundle inState) {
// just have the View's thread load its state from our Bundle
if (mSurfaceView.mSurfaceCreated)
{
mSurfaceView.createThread(mSurfaceView.getHolder());
setSurfaceType(View.LAYER_TYPE_SOFTWARE);
}
mSurfaceViewThread.restoreState(inState);
}
The main loop
• AFAFP
• Fixed step
@Override
public void run() {
long beginTime; // the time when the cycle begun
long timeDiff; // the time it took for the cycle to execute
int sleepTime; // ms to sleep (<0 if we're behind)
int framesSkipped; // number of frames being skipped
timeDiff = System.currentTimeMillis()+50;
sleepTime = 0;
while (mRun) {
Canvas c = null;
try {
beginTime = System.currentTimeMillis();
framesSkipped = 0; // resetting the frames skipped
// update game state
processInput();
//if (mMode == STATE_SCROLL_MAP)
if (mMode != STATE_PAUSE)
{
updatePhysics(timeDiff);
}
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
doDraw(c);
}
The main loop 1/3
The main loop 2/3
// calculate how long did the cycle take
timeDiff = System.currentTimeMillis() - beginTime;
// calculate sleep time
sleepTime = (int)(FRAME_PERIOD - timeDiff);
if (sleepTime > 0) {
// if sleepTime > 0 we're OK
try {
// send the thread to sleep for a short period
// very useful for battery saving
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
// we need to catch up
// update without rendering
processInput();
if (mMode != STATE_PAUSE)
{
updatePhysics(timeDiff);
}
// add frame period to check if in next frame
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
The main loop 3/3
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
UI Communication
Use a Handler:
static class MyInnerHandler extends Handler {
private final WeakReference<ChiBlastSurfaceView> mView;
MyInnerHandler(ChiBlastSurfaceView aView) {
mView = new WeakReference<ChiBlastSurfaceView>(aView);
}
@Override
public void handleMessage(Message m) {
ChiBlastSurfaceView theView = mView.get();
theView.mStatusText.setText(m.getData().getString("text"));
if (m.getData().getInt("viz") == View.VISIBLE)
{
theView.mStatusText.setVisibility(View.VISIBLE);
//mStatusText.setAnimation(displayTextAnim);
//mStatusText.startAnimation(displayTextAnim);
}
else
{
if (m.getData().getInt("viz") == View.INVISIBLE)
{
theView.mStatusText.setVisibility(View.INVISIBLE);
theView.mStatusText.setAnimation(null);
}
else if (m.getData().getInt("viz") == View.GONE)
{
theView.mStatusText.setVisibility(View.GONE);
}
}
theView.mStatusText.invalidate();
}
}
Setup: Cleanup
public void terminateThread ()
{
boolean retry = true;
thread.setRunning(false);
while (retry) {
try
{
thread.join();
retry = false;
}
catch (InterruptedException e)
{
}
//break; //THIS BREAKS IT ON PUSHING HOME
}
//thread = null; //THIS BREAKS IT ON PUSHING HOME
}
Tips
• Input buffer
• Object creation
• Scaling
• Drawing, bitmaps and other dirty
things
Tips: input buffer in SVActivity
private void createInputObjectPool() {
inputObjectPool = new ArrayBlockingQueue<InputObject>(INPUT_QUEUE_SIZE);
for (int i = 0; i < INPUT_QUEUE_SIZE; i++) {
inputObjectPool.add(new InputObject(inputObjectPool));
}
}
public class InputObject {
public static final byte EVENT_TYPE_KEY = 1;
public static final byte EVENT_TYPE_TOUCH = 2;
public static final int ACTION_KEY_DOWN = 1;
public static final int ACTION_KEY_UP = 2;
public static final int ACTION_TOUCH_DOWN = MotionEvent.ACTION_DOWN;
public static final int ACTION_TOUCH_POINTER_DOWN = MotionEvent.ACTION_POINTER_DOWN;
//public static final int ACTION_TOUCH_POINTER_2_DOWN = MotionEvent.ACTION_POINTER_2_DOWN;
public static final int ACTION_TOUCH_MOVE = MotionEvent.ACTION_MOVE;
public static final int ACTION_TOUCH_UP = MotionEvent.ACTION_UP;
public static final int ACTION_TOUCH_POINTER_UP = MotionEvent.ACTION_POINTER_UP;
//public static final int ACTION_TOUCH_POINTER_2_UP = MotionEvent.ACTION_POINTER_2_UP;
public ArrayBlockingQueue<InputObject> pool;
public byte eventType;
public long time;
public int action;
public int keyCode;
public int x;
public int y;
public int x2;
public int y2;
public int pointerID;
public int pointerIndex;
public int pointerIndex2;
InputObject 1/5
InputObject 2/5
public InputObject(ArrayBlockingQueue<InputObject> pool) {
this.pool = pool;
}
public void useEvent(KeyEvent event) {
eventType = EVENT_TYPE_KEY;
int a = event.getAction();
switch (a) {
case KeyEvent.ACTION_DOWN:
action = ACTION_KEY_DOWN;
break;
case KeyEvent.ACTION_UP:
action = ACTION_KEY_UP;
break;
default:
action = 0;
}
time = event.getEventTime();
keyCode = event.getKeyCode();
}
public void useEvent(MotionEvent event) {
eventType = EVENT_TYPE_TOUCH;
int a = event.getAction();
switch (a) {
case MotionEvent.ACTION_DOWN:
action = ACTION_TOUCH_DOWN;
break;
case MotionEvent.ACTION_POINTER_DOWN:
action = ACTION_TOUCH_POINTER_DOWN;
break;
case MotionEvent.ACTION_POINTER_2_DOWN:
action = ACTION_TOUCH_POINTER_DOWN;
break;
case MotionEvent.ACTION_MOVE:
action = ACTION_TOUCH_MOVE;
break;
case MotionEvent.ACTION_UP:
action = ACTION_TOUCH_UP;
break;
case MotionEvent.ACTION_POINTER_UP:
action = ACTION_TOUCH_POINTER_UP;
break;
case MotionEvent.ACTION_POINTER_2_UP:
action = ACTION_TOUCH_POINTER_UP;
break;
default:
action = -1;
}
InputObject 3/5
InputObject 4/5
time = event.getEventTime();
pointerIndex = (event.getAction() &
MotionEvent.ACTION_POINTER_ID_MASK) >>
MotionEvent.ACTION_POINTER_ID_SHIFT;
pointerID = event.getPointerId(pointerIndex);
x = (int) event.getX(pointerIndex);
y = (int) event.getY(pointerIndex);
if (event.getPointerCount() > 1)
{
pointerIndex2 = pointerIndex== 0 ? 1 : 0;
x2 = (int)event.getX(pointerIndex2);
y2 = (int)event.getY(pointerIndex2);
}
}
InputObject 5/5
public void useEventHistory(MotionEvent event, int historyItem) {
eventType = EVENT_TYPE_TOUCH;
action = ACTION_TOUCH_MOVE;
time = event.getHistoricalEventTime(historyItem);
pointerIndex = (event.getAction() &
MotionEvent.ACTION_POINTER_ID_MASK) >>
MotionEvent.ACTION_POINTER_ID_SHIFT;
pointerID = event.getPointerId(pointerIndex);
x = (int) event.getHistoricalX(pointerIndex, historyItem);
y = (int) event.getHistoricalY(pointerIndex, historyItem);
if (event.getPointerCount() > 1)
{
pointerIndex2 = pointerIndex== 0 ? 1 : 0;
x2 = (int) event.getHistoricalX(pointerIndex2, historyItem);
y2 = (int) event.getHistoricalY(pointerIndex2, historyItem);
}
}
public void returnToPool() {
pool.add(this);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
try {
// history first
int hist = event.getHistorySize();
if (hist > 0)
{
// add from oldest to newest
for (int i = 0; i < hist; i++)
{
//for (int i = hist-1; i > -1; i--) {
InputObject input = inputObjectPool.take();
input.useEventHistory(event, i);
mSurfaceViewThread.feedInput(input);
}
}
// current last
InputObject input = inputObjectPool.take();
input.useEvent(event);
mSurfaceViewThread.feedInput(input);
} catch (InterruptedException e) {
}
// don't allow more than 60 motion events per second
try {
Thread.sleep(16);
} catch (InterruptedException e) {
}
return true;
}
Back to the activity:
public void feedInput(InputObject input) {
synchronized(inputQueueMutex) {
try {
inputQueue.put(input);
} catch (InterruptedException e) {
//Log.e(TAG, e.getMessage(), e);
}
}
}
private void processInput() {
synchronized(inputQueueMutex) {
ArrayBlockingQueue<InputObject> inputQueue = ChiBlastSurfaceView.inputQueue;
while (!inputQueue.isEmpty()) {
try {
InputObject input = inputQueue.take();
if (input.eventType == InputObject.EVENT_TYPE_KEY) {
//processKeyEvent(input);
} else if (input.eventType == InputObject.EVENT_TYPE_TOUCH) {
processMotionEvent(input);
}
input.returnToPool();
} catch (InterruptedException e) {
//Log.e(TAG, e.getMessage(), e);
}
}
}
}
And in the SurfaceView.Thread:
Tips: object creation
Tips: object creation
Just don’t do it.
Tips: object creation
Or do it up front.
No matter how odd that sometimes
may seem.
Tips: scaling
Two types of scaling:
• Realtime whole view SV scaling
only works from Android N
• Fixed scaling (as done in Unreal
Tournament 3)
Tips: scaling
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//thread.setSurfaceSize(width, height);
if (mCanvasWidth != width)
{
int scaledWidth = (int)(width*0.75f);
int scaledHeight = (int)(height*0.75f);
if (scaledHeight != height)
{
yRatio = (float)(scaledHeight / (float)height);
xRatio = (float)(scaledWidth / (float)width);
}
holder.setFixedSize(scaledWidth, scaledHeight);
thread.setSurfaceSize(scaledWidth, scaledHeight);
}
}
Tips: drawing, bitmaps and other
dirty things
Tips: drawing, bitmaps and other
dirty things
In SurfaceView.Thread doDraw():
canvas.drawBitmap(mBackgroundImage,
null, fullscreenRect, mPicPaint);
Q&A
Thank you!
Maarten Edgar
lifeboatsoft@gmail.com
Resources:
https://source.android.com/devices/graphics/architecture.html
https://github.com/google/grafika

More Related Content

What's hot

Don't dump thread dumps
Don't dump thread dumpsDon't dump thread dumps
Don't dump thread dumps
Tier1app
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWeb
Bryan Helmig
 
Taking advantage of the Amazon Web Services (AWS) Family
Taking advantage of the Amazon Web Services (AWS) FamilyTaking advantage of the Amazon Web Services (AWS) Family
Taking advantage of the Amazon Web Services (AWS) Family
Ben Hall
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotXamarin
 
GC Tuning & Troubleshooting Crash Course
GC Tuning & Troubleshooting Crash CourseGC Tuning & Troubleshooting Crash Course
GC Tuning & Troubleshooting Crash Course
Tier1 app
 
Developing Async Sense
Developing Async SenseDeveloping Async Sense
Developing Async Sense
Nemanja Stojanovic
 
React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7
Dongho Cho
 
Troubleshooting real production problems
Troubleshooting real production problemsTroubleshooting real production problems
Troubleshooting real production problems
Tier1 app
 
MongoDB: tips, trick and hacks
MongoDB: tips, trick and hacksMongoDB: tips, trick and hacks
MongoDB: tips, trick and hacksScott Hernandez
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
KatyShimizu
 
Cassandra Summit EU 2014 Lightning talk - Paging (no animation)
Cassandra Summit EU 2014 Lightning talk - Paging (no animation)Cassandra Summit EU 2014 Lightning talk - Paging (no animation)
Cassandra Summit EU 2014 Lightning talk - Paging (no animation)
Christopher Batey
 
Third Party Auth in WebObjects
Third Party Auth in WebObjectsThird Party Auth in WebObjects
Third Party Auth in WebObjectsWO Community
 
RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015
Ben Lesh
 
Angular 1 + es6
Angular 1 + es6Angular 1 + es6
Angular 1 + es6
장현 한
 
Adventures in Multithreaded Core Data
Adventures in Multithreaded Core DataAdventures in Multithreaded Core Data
Adventures in Multithreaded Core DataInferis
 
LJC Conference 2014 Cassandra for Java Developers
LJC Conference 2014 Cassandra for Java DevelopersLJC Conference 2014 Cassandra for Java Developers
LJC Conference 2014 Cassandra for Java Developers
Christopher Batey
 
Troubleshooting performanceavailabilityproblems (1)
Troubleshooting performanceavailabilityproblems (1)Troubleshooting performanceavailabilityproblems (1)
Troubleshooting performanceavailabilityproblems (1)
Tier1 app
 
Snapshot clone-boot-presentation-final
Snapshot clone-boot-presentation-finalSnapshot clone-boot-presentation-final
Snapshot clone-boot-presentation-finalOpen Stack
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
Rick Warren
 
Taking advantage of Prometheus relabeling
Taking advantage of Prometheus relabelingTaking advantage of Prometheus relabeling
Taking advantage of Prometheus relabeling
Julien Pivotto
 

What's hot (20)

Don't dump thread dumps
Don't dump thread dumpsDon't dump thread dumps
Don't dump thread dumps
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWeb
 
Taking advantage of the Amazon Web Services (AWS) Family
Taking advantage of the Amazon Web Services (AWS) FamilyTaking advantage of the Amazon Web Services (AWS) Family
Taking advantage of the Amazon Web Services (AWS) Family
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien Pouliot
 
GC Tuning & Troubleshooting Crash Course
GC Tuning & Troubleshooting Crash CourseGC Tuning & Troubleshooting Crash Course
GC Tuning & Troubleshooting Crash Course
 
Developing Async Sense
Developing Async SenseDeveloping Async Sense
Developing Async Sense
 
React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7
 
Troubleshooting real production problems
Troubleshooting real production problemsTroubleshooting real production problems
Troubleshooting real production problems
 
MongoDB: tips, trick and hacks
MongoDB: tips, trick and hacksMongoDB: tips, trick and hacks
MongoDB: tips, trick and hacks
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
Cassandra Summit EU 2014 Lightning talk - Paging (no animation)
Cassandra Summit EU 2014 Lightning talk - Paging (no animation)Cassandra Summit EU 2014 Lightning talk - Paging (no animation)
Cassandra Summit EU 2014 Lightning talk - Paging (no animation)
 
Third Party Auth in WebObjects
Third Party Auth in WebObjectsThird Party Auth in WebObjects
Third Party Auth in WebObjects
 
RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015
 
Angular 1 + es6
Angular 1 + es6Angular 1 + es6
Angular 1 + es6
 
Adventures in Multithreaded Core Data
Adventures in Multithreaded Core DataAdventures in Multithreaded Core Data
Adventures in Multithreaded Core Data
 
LJC Conference 2014 Cassandra for Java Developers
LJC Conference 2014 Cassandra for Java DevelopersLJC Conference 2014 Cassandra for Java Developers
LJC Conference 2014 Cassandra for Java Developers
 
Troubleshooting performanceavailabilityproblems (1)
Troubleshooting performanceavailabilityproblems (1)Troubleshooting performanceavailabilityproblems (1)
Troubleshooting performanceavailabilityproblems (1)
 
Snapshot clone-boot-presentation-final
Snapshot clone-boot-presentation-finalSnapshot clone-boot-presentation-final
Snapshot clone-boot-presentation-final
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Taking advantage of Prometheus relabeling
Taking advantage of Prometheus relabelingTaking advantage of Prometheus relabeling
Taking advantage of Prometheus relabeling
 

Viewers also liked

Cognitive interaction using Wearables - Eyal herman, IBM
Cognitive interaction using Wearables - Eyal herman, IBMCognitive interaction using Wearables - Eyal herman, IBM
Cognitive interaction using Wearables - Eyal herman, IBM
DroidConTLV
 
3 things every Android developer must know about Microsoft - Ido Volff, Micro...
3 things every Android developer must know about Microsoft - Ido Volff, Micro...3 things every Android developer must know about Microsoft - Ido Volff, Micro...
3 things every Android developer must know about Microsoft - Ido Volff, Micro...
DroidConTLV
 
Creating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBM
Creating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBMCreating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBM
Creating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBM
DroidConTLV
 
Android Application Optimization: Overview and Tools - Oref Barad, AVG
Android Application Optimization: Overview and Tools - Oref Barad, AVGAndroid Application Optimization: Overview and Tools - Oref Barad, AVG
Android Application Optimization: Overview and Tools - Oref Barad, AVG
DroidConTLV
 
Android is going to Go! - Android and goland - Almog Baku
Android is going to Go! - Android and goland - Almog BakuAndroid is going to Go! - Android and goland - Almog Baku
Android is going to Go! - Android and goland - Almog Baku
DroidConTLV
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
DroidConTLV
 
Will it run or will it not run? Background processes in Android 6 - Anna Lifs...
Will it run or will it not run? Background processes in Android 6 - Anna Lifs...Will it run or will it not run? Background processes in Android 6 - Anna Lifs...
Will it run or will it not run? Background processes in Android 6 - Anna Lifs...
DroidConTLV
 
Good Rules for Bad Apps - Shem magnezi
Good Rules for Bad Apps - Shem magnezi Good Rules for Bad Apps - Shem magnezi
Good Rules for Bad Apps - Shem magnezi
DroidConTLV
 
Intro to Dependency Injection - Or bar
Intro to Dependency Injection - Or bar Intro to Dependency Injection - Or bar
Intro to Dependency Injection - Or bar
DroidConTLV
 
Mobile SDKs: Use with Caution - Ori Lentzitzky
Mobile SDKs: Use with Caution - Ori LentzitzkyMobile SDKs: Use with Caution - Ori Lentzitzky
Mobile SDKs: Use with Caution - Ori Lentzitzky
DroidConTLV
 
Context is Everything - Royi Benyossef
Context is Everything - Royi Benyossef Context is Everything - Royi Benyossef
Context is Everything - Royi Benyossef
DroidConTLV
 
Set it and forget it: Let the machine learn its job - Guy Baron, Vonage
Set it and forget it: Let the machine learn its job - Guy Baron, VonageSet it and forget it: Let the machine learn its job - Guy Baron, Vonage
Set it and forget it: Let the machine learn its job - Guy Baron, Vonage
DroidConTLV
 
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
DroidConTLV
 
Knock knock! Who's there? Doze. - Yonatan Levin
Knock knock! Who's there? Doze. - Yonatan Levin Knock knock! Who's there? Doze. - Yonatan Levin
Knock knock! Who's there? Doze. - Yonatan Levin
DroidConTLV
 
Optimize your delivery and quality with the right release methodology and too...
Optimize your delivery and quality with the right release methodology and too...Optimize your delivery and quality with the right release methodology and too...
Optimize your delivery and quality with the right release methodology and too...
DroidConTLV
 
Android Continuous Integration and Automation - Enrique Lopez Manas, Sixt
Android Continuous Integration and Automation - Enrique Lopez Manas, SixtAndroid Continuous Integration and Automation - Enrique Lopez Manas, Sixt
Android Continuous Integration and Automation - Enrique Lopez Manas, Sixt
DroidConTLV
 
Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak
DroidConTLV
 

Viewers also liked (17)

Cognitive interaction using Wearables - Eyal herman, IBM
Cognitive interaction using Wearables - Eyal herman, IBMCognitive interaction using Wearables - Eyal herman, IBM
Cognitive interaction using Wearables - Eyal herman, IBM
 
3 things every Android developer must know about Microsoft - Ido Volff, Micro...
3 things every Android developer must know about Microsoft - Ido Volff, Micro...3 things every Android developer must know about Microsoft - Ido Volff, Micro...
3 things every Android developer must know about Microsoft - Ido Volff, Micro...
 
Creating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBM
Creating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBMCreating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBM
Creating killer apps powered by watson cognitive services - Ronen Siman-Tov, IBM
 
Android Application Optimization: Overview and Tools - Oref Barad, AVG
Android Application Optimization: Overview and Tools - Oref Barad, AVGAndroid Application Optimization: Overview and Tools - Oref Barad, AVG
Android Application Optimization: Overview and Tools - Oref Barad, AVG
 
Android is going to Go! - Android and goland - Almog Baku
Android is going to Go! - Android and goland - Almog BakuAndroid is going to Go! - Android and goland - Almog Baku
Android is going to Go! - Android and goland - Almog Baku
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
 
Will it run or will it not run? Background processes in Android 6 - Anna Lifs...
Will it run or will it not run? Background processes in Android 6 - Anna Lifs...Will it run or will it not run? Background processes in Android 6 - Anna Lifs...
Will it run or will it not run? Background processes in Android 6 - Anna Lifs...
 
Good Rules for Bad Apps - Shem magnezi
Good Rules for Bad Apps - Shem magnezi Good Rules for Bad Apps - Shem magnezi
Good Rules for Bad Apps - Shem magnezi
 
Intro to Dependency Injection - Or bar
Intro to Dependency Injection - Or bar Intro to Dependency Injection - Or bar
Intro to Dependency Injection - Or bar
 
Mobile SDKs: Use with Caution - Ori Lentzitzky
Mobile SDKs: Use with Caution - Ori LentzitzkyMobile SDKs: Use with Caution - Ori Lentzitzky
Mobile SDKs: Use with Caution - Ori Lentzitzky
 
Context is Everything - Royi Benyossef
Context is Everything - Royi Benyossef Context is Everything - Royi Benyossef
Context is Everything - Royi Benyossef
 
Set it and forget it: Let the machine learn its job - Guy Baron, Vonage
Set it and forget it: Let the machine learn its job - Guy Baron, VonageSet it and forget it: Let the machine learn its job - Guy Baron, Vonage
Set it and forget it: Let the machine learn its job - Guy Baron, Vonage
 
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
Think Async: Understanding the Complexity of Multithreading - Avi Kabizon & A...
 
Knock knock! Who's there? Doze. - Yonatan Levin
Knock knock! Who's there? Doze. - Yonatan Levin Knock knock! Who's there? Doze. - Yonatan Levin
Knock knock! Who's there? Doze. - Yonatan Levin
 
Optimize your delivery and quality with the right release methodology and too...
Optimize your delivery and quality with the right release methodology and too...Optimize your delivery and quality with the right release methodology and too...
Optimize your delivery and quality with the right release methodology and too...
 
Android Continuous Integration and Automation - Enrique Lopez Manas, Sixt
Android Continuous Integration and Automation - Enrique Lopez Manas, SixtAndroid Continuous Integration and Automation - Enrique Lopez Manas, Sixt
Android Continuous Integration and Automation - Enrique Lopez Manas, Sixt
 
Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak Build an App with Blindfold - Britt Barak
Build an App with Blindfold - Britt Barak
 

Similar to Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarten Edger

Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
jonmarimba
 
Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)
Korhan Bircan
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
Tomek Kaczanowski
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
Krzysztof Szafranek
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/OJussi Pohjolainen
 
I wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdfI wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdf
feelinggifts
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаГлеб Тарасов
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Doug Hawkins
 
Implementing new WebAPIs
Implementing new WebAPIsImplementing new WebAPIs
Implementing new WebAPIs
Julian Viereck
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
Ankit Rastogi
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
Pavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon Berlin
 
Open Cv 2005 Q4 Tutorial
Open Cv 2005 Q4 TutorialOpen Cv 2005 Q4 Tutorial
Open Cv 2005 Q4 Tutorial
antiw
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
Azul Systems, Inc.
 

Similar to Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarten Edger (20)

Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Thread
ThreadThread
Thread
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
 
Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
 
I wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdfI wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdf
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Implementing New Web
Implementing New WebImplementing New Web
Implementing New Web
 
Implementing new WebAPIs
Implementing new WebAPIsImplementing new WebAPIs
Implementing new WebAPIs
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
 
Day 1
Day 1Day 1
Day 1
 
Open Cv 2005 Q4 Tutorial
Open Cv 2005 Q4 TutorialOpen Cv 2005 Q4 Tutorial
Open Cv 2005 Q4 Tutorial
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 

More from DroidConTLV

Mobile Development in the Information Age - Yossi Elkrief, Nike
Mobile Development in the Information Age - Yossi Elkrief, NikeMobile Development in the Information Age - Yossi Elkrief, Nike
Mobile Development in the Information Age - Yossi Elkrief, Nike
DroidConTLV
 
Doing work in the background - Darryn Campbell, Zebra Technologies
Doing work in the background - Darryn Campbell, Zebra TechnologiesDoing work in the background - Darryn Campbell, Zebra Technologies
Doing work in the background - Darryn Campbell, Zebra Technologies
DroidConTLV
 
No more video loss - Alex Rivkin, Motorola Solutions
No more video loss - Alex Rivkin, Motorola SolutionsNo more video loss - Alex Rivkin, Motorola Solutions
No more video loss - Alex Rivkin, Motorola Solutions
DroidConTLV
 
Mobile at Scale: from startup to a big company - Dor Samet, Booking.com
Mobile at Scale: from startup to a big company - Dor Samet, Booking.comMobile at Scale: from startup to a big company - Dor Samet, Booking.com
Mobile at Scale: from startup to a big company - Dor Samet, Booking.com
DroidConTLV
 
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, ClimacellLiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
DroidConTLV
 
MVVM In real life - Lea Cohen Tannoudji, Lightricks
MVVM In real life - Lea Cohen Tannoudji, LightricksMVVM In real life - Lea Cohen Tannoudji, Lightricks
MVVM In real life - Lea Cohen Tannoudji, Lightricks
DroidConTLV
 
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
DroidConTLV
 
Building Apps with Flutter - Hillel Coren, Invoice Ninja
Building Apps with Flutter - Hillel Coren, Invoice NinjaBuilding Apps with Flutter - Hillel Coren, Invoice Ninja
Building Apps with Flutter - Hillel Coren, Invoice Ninja
DroidConTLV
 
New Android Project: The Most Important Decisions - Vasiliy Zukanov
New Android Project: The Most Important Decisions - Vasiliy ZukanovNew Android Project: The Most Important Decisions - Vasiliy Zukanov
New Android Project: The Most Important Decisions - Vasiliy Zukanov
DroidConTLV
 
Designing a Design System - Shai Mishali, Gett
Designing a Design System - Shai Mishali, GettDesigning a Design System - Shai Mishali, Gett
Designing a Design System - Shai Mishali, Gett
DroidConTLV
 
The Mighty Power of the Accessibility Service - Guy Griv, Pepper
The Mighty Power of the Accessibility Service - Guy Griv, PepperThe Mighty Power of the Accessibility Service - Guy Griv, Pepper
The Mighty Power of the Accessibility Service - Guy Griv, Pepper
DroidConTLV
 
Kotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDev
Kotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDevKotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDev
Kotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDev
DroidConTLV
 
Flutter State Management - Moti Bartov, Tikal
Flutter State Management - Moti Bartov, TikalFlutter State Management - Moti Bartov, Tikal
Flutter State Management - Moti Bartov, Tikal
DroidConTLV
 
Reactive UI in android - Gil Goldzweig Goldbaum, 10bis
Reactive UI in android - Gil Goldzweig Goldbaum, 10bisReactive UI in android - Gil Goldzweig Goldbaum, 10bis
Reactive UI in android - Gil Goldzweig Goldbaum, 10bis
DroidConTLV
 
Fun with flutter animations - Divyanshu Bhargava, GoHighLevel
Fun with flutter animations - Divyanshu Bhargava, GoHighLevelFun with flutter animations - Divyanshu Bhargava, GoHighLevel
Fun with flutter animations - Divyanshu Bhargava, GoHighLevel
DroidConTLV
 
DroidconTLV 2019
DroidconTLV 2019DroidconTLV 2019
DroidconTLV 2019
DroidConTLV
 
Ok google, it's time to bot! - Hadar Franco, Albert + Stav Levi, Monday
Ok google, it's time to bot! - Hadar Franco, Albert + Stav Levi, MondayOk google, it's time to bot! - Hadar Franco, Albert + Stav Levi, Monday
Ok google, it's time to bot! - Hadar Franco, Albert + Stav Levi, Monday
DroidConTLV
 
Introduction to React Native - Lev Vidrak, Wix
Introduction to React Native - Lev Vidrak, WixIntroduction to React Native - Lev Vidrak, Wix
Introduction to React Native - Lev Vidrak, Wix
DroidConTLV
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
DroidConTLV
 
Educating your app – adding ML edge to your apps - Maoz Tamir
Educating your app – adding ML edge to your apps - Maoz TamirEducating your app – adding ML edge to your apps - Maoz Tamir
Educating your app – adding ML edge to your apps - Maoz Tamir
DroidConTLV
 

More from DroidConTLV (20)

Mobile Development in the Information Age - Yossi Elkrief, Nike
Mobile Development in the Information Age - Yossi Elkrief, NikeMobile Development in the Information Age - Yossi Elkrief, Nike
Mobile Development in the Information Age - Yossi Elkrief, Nike
 
Doing work in the background - Darryn Campbell, Zebra Technologies
Doing work in the background - Darryn Campbell, Zebra TechnologiesDoing work in the background - Darryn Campbell, Zebra Technologies
Doing work in the background - Darryn Campbell, Zebra Technologies
 
No more video loss - Alex Rivkin, Motorola Solutions
No more video loss - Alex Rivkin, Motorola SolutionsNo more video loss - Alex Rivkin, Motorola Solutions
No more video loss - Alex Rivkin, Motorola Solutions
 
Mobile at Scale: from startup to a big company - Dor Samet, Booking.com
Mobile at Scale: from startup to a big company - Dor Samet, Booking.comMobile at Scale: from startup to a big company - Dor Samet, Booking.com
Mobile at Scale: from startup to a big company - Dor Samet, Booking.com
 
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, ClimacellLiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
 
MVVM In real life - Lea Cohen Tannoudji, Lightricks
MVVM In real life - Lea Cohen Tannoudji, LightricksMVVM In real life - Lea Cohen Tannoudji, Lightricks
MVVM In real life - Lea Cohen Tannoudji, Lightricks
 
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
 
Building Apps with Flutter - Hillel Coren, Invoice Ninja
Building Apps with Flutter - Hillel Coren, Invoice NinjaBuilding Apps with Flutter - Hillel Coren, Invoice Ninja
Building Apps with Flutter - Hillel Coren, Invoice Ninja
 
New Android Project: The Most Important Decisions - Vasiliy Zukanov
New Android Project: The Most Important Decisions - Vasiliy ZukanovNew Android Project: The Most Important Decisions - Vasiliy Zukanov
New Android Project: The Most Important Decisions - Vasiliy Zukanov
 
Designing a Design System - Shai Mishali, Gett
Designing a Design System - Shai Mishali, GettDesigning a Design System - Shai Mishali, Gett
Designing a Design System - Shai Mishali, Gett
 
The Mighty Power of the Accessibility Service - Guy Griv, Pepper
The Mighty Power of the Accessibility Service - Guy Griv, PepperThe Mighty Power of the Accessibility Service - Guy Griv, Pepper
The Mighty Power of the Accessibility Service - Guy Griv, Pepper
 
Kotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDev
Kotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDevKotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDev
Kotlin Multiplatform in Action - Alexandr Pogrebnyak - IceRockDev
 
Flutter State Management - Moti Bartov, Tikal
Flutter State Management - Moti Bartov, TikalFlutter State Management - Moti Bartov, Tikal
Flutter State Management - Moti Bartov, Tikal
 
Reactive UI in android - Gil Goldzweig Goldbaum, 10bis
Reactive UI in android - Gil Goldzweig Goldbaum, 10bisReactive UI in android - Gil Goldzweig Goldbaum, 10bis
Reactive UI in android - Gil Goldzweig Goldbaum, 10bis
 
Fun with flutter animations - Divyanshu Bhargava, GoHighLevel
Fun with flutter animations - Divyanshu Bhargava, GoHighLevelFun with flutter animations - Divyanshu Bhargava, GoHighLevel
Fun with flutter animations - Divyanshu Bhargava, GoHighLevel
 
DroidconTLV 2019
DroidconTLV 2019DroidconTLV 2019
DroidconTLV 2019
 
Ok google, it's time to bot! - Hadar Franco, Albert + Stav Levi, Monday
Ok google, it's time to bot! - Hadar Franco, Albert + Stav Levi, MondayOk google, it's time to bot! - Hadar Franco, Albert + Stav Levi, Monday
Ok google, it's time to bot! - Hadar Franco, Albert + Stav Levi, Monday
 
Introduction to React Native - Lev Vidrak, Wix
Introduction to React Native - Lev Vidrak, WixIntroduction to React Native - Lev Vidrak, Wix
Introduction to React Native - Lev Vidrak, Wix
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
 
Educating your app – adding ML edge to your apps - Maoz Tamir
Educating your app – adding ML edge to your apps - Maoz TamirEducating your app – adding ML edge to your apps - Maoz Tamir
Educating your app – adding ML edge to your apps - Maoz Tamir
 

Recently uploaded

GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 

Recently uploaded (20)

GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 

Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarten Edger

  • 1. Tricks to Making a Realtime SurfaceView Actually Perform in Realtime Maarten Edgar
  • 2. Hello, my name is …
  • 3. Hello, my name is … Maarten Edgar
  • 4. What we’ll cover SurfaceViews: • Why • When • What • How • Hard earned lessons
  • 5. Why use a SurfaceView? SurfaceView GL_SurfaceView TextureView SurfaceTexture View
  • 6. What is a SurfaceView? A View which gives you access to a Surface using .getHolder(), which is drawn on a seperate thread and is double/triple buffered behind the scenes. It cuts holes and displays underneath the window it is in.
  • 7. How to use it: • Setup • Threads vs Runnables and other control mechanisms • Loops • UI communication • Tips
  • 9. Setup: Activity and View @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // set flags as needed getWindow().setFormat(PixelFormat.RGBA_8888); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); setContentView(R.layout.activity_game); // get handles to the View from XML, and its Thread mCSurfaceView = (MySurfaceView) findViewById(R.id.surfaceview); setSurfaceType(View.LAYER_TYPE_SOFTWARE); mSurfaceViewThread = mSurfaceView.getThread(); createInputObjectPool();
  • 10. Your SurfaceView class public class ChiBlastSurfaceView extends SurfaceView implements SurfaceHolder.Callback { public ChiBlastSurfaceView(Context context) { super(context); mSurfaceCreated = false; touchBool = true; // register our interest in hearing about changes to our surface SurfaceHolder holder = getHolder(); holder.addCallback(this); myHandler = new MyInnerHandler(this); // create thread only; it's started in surfaceCreated() thread = new ChiBlastSurfaceViewThread(holder, context, myHandler); setFocusable(true); // make sure we get key events }
  • 11. Your SurfaceView callbacks 1/3 SurfaceHolder.Callback: @Override public void surfaceCreated(SurfaceHolder holder) { // start the thread here so that we don't busy-wait in run() waiting for the surface to be created if (mSurfaceCreated == false) { createThread(holder); mSurfaceCreated = true; touchBool = true; } }
  • 12. Your SurfaceView callbacks 2/3 SurfaceHolder.Callback: @Override public void surfaceDestroyed(SurfaceHolder holder) { mSurfaceCreated = false; cleanupResource(); terminateThread(); }
  • 13. Your SurfaceView callbacks 3/3 SurfaceHolder.Callback: @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { thread.setSurfaceSize(width, height); }
  • 14. Setup: driving the SurfaceView Runnables, thread and loops, oh my!
  • 15. Setup: Thread public class ChiBlastSurfaceViewThread extends Thread { public ChiBlastSurfaceViewThread(SurfaceHolder surfaceHolder, Context context, Handler handler) { // get handles to some important objects mSurfaceHolder = surfaceHolder; mSurfaceHolder.setFormat(PixelFormat.RGBA_8888); mContext = context; res = context.getResources(); //any other initialization: ops = new BitmapFactory.Options(); ops.inPurgeable = true; ops.inDensity = 0; ops.inDither = false; ops.inScaled = false; ops.inPreferredConfig = Bitmap.Config.ARGB_8888; ops.inJustDecodeBounds = false; }
  • 16. @Override public void run() { while (mRun) { Canvas c = null; try { // update game state processInput(); //if (mMode == STATE_SCROLL_MAP) if (mMode != STATE_PAUSE) { updatePhysics(timeDiff); } c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { doDraw(c); } } finally { // do this in a finally so that if an exception is thrown // during the above, we don't leave the Surface in an // inconsistent state if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } Setup: Thread
  • 17. The Thread and your Activity What does this now mean for your Activity? or How do we make this fit into the Android Lifecycle?
  • 18. The Thread and your Activity @Override protected void onPause() { super.onPause(); // pause game when Activity pauses mSurfaceView.getThread().pause(); mSurfaceView.terminateThread(); System.gc(); }
  • 19. The Thread and your Activity @Override protected void onResume() { super.onResume(); if (mSurfaceView.mSurfaceCreated) { mSurfaceView.createThread(mSurfaceView.getHolder()); setSurfaceType(View.LAYER_TYPE_SOFTWARE); } mSurfaceView.SetTouch(true); }
  • 20. The Thread and your Activity @Override protected void onRestoreInstanceState(Bundle inState) { // just have the View's thread load its state from our Bundle if (mSurfaceView.mSurfaceCreated) { mSurfaceView.createThread(mSurfaceView.getHolder()); setSurfaceType(View.LAYER_TYPE_SOFTWARE); } mSurfaceViewThread.restoreState(inState); }
  • 21. The main loop • AFAFP • Fixed step
  • 22. @Override public void run() { long beginTime; // the time when the cycle begun long timeDiff; // the time it took for the cycle to execute int sleepTime; // ms to sleep (<0 if we're behind) int framesSkipped; // number of frames being skipped timeDiff = System.currentTimeMillis()+50; sleepTime = 0; while (mRun) { Canvas c = null; try { beginTime = System.currentTimeMillis(); framesSkipped = 0; // resetting the frames skipped // update game state processInput(); //if (mMode == STATE_SCROLL_MAP) if (mMode != STATE_PAUSE) { updatePhysics(timeDiff); } c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { doDraw(c); } The main loop 1/3
  • 23. The main loop 2/3 // calculate how long did the cycle take timeDiff = System.currentTimeMillis() - beginTime; // calculate sleep time sleepTime = (int)(FRAME_PERIOD - timeDiff); if (sleepTime > 0) { // if sleepTime > 0 we're OK try { // send the thread to sleep for a short period // very useful for battery saving Thread.sleep(sleepTime); } catch (InterruptedException e) {} } while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) { // we need to catch up // update without rendering processInput(); if (mMode != STATE_PAUSE) { updatePhysics(timeDiff); } // add frame period to check if in next frame sleepTime += FRAME_PERIOD; framesSkipped++; }
  • 24. The main loop 3/3 } finally { // do this in a finally so that if an exception is thrown // during the above, we don't leave the Surface in an // inconsistent state if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } }
  • 26. static class MyInnerHandler extends Handler { private final WeakReference<ChiBlastSurfaceView> mView; MyInnerHandler(ChiBlastSurfaceView aView) { mView = new WeakReference<ChiBlastSurfaceView>(aView); } @Override public void handleMessage(Message m) { ChiBlastSurfaceView theView = mView.get(); theView.mStatusText.setText(m.getData().getString("text")); if (m.getData().getInt("viz") == View.VISIBLE) { theView.mStatusText.setVisibility(View.VISIBLE); //mStatusText.setAnimation(displayTextAnim); //mStatusText.startAnimation(displayTextAnim); } else { if (m.getData().getInt("viz") == View.INVISIBLE) { theView.mStatusText.setVisibility(View.INVISIBLE); theView.mStatusText.setAnimation(null); } else if (m.getData().getInt("viz") == View.GONE) { theView.mStatusText.setVisibility(View.GONE); } } theView.mStatusText.invalidate(); } }
  • 27. Setup: Cleanup public void terminateThread () { boolean retry = true; thread.setRunning(false); while (retry) { try { thread.join(); retry = false; } catch (InterruptedException e) { } //break; //THIS BREAKS IT ON PUSHING HOME } //thread = null; //THIS BREAKS IT ON PUSHING HOME }
  • 28. Tips • Input buffer • Object creation • Scaling • Drawing, bitmaps and other dirty things
  • 29. Tips: input buffer in SVActivity private void createInputObjectPool() { inputObjectPool = new ArrayBlockingQueue<InputObject>(INPUT_QUEUE_SIZE); for (int i = 0; i < INPUT_QUEUE_SIZE; i++) { inputObjectPool.add(new InputObject(inputObjectPool)); } }
  • 30. public class InputObject { public static final byte EVENT_TYPE_KEY = 1; public static final byte EVENT_TYPE_TOUCH = 2; public static final int ACTION_KEY_DOWN = 1; public static final int ACTION_KEY_UP = 2; public static final int ACTION_TOUCH_DOWN = MotionEvent.ACTION_DOWN; public static final int ACTION_TOUCH_POINTER_DOWN = MotionEvent.ACTION_POINTER_DOWN; //public static final int ACTION_TOUCH_POINTER_2_DOWN = MotionEvent.ACTION_POINTER_2_DOWN; public static final int ACTION_TOUCH_MOVE = MotionEvent.ACTION_MOVE; public static final int ACTION_TOUCH_UP = MotionEvent.ACTION_UP; public static final int ACTION_TOUCH_POINTER_UP = MotionEvent.ACTION_POINTER_UP; //public static final int ACTION_TOUCH_POINTER_2_UP = MotionEvent.ACTION_POINTER_2_UP; public ArrayBlockingQueue<InputObject> pool; public byte eventType; public long time; public int action; public int keyCode; public int x; public int y; public int x2; public int y2; public int pointerID; public int pointerIndex; public int pointerIndex2; InputObject 1/5
  • 31. InputObject 2/5 public InputObject(ArrayBlockingQueue<InputObject> pool) { this.pool = pool; } public void useEvent(KeyEvent event) { eventType = EVENT_TYPE_KEY; int a = event.getAction(); switch (a) { case KeyEvent.ACTION_DOWN: action = ACTION_KEY_DOWN; break; case KeyEvent.ACTION_UP: action = ACTION_KEY_UP; break; default: action = 0; } time = event.getEventTime(); keyCode = event.getKeyCode(); }
  • 32. public void useEvent(MotionEvent event) { eventType = EVENT_TYPE_TOUCH; int a = event.getAction(); switch (a) { case MotionEvent.ACTION_DOWN: action = ACTION_TOUCH_DOWN; break; case MotionEvent.ACTION_POINTER_DOWN: action = ACTION_TOUCH_POINTER_DOWN; break; case MotionEvent.ACTION_POINTER_2_DOWN: action = ACTION_TOUCH_POINTER_DOWN; break; case MotionEvent.ACTION_MOVE: action = ACTION_TOUCH_MOVE; break; case MotionEvent.ACTION_UP: action = ACTION_TOUCH_UP; break; case MotionEvent.ACTION_POINTER_UP: action = ACTION_TOUCH_POINTER_UP; break; case MotionEvent.ACTION_POINTER_2_UP: action = ACTION_TOUCH_POINTER_UP; break; default: action = -1; } InputObject 3/5
  • 33. InputObject 4/5 time = event.getEventTime(); pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; pointerID = event.getPointerId(pointerIndex); x = (int) event.getX(pointerIndex); y = (int) event.getY(pointerIndex); if (event.getPointerCount() > 1) { pointerIndex2 = pointerIndex== 0 ? 1 : 0; x2 = (int)event.getX(pointerIndex2); y2 = (int)event.getY(pointerIndex2); } }
  • 34. InputObject 5/5 public void useEventHistory(MotionEvent event, int historyItem) { eventType = EVENT_TYPE_TOUCH; action = ACTION_TOUCH_MOVE; time = event.getHistoricalEventTime(historyItem); pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; pointerID = event.getPointerId(pointerIndex); x = (int) event.getHistoricalX(pointerIndex, historyItem); y = (int) event.getHistoricalY(pointerIndex, historyItem); if (event.getPointerCount() > 1) { pointerIndex2 = pointerIndex== 0 ? 1 : 0; x2 = (int) event.getHistoricalX(pointerIndex2, historyItem); y2 = (int) event.getHistoricalY(pointerIndex2, historyItem); } } public void returnToPool() { pool.add(this); }
  • 35. @Override public boolean onTouchEvent(MotionEvent event) { try { // history first int hist = event.getHistorySize(); if (hist > 0) { // add from oldest to newest for (int i = 0; i < hist; i++) { //for (int i = hist-1; i > -1; i--) { InputObject input = inputObjectPool.take(); input.useEventHistory(event, i); mSurfaceViewThread.feedInput(input); } } // current last InputObject input = inputObjectPool.take(); input.useEvent(event); mSurfaceViewThread.feedInput(input); } catch (InterruptedException e) { } // don't allow more than 60 motion events per second try { Thread.sleep(16); } catch (InterruptedException e) { } return true; } Back to the activity:
  • 36. public void feedInput(InputObject input) { synchronized(inputQueueMutex) { try { inputQueue.put(input); } catch (InterruptedException e) { //Log.e(TAG, e.getMessage(), e); } } } private void processInput() { synchronized(inputQueueMutex) { ArrayBlockingQueue<InputObject> inputQueue = ChiBlastSurfaceView.inputQueue; while (!inputQueue.isEmpty()) { try { InputObject input = inputQueue.take(); if (input.eventType == InputObject.EVENT_TYPE_KEY) { //processKeyEvent(input); } else if (input.eventType == InputObject.EVENT_TYPE_TOUCH) { processMotionEvent(input); } input.returnToPool(); } catch (InterruptedException e) { //Log.e(TAG, e.getMessage(), e); } } } } And in the SurfaceView.Thread:
  • 38. Tips: object creation Just don’t do it.
  • 39. Tips: object creation Or do it up front. No matter how odd that sometimes may seem.
  • 40. Tips: scaling Two types of scaling: • Realtime whole view SV scaling only works from Android N • Fixed scaling (as done in Unreal Tournament 3)
  • 41. Tips: scaling @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { //thread.setSurfaceSize(width, height); if (mCanvasWidth != width) { int scaledWidth = (int)(width*0.75f); int scaledHeight = (int)(height*0.75f); if (scaledHeight != height) { yRatio = (float)(scaledHeight / (float)height); xRatio = (float)(scaledWidth / (float)width); } holder.setFixedSize(scaledWidth, scaledHeight); thread.setSurfaceSize(scaledWidth, scaledHeight); } }
  • 42. Tips: drawing, bitmaps and other dirty things
  • 43. Tips: drawing, bitmaps and other dirty things In SurfaceView.Thread doDraw(): canvas.drawBitmap(mBackgroundImage, null, fullscreenRect, mPicPaint);
  • 44. Q&A