-
Notifications
You must be signed in to change notification settings - Fork 702
Expand file tree
/
Copy pathindex.html
More file actions
4608 lines (3947 loc) · 260 KB
/
Copy pathindex.html
File metadata and controls
4608 lines (3947 loc) · 260 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>WebGL Specification</title>
<meta name="generator" content="BBEdit 9.1">
<link rel="stylesheet" type="text/css" href="../../../resources/Khronos-WD.css" />
<script src="../../../resources/jquery-1.3.2.min.js" type="application/javascript"></script>
<script src="../../../resources/generateTOC.js" type="application/javascript"></script>
</head>
<body onload="generateTOC(document.getElementById('toc'))">
<!--begin-logo-->
<div class="head">
<div class="left">
<p>
<a href="http://webgl.org/">
<img alt=WebGL width=240 height=100 src="../../../resources/WebGL-Logo.png"/>
</a>
</p>
</div>
<div class="right">
<p>
<a href="http://khronos.org/">
<img alt=Khronos width=336 height=80 src="../../../resources/Khronos_100px_June18.png"/>
</a>
</p>
</div>
</div>
<div style="clear: both;"></div>
<!--end-logo-->
<h1>WebGL Specification</h1>
<h2 class="no-toc">Editor's Draft <span id="LastEditDate"></span></h2>
<dl>
<dt>This version:
<dd>
<a href="https://www.khronos.org/registry/webgl/specs/latest/1.0/">
https://www.khronos.org/registry/webgl/specs/latest/1.0/
</a>
<br>
<a href="https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl">
<b>WebIDL:</b> https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
</a>
</dd>
<dt>Latest version:
<dd>
<a href="https://www.khronos.org/registry/webgl/specs/latest/1.0/">
https://www.khronos.org/registry/webgl/specs/latest/1.0/
</a>
<br>
<a href="https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl">
<b>WebIDL:</b> https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
</a>
</dd>
<dt>Previous version:
<dd>
<a href="https://www.khronos.org/registry/webgl/specs/1.0.3/">
https://www.khronos.org/registry/webgl/specs/1.0.3/
</a>
<br>
<a href="https://www.khronos.org/registry/webgl/specs/1.0.3/webgl.idl">
<b>WebIDL:</b> https://www.khronos.org/registry/webgl/specs/1.0.3/webgl.idl
</a>
</dd>
<dt>Editors:
<dd>
<a href="mailto:dino@apple.com">Dean Jackson</a>
<a href="http://www.apple.com/">(Apple Inc.)</a>
</dd>
<dd>
<a href="mailto:jgilbert@mozilla.com">Jeff Gilbert</a>
<a href="https://www.mozilla.org/">(Mozilla Corp.)</a>
</dd>
</dl>
<span style="font-size: x-small; font-style: oblique">Copyright © 2015 Khronos Group</span>
<hr />
<h2 class="no-toc">Abstract</h2>
<p>
This specification describes an additional rendering context and support
objects for the
<a href="https://www.w3.org/TR/html5/scripting-1.html#the-canvas-element"
title="HTML 5 Canvas Element">
HTML 5 <span class="prop-name">canvas</span> element <a href="#refsCANVAS">[CANVAS]</a>.
</a>
This context allows rendering using an API that conforms closely to the OpenGL ES 2.0 API.
</p>
<h2 class="no-toc">Status of this document</h2>
<!--begin-status-->
<p>
This document is an editor's draft. Do not cite this document as other than work in
progress.
</p>
<!--end-status-->
<h2 class="no-toc">Feedback</h2>
<p>
Public discussion of this specification is welcome on
the <a href="mailto:public_webgl@khronos.org">public_webgl@khronos.org</a> mailing list
(<a href="http://www.khronos.org/webgl/public-mailing-list/">instructions</a>, <a href="https://www.khronos.org/webgl/public-mailing-list/archives/">archives</a>).
</p>
<p>
Please file bugs against the specification or its conformance tests in
the <a href="https://github.com/KhronosGroup/WebGL/issues">issue tracker</a>. Pull requests
are welcome against the <a href="https://github.com/KhronosGroup/WebGL">Github
repository</a>.
</p>
<h2 class="no-toc">Table of contents</h2>
<div id="toc"></div>
<h2>Introduction</h2>
<div class="note">
<p>
WebGL™ is an immediate mode 3D rendering API designed for the
web. It is derived from OpenGL® ES 2.0, and provides similar
rendering functionality, but in an HTML context. WebGL is
designed as a rendering context for the HTML Canvas element.
The HTML Canvas provides a destination for programmatic
rendering in web pages, and allows for performing that rendering
using different rendering APIs. The only such interface
described as part of the Canvas specification is the 2D canvas
rendering context, CanvasRenderingContext2D. This document
describes another such interface, WebGLRenderingContext, which
presents the WebGL API.
</p>
<p>
The immediate mode nature of the API is a divergence from most
web APIs. Given the many use cases of 3D graphics, WebGL
chooses the approach of providing flexible primitives that can
be applied to any use case. Libraries can provide an API on top
of WebGL that is more tailored to specific areas, thus adding a
convenience layer to WebGL that can accelerate and simplify development.
However, because of its OpenGL ES 2.0 heritage, it should be
straightforward for developers familiar with modern desktop
OpenGL or OpenGL ES 2.0 development to transition to WebGL
development.
</p>
</div>
<h3>Conventions</h3>
<p>
Many functions described in this document contain links to OpenGL ES
man pages. While every effort is made to make these pages match the
OpenGL ES 2.0 specification <a href="#refsGLES20">[GLES20]</a>,
they may contain errors. In the case of a contradiction, the OpenGL
ES 2.0 specification is the final authority.
</p>
<p>
The remaining sections of this document are intended to be read in conjunction
with the OpenGL ES 2.0 specification (2.0.25 at the time of this writing, available
from the <a href="http://www.khronos.org/registry/gles/">Khronos OpenGL ES API Registry</a>).
Unless otherwise specified, the behavior of each method is defined by the
OpenGL ES 2.0 specification. This specification may diverge from OpenGL ES 2.0
in order to ensure interoperability or security, often defining areas that
OpenGL ES 2.0 leaves implementation-defined. These differences are summarized in the
<a href="#webgl_gl_differences">Differences Between WebGL and OpenGL ES 2.0</a> section.
</p>
<!-- ======================================================================================================= -->
<h2>Context Creation and Drawing Buffer Presentation</h2>
<p>
Before using the WebGL API, the author must obtain a <code>WebGLRenderingContext</code>
object for a given HTMLCanvasElement <a href="#refsCANVAS">[CANVAS]</a> or
OffscreenCanvas <a href="#refsOFFSCREENCANVAS">[OFFSCREENCANVAS]</a> as described
below. This object is used to manage OpenGL state and render to the drawing buffer, which
must be created at the time of context creation.
</p>
<!-- ======================================================================================================= -->
<h3>Context Creation</h3>
<p>
Each <code>WebGLRenderingContext</code> has an
associated <b><a name="context-canvas">canvas</a></b>, set upon creation, which is
a <em>canvas</em> <a href="#refsCANVAS">[CANVAS]</a> or <em>offscreen
canvas</em> <a href="#refsOFFSCREENCANVAS">[OFFSCREENCANVAS]</a>.
</p>
<p>
Each <code>WebGLRenderingContext</code> has <b><a name="context-creation-parameters">context
creation parameters</a></b>, set upon creation, in
a <a href="#WEBGLCONTEXTATTRIBUTES"><code>WebGLContextAttributes</code></a> object.
</p>
<p>
Each <code>WebGLRenderingContext</code> has <b><a name="actual-context-parameters">actual
context parameters</a></b>, set each time the drawing buffer is created, in
a <a href="#WEBGLCONTEXTATTRIBUTES"><code>WebGLContextAttributes</code></a> object.
</p>
<p>
Each <code>WebGLRenderingContext</code> has a <b><a name="webgl-context-lost-flag">webgl
context lost flag</a></b>, which is initially unset.
</p>
<p>
When the <code>getContext()</code> method of a <code>canvas</code> element
or <code>offscreen canvas</code> object is to return a new object for
the <em>contextId</em> <code>webgl</code> <a href="#refsCANVASCONTEXTS">[CANVASCONTEXTS]</a>,
the user agent must perform the following steps:
<ol class="nestedlist">
<li> Create a new <code>WebGLRenderingContext</code> object, <em>context</em>.
<li> Let <em>context's</em> <a href="#context-canvas">canvas</a> be the canvas or offscreen
canvas the <code>getContext()</code> method is associated with.
<li> Create a new <code>WebGLContextAttributes</code> object, <em>contextAttributes</em>.
<li> If <code>getContext()</code> was invoked with a second argument, <em>options</em>, set
the attributes of <em>contextAttributes</em> from those specified in <em>options</em>.
<li> <a href="#create-a-drawing-buffer">Create a <em>drawing buffer</em></a> using the settings
specified in <em>contextAttributes</em>, and associate the <em>drawing buffer</em>
with <em>context</em>.
<li> If drawing buffer creation failed, perform the following steps:
<ol class="nestedlist">
<li> <a href="#fire-a-webgl-context-creation-error">Fire a WebGL context creation
error</a> at <em>canvas</em>.
<li> Return null and terminate these steps.
</ol>
<li> Create a new <code>WebGLContextAttributes</code> object, <em>actualAttributes</em>.
<li> Set the attributes of <em>actualAttributes</em> based on the properties of the newly
created drawing buffer.
<li> Set <em>context's</em> <a href="#context-creation-parameters">context creation
parameters</a> to <em>contextAttributes</em>.
<li> Set <em>context's</em> <a href="#actual-context-parameters">actual context
parameters</a> to <em>actualAttributes</em>.
<li> Return <em>context</em>.
</ol>
</p>
<div class="note">
<p>
The canvas context type 'experimental-webgl' has historically been used to provide access to
WebGL implementations which are not yet complete or conformant.
</p>
</div>
<p>
If the user agent supports both the <code>webgl</code> and <code>experimental-webgl</code>
canvas context types, they shall be treated as aliases. For example, if a call
to <code>getContext('webgl')</code> successfully creates a WebGLRenderingContext, a subsequent
call to <code>getContext('experimental-webgl')</code> shall return the same context object.
</p>
<!-- ======================================================================================================= -->
<h3><a name="THE_DRAWING_BUFFER">The Drawing Buffer</a></h3>
<p>
The drawing buffer into which the API calls are rendered shall be defined upon creation of
the WebGLRenderingContext object. The following description defines how
to <b><a name="create-a-drawing-buffer">create a drawing buffer</a></b>.
</p>
<p>
The table below shows all the buffers which make up the drawing buffer, along with their
minimum sizes and whether they are defined or not by default. The size of this drawing
buffer shall be determined by the <code>width</code> and <code>height</code> attributes of
the HTMLCanvasElement or OffscreenCanvas. The table below also shows the value to which
these buffers shall be cleared when first created, when the size is changed, or after
presentation when the <code>preserveDrawingBuffer</code> context creation attribute
is <code>false</code>.
</p>
<table class="foo">
<tr><th>Buffer</th><th>Clear value</th><th>Minimum size</th><th>Defined by default?</th></tr>
<tr><td>Color</td><td>(0, 0, 0, 0)</td><td>8 bits per component</td><td>yes</td></tr>
<tr><td>Depth</td><td>1.0</td><td>16 bit integer</td><td>yes</td></tr>
<tr><td>Stencil</td><td>0</td><td>8 bits</td><td>no</td></tr>
</table>
<br>
<p>
<code>HTMLCanvasElement.width</code> and <code>.height</code> values less than 1 are treated as 1.
A 0x0 canvas will yield a 1x1 drawingBufferWidth/Height.
</p>
<p>
If the requested width or height cannot be satisfied, either when the drawing buffer is first
created or when the <code>width</code> and <code>height</code> attributes of the
<code>HTMLCanvasElement</code> or <code>OffscreenCanvas</code> are changed, a drawing buffer
with smaller dimensions shall be created. The dimensions actually used are implementation
dependent and there is no guarantee that a buffer with the same aspect ratio will be
created. The actual drawing buffer size can be obtained from
the <code>drawingBufferWidth</code> and <code>drawingBufferHeight</code> attributes.
</p>
<p>
A WebGL implementation must not perform any automatic scaling of the size of the drawing
buffer on high-definition displays. The context's <code>drawingBufferWidth</code>
and <code>drawingBufferHeight</code> must match the canvas's <code>width</code>
and <code>height</code> attributes as closely as possible, modulo implementation-dependent
constraints.
</p>
<div class="note">
<p>
The constraint above does not change the amount of space the canvas element consumes on
the web page, even on a high-definition display. The
canvas's <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#attr-canvas-width">intrinsic
dimensions</a> <a href="#refsCANVAS">[CANVAS]</a> equal the size of its coordinate
space, with the numbers interpreted in CSS pixels, and CSS pixels
are <a href="http://www.w3.org/TR/CSS21/syndata.html#length-units">resolution-independent</a> <a href="#refsCSS">[CSS]</a>.
</p>
<p>
A WebGL application can achieve a 1:1 ratio between drawing buffer pixels and on-screen
pixels on high-definition displays by examining properties
like <code>window.devicePixelRatio</code>, scaling the canvas's <code>width</code>
and <code>height</code> by that factor, and setting its CSS width and height to the
original width and height. An application can simulate the effect of running on a
higher-resolution display simply by scaling up the canvas's <code>width</code>
and <code>height</code> properties.
</p>
</div>
<p>
The optional <a href="#WEBGLCONTEXTATTRIBUTES">WebGLContextAttributes</a> object may be used
to change whether or not the buffers are defined. It can also be used to define whether the
color buffer will include an alpha channel. If defined, the alpha channel is used by the
HTML compositor to combine the color buffer with the rest of the page. The
WebGLContextAttributes object is only used on the first call to
<code>getContext</code>. No facility is provided to change the attributes of the drawing
buffer after its creation.
</p>
<p>
The <code>depth</code>, <code>stencil</code> and <code>antialias</code> attributes, when set
to true, are requests, not requirements. The WebGL implementation should make a best effort
to honor them. When any of these attributes is set to false, however, the WebGL
implementation must not provide the associated functionality. Combinations of attributes not
supported by the WebGL implementation or graphics hardware shall not cause a failure to
create a WebGLRenderingContext. The <a href="#actual-context-parameters">actual context
parameters</a> are set to the attributes of the created drawing buffer. The
<code>alpha</code>, <code>premultipliedAlpha</code> and <code>preserveDrawingBuffer</code>
attributes must be obeyed by the WebGL implementation.
</p>
<p>
WebGL presents its drawing buffer to the HTML page compositor immediately before a
compositing operation, but only if at least one of the following has occurred since the
previous compositing operation:
<ul>
<li>Context creation</li>
<li>Canvas resize</li>
<li>
<code>clear</code>, <code>drawArrays</code>, or <code>drawElements</code> has been
called while the drawing buffer is the currently bound framebuffer
</li>
</ul>
</p>
<p>
Before the drawing buffer is presented for compositing the implementation shall ensure that
all rendering operations have been flushed to the drawing buffer. By default, after
compositing the contents of the drawing buffer shall be cleared to their default values, as
shown in the table above.
</p>
<p>
This default behavior can be changed by setting the <code>preserveDrawingBuffer</code>
attribute of the <a href="#WEBGLCONTEXTATTRIBUTES">WebGLContextAttributes</a> object. If
this flag is true, the contents of the drawing buffer shall be preserved until the author
either clears or overwrites them. If this flag is false, attempting to perform operations
using this context as a source image after the rendering function has returned can lead to
undefined behavior. This includes <code>readPixels</code> or <code>toDataURL</code> calls,
using this context as the source image of another context's <code>texImage2D</code> or
<code>drawImage</code> call, or creating
an <a href="https://html.spec.whatwg.org/multipage/webappapis.html#imagebitmap">ImageBitmap</a> <a href="#refsHTML">[HTML]</a>
from this context's canvas.
</p>
<div class="note">
<p>
While it is sometimes desirable to preserve the drawing buffer, it can cause significant
performance loss on some platforms. Whenever possible this flag should remain false
and other techniques used. Techniques like synchronous drawing buffer access (e.g.,
calling <code>readPixels</code> or <code>toDataURL</code> in the same function that
renders to the drawing buffer) can be used to get the contents of the drawing buffer.
If the author needs to render to the same drawing buffer over a series of calls, a
<a href="#WEBGL_FRAMEBUFFER">Framebuffer Object</a> can be used.
</p>
<p>
Implementations may optimize away the required implicit clear operation of the Drawing
Buffer as long as a guarantee can be made that the author cannot gain access to buffer
contents from another process. For instance, if the author performs an explicit
clear then the implicit clear is not needed.
</p>
</div>
<!-- ======================================================================================================= -->
<h3><a name="WEBGL_VIEWPORT">The WebGL Viewport</a></h3>
<p>
OpenGL manages a rectangular viewport as part of its state which defines the placement of
the rendering results in the drawing buffer. Upon creation of WebGL
context <em>context</em>, the viewport is initialized to a rectangle with origin at (0, 0)
and width and height equal to (context.drawingBufferWidth, context.drawingBufferHeight).
</p>
<p>
A WebGL implementation <em>shall not</em> affect the state of the OpenGL viewport in response to
resizing of the canvas element.
</p>
<div class="example">
Note that if a WebGL program does not contain logic to set the viewport, it will not properly
handle the case where the canvas is resized. The following ECMAScript example illustrates how
a WebGL program might resize the canvas programmatically.
<pre>
var canvas = document.getElementById('canvas1');
var gl = canvas.getContext('webgl');
canvas.width = newWidth;
canvas.height = newHeight;
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
</pre>
</div>
<p>
<em>Rationale</em>: automatically setting the viewport will interfere with applications that set
it manually. Applications are expected to use <code>onresize</code> handlers to respond to
changes in size of the canvas and set the OpenGL viewport in turn.
</p>
<!-- ======================================================================================================= -->
<h3><a name="PREMULTIPLIED_ALPHA">Premultiplied Alpha, Canvas APIs and texImage2D</a></h3>
<p>
The OpenGL API allows the application to modify the blending modes used during rendering,
and for this reason allows control over how alpha values in the drawing buffer are
interpreted; see the <code>premultipliedAlpha</code> parameter in
the <a href="#WEBGLCONTEXTATTRIBUTES">WebGLContextAttributes</a> section.
</p>
<p>
The HTML Canvas APIs <code>toDataURL</code> and <code>drawImage</code> must respect
the <code>premultipliedAlpha</code> context creation parameter. When <code>toDataURL</code>
is called against a Canvas into which WebGL content is being rendered, then if the requested
image format does not specify premultiplied alpha and the WebGL context has
the <code>premultipliedAlpha</code> parameter set to true, then the pixel values must be
de-multiplied; i.e., the color channels are divided by the alpha channel. <b>Note</b> that
this operation is lossy.
</p>
<p>
Passing a WebGL-rendered Canvas to the <code>drawImage</code> method
of <code>CanvasRenderingContext2D</code> may or may not need to modify the the rendered
WebGL content during the drawing operation, depending on the premultiplication needs of the
<code>CanvasRenderingContext2D</code> implementation.
</p>
<p>
When passing a WebGL-rendered Canvas to the <code>texImage2D</code> API, then depending on
the setting of the <code>premultipliedAlpha</code> context creation parameter of the passed
canvas and the <code>UNPACK_PREMULTIPLY_ALPHA_WEBGL</code> pixel store parameter of the
destination WebGL context, the pixel data may need to be changed to or from premultiplied
form.
</p>
<!-- ======================================================================================================= -->
<h2>WebGL Resources</h2>
<p>
OpenGL manages several types of resources as part of its state. These are identified
by integer object names and are obtained from OpenGL by various creation calls.
In contrast WebGL represents these resources as DOM objects. Each object is derived
from the WebGLObject interface. Currently supported resources are:
textures, buffers (i.e., VBOs), framebuffers, renderbuffers, shaders and
programs. The WebGLRenderingContext interface has a method to create a
WebGLObject subclass for each type. Data from the underlying graphics library are
stored in these objects and are fully managed by them.
The DOM object will stay alive not only as long as the author retains an explicit reference
to it, but also as long as it is in use by the underlying graphics library.
When the DOM object is destroyed, it marks its resources for deletion.
If authors wish to mark an object for deletion prior to the DOM object being destroyed,
they may explicitly call the respective delete function. (e.g. deleteTexture)
</p>
<!-- ======================================================================================================= -->
<h2>Security</h2>
<p>
</p>
<!-- ======================================================================================================= -->
<h3>Resource Restrictions</h3>
<p>
WebGL resources such as textures and vertex buffer objects (VBOs) must always
contain initialized data, even if they were created without initial user
data values. Creating a resource without initial values is commonly used to
reserve space for a texture or VBO, which is then modified using <code>texSubImage</code> or
<code>bufferSubData</code> calls. If initial data is not provided to these calls, the WebGL
implementation must initialize their contents to 0; depth resources must be cleared to
the default 1.0 clear depth. This may require creating a zeroed temporary buffer the size
of a requested VBO, so that it can be initialized correctly. All other forms of loading
data into a texture or VBO involve either ArrayBuffers or DOM objects such as images, and
are therefore already required to be initialized.
</p>
<p>
When WebGL resources are accessed by shaders through a call such as
<code>drawElements</code> or <code>drawArrays</code>, the WebGL implementation must ensure
that the shader cannot access either out of bounds or uninitialized data.
See <a href="#ATTRIBS_AND_RANGE_CHECKING">Enabled Vertex Attributes and Range Checking</a>
for restrictions which must be enforced by the WebGL implementation.
</p>
<!-- ======================================================================================================= -->
<h3><a name="ORIGIN_RESTRICTIONS">Origin Restrictions</a></h3>
<p>
In order to prevent information leakage, WebGL disallows uploading as textures:
<ul>
<li> Image or video elements whose origin is not the same as the origin of the Document that
contains the WebGLRenderingContext's canvas element
<li> Canvas elements whose bitmap's <i>origin-clean</i> flag is set to false
<li> ImageBitmap objects whose bitmap's <i>origin-clean</i> flag is set to false
</ul>
</p>
<p>
If the <code>texImage2D</code> or <code>texSubImage2D</code> method is called with otherwise
correct arguments and an <code>HTMLImageElement</code>, <code>HTMLVideoElement</code>,
<code>HTMLCanvasElement</code>, or <code>ImageBitmap</code> violating these restrictions, a
<code>SECURITY_ERR</code> exception must be thrown.
</p>
<div class="note">
<p>
WebGL necessarily imposes stronger restrictions on the use of cross-domain media than other
APIs such as the 2D canvas rendering context, because shaders can be used to indirectly
deduce the contents of textures which have been uploaded to the GPU.
</p>
<p>
WebGL applications may utilize images and videos that come from other domains, with the
cooperation of the server hosting the media,
using <a href="http://www.w3.org/TR/cors/">Cross-Origin Resource
Sharing</a> <a href="#refsCORS">[CORS]</a>. In order to use such media, the application
needs to explicitly request permission to do so, and the server needs to explicitly grant
permission. Successful CORS-enabled fetches of image and video elements from other
domains <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/origin-0.html#origin-0">cause
the origin of these elements</a> to be set to that of the containing
Document <a href="#refsHTML">[HTML]</a>.
</p>
<div class="example">
<p>
The following ECMAScript example demonstrates how to issue a CORS request for an
image coming from another domain. The image is fetched from the server without any
credentials, i.e., cookies.
</p>
<pre>
var gl = ...;
var image = new Image();
// The onload handler should be set to a function which uploads the HTMLImageElement
// using texImage2D or texSubImage2D.
image.onload = ...;
image.crossOrigin = "anonymous";
image.src = "http://other-domain.com/image.jpg";
</pre>
</div>
<p>
Note that these rules imply that the <i>origin-clean</i> flag for a canvas rendered
using WebGL will never be set to false.
</p>
<p>
For more information on issuing CORS requests for image and video elements, consult:
<ul>
<li> <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#cors-settings-attribute">CORS settings attributes</a> <a href="#refsHTML">[HTML]</a>
<li> <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#the-img-element">The <code>img</code> element</a> <a href="#refsHTML">[HTML]</a>
<li> <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#media-elements">Media elements</a> <a href="#refsHTML">[HTML]</a>
</ul>
</p>
</div>
<!-- ======================================================================================================= -->
<h3><a name="SUPPORTED_GLSL_CONSTRUCTS">Supported GLSL Constructs</a></h3>
<p>
A WebGL implementation must only accept shaders which conform to The OpenGL ES Shading
Language, Version 1.00 <a href="#refsGLES20GLSL">[GLES20GLSL]</a>, and which do not exceed
the minimum functionality mandated in Sections 4 and 5 of Appendix A. In particular:
<ul>
<li> A shader referencing state variables or functions that are available in other versions
of GLSL, such as that found in versions of OpenGL for the desktop, must not be allowed
to load. </li>
<li> <code>for</code> loops must conform to the structural constraints in Appendix A. </li>
<li> <code>while</code> and <code>do-while</code> loops are disallowed, since they are
optional in Appendix A.</li>
<li> Appendix A mandates certain forms of indexing of arrays; for example, within fragment
shaders, indexing is only mandated with a <i>constant-index-expression</i>
(see <a href="#refsGLES20GLSL">[GLES20GLSL]</a> for the definition of this term). In
the WebGL API, only the forms of indexing mandated in Appendix A are supported. </li>
</ul>
</p>
<p>
In addition to the reserved identifiers in the aforementioned specification, identifiers
starting with "webgl_" and "_webgl_" are reserved for use by WebGL. A shader which declares
a function, variable, structure name, or structure field starting with these prefixes must
not be allowed to load.
</p>
<p>
WebGL 1.0 implementations must additionally support the line continuation character '\' in
shaders.
</p>
<!-- ======================================================================================================= -->
<h3>Defense Against Denial of Service</h3>
<div class="note">
<p>
It is possible to create, either intentionally or unintentionally, combinations of shaders and
geometry that take an undesirably long time to render. This issue is analogous to that of
long-running scripts, for which user agents already have safeguards. However, long-running draw
calls can cause loss of interactivity for the entire window system, not just the user agent.
</p>
<p>
In the general case it is not possible to impose limits on the structure of incoming shaders to
guard against this problem. Experimentation has shown that even very strict structural limits
are insufficient to prevent long rendering times, and such limits would prevent shader authors
from implementing common algorithms.
</p>
<p>
User agents should implement safeguards to prevent excessively long rendering times and
associated loss of interactivity. Suggested safeguards include:
</p>
<ul>
<li> Splitting up draw calls with large numbers of elements into smaller draw calls.
<li> Timing individual draw calls and forbidding further rendering from a page if a certain
timeout is exceeded.
<li> Using any watchdog facilities available at the user level, graphics API level, or operating
system level to limit the duration of draw calls.
<li> Separating the graphics rendering of the user agent into a distinct operating system
process which can be terminated and restarted without losing application state.
</ul>
<p>
The supporting infrastructure at the OS and graphics API layer is expected to improve over time,
which is why the exact nature of these safeguards is not specified.
</p>
</div>
<!-- ======================================================================================================= -->
<h3><a name="OUT_OF_RANGE_ARRAY_ACCESSES">Out-of-Range Array Accesses</a></h3>
<p>
Shaders must not be allowed to read or write array elements that lie outside of the application's own
data. This includes any variable of array type, as well as vector or matrix types such as
<code>vec3</code> or <code>mat4</code> when accessed using array subscripting syntax. If
detected during compilation, such accesses must generate an error and prevent the shader
from compiling. Otherwise, at runtime, out-of-range reads shall return any of the following values:
</p>
<ul>
<li>Values from anywhere within the storage accessible to the program.</li>
<li>Zero values, or (0,0,0,x) vectors for vector reads where x is a
valid value represented in the type of the vector components and may
be any of:
<ul>
<li>0, 1, or the maximum representable positive integer value, for
signed or unsigned integer components</li>
<li>0.0 or 1.0, for floating-point components</li>
</ul>
</li>
</ul>
<p>
Out-of-range writes are either discarded or modify an
unspecified value in the storage accessible to the program.
</p>
<div class="note">
<p>
This behavior replicates that defined in <a href="#refsKHRROBUSTACCESS">[KHRROBUSTACCESS]</a>.
</p>
<p>
See <a href="#SUPPORTED_GLSL_CONSTRUCTS">Supported GLSL Constructs</a> for more information
on restrictions which simplify static analysis of the array indexing operations in shaders.
</p>
</div>
<!-- ======================================================================================================= -->
<h2>DOM Interfaces</h2>
<p>
This section describes the interfaces and functionality added to the
DOM to support runtime access to the functionality described above.
</p>
<!-- ======================================================================================================= -->
<h3>Types</h3>
<p>
The following types are used in all interfaces in the following section.
</p>
<pre class="idl">
typedef unsigned long GLenum;
typedef boolean GLboolean;
typedef unsigned long GLbitfield;
typedef byte GLbyte; /* 'byte' should be a signed 8 bit type. */
typedef short GLshort;
typedef long GLint;
typedef long GLsizei;
typedef long long GLintptr;
typedef long long GLsizeiptr;
// Ideally the typedef below would use 'unsigned byte', but that doesn't currently exist in Web IDL.
typedef octet GLubyte; /* 'octet' should be an unsigned 8 bit type. */
typedef unsigned short GLushort;
typedef unsigned long GLuint;
typedef unrestricted float GLfloat;
typedef unrestricted float GLclampf;
// The power preference settings are documented in the WebGLContextAttributes
// section of the specification.
enum WebGLPowerPreference { "default", "low-power", "high-performance" };
</pre>
<!-- ======================================================================================================= -->
<h3><a name="WEBGLCONTEXTATTRIBUTES">WebGLContextAttributes</a></h3>
<p>
The <code>WebGLContextAttributes</code> dictionary contains drawing surface attributes and
is passed as the second parameter to <code>getContext</code>.
</p>
<!-- The capitalization rules here match those of the crossOrigin
attribute, which was added to HTMLMediaElement on behalf of
WebGL. -->
<pre class="idl">dictionary <dfn data-dfn-type="dictionary" id="WebGLContextAttributes">WebGLContextAttributes</dfn> {
boolean alpha = true;
boolean depth = true;
boolean stencil = false;
boolean antialias = true;
boolean premultipliedAlpha = true;
boolean preserveDrawingBuffer = false;
WebGLPowerPreference powerPreference = "default";
boolean failIfMajorPerformanceCaveat = false;
boolean desynchronized = false;
};</pre>
<h4>Context creation parameters</h4>
<p>
The following list describes each attribute in the WebGLContextAttributes object and its
use. The default value for each attribute is shown above. The default value is used either
if no second parameter is passed to <code>getContext</code>, or if a user object is passed
which has no attribute of the given name.
</p>
<dl>
<dt><span class=prop-value>alpha</span></dt>
<dd>
If the value is true, the drawing buffer has an alpha channel for the purposes of
performing OpenGL destination alpha operations and compositing with the page. If the
value is false, no alpha buffer is available.
</dd>
<dt> <span class=prop-value>depth</span>
<dd>
If the value is true, the drawing buffer has a depth buffer of at least 16 bits. If
the value is false, no depth buffer is available.
</dd>
<dt> <span class=prop-value>stencil</span>
<dd>
If the value is true, the drawing buffer has a stencil buffer of at least 8 bits. If
the value is false, no stencil buffer is available.
</dd>
<dt> <span class=prop-value>antialias</span>
<dd>
If the value is true and the implementation supports antialiasing the drawing buffer
will perform antialiasing using its choice of technique (multisample/supersample)
and quality. If the value is false or the implementation does not support
antialiasing, no antialiasing is performed.
</dd>
<dt> <span class=prop-value>premultipliedAlpha</span>
<dd>
If the value is true the page compositor will assume the drawing buffer contains
colors with premultiplied alpha. If the value is false the page compositor will
assume that colors in the drawing buffer are not premultiplied. This flag is ignored
if the <strong>alpha</strong> flag is
false. See <a href="#PREMULTIPLIED_ALPHA">Premultiplied Alpha</a> for more
information on the effects of the <code>premultipliedAlpha</code> flag.
</dd>
<dt> <span class=prop-value>preserveDrawingBuffer</span>
<dd>
If false, once the drawing buffer is presented as described in
the<a href="#THE_DRAWING_BUFFER">Drawing Buffer</a> section, the contents of the
drawing buffer are cleared to their default values. All elements of the drawing
buffer (color, depth and stencil) are cleared. If the value is true the buffers
will not be cleared and will preserve their values until cleared or overwritten by
the author.
<blockquote>
<em>
On some hardware setting the <code>preserveDrawingBuffer</code> flag
to true can have significant performance implications.
</em>
</blockquote>
</dd>
<dt><span class=prop-value>powerPreference</span></dt>
<dd>
<p>
Provides a hint to the user agent indicating what configuration of GPU is suitable
for this WebGL context. This may influence which GPU is used in a system with
multiple GPUs. For example, a dual-GPU system might have one GPU that consumes
less power at the expense of rendering performance. Note that this property is
only a hint and a WebGL implementation may choose to ignore it.
</p>
<p>
WebGL implementations use context lost and restored events to regulate power and
memory consumption, <em>regardless</em> of the value of this attribute.
</p>
<p>
The allowed values are:
</p>
<dl><dd>
<p>
<em>default</em>
</p>
<p>
Let the user agent decide which GPU configuration is most suitable. This is the
default value.
</p>
<p>
<em>high-performance</em>
</p>
<p>
Indicates a request for a GPU configuration that prioritizes rendering
performance over power consumption.
Developers are encouraged to only specify this value if they believe it
is absolutely necessary, since it may significantly decrease battery life on
mobile devices.
Implementations may decide to initially respect this request and,
after some time, lose the context and restore a new context ignoring the
request.
</p>
<div class="note">
<p>
Applications that request <code>high-performance</code> should test and
maintain robust context loss handling, as User Agents are very likely to decide
to lose background <code>high-performance</code> contexts.
</p>
</div>
<p>
<em>low-power</em>
</p>
<p>
Indicates a request for a GPU configuration that prioritizes power saving over
rendering performance. Generally, content should use this if it is unlikely to
be constrained by drawing performance; for example, if it renders only one frame
per second, draws only relatively simple geometry with simple shaders, or uses a
small HTML canvas element. Developers are encouraged to use this value if their
content allows, since it may significantly improve battery life on mobile
devices.
</p>
</dd></dl>
</dd>
<dt> <span class=prop-value>failIfMajorPerformanceCaveat</span></dt>
<dd>
If the value is true, context creation will fail if the implementation determines
that the performance of the created WebGL context would be dramatically lower
than that of a native application making equivalent OpenGL calls. This could happen
for a number of reasons, including:
<ul>
<li>An implementation might switch to a software rasterizer if the user's GPU
driver is known to be unstable.
<li>An implementation might require reading back the framebuffer from GPU memory
to system memory before compositing it with the rest of the page,
significantly reducing performance.
</ul>
Applications that don't require high performance should leave this parameter at its
default value of <code>false</code>. Applications that require high performance may
set this parameter to <code>true</code>, and if context creation fails then the
application may prefer to use a fallback rendering path such as a 2D canvas context.
Alternatively the application can retry WebGL context creation with this parameter
set to <code>false</code>, with the knowledge that a reduced-fidelity rendering mode
should be used to improve performance.
</dd>
<dt> <span class=prop-value>desynchronized</span></dt>
<dd>
<p>
If the value is true, then the user agent may optimize the rendering of the canvas
to reduce the latency, as measured from input events to rasterization, by
desynchronizing the canvas paint cycle from the event loop, bypassing the ordinary
user agent rendering algorithm, or both. Insofar as this mode involves bypassing the
usual paint mechanisms, rasterization, or both, it might introduce visible tearing
artifacts.
</p>
<div class="note">
<p>
The user agent usually renders on a buffer which is not being displayed, quickly
swapping it and the one being scanned out for presentation; the former buffer is
called back buffer and the latter <i>front buffer</i>. A popular technique for
reducing latency is called front buffer rendering, also known as <i>single
buffer</i> rendering, where rendering happens inparallel and racily with the
scanning out process. This technique reduces the latency at the price of
potentially introducing tearing artifacts and can be used to implement in total or
part of the <code>desynchronized</code>
boolean. <a href="#refsMULTIPLEBUFFERING">[MULTIPLEBUFFERING]</a>
</p>
<p>
The <code>desynchronized</code> boolean can be useful when implementing certain
kinds of applications, such as drawing applications, where the latency between
input and rasterization is critical.
</p>
</div>
</dd>
</dl>
<div class="example">
Here is an ECMAScript example which passes a WebGLContextAttributes argument
to <code>getContext</code>. It assumes the presence of a canvas element named "canvas1" on the
page.
<pre>
var canvas = document.getElementById('canvas1');
var context = canvas.getContext('webgl',
{ antialias: false,
stencil: true });
</pre>
</div>
<!-- ======================================================================================================= -->
<h3>WebGLObject</h3>
<p>
The <code>WebGLObject</code> interface is the parent interface for all GL objects.
</p>
<p>
Each <code>WebGLObject</code> has
an <b><a name="webgl-object-invalidated-flag">invalidated</a></b> flag, which is initially unset.
</p>
<pre class="idl">[Exposed=(Window,Worker)]
interface <dfn data-dfn-type="interface" id="WebGLObject">WebGLObject</dfn> {
};</pre>
<!-- ======================================================================================================= -->
<h3>WebGLBuffer</h3>
<p>
The <code>WebGLBuffer</code> interface represents an OpenGL Buffer Object. The
underlying object is created as if by calling glGenBuffers
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.9">OpenGL ES 2.0 §2.9</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenBuffers.xml">man page</a>)</span>
, bound as if by calling glBindBuffer
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.9">OpenGL ES 2.0 §2.9</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBindBuffer.xml">man page</a>)</span>
and marked for deletion as if by calling glDeleteBuffers
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.9">OpenGL ES 2.0 §2.9</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteBuffers.xml">man page</a>)</span>
.
</p>
<pre class="idl">[Exposed=(Window,Worker)]
interface <dfn data-dfn-type="interface" id="WebGLBuffer">WebGLBuffer</dfn> : WebGLObject {
};</pre>
<!-- ======================================================================================================= -->
<h3><a name="WEBGL_FRAMEBUFFER">WebGLFramebuffer</a></h3>
<p>
The <code>WebGLFramebuffer</code> interface represents an OpenGL Framebuffer Object. The
underlying object is created as if by calling glGenFramebuffers
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-4.4.1">OpenGL ES 2.0 §4.4.1</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenFramebuffers.xml">man page</a>)</span>
, bound as if by calling glBindFramebuffer
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-4.4.1">OpenGL ES 2.0 §4.4.1</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBindFramebuffer.xml">man page</a>)</span>
and marked for deletion as if by calling glDeleteFramebuffers
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-4.4.1">OpenGL ES 2.0 §4.4.1</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteFramebuffers.xml">man page</a>)</span>
.
</p>
<pre class="idl">[Exposed=(Window,Worker)]
interface <dfn data-dfn-type="interface" id="WebGLFramebuffer">WebGLFramebuffer</dfn> : WebGLObject {
};</pre>
<!-- ======================================================================================================= -->
<h3>WebGLProgram</h3>
<p>
The <code>WebGLProgram</code> interface represents an OpenGL Program Object. The
underlying object is created as if by calling glCreateProgram
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.10.3">OpenGL ES 2.0 §2.10.3</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glCreateProgram.xml">man page</a>)</span>
, used as if by calling glUseProgram
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.10.3">OpenGL ES 2.0 §2.10.3</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUseProgram.xml">man page</a>)</span>
and marked for deletion as if by calling glDeleteProgram
<span class="gl-spec">(<a href="http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.10.3">OpenGL ES 2.0 §2.10.3</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteProgram.xml">man page</a>)</span>
.
</p>