Google I/O 2012 – Native Client LIVE


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.

Tags:, , , ,

7 Comments

Add a Comment

Your email address will not be published. Required fields are marked *