Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Side by Side Diff: native_client_sdk/doc_generated/devguide/coding/3D-graphics.html

Issue 438403003: [NaCl SDK Docs] Only generate one top-level <section> element. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 {{+bindTo:partials.standard_nacl_article}} 1 {{+bindTo:partials.standard_nacl_article}}
2 2
3 <section id="d-graphics"> 3 <section id="d-graphics">
4 <span id="devguide-coding-3d-graphics"></span><h1 id="d-graphics"><span id="devg uide-coding-3d-graphics"></span>3D Graphics</h1> 4 <span id="devguide-coding-3d-graphics"></span><h1 id="d-graphics"><span id="devg uide-coding-3d-graphics"></span>3D Graphics</h1>
5 <p>Native Client applications use the <a class="reference external" href="http:/ /en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES 2.0</a> API for 3D rendering. This d ocument 5 <p>Native Client applications use the <a class="reference external" href="http:/ /en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES 2.0</a> API for 3D rendering. This d ocument
6 describes how to call the OpenGL ES 2.0 interface in a Native Client module and 6 describes how to call the OpenGL ES 2.0 interface in a Native Client module and
7 how to build an efficient rendering loop. It also explains how to validate GPU 7 how to build an efficient rendering loop. It also explains how to validate GPU
8 drivers and test for specific GPU capabilities, and provides tips to help ensure 8 drivers and test for specific GPU capabilities, and provides tips to help ensure
9 your rendering code runs efficiently.</p> 9 your rendering code runs efficiently.</p>
10 <aside class="note"> 10 <aside class="note">
11 <strong>Note</strong>: 3D drawing and OpenGL are complex topics. This document d eals only 11 <strong>Note</strong>: 3D drawing and OpenGL are complex topics. This document d eals only
12 with issues directly related to programming in the Native Client 12 with issues directly related to programming in the Native Client
13 environment. To learn more about OpenGL ES 2.0 itself, see the <a class="referen ce external" href="http://opengles-book.com/">OpenGL ES 2.0 13 environment. To learn more about OpenGL ES 2.0 itself, see the <a class="referen ce external" href="http://opengles-book.com/">OpenGL ES 2.0
14 Programming Guide</a>. 14 Programming Guide</a>.
15 </aside> 15 </aside>
16 <section id="validating-the-client-graphics-platform">
17 <h2 id="validating-the-client-graphics-platform">Validating the client graphics platform</h2> 16 <h2 id="validating-the-client-graphics-platform">Validating the client graphics platform</h2>
18 <p>Native Client is a software technology that lets you code an application once 17 <p>Native Client is a software technology that lets you code an application once
19 and run it on multiple platforms without worrying about the implementation 18 and run it on multiple platforms without worrying about the implementation
20 details on every possible target platform. It&#8217;s difficult to provide the s ame 19 details on every possible target platform. It&#8217;s difficult to provide the s ame
21 support at the hardware level. Graphics hardware comes from many different 20 support at the hardware level. Graphics hardware comes from many different
22 manufacturers and is controlled by drivers of varying quality. A particular GPU 21 manufacturers and is controlled by drivers of varying quality. A particular GPU
23 driver may not support every OpenGL ES 2.0 feature, and some drivers are known 22 driver may not support every OpenGL ES 2.0 feature, and some drivers are known
24 to have vulnerabilities that can be exploited.</p> 23 to have vulnerabilities that can be exploited.</p>
25 <p>Even if the GPU driver is safe to use, your program should perform a validati on 24 <p>Even if the GPU driver is safe to use, your program should perform a validati on
26 check before you launch your application to ensure that the driver supports all 25 check before you launch your application to ensure that the driver supports all
27 the features you need.</p> 26 the features you need.</p>
28 <section id="vetting-the-driver-in-javascript">
29 <h3 id="vetting-the-driver-in-javascript">Vetting the driver in JavaScript</h3> 27 <h3 id="vetting-the-driver-in-javascript">Vetting the driver in JavaScript</h3>
30 <p>At startup, the application should perform a few additional tests that can be 28 <p>At startup, the application should perform a few additional tests that can be
31 implemented in JavaScript on its hosting web page. The script that performs 29 implemented in JavaScript on its hosting web page. The script that performs
32 these tests should be included before the module&#8217;s <code>embed</code> tag, and ideally 30 these tests should be included before the module&#8217;s <code>embed</code> tag, and ideally
33 the <code>embed</code> tag should appear on the hosting page only if these tests succeed.</p> 31 the <code>embed</code> tag should appear on the hosting page only if these tests succeed.</p>
34 <p>The first thing to check is whether you can create a graphics context. If you 32 <p>The first thing to check is whether you can create a graphics context. If you
35 can, use the context to confirm the existence of any required OpenGL ES 2.0 33 can, use the context to confirm the existence of any required OpenGL ES 2.0
36 extensions. You may want to refer to the <a class="reference external" href="ht tp://www.khronos.org/registry/webgl/extensions/">extension registry</a> and incl ude <a class="reference external" href="https://developer.mozilla.org/en-US/docs /WebGL/Using_Extensions">vendor 34 extensions. You may want to refer to the <a class="reference external" href="ht tp://www.khronos.org/registry/webgl/extensions/">extension registry</a> and incl ude <a class="reference external" href="https://developer.mozilla.org/en-US/docs /WebGL/Using_Extensions">vendor
37 prefixes</a> 35 prefixes</a>
38 when checking for extensions.</p> 36 when checking for extensions.</p>
39 </section><section id="vetting-the-driver-in-native-client">
40 <h3 id="vetting-the-driver-in-native-client">Vetting the driver in Native Client </h3> 37 <h3 id="vetting-the-driver-in-native-client">Vetting the driver in Native Client </h3>
41 <section id="create-a-context">
42 <h4 id="create-a-context">Create a context</h4> 38 <h4 id="create-a-context">Create a context</h4>
43 <p>Once you&#8217;ve passed the JavaScript validation tests, it&#8217;s safe to add a Native 39 <p>Once you&#8217;ve passed the JavaScript validation tests, it&#8217;s safe to add a Native
44 Client embed tag to the hosting web page and load the module. As part of the 40 Client embed tag to the hosting web page and load the module. As part of the
45 module initialization code, you must create a graphics context for the app by 41 module initialization code, you must create a graphics context for the app by
46 either creating a C++ <code>Graphics3D</code> object or calling <code>PPB_Graphi cs3D</code> API 42 either creating a C++ <code>Graphics3D</code> object or calling <code>PPB_Graphi cs3D</code> API
47 function <code>Create</code>. Don&#8217;t assume this will always succeed; you s till might have 43 function <code>Create</code>. Don&#8217;t assume this will always succeed; you s till might have
48 problems creating the context. If you are in development mode and can&#8217;t cr eate 44 problems creating the context. If you are in development mode and can&#8217;t cr eate
49 the context, try creating a simpler version to see if you&#8217;re asking for an 45 the context, try creating a simpler version to see if you&#8217;re asking for an
50 unsupported feature or exceeding a driver resource limit. Your production code 46 unsupported feature or exceeding a driver resource limit. Your production code
51 should always check that the context was created and fail gracefully if that&#82 17;s 47 should always check that the context was created and fail gracefully if that&#82 17;s
52 not the case.</p> 48 not the case.</p>
53 </section><section id="check-for-extensions-and-capabilities">
54 <h4 id="check-for-extensions-and-capabilities">Check for extensions and capabili ties</h4> 49 <h4 id="check-for-extensions-and-capabilities">Check for extensions and capabili ties</h4>
55 <p>Not every GPU supports every extension or has the same amount of texture unit s, 50 <p>Not every GPU supports every extension or has the same amount of texture unit s,
56 vertex attributes, etc. On startup, call <code>glGetString(GL_EXTENSIONS)</code> and 51 vertex attributes, etc. On startup, call <code>glGetString(GL_EXTENSIONS)</code> and
57 check for the extensions and the features you need. For example:</p> 52 check for the extensions and the features you need. For example:</p>
58 <ul class="small-gap"> 53 <ul class="small-gap">
59 <li>If you are using non power-of-2 texture with mipmaps, make sure 54 <li>If you are using non power-of-2 texture with mipmaps, make sure
60 <code>GL_OES_texture_npot</code> exists.</li> 55 <code>GL_OES_texture_npot</code> exists.</li>
61 <li>If you are using floating point textures, make sure <code>GL_OES_texture_flo at</code> 56 <li>If you are using floating point textures, make sure <code>GL_OES_texture_flo at</code>
62 exists.</li> 57 exists.</li>
63 <li>If you are using DXT1, DXT3, or DXT5 textures, make sure the corresponding 58 <li>If you are using DXT1, DXT3, or DXT5 textures, make sure the corresponding
(...skipping 21 matching lines...) Expand all
85 <p>Check for system capabilites with <code>glGetIntegerv</code> and adjust shade r programs 80 <p>Check for system capabilites with <code>glGetIntegerv</code> and adjust shade r programs
86 as well as texture and vertex data accordingly:</p> 81 as well as texture and vertex data accordingly:</p>
87 <ul class="small-gap"> 82 <ul class="small-gap">
88 <li>If you are using textures in vertex shaders, make sure 83 <li>If you are using textures in vertex shaders, make sure
89 <code>glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, ...)</code> and 84 <code>glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, ...)</code> and
90 <code>glGetIntegerv(GL_MAX_TEXTURE_SIZE, ...)</code> return values greater than 0.</li> 85 <code>glGetIntegerv(GL_MAX_TEXTURE_SIZE, ...)</code> return values greater than 0.</li>
91 <li>If you are using more than 8 textures in a single shader, make sure 86 <li>If you are using more than 8 textures in a single shader, make sure
92 <code>glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, ...)</code> returns a value grea ter 87 <code>glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, ...)</code> returns a value grea ter
93 than or equal to the number of simultaneous textures you need.</li> 88 than or equal to the number of simultaneous textures you need.</li>
94 </ul> 89 </ul>
95 </section></section><section id="vetting-the-driver-in-the-chrome-web-store">
96 <h3 id="vetting-the-driver-in-the-chrome-web-store">Vetting the driver in the Ch rome Web Store</h3> 90 <h3 id="vetting-the-driver-in-the-chrome-web-store">Vetting the driver in the Ch rome Web Store</h3>
97 <p>If you choose to place your application in the <a class="reference external" href="/webstore">Chrome Web Store</a>, 91 <p>If you choose to place your application in the <a class="reference external" href="/webstore">Chrome Web Store</a>,
98 its Web Store <a class="reference external" href="/extensions/manifest">manifest file</a> can include the <code>webgl</code> 92 its Web Store <a class="reference external" href="/extensions/manifest">manifest file</a> can include the <code>webgl</code>
99 feature in the requirements parameter. It looks like this:</p> 93 feature in the requirements parameter. It looks like this:</p>
100 <pre class="prettyprint"> 94 <pre class="prettyprint">
101 &quot;requirements&quot;: { 95 &quot;requirements&quot;: {
102 &quot;3D&quot;: { 96 &quot;3D&quot;: {
103 &quot;features&quot;: [&quot;webgl&quot;] 97 &quot;features&quot;: [&quot;webgl&quot;]
104 } 98 }
105 } 99 }
106 </pre> 100 </pre>
107 <p>While WebGL is technically a JavaScript API, specifying the <code>webgl</code > feature 101 <p>While WebGL is technically a JavaScript API, specifying the <code>webgl</code > feature
108 also works for OpenGL ES 2.0 because both interfaces use the same driver.</p> 102 also works for OpenGL ES 2.0 because both interfaces use the same driver.</p>
109 <p>This manifest item is not required, but if you include it, the Chrome Web Sto re 103 <p>This manifest item is not required, but if you include it, the Chrome Web Sto re
110 will prevent a user from installing the application if the browser is running on 104 will prevent a user from installing the application if the browser is running on
111 a machine that does not support OpenGL ES 2.0 or that is using a known 105 a machine that does not support OpenGL ES 2.0 or that is using a known
112 blacklisted GPU driver that could invite an attack.</p> 106 blacklisted GPU driver that could invite an attack.</p>
113 <p>If the Web Store determines that the user&#8217;s driver is deficient, the ap p won&#8217;t 107 <p>If the Web Store determines that the user&#8217;s driver is deficient, the ap p won&#8217;t
114 appear on the store&#8217;s tile display. However, it will appear in store searc h 108 appear on the store&#8217;s tile display. However, it will appear in store searc h
115 results or if the user links to it directly, in which case the user could still 109 results or if the user links to it directly, in which case the user could still
116 download it. But the manifest requirements will be checked when the user reaches 110 download it. But the manifest requirements will be checked when the user reaches
117 the install page, and if there is a problem, the browser will display the 111 the install page, and if there is a problem, the browser will display the
118 message &#8220;This application is not supported on this computer. Installation has 112 message &#8220;This application is not supported on this computer. Installation has
119 been disabled.&#8221;</p> 113 been disabled.&#8221;</p>
120 <p>The manifest-based check applies only to downloads directly from the Chrome W eb 114 <p>The manifest-based check applies only to downloads directly from the Chrome W eb
121 Store. It is not performed when an application is loaded via <a class="reference external" href="/webstore/inline_installation">inline 115 Store. It is not performed when an application is loaded via <a class="reference external" href="/webstore/inline_installation">inline
122 installation</a>.</p> 116 installation</a>.</p>
123 </section><section id="what-to-do-when-there-are-problems">
124 <h3 id="what-to-do-when-there-are-problems">What to do when there are problems</ h3> 117 <h3 id="what-to-do-when-there-are-problems">What to do when there are problems</ h3>
125 <p>Using the vetting procedure described above, you should be able to detect the 118 <p>Using the vetting procedure described above, you should be able to detect the
126 most common problems before your application runs. If there are problems, your 119 most common problems before your application runs. If there are problems, your
127 code should describe the issue as clearly as possible. That&#8217;s easy if ther e is a 120 code should describe the issue as clearly as possible. That&#8217;s easy if ther e is a
128 missing feature. Failure to create a graphics context is tougher to diagnose. At 121 missing feature. Failure to create a graphics context is tougher to diagnose. At
129 the very least, you can suggest that the user try to update the driver. You 122 the very least, you can suggest that the user try to update the driver. You
130 might want to linke to the Chrome page that describes <a class="reference extern al" href="http://support.google.com/chrome/bin/answer.py?hl=en&amp;answer=120294 6">how to do updates</a>.</p> 123 might want to linke to the Chrome page that describes <a class="reference extern al" href="http://support.google.com/chrome/bin/answer.py?hl=en&amp;answer=120294 6">how to do updates</a>.</p>
131 <p>If a user can&#8217;t update the driver, or their problem persists, be sure t o gather 124 <p>If a user can&#8217;t update the driver, or their problem persists, be sure t o gather
132 information about their graphics environment. Ask for the contents of the Chrome 125 information about their graphics environment. Ask for the contents of the Chrome
133 <code>about:gpu</code> page.</p> 126 <code>about:gpu</code> page.</p>
134 </section><section id="document-unreliable-drivers">
135 <h3 id="document-unreliable-drivers">Document unreliable drivers</h3> 127 <h3 id="document-unreliable-drivers">Document unreliable drivers</h3>
136 <p>It can be helpful to include information about known dubious drivers in your 128 <p>It can be helpful to include information about known dubious drivers in your
137 user documentation. This might help identify if a rogue driver is the cause of a 129 user documentation. This might help identify if a rogue driver is the cause of a
138 problem. There are many sources of GPU driver blacklists. Two such lists can be 130 problem. There are many sources of GPU driver blacklists. Two such lists can be
139 found at the <a class="reference external" href="http://src.chromium.org/viewvc/ chrome/trunk/deps/gpu/software_rendering_list/software_rendering_list.json">Chro mium project</a> 131 found at the <a class="reference external" href="http://src.chromium.org/viewvc/ chrome/trunk/deps/gpu/software_rendering_list/software_rendering_list.json">Chro mium project</a>
140 and <a class="reference external" href="http://www.khronos.org/webgl/wiki/Blackl istsAndWhitelists">Khronos</a>. You 132 and <a class="reference external" href="http://www.khronos.org/webgl/wiki/Blackl istsAndWhitelists">Khronos</a>. You
141 can use these lists to include information in your documentation that warns 133 can use these lists to include information in your documentation that warns
142 users about dangerous drivers.</p> 134 users about dangerous drivers.</p>
143 </section><section id="test-your-defenses">
144 <h3 id="test-your-defenses">Test your defenses</h3> 135 <h3 id="test-your-defenses">Test your defenses</h3>
145 <p>You can test your driver validation code by running Chrome with the following 136 <p>You can test your driver validation code by running Chrome with the following
146 flags (all at once) and watching how your application responds:</p> 137 flags (all at once) and watching how your application responds:</p>
147 <ul class="small-gap"> 138 <ul class="small-gap">
148 <li><code>--disable-webgl</code></li> 139 <li><code>--disable-webgl</code></li>
149 <li><code>--disable-pepper-3d</code></li> 140 <li><code>--disable-pepper-3d</code></li>
150 <li><code>--disable_multisampling</code></li> 141 <li><code>--disable_multisampling</code></li>
151 <li><code>--disable-accelerated-compositing</code></li> 142 <li><code>--disable-accelerated-compositing</code></li>
152 <li><code>--disable-accelerated-2d-canvas</code></li> 143 <li><code>--disable-accelerated-2d-canvas</code></li>
153 </ul> 144 </ul>
154 </section></section><section id="calling-opengl-es-2-0-commands">
155 <h2 id="calling-opengl-es-2-0-commands">Calling OpenGL ES 2.0 commands</h2> 145 <h2 id="calling-opengl-es-2-0-commands">Calling OpenGL ES 2.0 commands</h2>
156 <p>There are three ways to write OpenGL ES 2.0 calls in Native Client.</p> 146 <p>There are three ways to write OpenGL ES 2.0 calls in Native Client.</p>
157 <section id="use-pure-opengl-es-2-0-function-calls">
158 <h3 id="use-pure-opengl-es-2-0-function-calls">Use &#8220;pure&#8221; OpenGL ES 2.0 function calls</h3> 147 <h3 id="use-pure-opengl-es-2-0-function-calls">Use &#8220;pure&#8221; OpenGL ES 2.0 function calls</h3>
159 <p>You can make OpenGL ES 2.0 calls through a Pepper extension library. The SDK 148 <p>You can make OpenGL ES 2.0 calls through a Pepper extension library. The SDK
160 example <code>examples/api/graphics_3d</code> works this way. In the file 149 example <code>examples/api/graphics_3d</code> works this way. In the file
161 <code>graphics_3d.cc</code>, the key initialization steps are as follows:</p> 150 <code>graphics_3d.cc</code>, the key initialization steps are as follows:</p>
162 <ul class="small-gap"> 151 <ul class="small-gap">
163 <li><p class="first">Add these includes at the top of the file:</p> 152 <li><p class="first">Add these includes at the top of the file:</p>
164 <pre class="prettyprint"> 153 <pre class="prettyprint">
165 #include &lt;GLES2/gl2.h&gt; 154 #include &lt;GLES2/gl2.h&gt;
166 #include &quot;ppapi/lib/gl/gles2/gl2ext_ppapi.h&quot; 155 #include &quot;ppapi/lib/gl/gles2/gl2ext_ppapi.h&quot;
167 </pre> 156 </pre>
(...skipping 25 matching lines...) Expand all
193 182
194 glSetCurrentContextPPAPI(context_.pp_resource()); 183 glSetCurrentContextPPAPI(context_.pp_resource());
195 return true; 184 return true;
196 } 185 }
197 </pre> 186 </pre>
198 </li> 187 </li>
199 <li>Include logic in <code>Instance::DidChangeView</code> to call <code>InitGL</ code> whenever 188 <li>Include logic in <code>Instance::DidChangeView</code> to call <code>InitGL</ code> whenever
200 necessary: upon application launch (when the graphics context is NULL) and 189 necessary: upon application launch (when the graphics context is NULL) and
201 whenever the module&#8217;s View changes size.</li> 190 whenever the module&#8217;s View changes size.</li>
202 </ul> 191 </ul>
203 </section><section id="use-regal">
204 <h3 id="use-regal">Use Regal</h3> 192 <h3 id="use-regal">Use Regal</h3>
205 <p>If you are porting an OpenGL ES 2.0 application, or are comfortable writing i n 193 <p>If you are porting an OpenGL ES 2.0 application, or are comfortable writing i n
206 OpenGL ES 2.0, you should stick with the Pepper APIs or pure OpenGL ES 2.0 calls 194 OpenGL ES 2.0, you should stick with the Pepper APIs or pure OpenGL ES 2.0 calls
207 described above. If you are porting an application that uses features not in 195 described above. If you are porting an application that uses features not in
208 OpenGL ES 2.0, consider using Regal. Regal is an open source library that 196 OpenGL ES 2.0, consider using Regal. Regal is an open source library that
209 supports many versions of OpenGL. Regal recently added support for Native 197 supports many versions of OpenGL. Regal recently added support for Native
210 Client. Regal forwards most OpenGL calls directly to the underlying graphics 198 Client. Regal forwards most OpenGL calls directly to the underlying graphics
211 library, but it can also emulate other calls that are not included (when 199 library, but it can also emulate other calls that are not included (when
212 hardware support exists). See <a class="reference external" href="http://www.alt devblogaday.com/2012/09/04/bringing-regal-opengl-to-native-client/">libregal</a> 200 hardware support exists). See <a class="reference external" href="http://www.alt devblogaday.com/2012/09/04/bringing-regal-opengl-to-native-client/">libregal</a>
213 for more info.</p> 201 for more info.</p>
214 </section><section id="use-the-pepper-api">
215 <h3 id="use-the-pepper-api">Use the Pepper API</h3> 202 <h3 id="use-the-pepper-api">Use the Pepper API</h3>
216 <p>Your code can call the Pepper PPB_OpenGLES2 API directly, as with any Pepper 203 <p>Your code can call the Pepper PPB_OpenGLES2 API directly, as with any Pepper
217 interface. When you write in this way, each invocation of an OpenGL ES 2.0 204 interface. When you write in this way, each invocation of an OpenGL ES 2.0
218 function must begin with a reference to the Pepper interface, and the first 205 function must begin with a reference to the Pepper interface, and the first
219 argument is the graphics context. To invoke the function <code>glCompileShader</ code>, 206 argument is the graphics context. To invoke the function <code>glCompileShader</ code>,
220 your code might look like:</p> 207 your code might look like:</p>
221 <pre class="prettyprint"> 208 <pre class="prettyprint">
222 ppb_g3d_interface-&gt;CompileShader(graphicsContext, shader); 209 ppb_g3d_interface-&gt;CompileShader(graphicsContext, shader);
223 </pre> 210 </pre>
224 <p>This approach specifically targets the Pepper APIs. Each call corresponds to a 211 <p>This approach specifically targets the Pepper APIs. Each call corresponds to a
225 OpenGL ES 2.0 function, but the syntax is unique to Native Client, so the source 212 OpenGL ES 2.0 function, but the syntax is unique to Native Client, so the source
226 file is not portable.</p> 213 file is not portable.</p>
227 </section></section><section id="implementing-a-rendering-loop">
228 <h2 id="implementing-a-rendering-loop">Implementing a rendering loop</h2> 214 <h2 id="implementing-a-rendering-loop">Implementing a rendering loop</h2>
229 <p>Graphics applications require a continuous frame render-and-redraw cycle that 215 <p>Graphics applications require a continuous frame render-and-redraw cycle that
230 runs at a high frequency. To achieve the best frame rate, is important to 216 runs at a high frequency. To achieve the best frame rate, is important to
231 understand how the OpenGL ES 2.0 code in a Native Client module interacts with 217 understand how the OpenGL ES 2.0 code in a Native Client module interacts with
232 Chrome.</p> 218 Chrome.</p>
233 <section id="the-chrome-and-native-client-processes">
234 <h3 id="the-chrome-and-native-client-processes">The Chrome and Native Client pro cesses</h3> 219 <h3 id="the-chrome-and-native-client-processes">The Chrome and Native Client pro cesses</h3>
235 <p>Chrome is a multi-process browser. Each Chrome tab is a separate process that is 220 <p>Chrome is a multi-process browser. Each Chrome tab is a separate process that is
236 running an application with its own main thread (we&#8217;ll call it the Chrome main 221 running an application with its own main thread (we&#8217;ll call it the Chrome main
237 thread). When an application launches a Native Client module, the module runs in 222 thread). When an application launches a Native Client module, the module runs in
238 a new, separate sandboxed process. The module&#8217;s process has its own main t hread 223 a new, separate sandboxed process. The module&#8217;s process has its own main t hread
239 (the Native Client thread). The Chrome and Native Client processes communicate 224 (the Native Client thread). The Chrome and Native Client processes communicate
240 with each other using Pepper API calls on their main threads.</p> 225 with each other using Pepper API calls on their main threads.</p>
241 <p>When the Chrome main thread calls the Native Client thread (keyboard and mous e 226 <p>When the Chrome main thread calls the Native Client thread (keyboard and mous e
242 callbacks, for example), the Chrome main thread will block. This means that 227 callbacks, for example), the Chrome main thread will block. This means that
243 lengthy operations on the Native Client thread can steal cycles from Chrome, and 228 lengthy operations on the Native Client thread can steal cycles from Chrome, and
244 performing blocking operations on the Native Client thread can bring your app to 229 performing blocking operations on the Native Client thread can bring your app to
245 a standstill.</p> 230 a standstill.</p>
246 <p>Native Client uses callback functions to synchronize the main threads of the 231 <p>Native Client uses callback functions to synchronize the main threads of the
247 two processes. Only certain Pepper functions use callbacks; <a class="reference external" href="/native-client/pepper_stable/c/struct_p_p_b___graphics3_d__1__0# a293c6941c0da084267ffba3954793497">SwapBuffers</a> 232 two processes. Only certain Pepper functions use callbacks; <a class="reference external" href="/native-client/pepper_stable/c/struct_p_p_b___graphics3_d__1__0# a293c6941c0da084267ffba3954793497">SwapBuffers</a>
248 is one.</p> 233 is one.</p>
249 </section><section id="swapbuffers-and-its-callback-function">
250 <h3 id="swapbuffers-and-its-callback-function"><code>SwapBuffers</code> and its callback function</h3> 234 <h3 id="swapbuffers-and-its-callback-function"><code>SwapBuffers</code> and its callback function</h3>
251 <p><code>SwapBuffers</code> is non-blocking; it is called from the Native Client thread and 235 <p><code>SwapBuffers</code> is non-blocking; it is called from the Native Client thread and
252 returns immediately. When <code>SwapBuffers</code> is called, it runs asynchrono usly on 236 returns immediately. When <code>SwapBuffers</code> is called, it runs asynchrono usly on
253 the Chrome main thread. It switches the graphics data buffers, handles any 237 the Chrome main thread. It switches the graphics data buffers, handles any
254 needed compositing operations, and redraws the screen. When the screen update is 238 needed compositing operations, and redraws the screen. When the screen update is
255 complete, the callback function that was included as one of <code>SwapBuffer</co de>&#8216;s 239 complete, the callback function that was included as one of <code>SwapBuffer</co de>&#8216;s
256 arguments will be called from the Chrome thread and executed on the Native 240 arguments will be called from the Chrome thread and executed on the Native
257 Client thread.</p> 241 Client thread.</p>
258 <p>To create a rendering loop, your Native Client module should include a functi on 242 <p>To create a rendering loop, your Native Client module should include a functi on
259 that does the rendering work and then executes <code>SwapBuffers</code>, passing itself 243 that does the rendering work and then executes <code>SwapBuffers</code>, passing itself
260 as the <code>SwapBuffer</code> callback. If your rendering code is efficient and runs 244 as the <code>SwapBuffer</code> callback. If your rendering code is efficient and runs
261 quickly, this scheme will achieve the highest frame rate possible. The 245 quickly, this scheme will achieve the highest frame rate possible. The
262 documentation for <code>SwapBuffers</code> explains why this is optimal: because the 246 documentation for <code>SwapBuffers</code> explains why this is optimal: because the
263 callback is executed only when the plugin&#8217;s current state is actually on t he 247 callback is executed only when the plugin&#8217;s current state is actually on t he
264 screen, this function provides a way to rate-limit animations. By waiting until 248 screen, this function provides a way to rate-limit animations. By waiting until
265 the image is on the screen before painting the next frame, you can ensure you&#8 217;re 249 the image is on the screen before painting the next frame, you can ensure you&#8 217;re
266 not generating updates faster than the screen can be updated.</p> 250 not generating updates faster than the screen can be updated.</p>
267 <p>The following diagram illustrates the interaction between the Chrome and Nati ve 251 <p>The following diagram illustrates the interaction between the Chrome and Nati ve
268 Client processes. The application-specific rendering code runs in the function 252 Client processes. The application-specific rendering code runs in the function
269 called <code>Draw</code> on the Native Client thread. Blue down-arrows are block ing calls 253 called <code>Draw</code> on the Native Client thread. Blue down-arrows are block ing calls
270 from the main thread to Native Client, green up-arrows are non-blocking 254 from the main thread to Native Client, green up-arrows are non-blocking
271 <code>SwapBuffers</code> calls from Native Client to the main thread. All OpenGL ES 2.0 255 <code>SwapBuffers</code> calls from Native Client to the main thread. All OpenGL ES 2.0
272 calls are made from <code>Draw</code> in the Native Client thread.</p> 256 calls are made from <code>Draw</code> in the Native Client thread.</p>
273 <img alt="/native-client/images/3d-graphics-render-loop.png" src="/native-client /images/3d-graphics-render-loop.png" /> 257 <img alt="/native-client/images/3d-graphics-render-loop.png" src="/native-client /images/3d-graphics-render-loop.png" />
274 </section><section id="sdk-example-graphics-3d">
275 <h3 id="sdk-example-graphics-3d">SDK example <code>graphics_3d</code></h3> 258 <h3 id="sdk-example-graphics-3d">SDK example <code>graphics_3d</code></h3>
276 <p>The SDK example <code>graphics_3d</code> uses the function <code>MainLoop</co de> (in 259 <p>The SDK example <code>graphics_3d</code> uses the function <code>MainLoop</co de> (in
277 <code>hello_world.cc</code>) to create a rendering loop as described above. <cod e>MainLoop</code> 260 <code>hello_world.cc</code>) to create a rendering loop as described above. <cod e>MainLoop</code>
278 calls <code>Render</code> to do the rendering work, and then invokes <code>SwapB uffers</code>, 261 calls <code>Render</code> to do the rendering work, and then invokes <code>SwapB uffers</code>,
279 passing itself as the callback.</p> 262 passing itself as the callback.</p>
280 <pre class="prettyprint"> 263 <pre class="prettyprint">
281 void MainLoop(void* foo, int bar) { 264 void MainLoop(void* foo, int bar) {
282 if (g_LoadCnt == 3) { 265 if (g_LoadCnt == 3) {
283 InitProgram(); 266 InitProgram();
284 g_LoadCnt++; 267 g_LoadCnt++;
285 } 268 }
286 if (g_LoadCnt &gt; 3) { 269 if (g_LoadCnt &gt; 3) {
287 Render(); 270 Render();
288 PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0); 271 PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0);
289 ppb_g3d_interface-&gt;SwapBuffers(g_context, cc); 272 ppb_g3d_interface-&gt;SwapBuffers(g_context, cc);
290 } else { 273 } else {
291 PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0); 274 PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0);
292 ppb_core_interface-&gt;CallOnMainThread(0, cc, 0); 275 ppb_core_interface-&gt;CallOnMainThread(0, cc, 0);
293 } 276 }
294 } 277 }
295 </pre> 278 </pre>
296 </section></section><section id="managing-the-opengl-es-2-0-pipeline">
297 <h2 id="managing-the-opengl-es-2-0-pipeline">Managing the OpenGL ES 2.0 pipeline </h2> 279 <h2 id="managing-the-opengl-es-2-0-pipeline">Managing the OpenGL ES 2.0 pipeline </h2>
298 <p>OpenGL ES 2.0 commands do not run in the Chrome or Native Client processes. T hey 280 <p>OpenGL ES 2.0 commands do not run in the Chrome or Native Client processes. T hey
299 are passed into a FIFO queue in shared memory which is best understood as a <a c lass="reference external" href="http://www.chromium.org/developers/design-docume nts/gpu-command-buffer">GPU 281 are passed into a FIFO queue in shared memory which is best understood as a <a c lass="reference external" href="http://www.chromium.org/developers/design-docume nts/gpu-command-buffer">GPU
300 command buffer</a>. The 282 command buffer</a>. The
301 command buffer is shared by a dedicated GPU process. By using a separate GPU 283 command buffer is shared by a dedicated GPU process. By using a separate GPU
302 process, Chrome implements another layer of runtime security, vetting all OpenGL 284 process, Chrome implements another layer of runtime security, vetting all OpenGL
303 ES 2.0 commands and their arguments before they are sent on to the 285 ES 2.0 commands and their arguments before they are sent on to the
304 GPU. Buffering commands through the FIFO also speeds up your code, since each 286 GPU. Buffering commands through the FIFO also speeds up your code, since each
305 OpenGL ES 2.0 call in your Native Client thread returns immediately, while the 287 OpenGL ES 2.0 call in your Native Client thread returns immediately, while the
306 processing may be delayed as the GPU works down the commands queued up in the 288 processing may be delayed as the GPU works down the commands queued up in the
(...skipping 10 matching lines...) Expand all
317 calls to speed up the flow of the OpenGL ES 2.0 command FIFO. Before you start 299 calls to speed up the flow of the OpenGL ES 2.0 command FIFO. Before you start
318 to add your own flushes, first try to determine if pipeline saturation is really 300 to add your own flushes, first try to determine if pipeline saturation is really
319 the problem by monitoring the rendering time per frame and looking for irregular 301 the problem by monitoring the rendering time per frame and looking for irregular
320 spikes that do not consistently fall on the same OpenGL ES 2.0 call. If you&#821 7;re 302 spikes that do not consistently fall on the same OpenGL ES 2.0 call. If you&#821 7;re
321 convinced the pipeline needs to be accelerated, insert <code>glFlush</code> call s in your 303 convinced the pipeline needs to be accelerated, insert <code>glFlush</code> call s in your
322 code before starting blocks of processing that do not generate OpenGL ES 2.0 304 code before starting blocks of processing that do not generate OpenGL ES 2.0
323 commands. For example, issue a flush before you begin any multithreaded particle 305 commands. For example, issue a flush before you begin any multithreaded particle
324 work, so that the command buffer will be clear when you start doing OpenGL ES 306 work, so that the command buffer will be clear when you start doing OpenGL ES
325 2.0 calls again. Determining where and how often to call <code>glFlush</code> ca n be 307 2.0 calls again. Determining where and how often to call <code>glFlush</code> ca n be
326 tricky, you will need to experiment to find the sweet spot.</p> 308 tricky, you will need to experiment to find the sweet spot.</p>
327 </section><section id="rendering-and-inactive-tabs">
328 <h2 id="rendering-and-inactive-tabs">Rendering and inactive tabs</h2> 309 <h2 id="rendering-and-inactive-tabs">Rendering and inactive tabs</h2>
329 <p>Users will often switch between tabs in a multi-tab browser. A well-behaved 310 <p>Users will often switch between tabs in a multi-tab browser. A well-behaved
330 application that&#8217;s performing 3D rendering should pause any real-time proc essing 311 application that&#8217;s performing 3D rendering should pause any real-time proc essing
331 and yield cycles to other processes when its tab becomes inactive.</p> 312 and yield cycles to other processes when its tab becomes inactive.</p>
332 <p>In Chrome, an inactive tab will continue to execute timed functions (such as 313 <p>In Chrome, an inactive tab will continue to execute timed functions (such as
333 <code>setInterval</code> and <code>setTimeout</code>) but the timer interval wil l be automatically 314 <code>setInterval</code> and <code>setTimeout</code>) but the timer interval wil l be automatically
334 overridden and limited to not less than one second while the tab is inactive. In 315 overridden and limited to not less than one second while the tab is inactive. In
335 addition, any callback associated with a <code>SwapBuffers</code> call will not be sent 316 addition, any callback associated with a <code>SwapBuffers</code> call will not be sent
336 until the tab is active again. You may receive asynchronous callbacks from 317 until the tab is active again. You may receive asynchronous callbacks from
337 functions other than <code>SwapBuffers</code> while a tab is inactive. Depending on the 318 functions other than <code>SwapBuffers</code> while a tab is inactive. Depending on the
338 design of your application, you might choose to handle them as they arrive, or 319 design of your application, you might choose to handle them as they arrive, or
339 to queue them in a buffer and process them when the tab becomes active.</p> 320 to queue them in a buffer and process them when the tab becomes active.</p>
340 <p>The time that passes while a tab is inactive can be considerable. If your mai n 321 <p>The time that passes while a tab is inactive can be considerable. If your mai n
341 thread pulse is based on the <code>SwapBuffers</code> callback, your app won&#82 17;t update 322 thread pulse is based on the <code>SwapBuffers</code> callback, your app won&#82 17;t update
342 while a tab is inactive. A Native Client module should be able to detect and 323 while a tab is inactive. A Native Client module should be able to detect and
343 respond to the state of the tab in which it&#8217;s running. For example, when a tab 324 respond to the state of the tab in which it&#8217;s running. For example, when a tab
344 becomes inactive, you can set an atomic flag in the Native Client thread that 325 becomes inactive, you can set an atomic flag in the Native Client thread that
345 will skip the 3D rendering and <code>SwapBuffers</code> calls and continue to ca ll the 326 will skip the 3D rendering and <code>SwapBuffers</code> calls and continue to ca ll the
346 main thread every 30 msec or so. This provides time to update features that 327 main thread every 30 msec or so. This provides time to update features that
347 should still run in the background, like audio. It may also be helpful to call 328 should still run in the background, like audio. It may also be helpful to call
348 <code>sched_yield</code> or <code>usleep</code> on any worker threads to release resources and 329 <code>sched_yield</code> or <code>usleep</code> on any worker threads to release resources and
349 cede cycles to the OS.</p> 330 cede cycles to the OS.</p>
350 <section id="handling-tab-activation-from-the-main-thread">
351 <h3 id="handling-tab-activation-from-the-main-thread">Handling tab activation fr om the main thread</h3> 331 <h3 id="handling-tab-activation-from-the-main-thread">Handling tab activation fr om the main thread</h3>
352 <p>You can detect and respond to the activation or deactivation of a tab with 332 <p>You can detect and respond to the activation or deactivation of a tab with
353 JavaScript on your hosting page. Add an EventListener for <code>visibilitychange </code> 333 JavaScript on your hosting page. Add an EventListener for <code>visibilitychange </code>
354 that sends a message to the Native Client module, as in this example:</p> 334 that sends a message to the Native Client module, as in this example:</p>
355 <pre class="prettyprint"> 335 <pre class="prettyprint">
356 document.addEventListener('visibilitychange', function(){ 336 document.addEventListener('visibilitychange', function(){
357 if (document.hidden) { 337 if (document.hidden) {
358 // PostMessage to your Native Client module 338 // PostMessage to your Native Client module
359 document.nacl_module.postMessage('INACTIVE'); 339 document.nacl_module.postMessage('INACTIVE');
360 } else { 340 } else {
361 // PostMessage to your Native Client module 341 // PostMessage to your Native Client module
362 document.nacl_module.postMessage('ACTIVE'); 342 document.nacl_module.postMessage('ACTIVE');
363 } 343 }
364 344
365 }, false); 345 }, false);
366 </pre> 346 </pre>
367 </section><section id="handling-tab-activation-from-the-native-client-thread">
368 <h3 id="handling-tab-activation-from-the-native-client-thread">Handling tab acti vation from the Native Client thread</h3> 347 <h3 id="handling-tab-activation-from-the-native-client-thread">Handling tab acti vation from the Native Client thread</h3>
369 <p>You can also detect and respond to the activation or deactivation of a tab 348 <p>You can also detect and respond to the activation or deactivation of a tab
370 directly from your Native Client module by including code in the function 349 directly from your Native Client module by including code in the function
371 <code>pp::Instance::DidChangeView</code>, which is called whenever a change in t he 350 <code>pp::Instance::DidChangeView</code>, which is called whenever a change in t he
372 module&#8217;s view occurs. The code can call <code>ppb::View::IsPageVisible</co de> to 351 module&#8217;s view occurs. The code can call <code>ppb::View::IsPageVisible</co de> to
373 determine if the page is visible or not. The most common cause of invisible 352 determine if the page is visible or not. The most common cause of invisible
374 pages is that the page is in a background tab.</p> 353 pages is that the page is in a background tab.</p>
375 </section></section><section id="tips-and-best-practices">
376 <h2 id="tips-and-best-practices">Tips and best practices</h2> 354 <h2 id="tips-and-best-practices">Tips and best practices</h2>
377 <p>Here are some suggestions for writing safe code and getting the maximum 355 <p>Here are some suggestions for writing safe code and getting the maximum
378 performance with the Pepper 3D API.</p> 356 performance with the Pepper 3D API.</p>
379 <section id="do-s">
380 <h3 id="do-s">Do&#8217;s</h3> 357 <h3 id="do-s">Do&#8217;s</h3>
381 <ul class="small-gap"> 358 <ul class="small-gap">
382 <li><p class="first"><strong>Make sure to enable attrib 0.</strong> OpenGL requi res that you enable attrib 0, 359 <li><p class="first"><strong>Make sure to enable attrib 0.</strong> OpenGL requi res that you enable attrib 0,
383 but OpenGL ES 2.0 does not. For example, you can define a vertex shader with 2 360 but OpenGL ES 2.0 does not. For example, you can define a vertex shader with 2
384 attributes, numbered like this:</p> 361 attributes, numbered like this:</p>
385 <pre class="prettyprint"> 362 <pre class="prettyprint">
386 glBindAttribLocation(program, &quot;positions&quot;, 1); 363 glBindAttribLocation(program, &quot;positions&quot;, 1);
387 glBindAttribLocation(program, &quot;normals&quot;, 2); 364 glBindAttribLocation(program, &quot;normals&quot;, 2);
388 </pre> 365 </pre>
389 <p>In this case the shader is not using attrib 0 and Chrome may have to perform 366 <p>In this case the shader is not using attrib 0 and Chrome may have to perform
(...skipping 11 matching lines...) Expand all
401 issues, it may be beneficial to perform scaling via CSS. The size your plugin 378 issues, it may be beneficial to perform scaling via CSS. The size your plugin
402 renders is determined by the width and height attributes of the <code>&lt;embed& gt;</code> 379 renders is determined by the width and height attributes of the <code>&lt;embed& gt;</code>
403 element for the module. The actual size displayed on the web page is 380 element for the module. The actual size displayed on the web page is
404 controlled by the CSS styles applied to the element.</li> 381 controlled by the CSS styles applied to the element.</li>
405 <li><strong>Avoid matrix-to-matrix conversions.</strong> With some versions of M ac OS, there is 382 <li><strong>Avoid matrix-to-matrix conversions.</strong> With some versions of M ac OS, there is
406 a driver problem when compiling shaders. If you get compiler errors for matrix 383 a driver problem when compiling shaders. If you get compiler errors for matrix
407 transforms, avoid matrix-to-matrix conversions. For instance, upres a vec3 to 384 transforms, avoid matrix-to-matrix conversions. For instance, upres a vec3 to
408 a vec4 before transforming it by a mat4, rather than converting the mat4 to a 385 a vec4 before transforming it by a mat4, rather than converting the mat4 to a
409 mat3.</li> 386 mat3.</li>
410 </ul> 387 </ul>
411 </section><section id="don-ts">
412 <h3 id="don-ts">Don&#8217;ts</h3> 388 <h3 id="don-ts">Don&#8217;ts</h3>
413 <ul class="small-gap"> 389 <ul class="small-gap">
414 <li><strong>Don&#8217;t use client side buffers.</strong> OpenGL ES 2.0 can use client side data with 390 <li><strong>Don&#8217;t use client side buffers.</strong> OpenGL ES 2.0 can use client side data with
415 <code>glVertexAttribPointer</code> and <code>glDrawElements</code>, but this is really slow. Try 391 <code>glVertexAttribPointer</code> and <code>glDrawElements</code>, but this is really slow. Try
416 to avoid client side buffers. Use Vertex Buffer Objects (VBOs) instead.</li> 392 to avoid client side buffers. Use Vertex Buffer Objects (VBOs) instead.</li>
417 <li><strong>Don&#8217;t mix vertex data and index data.</strong> By default, Pep per 3D binds buffers 393 <li><strong>Don&#8217;t mix vertex data and index data.</strong> By default, Pep per 3D binds buffers
418 to a single point. You could create a buffer and bind it to both 394 to a single point. You could create a buffer and bind it to both
419 <code>GL_ARRAY_BUFFER</code> and <code>GL_ELEMENT_ARRAY_BUFFER</code>, but that would be 395 <code>GL_ARRAY_BUFFER</code> and <code>GL_ELEMENT_ARRAY_BUFFER</code>, but that would be
420 expensive overhead and it is not recommended.</li> 396 expensive overhead and it is not recommended.</li>
421 <li><strong>Don&#8217;t call ``glGet*`` or ``glCheck*`` during rendering.</stron g> This is normal 397 <li><strong>Don&#8217;t call ``glGet*`` or ``glCheck*`` during rendering.</stron g> This is normal
422 advice for OpenGL programs, but is particularly important for 3D on 398 advice for OpenGL programs, but is particularly important for 3D on
423 Chrome. Calls to any OpenGL ES 2.0 function whose name begins with these 399 Chrome. Calls to any OpenGL ES 2.0 function whose name begins with these
424 strings blocks the Native Client thread. This includes <code>glGetError</code>; avoid 400 strings blocks the Native Client thread. This includes <code>glGetError</code>; avoid
425 calling it in release builds.</li> 401 calling it in release builds.</li>
426 <li><strong>Don&#8217;t use fixed point (``GL_FIXED``) vertex attributes.</stron g> Fixed point 402 <li><strong>Don&#8217;t use fixed point (``GL_FIXED``) vertex attributes.</stron g> Fixed point
427 attributes are not supported in OpenGL ES 2.0, so emulating them in OpenGL ES 403 attributes are not supported in OpenGL ES 2.0, so emulating them in OpenGL ES
428 2.0 is slow. By default, <code>GL_FIXED</code> support is turned off in the Pepp er 3D 404 2.0 is slow. By default, <code>GL_FIXED</code> support is turned off in the Pepp er 3D
429 API.</li> 405 API.</li>
430 <li><strong>Don&#8217;t read data from the GPU.</strong> Don&#8217;t call <code> glReadPixels</code>, as it is slow.</li> 406 <li><strong>Don&#8217;t read data from the GPU.</strong> Don&#8217;t call <code> glReadPixels</code>, as it is slow.</li>
431 <li><strong>Don&#8217;t update a small portion of a large buffer.</strong> In th e current OpenGL ES 407 <li><strong>Don&#8217;t update a small portion of a large buffer.</strong> In th e current OpenGL ES
432 2.0 implementation when you update a portion of a buffer (with 408 2.0 implementation when you update a portion of a buffer (with
433 <code>glSubBufferData</code> for example) the entire buffer must be reprocessed. To 409 <code>glSubBufferData</code> for example) the entire buffer must be reprocessed. To
434 avoid this problem, keep static and dynamic data in different buffers.</li> 410 avoid this problem, keep static and dynamic data in different buffers.</li>
435 <li><strong>Don&#8217;t call ``glDisable(GL_TEXTURE_2D)``.</strong> This is an O penGL ES 2.0 411 <li><strong>Don&#8217;t call ``glDisable(GL_TEXTURE_2D)``.</strong> This is an O penGL ES 2.0
436 error. Each time it is called, an error messages will appear in Chrome&#8217;s 412 error. Each time it is called, an error messages will appear in Chrome&#8217;s
437 <code>about:gpu</code> tab.</li> 413 <code>about:gpu</code> tab.</li>
438 </ul> 414 </ul>
439 </section></section></section> 415 </section>
440 416
441 {{/partials.standard_nacl_article}} 417 {{/partials.standard_nacl_article}}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698