Google I/O 2012 - Native Client LIVE


Uploaded by GoogleDevelopers on 02.07.2012

Transcript:

COLT MCANLIS: Better yet, I use Chrome OS, because I don't
know what defrag is.
NOEL ALLEN: There you are.
COLT MCANLIS: There is actually.
NOEL ALLEN: Ooh.

COLT MCANLIS: All right.
It looks like we are alive.
Fantastic.
Hello.
Welcome, everyone.
Wow.
We have a post-lunch coma crowd.
Hello, everyone!
AUDIENCE: Hello!
COLT MCANLIS: Fantastic.
Perfect.
Guys, we're getting recorded on YouTube, and you're going
to be like, no, let's not talk to the presenter.
That's horrible.
Your voice will be recorded and saved for
the annals of time.
Anyhow, hello everyone.
Welcome today to Native Client Live.
My name is Colt McAnlis.
I'm a developer advocate at Google
working on Native Client.
NOEL ALLEN: I'm Noel Allen, the SDK lead.
COLT MCANLIS: SDK lead.
And we have fancy hats, as well.
We figured these lights are actually
pretty gnarly up here.
We can't see people.
So we're like, let's wear our hats.
That'll be funny.
NOEL ALLEN: It actually kind of works, because it is a
little bright.
COLT MCANLIS: OK.
So what today's talk is about is, we're actually going to
port an application to Native Client live in 60 minutes.
Now, just quick show of hands in here, how many have
actually played with Native Client?
Wow.
That's actually a surprising amount of people.
I'm very encouraged by that, actually.
They'll know what we're talking about today.
Funny story is we actually decided to sign off to do this
about three to four months ago.
And we actually walked into Noel's office, and I was like,
hey, we're going to give a talk at Google I/O, and we're
going to port something to Native
Client live in 60 minutes.
And he was like, uh, no you're not.
And I said, yes, yes we are.
So we got him to sign off on it.
I convinced him with alcohol or something else.
And we started going through the process.
And the truth was, we failed.
We failed a lot.
Horribly.
Like crash and burn style.
NOEL ALLEN: You failed before I started.
Let's just get that clear.
COLT MCANLIS: Fair enough, fair enough.
That is true.
The original port of the application we're going to
show you today actually took about 2.5 weeks the very first
time we did it, which was kind of embarrassing on our side,
because it's a very simple piece of technology we're
going to look at today.
But the good news is that we actually learned from that.
We said, where are we.
This isn't good for our developers.
Let's improve the process.
Let's improve the SDK, the workflow.
And what we're going to talk about today is the learn-ins,
the learn-ins of those things.
So how you should view today's class session
is a cooking show.
How many people watch late night cooking?
Really?
That's it?
The rest of you are liars, and you're dirty, filthy liars.
If you do not watch Iron Chef there is
something wrong with you.
That is an amazing show.

When did--
OK--
NOEL ALLEN: You kept changing the slides on me.
I figured I'd have some fun too.
COLT MCANLIS: That's new.
OK.
We're going there.
Today is a cooking show, and we have Chef
Noel Allen over here.
In these shows, you usually have some very peppy person
standing up there showing you how they're going to make a
lamb sorbet, which is normally like a nine-day endeavor.
And they're going to do it in 30 minutes and show you how to
do it, too.
Well, we're going to do the same process today.
We're going to take the knowledge and everything we've
learned in the past couple of months and dissect it down.
Now, we've had to pre-chop some onions so that we can get
this in our 60 minute window here, but we'll be sure to
call that out so you know what was pre-chopped, what was
canned, and what was actually fresh tuna fish
for our lamb sorbet.
And that hat is awesome.
Where did you even find that?
NOEL ALLEN: I got it at the store.
COLT MCANLIS: You have two?
Sweet.
Sorry, guys.
I'm getting fired.
This is going to be awesome.
How does it look?
NOEL ALLEN: Very nice.
Very convincing.
COLT MCANLIS: I feel like I have a pope hat.
Is this even on right?
NOEL ALLEN: I can't tell.
I don't know what it's supposed to look like.
COLT MCANLIS: OK, cool.
All right.
We're wearing these now.
Fantastic.
I'm sure the YouTube guys love this.
OK.
This is a cooking show with your chefs.
So let's get started and talk about Native Client a little
bit, sort of set the groundwork and the ecosystem
of we're talking about today.
Native Client is a technology that allows you to run C and
C++ code in a web page with the same safety as JavaScript.
And here's the really cool part, is that the user is not
required to install a plug-in.
So what we've seen is that with a lot of technologies out
there, you can actually run C and C++ code in a web browser,
but the user gets this really scary pop-up that's like, hey,
you're about to install a plug-in that's going to
violate every piece of data you have on your hard drive.
What we've been seeing over time is that that, of course,
affects user retention rates.
NOEL ALLEN: And installation.
COLT MCANLIS: Say again?
NOEL ALLEN: And installation.
COLT MCANLIS: And installation.
Exactly.
So users get there, and they go, hey, this is too scary.
And they move on.
And so this means that high performance applications that
want to run C++ code in a web page really lose a lot of
their users to this scary dialogue.
Now, with Native Client, C++ and the fact it can be run
safely in the web browser and they're not prompted to
install a plug-in, means that your C++ code can actually
bridge a lot of ecosystems and a lot of platforms.
So predominantly, C++ code was in the realm of game consoles,
PC development mobile.
And now you can actually use your same code base right in
the web, which is fantastic for a lot of companies and
studios who spend a lot of time not only training their
engineers in C++ code, but also, you have legacy code.
You've got 10 years of C++ memory management code, STL
containers sitting around, and you don't want to
throw all that out.
Now, we had our official Native Client launch event in
December of last year.
In truth, Native Client was out for quite a while before
that, but we decided to snazzy it up and actually have some
hors d'oeuvres and call it a launch event.
Since then, NaCl has been doing fantastic.
We've seen already 27 titles, actual products, ship with
Native Client since the announcement.
In addition to that, we've seen that game developers
predominantly love Native Client.
We see a lot of technology middleware for games on the
side there.
They're finding that Native Client provides them this nice
little niche between performance and reach.
You can run all of your code extremely fast and reach all
of the 310 million users that Chrome has active.
That was a new stat today.
Watch the keynote.
So let's talk about what we're cooking today.
Let's switch this over to you.
So Chef Noel, can you show us what our lamb sorbet looks
like today?
NOEL ALLEN: Absolutely.
So for today, we have a fabulous spinning cube.
COLT MCANLIS: That wasn't what we looked at yesterday.
What--
NOEL ALLEN: Well, we still had a couple, you know, bugs.
Issues.
COLT MCANLIS: You didn't fix the bugs?
We were supposed to have--
you were buying the hats.
NOEL ALLEN: I was busy.
I had stuff to do.
I had a new Nexus to play with.
COLT MCANLIS: Fair enough.
Cool.
You had a new Nexus.
Awesome.
So we're doing a spinning cube.
So what is this thing actually doing behind the scenes?
NOEL ALLEN: OK.
So this is an open GL demo.
It's a kind of standard demo that you do, make sure your
graphics engine is rendering correctly, hence the arrows
and the lighting and whatnot.
So this is a standard Windows 32 application.
And we're going to port that to Native Client.
COLT MCANLIS: And so this is doing just standard rendering.
So we're [? reading ?] in some shaders, reading some
textures, doing some a platform calls.
NOEL ALLEN: Exactly.
COLT MCANLIS: This is our lamb sorbet.
Fantastic.
So with that spinning cube up and running over there to
distract all of you, I'm going to point over this way with
sock puppets.
Let's talk about our kitchen.
Let's talk about what development with Native Client
should actually look like today for most of you.
So, when porting to Native Client, you need to approach
it from the concept of any other ports.
So let's say you're actually porting an application from
Windows to Linux.
This is going to have a specific set of processes that
you're going to need to go through.
First off, you're going to need to actually change over
from using DirectX to OpenGL.
That's actually a big set of code, different APIs that
aren't available on the Linux machines.
Also some APIs are only available on Windows for the
same process.
So you want to spawn up a thread.
Well on Windows, you'd use beginthread or beginthreadex.
On Linux, you would have to use sort of a more POSIX style
pthread_create.
And for other things, Windows actually provides a very rich
ecosystem for UI components that you can use as part of
their platform that may not exist on other
platforms like Linux.
So instead of being able to actually use the message box
function directly, you'd have to get shifted over to printf.
Right?
So viewing your port to Native Client should be the same way.
You should view it like porting from anything to
another platform.
But with Native Client, what you're actually porting to are
these specific functions.
You're actually porting to an API we call Pepper.
Now, what Pepper is, is it's actually a plug-in API that
Chrome provides that allows plug-ins to interact with
lower-level system resources like FileIO, rendering, audio,
and even the ability to communicate directly to the
JavaScript page.
And it allows it to do this inside of the Chrome sandbox,
which means that these plug-ins are actually
communicating through the same exact code paths that
JavaScript is communicating to, to do the same
functionality.
This hat is awesome, by the way.
I'm not sure--
I need an ear-in.
It's popping over my head.
Anyhow, Native Client should be viewed as a plug-in that's
provided with Chrome.
It's compiled with Chrome.
It's shipped with Chrome.
And what Native Client allows you to do is it allows you to
load pre-compiled executable code that can then target the
Pepper APIs.
It'll load it up, execute the code, and allow that code to
actually, directly trampoline over and get access to these
lower-level system resources.
How this works at a developer level starts with the
original C++ code.
The C++ code is then sent through our custom GCC
compiler, provided by the SDK.
This spits out a set of NEXE files, or
Native Client exe files.
These have been munged and messed
around a bit to ensure--
well, to do the best we can to ensure safety.
We remove a lot of malicious codes that may cause security
vulnerabilities and some other fun stuff that we'll talk
about later.
You take this data that's actually generated from the
toolchain, and with a simple HTML embed tag, you can
actually get it running right in your web page.
So what you're actually seeing on the screen there is a
screenshot from a game called From Dust.
From Dust was actually an Xbox 360 title that was ported over
to Native Client that we unveiled earlier this year.
Now, this is running the same shaders, the same code.
It's actually doing quite amazing.
I think I have this backwards.
How about that?
Is that better?
NOEL ALLEN: You're going to fiddle with this the whole
presentation, aren't you?
COLT MCANLIS: It's annoying me.
My head's too small and my ears are too big.
That's the problem.
So let's talk a little bit about the SDK.
The SDK itself allows for cross platform development on
platforms for Linux, Windows and Mac.
And we do this through providing a simple command
line GCC compiler.
So the compiler itself is just simple command line.
Everybody in here has probably used GCC at one time in your
programming life.
We also provide a full set of working code examples so that
you can actually see how to properly use Pepper and how to
use Native Client and best practices
involved with that process.
And then in addition to that, we also provide debugging and
profiling tools that are currently an
AlphaRev of our SDK.
Now, this takes a little bit to understand.
So you need to know that when we generate these Native
Client executables, the NEXE files, it's not your
standard x86 code.
We've got a lot of paperwork that we're not going to talk
about today so much.
It actually isn't an exe that you can just double click on
your desktop and run.
It's actually a modified DWARF file.
Right?
NOEL ALLEN: Correct.
DWARF and ELF.
COLT MCANLIS: OK.
Fantastic.
Which means that debugging systems work a little bit
differently.
You don't have a PDB file full of symbols and
all these other things.
It requires some massaging.
Now with these things in mind, let's talk about actually
porting, because we've only got 47 minutes left.
And my hat is funny.
And I'm running on reserve power.
This isn't even plugged in.

If it was a perfect demo, we wouldn't do it.
So here's our plan of attack today.
First, what we're going to do is we're actually going to
build as a Pepper plug-in first.
Pepper's a fantastic API, but we're going to actually ignore
the Native Client part of the equation and just migrate over
our platform-specific APIs over to the Pepper APIs first.
And then as a last step, we'll actually do the generation of
the Native Client exe.
This allows us to actually use our plug-in system in an
existing IDE of choice.
So standard plug-in development is pretty much
exposed in every IDE out there.
It's a standard loop.
You create a DLL or an SO.
The external application loads it up.
You can set break points, see memory, all
this other fun stuff.
Now to facilitate this, and this is one of the biggest
things that we learned in our failures that I mentioned
earlier in this project, was that we really didn't have
good integration into existing IDEs at the
level we wanted to.
So today we're actually really excited to announce that we're
actually providing a Visual Studio 2010 plug-in for Native
Client and Pepper.
And we'll actually provide this--
Please.
Yes, applause.
Yeah.
That's cool.
Add-ins are awesome.
This will be available in the Pepper 22 SDK.
So if you guys go to GoNaCl.com, grab the SDK
chain, you'll actually get a preview.
Because we actually have a few Peppers
ahead of stable available.
Right?
Canary builds and the other stuff.
NOEL ALLEN: Yes.
COLT MCANLIS: So this is actually available, and you
guys can totally take a look at it.
So we're really excited about that, because it really helps
with ease of use.
Now, what chef Noel is going to do today for us, can you
walk us through some of the things that the add-in does
inside of Visual Studio?
NOEL ALLEN: Sure.
Absolutely.
So I have already created some different configurations.
We can see a Native Client configuration, a Pepper
configuration, and the original Windows 32
configuration.
So what the add-in is doing is we can go over here and--

so the add-in drives the compiler.
Now for the Pepper configuration, it's actually
pretty straightforward.
All we're actually going to do is convert from an
executable to a DLL.
So Chrome's going to load this and run it as a plug-in.
Very little change.
I'm just going to go ahead and point my Include Directories
to the Pepper SDK.
I'm going to create a macro for Pepper so that I know in
my code which particular view of the code I'm looking at.
And that's pretty much it.
I'm ready to go.
COLT MCANLIS: OK.
Fantastic.
So you set up these properties, so you create the
platform, and then you compile.
And what happens here?
NOEL ALLEN: Right.
So now I'm going to switch to the Pepper configuration, and
I'm going to go ahead and re-launch.
Now, I did actually do one other thing, which is for the
sake of debugging, I set this up to launch Chrome for me.
COLT MCANLIS: Oh.
Now, I see some other flags in there.
Can you walk us through what exactly is going on?
NOEL ALLEN: Sure.
So there's a couple flags in here that make things a little
bit easier for you.
So I am setting user data dir to not pollute
my normal user settings.
I have Incognito to let Chrome forget what I've done, so we
don't actually get caching effects.
And then, register Pepper plug-in.
Here's the interesting one where I am telling Chrome,
please load this plug-in, and then I want you to answer any
request to the particular MIME type I have described here,
which in this case is application xNaCl.
COLT MCANLIS: Interesting.
So to be very clear about this, what happens is, any
time Chrome actually encounters the MIME type
application NaCl, it'll actually go load the Native
Client exe and pass the data over to it.
What this command line option allows us to do is override
that process.
And so instead of actually finding MIME type NaCl and
running NaCl, it's going to run our plug-in instead.
NOEL ALLEN: Exactly.
So we can go ahead and launch that.

And it helps if I start the web server first.
Always useful.
All right.
Now, it couldn't find the plug-in.
COLT MCANLIS: So why is it saying that, though?
NOEL ALLEN: Well, I am missing the components that let Pepper
talk to the plug-in.
COLT MCANLIS: I see.
So we had our Win32 codes.
So even though we've compiled it as a DLL, we haven't added
the hooks, the API hooks, for Pepper for
Chrome to actually load.
NOEL ALLEN: Exactly.
COLT MCANLIS: So where do we get those, and
how do we get those?
NOEL ALLEN: OK.
Well, the easiest thing to do is I am just going to sit here
and go over to one of the examples that we ship, and
just copy and paste it in, so that I have all
that start-up code.
COLT MCANLIS: I like your style.
What is that they say?
That good programmers code and great programmers reuse?
I like it.
NOEL ALLEN: So if we take this Hello World example, And I'm
going to select that, and paste it here into the bottom,
and then run again.

So now we can see the Hello World demo that
ships with the SDK.
COLT MCANLIS: And then that's running in our existing code?
NOEL ALLEN: Correct.
COLT MCANLIS: So, but where'd the spinning cube go?
NOEL ALLEN: Well, we haven't called it yet.
So we haven't actually called any of the original
code that we had.
COLT MCANLIS: Can you?
NOEL ALLEN: I can do that real quick.
COLT MCANLIS: OK.
You do that.
Awesome.

NOEL ALLEN: OK.
So if I come up here and just say--

COLT MCANLIS: Now, really quick while you're scrolling
up here, what are these functions we're looking at?
These are Pepper functions, right?
NOEL ALLEN: So these are Pepper functions.
So as I said, there's three functions that we look at.
We have a module initialization, we have an API
request, and we have a shut down function.

One of the APIs that gets requested is an
API for your interface.
So you're going to provide functions that Chrome can call
into to do things.
And one of those is this Did Create, which is very similar
to the regular Main function.
So from there I'm actually going to call into the
original WinMain.

And now we've got our box, but no alert.
COLT MCANLIS: Interesting.
OK, so what we're seeing here though is really cool, because
we're actually seeing Win32 code running side by side as
launched from a plug-in inside of Chrome.
So now we can call this code, because we're actually running
on a Windows system.
NOEL ALLEN: Exactly.
COLT MCANLIS: OK.
So the goal here is to actually get that spinning
cube running in the web page.
So we've got all that stuff set up.
The next step for us is to actually port over to Pepper.
Now, when understanding the Pepper API, it's important to
understand how an application communicates with a plug-in to
kind of give a little bit more visibility
into what it's doing.
So let's say we've got our Chrome, and let's say we've
got our plug-in.
Chrome, of course, will call init, like it did.
And then the plug-in will go do some processing.
Now, in order for the plug-in to get a sort of persistent
heartbeat--
right, because this is a plug-in.
We can't just allow yourself to go call code into it,
otherwise you'll never receive execution
control back into Chrome.
So once the plug-in's done, it can actually tell Chrome, hey,
can you call me again in 10 minutes, or whenever
you get some time.
And so what'll happen is the plug-in, and Pepper
specifically, provides APIs that allow you to push a
callback up into Chrome.
And then Chrome can run off, do some processing, render a
web page, check your local listings for cars and salty
pork products.
And then when it gets around to it, it can actually call
that callback, giving execution
control back your plug-in.
And then of course, your plug-in does some processing
and the cycle repeats.
And this is as close as you can get actually having a
while loop inside of Pepper or inside of a plug-in.
We allow you to get this processing over time.
Now, let's talk about a couple road blocks you're going to
run into when working with Pepper.
First off, all of the APIs for Pepper are non-blocking.
And you can see why when looking at it
as a plug-in API.
If one of these APIs were blocking, what would occur is
that you can effectively stall out all of Chrome, because
execution control goes into the plug-in and then they,
Chrome, won't get any more time slices to give to v8 or
anything else.
And so you get that nice, little aw snap
little sad face dude.
My heart always breaks when I see him.
I'm like, aw, he's so sad.
Don't worry, the internet is still there.
Anyhow, second off is that Pepper APIs can only be called
from the main thread.
This is another restriction that we enforce to ensure
stability and security over time.
And then finally, that there's really no main loop in Pepper.
As you can see, based upon the APIs, that you can't actually
just create a while loop and sit there and spin.
Now, I want to point out that this is sort of temporary
restrictions as of Pepper 21.
The team is working very, very hard at removing these
restrictions, including the ability to call Pepper from
any thread in your environment, which would be a
huge step forward for those of you who've done development.
So let's talk about the call loop a little bit more, and
why exactly we didn't see the plug-in, but
we did see the cube.
So what exactly happened was this, Chrome called init and
gave execution control to the plug-in.
Well, the plug-in at that point actually called into
Windows and said, hey, let's go run this.
Now, Windows being Windows code effectively sucked up all
of the processing time.
And we actually didn't ever give execution control back
into Chrome.
So WinMain has a little while loop in there where it
processes events and message pumps and everything else that
it passes to the window.
And we were never actually able to give
control back into Chrome.
So we starved it out.
But you guys didn't see the aw snap sad face, because we
didn't hit the time out period for the demo.
Our floppy hats kept us from doing that.
So in order to fix this though, Chef Noel, Chef
Noelington III, can you show us how you address this issue?
NOEL ALLEN: OK.
So here are a couple of changes that I'm making.
So we want to break that main loop into two separate pieces,
the initialization piece and the actual loop.
So I am going to ifdef out the loop and instead put it in a
new function.
And I'm going to have that function request to get more
execution time by asking Pepper, please call on the
main thread this function again at a later time.
COLT MCANLIS: And so this is the function that effectively
pushes the function pointer back into Chrome.
NOEL ALLEN: Correct.
COLT MCANLIS: Excellent.
So then, what's this look like?
NOEL ALLEN: Well, let's fire that up.

COLT MCANLIS: So we get the pop up and we get the cube.
So the execution happened side by side.
Fantastic.
So now that that's handled and we know that we're actually
not stalling out Chrome and we have execution control being
handed back to the main application, let's actually
talk about loading files.
Now, Native Client is an internet technology, which
means that it's served from a web server somewhere and the
client is going to make a request to pull things down.
Now, any time you have communication between client
and server with a web browser-- we'll talk about
Chrome just to limit our scope of discussion here--
when a page load request occurs, Chrome, on your
behalf, will go ahead and fetch specific files and store
them in Chrome's cache.
Which means it'll grab HTML files, it'll grab NEXE files
and the Native Client Manifest file, the NMF file.
Now, this'll be stored in the cache on your
behalf, which is fantastic.
Because if you have executable code sitting on a server
somewhere, it's probably between the
range of 5 to 13 megabytes.
And you don't want the user to have to keep grabbing that
code and pulling it down every time they hit refresh.
Now, the bad part about this, though, is that Chrome won't
go fetch all of those other files which are usually
required by your application.
You've usually got a bunch of binary data.
If you're a game developer, you've got textures, assets,
map data, XML information, all this other sort of stuff.
Now, to grab that data--
that's specifically what we're going to focus on today--
Pepper provides an API called GetURL.
GetURL, again being an internet technology, says,
hey, here's a URL, go fetch me the bits of this.
So in JavaScript, this would be equivalent to
an XHR, XHTTP request.
So everyone in here is a net developer.
You should grock that.
I see one head nodding.
I like your style.
Can I nod with this and that actually work?
Maybe.
Everyone on YouTube just jumped.
Cool.
In addition to that, because you can actually pull down
this data, again, that's not cached on your behalf.
So you actually have to have an answer for that.
Because, again, if the user reloads your page, you're
going to have to go grab another 40 megs worth of data
every time they do that.
To address this, Pepper actually provides another API
called the FileStore API.
So you can actually grab your data and write it to the
Persistent Sandbox file storage on disk.
This way, when the user closes Chrome, reloads the page, goes
on vacation for 15 days, that data will still stay on disk
that you can pick up and grab later.
So this is a great place to put save state, user
preferences that you may not want to sync to the cloud, or
just, again, the 80 megs of binary data that's needed for
your application.
Now, one thing we talked about earlier was that the Pepper
APIs are non-blocking.
So for all of you who have used fread, we can't use that
in Native Client, because that would actually stall the
system, wouldn't relinquish control back to Chrome.
So we actually don't allow you to use that command.
You have to use GetURL.
And any of you who have done asynchronous file loading know
what this looks like.
Effectively, we have an init phase.
The init phase will kick off an open URL command to Chrome
and say, hey, go load some data.
Then our plug-in will actually go into a loader loop phase.
What we're going to do is we're
effectively going to spin--
well, we can't exactly spin, but we're going to go through
a process of allowing Chrome to do call on main thread and
allowing the plug-in to relinquish control, gain
control, et cetera, et cetera, until Chrome actually tells us
the file has actually been opened.
Chrome will signal to us and give us a specific call.
Once we've received the file open command, we then can
issue a read bytes and say, hey, you've opened the file.
Please give me some data.
And then we can continue this loop until the data's actually
been fetched.
And this is the standard loader loop that we're going
to work through here.
Once the data's been fetched or pre-loaded everything, you
can then move on to your actual render loop and start
drawing the cube on the screen.
So you haven't seen that one yet, have you?
NOEL ALLEN: You know I'm allergic to fish.
COLT MCANLIS: Really?
That makes it even awesomer.
NOEL ALLEN: I'm going to itch.
COLT MCANLIS: So by the way, don't Google man hugging fish.
Different sort of results that you get there.
Anyhow, your royal majesty Noelington Chefton III, can
you please walk us through what this FileIO asynchronous
stuff looks like in our demo.
NOEL ALLEN: Sure.
So what we're going to do is we are going to request for
these assets to get loaded in the background.
And we're going to do that by first issuing an Open, as you
described, which is basically a Get request to the asset.
Once that open completes, it's going to call us back.
And then in that callback function, we're going to
record the size of the object that we're getting, we're
going to allocate memory for it, and then we're going to
start reading bites.
And again, this happens as a callback.
So every time we get some bites back, we're then going
to call this other function, which is going to store it in
that block of memory that I allocated.
And eventually, when I get enough of it, I'm going to go
ahead and give myself a call back to let me
know that it's there.
And when it's there, I'm simply going to increment a
global counter that says, hey, I got another asset.
COLT MCANLIS: Now, to be very clear, we know that all of you
have very sophisticated code bases, and asynchronous file
loading is probably part of your general platform library.
We are not at all advocating this as best practices for
loading files on the internet.
Please write a good asset manager with mutexes and
callbacks and everything else.
Don't just use a counter.
That's really just a bad idea.
Sorry.
I had to give the disclaimer, otherwise it'll show up like,
Google says you should just use a counter to load all of
your files with Native Client.
NOEL ALLEN: Yes.
Well the ugly counter hack is, in fact, right here.
We're going to call the initialization programs.
I've changed this main loop.
So we do the initialization.
And then once we actually discover three assets, then
we're going to switch to rendering.
But in either case, we're just going to go back and ask for
more processing time every time we go
through the loop as normal.
COLT MCANLIS: So effectively, if we haven't loaded it yet,
we still submit our call on main thread so we can get
processing in the future to determine if it's all loaded?
NOEL ALLEN: Correct.
COLT MCANLIS: And then once the things are loaded, we go
to our render loop at that point.
NOEL ALLEN: Exactly.
COLT MCANLIS: And so this has changed.
Let's see this live.

NOEL ALLEN: OK.
So it looks much the same.
But if we go over here and look at the web server, you
can see that originally we were getting--
hold on.
Ran the wrong file.

COLT MCANLIS: Stop it.
Stop it all.
Hit buttons.
NOEL ALLEN: Please stop.
COLT MCANLIS: Click more.
Panic click.
Panic click.
Take evasive action.
Scatter.
NOEL ALLEN: You're not being helpful.
COLT MCANLIS: I know.
NOEL ALLEN: I want you to know,
you're not being helpful.
So as we can see here, we now actually see the requests for
those assets coming into the web server.
So we have successfully moved over to serving the
data from the web.
COLT MCANLIS: Awesome.
So as a Pepper plug-in, we were actually able to just use
fread and actually load the data.
But as part of the Pepper API, you can see that we're
fetching it right from the server.
You need to nod with authority.
NOEL ALLEN: Is my hat not correctly--
COLT MCANLIS: Well, you have hair, and so it keeps it from
sliding around.
That my problem, is the balding thing.
So once we've got a rendering with our simple example, the
next step is actually to get us porting from OpenGL, which
is desktop GL, to GLES2, which is the API that we provide in
Native Client that allows you to do fancy rendering of cube
with arrow texture.
I really think we should have done the other demo.
You should have fixed stuff instead of playing with your
new hardware.
So what we're going to do today is we're not going to
talk about the actual porting process of GL to GLES.
There's a lot of documentation out there on how to actually
do this process.
GLES2.0 is very dominant on mobile devices right now.
And if you just Google for-- don't Google
for man hugs fish.
Instead, Google for desktop GL2, GLES2, you'll find much
more useful information in that process.
We are going to note a couple things that are different
between the two.
Just so if you've never actually dealt with
OpenGLES2.0, you're aware of some of the things you're
going to run into moving forward.
First off, they are not the same thing.
The predominant one is that GLES2 could be considered a
subset of GL.
The most shocking change there is that GLES2.0 has no fixed
function of support.
So in order to draw a polygon or set some state or even get
a texture on screen, you have to provide a vertex shader and
a pixel shader.
If you've never written a vertex shader or a pixel
shader, don't worry.
The internet can help you.
Which I find I need on my business card.
Don't worry.
The internet can help you.
In addition to that, there's a different shader syntax.
When you actually do write your shader for the system,
because standard GL does support shaders, the syntax
itself is different.
So you have to set different precision values for your
pixel shaders, as well as some other nuances with how you
handle skinning and constant register access.
And probably one of the interesting things is because
GLES2.0 is actually a subset of GL, some things that you'd
normally have to go to GL and fetch extensions for you no
longer have to.
So with standard desktop GL, you would have to go grab an
extension to actually do multiple render targets or to
do deferred rendering or some other interesting things.
With GLES2, a lot of that stuff is just provided
natively, which is fantastic.
There is one API we're going to talk about today, though.
And this is really the only thing that's Pepper specific
in the translation from GL to GLES.
And that is a function called SwapBuffers.
So what happens is, when you're doing your render loop
you're going to render some polygons, you're going to set
some textures, blow up some aliens, do really cool stuff.
From there, you're actually going to call
the SwapBuffers API.
Now typically, what SwapBuffers will do with the
GL API is it'll actually trigger off a command to the
device driver and to the GPU to swap the front screen with
the back screen.
So when you actually do your rendering, all of the commands
are actually compositing to a buffer that's not currently
displayed to the user.
And the swap screen command tells it to say, hey, swap it
so the user can see the work that you've all done.
The SwapBuffers command provided with Pepper, part of
our header suite, actually contains a function that
allows you to actually kick off your callback.
So typically, like we said before, you're going to need
to use a call on main thread so that sometime in the future
you'll get called again.
The SwapBuffers API sort of encapsulates these two
concepts into a single call.
So you can actually kick off your SwapBuffer call as well
as push your function pointer back into Chrome.
Now, if you're doing rendering, you should consider
this the end of your Pepper frame.
Because if you've called SwapBuffers it's time to
relinquish control off to Chrome.
Chrome's going to do some cool stuff, fix the internet, make
everything amazing, and do it really fast.
And then eventually it'll come back and call your function,
because you've passed it off.
And that's your start of your frame again.
So this is really the only difference.
Everything else is a standard GL to GLES port.
This is the one thing you need to be aware of.
So we're not talking about GL to GLES.
So this is the chopped onions part of the talk.
We're not going to walk you through that change.
We've already got it live.
Can you show us what that looks like?
NOEL ALLEN: Sure thing.
So here is the change that we discussed, the SwapBuffer.
And I am going to go ahead and run this.

COLT MCANLIS: Very cool.
So we're actually running in the web page.
NOEL ALLEN: We now have our cube in the web page.
COLT MCANLIS: Very cool.
I like that.
So now, quick question here.
If we actually are creating a Pepper plug-in, and we can
actually get it to run in the web page like this and do full
graphics and high precision timing and everything, why are
we even messing with NaCl?
Why don't we just ship a Pepper plug-in
and that's our product?
NOEL ALLEN: Well first, Chrome isn't going to let you just
load some random plug-in.
Native code is kind of an ugly, unsafe thing, so we want
to make sure that we take care of it correctly.
So in order to use that C and C++ code, you're going to want
to ship that as a NEXE so that you get that extra protection.
COLT MCANLIS: So you're saying that me downloading an
arbitrary plug-in from Bob's hugging fish website is not
necessarily a safe thing to do?
NOEL ALLEN: Yes.
Especially not the websites you go to.
COLT MCANLIS: Let's edit that part out of YouTube, please.
So the next step then, since we actually don't want to
provide just a plug-in to the masses, because, again,
that'll come back to the point, the user will get that
really nasty pop-up that says, hey, Bob's Hugging Fish
Basement would really like to install some
things on your computer.
Which, never click OK to that.
What we're going to do now is we're actually going to do the
final step of our process of creating our lamb sorbet and
actually go and compile our code with Native Client,
generating the proper NEXE files that can be distributed
on the internet.
So now, recall this graph here is that Native Client is a
plug-in that's provided with Chrome that allows external
compiled code to effectively call the APIs that allow
secure sandbox execution to lower-level system resources.
Now, the add-in for Visual Studio provides some specific
nuances that we should talk about here.
What the Visual Studio plug-in does at this point in time,
because debugging and profiling support is still in
alpha, the add-in actually doesn't allow you to set break
points and do debugging inside of Native Client.
Yet.
That's coming soon.
Stay tuned.
Follow me on G+.
What it does now though is it'll actually scrape the
Visual Studio properties on your behalf and create the
proper command line that's required to send off to GCC.
GCC, of course, will then produce the NEXE from our SDK
and then output any information for command line
errors or processes back to Visual Studio.
So the good thing is if you are a Visual Studio developer,
you've got a lot of legacy code there, this allows you to
operate and compile with Native Client in a way that
feels very natural to you, save for the break points and
the debugging.
But again, that's in alpha.
We're working very hard on that.
Right, Noel?
NOEL ALLEN: Exactly.
COLT MCANLIS: Noel's actually the guy heading that up.
Right?
NOEL ALLEN: Yes.
COLT MCANLIS: Your hat is heading that up, actually.
NOEL ALLEN: My hat is in charge.
COLT MCANLIS: Your hat is in charge of debugging.
It's still floppy.
I don't know what to do.

Anyhow, this is actually my favorite picture in the deck,
by the way.
NOEL ALLEN: Thanks.
COLT MCANLIS: It's the salt head.
We did a rehearsal of this a couple weeks ago, and someone
said, you should probably Photoshop some
salt shakers in there.
And I was like, well, here's a salt head.
So part of our add-in allows the Pepper configuration as
well as the NaCl configuration.
So can you show us the NaCl config and what it does?
NOEL ALLEN: Absolutely.
OK.
So again from the add-in that you'll get in Pepper 22, you
can go ahead and set up for a Native Client configuration.
And as Colt said, this is going to drive that GCC
toolchain for you.
And then we have the standard settings.
Again, I'm going to use Chrome as the application that I'm
actually going to run.
And I am going to set some additional flags.
I'm going to set my include directories.
I'm going to set my library paths.
All the standard things that you would set
for using an SDK.
And we can take a look at that.
COLT MCANLIS: So now, once you create the configuration is
there anything else?
Or can we actually just run live?
Will it do a lot of automation for you?
NOEL ALLEN: Well, what'll end up happening is if we try to
run it right now, we still have that Windows window and
some other stuff that we need to clean up.
So we'd actually get a lot of compile errors or link errors
or whatnot.
So we still have to get rid of those platform specific things
to Windows.
COLT MCANLIS: OK.
Let's take a look at that.
Or at least, can you point them out or make
[? the right ?]
change, or--
NOEL ALLEN: Sure.
So let me show you the changes that we had to do here.
So we need to obviously no longer include the Windows
header, because that's not going to work,
or the Windows libraries.
We need to stop calling main, because that had a lot of
Windows code in it.
So instead, we just call the
initialization function directly.
And we need to no longer use those old GL calls and things
that were pointing to screen resolution and things like
that that were described in Windows, so
basically the WGL calls.
COLT MCANLIS: Got it.
NOEL ALLEN: So once those have all been ifdeffed out, then
we're actually ready to make that change.
COLT MCANLIS: Cool.
So we've converted all of our stuff over to Pepper.
So we're using those API calls.
We've also removed any platform specific code from
our application at this point.
That's the good thing.
And so now we can actually run--?
NOEL ALLEN: OK.
So this is the Pepper version.
And now I'm going to switch to the Native Client version.
Rebuild, and you can see in the output window the
toolchain running.
And now we have the cube actually running as a Native
Client module.
COLT MCANLIS: Fantastic.
Perfect.
That's cool.
NOEL ALLEN: And you can see the load is
right here of the NEXE.
COLT MCANLIS: Excellent.
Excellent.
So now with the Visual Studio plug-in--
because we want to empower developers to do great
things-- you can actually swap back and run the original
Win32 as well still.
Right?
NOEL ALLEN: Exactly.
So the Windows 32 version is still available.
So I will switch back to that.

And here we are.
COLT MCANLIS: Really?

You honestly went to my G+ stream and pulled down a
picture of me eating barbecue in Austin, Texas?
NOEL ALLEN: You put it up there.
Anybody can get access to it.
What do you want?
COLT MCANLIS: There's a great--
you didn't do this yesterday.
OK.
Awesome.
That's a great barbecue place in Austin, Texas.
I highly recommend you going to it.

Stop going to my G+ page.
I'm going to put you in a separate Circle.
You don't get any access to photos.
I lost myself.
What are we talking about?
OK.
Win32.
So this is the original Win32 application.
Fantastic.
OK.
It's mesmerizing.
NOEL ALLEN: Actually, I find it a
little disturbing, myself.
COLT MCANLIS: I'm very disturbed right now.
So, fantastic.
So we've done the port.
We actually have, according to that timer back there, we've
got 20 minutes left.
So even with me blathering on about all this other stuff
about Native Client, we've been able to chop some onions,
dice some things up.
The power of the Visual Studio add-in actually propelled us
to do a lot of these things--
do it in a faster manner.
A lot of the heavy lifting was done by the add-in.
Pepper was really the hard place that we had to do some
API conversions.
Now, what we didn't talk about today was anything under the
hood of Native Client.
Today's talk has been specifically focusing on the
developer side of things.
Now, if you're interested in what Native Client is doing
under the hood, to make sure that you can run native code
in a browser with the same security and safety as
JavaScript, I highly recommend you check out Nick Bray's talk
on Life of Native Client Instruction.
It's happening today, in fact.
He is actually going to pull back the mask of running x86
code in the web and talk about all the bad things it can do
and how Native Client addresses those issues.
So I highly recommend checking out his talk.
So what did we learn today?
Let's talk about this, the leftovers.
So develop as a Pepper plug-in first.
This is going to allow you to use your existing IDE.
It's going to allow you to develop as a plug-in, which a
lot of developers are familiar with.
And it's going to allow you to use the debugger properly.
Now, again you can use debugging and profiling with
Native Client, but they're very alpha right now.
So if you're used to using Visual Studio all the time,
you're probably going to have a lot of teeth gnashing in
that process.
Instead, use your IDE, get everything ported over to
Pepper, make your big code changes there.
Never underestimate the power of a good platform wrapper.
Right?
Because all the platform code that effectively you're using
for Pepper, you should properly abstract out.
So when you're about to jump in the code and be like, I'm
going to do Native Client, stop, hammer
time, think about it.
And then write a good wrapper so you can actually maintain
your backward compatibility to the other [? SKUs ?] that
you're targeting.
We ported FileIO.
We ported GL to GLES.
And then we remove all of our platform specific stuff from
NaCl, and we did it with really cool looking hats.
I'm still amazed you found these.
And with that, we're done with the port.
I'm Colt McAnlis.
NOEL ALLEN: I'm Noel Allen.
COLT MCANLIS: That's porting in 60 minutes.
And we'll open the floor for some questions right now.

You did good.
I don't know if I should curtsy.
NOEL ALLEN: I don't do that funny bow.
I'd probably just fall right over.
COLT MCANLIS: Probably.
We're a little bit top heavy.
So there's some microphones here.
If you've got some questions, please feel free to speak up.
Yes, sir.
No, the guy behind you.
No, I'm just messing with you.
Sorry.
The hat, it gives me power.
AUDIENCE: I was wondering if there are any plans to be able
to target Pepper to native binaries so that I could use
the same APIs for deploying to NaCl and to deploying to just
an application running on there and not have that,
ifdeffed out Win32 code.
COLT MCANLIS: That's actually a great question.
I'm going to let you field this.
NOEL ALLEN: Actually, could you repeat that again?
I'm not sure exactly what you were asking there.
Can you take a binary that's already compiled?
AUDIENCE: So no.
So the question is you've been porting the app to use these
Pepper APIs instead of using the native Windows APIs.
Is there any plans to create kind of a wrapper that is the
Pepper API but it targets Windows functions instead of
the Chrome functions?
COLT MCANLIS: So we could use fread, and under the hood it
would do the right Pepper thing.
AUDIENCE: Right.
NOEL ALLEN: Gotcha.
Yes.
So actually, there's some stuff already out there that
other people have developed.
But we are actually putting in a subset of that into the SDK
as we speak.
So you can expect to see things like pthread wrappers,
access to fread open, closed, the standard POSIX-y things,
except running in Win32 so that you can take that Native
Client application and then run it as a Pepper plug-in so
that you can do your development
a little bit easier.

AUDIENCE: So the question I have is about the transition
from the no sandbox to the sandbox.
So basically, obviously, since you are using Windows calls,
you used the no sandbox call initially when you just made
it a Pepper plug-in.
So where does the transition happen?
So when you actually make it a NEXE and when you download it,
is it that the MIME type is handled by the Native Client?

Where does the transition to the sandbox happen?
When you ran it finally, did you also
run it with no sandbox?
NOEL ALLEN: OK.
So what the no sandbox does is it takes out that
outer Chrome sandbox.
AUDIENCE: I know what no sandbox does.
NOEL ALLEN: I was just explaining it
for everybody else.
COLT MCANLIS: There's a lot of other people in the room who
may not know.
NOEL ALLEN: But what that outer sandbox does is it gives
you that OS protection.
So it interferes with things like debugging.
So I have the no sandbox off to enable me to debug at every
single step.
Now, when you actually deploy it-- so if I took this
application, I can switch it back to Native Client.
Go over here to Properties, Debugging.
And as you can see, I do not have No
Sandbox set at this point.
So I'm actually running it with the sandbox on.
AUDIENCE: Right.
So that was my question.
So how does this actually work in the sense that--
so when the page actually loads, does it have a MIME
type that is whatever application slash xNaCl, and
that's handled by whatever the NaCl processor inside Chrome?
COLT MCANLIS: Yes.
So remember early on in the talk, we talked about using
the embed tag to actually signify and point to the
Native Client manifest.
And we defined the MIME type there.
And then, when the page is parsed by Chrome, it'll say,
hey, we found this MIME type.
And it has a table that says, load this plug-in to handle
this MIME type.
NOEL ALLEN: Correct.
So, the application xNaCl typically points to the Native
Client plug-in.
But we were overwriting that for the purpose of developing
as a Pepper plug-in to make it easier.
COLT MCANLIS: We were hacking the planet.
AUDIENCE: Thanks.
COLT MCANLIS: No problem.

AUDIENCE: I was wondering if there's plans to get this in
the mobile version of Chrome.
And if so, when?

NOEL ALLEN: I actually don't know.
I'll leave that to you.
COLT MCANLIS: Next question.
I've got no answers for you today.
I'm sorry.
AUDIENCE: Then maybe--
the NEXE format very specific to x86.
Or is it something like LLVM that might be able to be
compiled for an ARM?
NOEL ALLEN: So let me rephrase that question.
So what you're looking at right now is specifically an
x86, 64-bit binary that was generated by the toolchains.
OK?
So if someone had a 32-bit version of the browser, then
they would be using the 32-bit version.
Or if they had an ARM, they'd be using the ARM version.
Now, we are working on a portable version that will, in
fact, use LLVM to generate bitcode.
And then we will do the translation at
the browser for you.
So you can expect that to be coming around like, say, end
of the year.
AUDIENCE: Thank you.
AUDIENCE: Hi there.
If I have a pretty sophisticated Pepper plug-in
already made--
Well, I guess my question is do I have full access to all
the Pepper APIs inside NaCl, or is it some subset?
NOEL ALLEN: It is a subset, but it's almost all.
So there's a few private interfaces that are only
usable by a few different plug-ins.
So unless you were one of those special cases already,
you wouldn't have had access to it.
AUDIENCE: OK, thanks.

AUDIENCE: I noticed you took out two of the libs.
If I have an external lib, I need to recompile
that lib as a NaCl.
Is that correct?
And then statically link it?
COLT MCANLIS: Yes.
NOEL ALLEN: Yes.
So you're asking what do you have to do
with the two libraries.
So the libraries that we see here, that I took out, is the
Windows GL libraries.
Since we're GLES, you're going to be using GLES.
Now, as you can see here, what I'm doing is I am loading the
PPAPI version of the GLES2 library.
So you will get this in the SDK in the native form for
your platform.
So Windows, Mac, Linux.
And of course, the GCC toolchain
ships with it as well.
So you'll have it on all the platforms.
And we do actually ship the source for this library.
So you could actually recompile it yourself, if you
wanted to as well.
COLT MCANLIS: And If you have libraries, you do have to
recompile them, because otherwise it may have unsafe
code or it may use fread or try to open a window and that
would, of course, fail the validation.
AUDIENCE: I'm sure there's an example I can follow.
That sounds great.
The other question was, now that Chrome is in Android 4.1,
is Native Client also runnable through that Chrome version?
COLT MCANLIS: I believe the correct answer is no.
Because remember Chrome on Android doesn't have all of
the big wizbang features today.
We want to, of course, as Chrome, move towards having
feature parity in as many places as we do.
Right now, we actually don't have Native
Client running on Chrome.
NOEL ALLEN: Yes.
Currently, this is a desktop only--
COLT MCANLIS: Yes.
Currently desktop only.

Fantastic.
Going once, going twice.
Thank you, guys, for your attention today.
We appreciate it.
Thank you.