Platform/GFX/WebGL/Contribute/Extensions: Difference between revisions
mNo edit summary |
mNo edit summary |
||
Line 7: | Line 7: | ||
==General Approach== | ==General Approach== | ||
For the purposes of this page, we will pretend there is a WebGL extension named WEBGL_foo_bar that we're trying to implement. | For the purposes of this page, we will pretend there is a WebGL extension named <code>WEBGL_foo_bar</code> that we're trying to implement. | ||
===Adding the IDL=== | ===Adding the IDL=== | ||
Add the IDL from the spec to {{moz-central|dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl}}, with a new UUID | Add the IDL from the spec to {{moz-central|dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl}}, with a new UUID. | ||
Let's call this interface, nsIWebGLExtensionFooBar. A C++ header will be auto-generated from that IDL, and will define a nsIWebGLExtensionFooBar class. But that's just a base class. Below we'll manually define a WebGLExtensionFooBar (notice: no nsI prefix) class, inheriting nsIWebGLExtensionFooBar. | Let's call this interface, <code>nsIWebGLExtensionFooBar</code>. A C++ header will be auto-generated from that IDL, and will define a <code>nsIWebGLExtensionFooBar</code> class. But that's just a base class. Below we'll manually define a <code>WebGLExtensionFooBar</code> (notice: no nsI prefix) class, inheriting <code>nsIWebGLExtensionFooBar</code>. | ||
===The Goop=== | ===The Goop=== | ||
Edit these files, add goop similar to what there is for WebGLExtensionStandardDerivatives / nsIWebGLExtensionStandardDerivatives: | Edit these files, add goop similar to what there is for <code>WebGLExtensionStandardDerivatives</code> / <code>nsIWebGLExtensionStandardDerivatives</code>: | ||
*{{moz-central|dom/base/nsDOMClassInfo.cpp}} | *{{moz-central|dom/base/nsDOMClassInfo.cpp}} | ||
Line 23: | Line 23: | ||
===The Extension Class=== | ===The Extension Class=== | ||
Edit {{moz-central|content/canvas/src/WebGLExtensions.h}} and define the WebGLExtensionFooBar class, inheriting nsIWebGLExtensionFooBar, similar to what's being done for WebGLExtensionStandardDerivatives. | Edit {{moz-central|content/canvas/src/WebGLExtensions.h}} and define the <code>WebGLExtensionFooBar</code> class, inheriting <code>nsIWebGLExtensionFooBar</code>, similar to what's being done for <code>WebGLExtensionStandardDerivatives</code>. | ||
You shouldn't have to do anything nontrivial there, as this class only has to expose the constants that were already defined in the IDL, so it's already inheriting them. I would implement the (empty) constructor and destructor inline there, to save the hassle of having to add a new .cpp file just for them. | You shouldn't have to do anything nontrivial there, as this class only has to expose the constants that were already defined in the IDL, so it's already inheriting them. I would implement the (empty) constructor and destructor inline there, to save the hassle of having to add a new .cpp file just for them. | ||
===Exposing the Extension=== | ===Exposing the Extension=== | ||
Now let's do the work to actually expose this extension, in WebGL getExtension and getSupportedExtensions methods. | Now let's do the work to actually expose this extension, in WebGL <code>getExtension</code> and <code>getSupportedExtensions</code> methods. | ||
The file to edit is {{moz-central|content/canvas/src/WebGLContext.cpp}} | The file to edit is {{moz-central|content/canvas/src/WebGLContext.cpp}} | ||
The functions exposed to scripts are WebGLContext::GetExtension and WebGLContext::GetSupportedExtensions. They call another internal function that you'll have to edit as well: WebGLContext::IsExtensionSupported. That's where you'll have to decide whether this extension is supported or not by the client. If you have to query the GL_EXTENSIONS string of the underlying OpenGL context, call gl->IsExtensionSupported(enum value). Indeed, we are checking for a list of extensions when we create a OpenGL context, so that subsequent checking for them is really fast. If the OpenGL extensions you need to check for haven't yet been added to the list that we check for, you'll have to edit these files in a straightforward way (search for IsExtensionSupported): | The functions exposed to scripts are <code>WebGLContext::GetExtension</code> and <code>WebGLContext::GetSupportedExtensions</code>. They call another internal function that you'll have to edit as well: <code>WebGLContext::IsExtensionSupported</code>. That's where you'll have to decide whether this extension is supported or not by the client. If you have to query the <code>GL_EXTENSIONS</code> string of the underlying OpenGL context, call <code>gl->IsExtensionSupported(enum value)</code>. Indeed, we are checking for a list of extensions when we create a OpenGL context, so that subsequent checking for them is really fast. If the OpenGL extensions you need to check for haven't yet been added to the list that we check for, you'll have to edit these files in a straightforward way (search for <code>IsExtensionSupported</code>): | ||
*{{moz-central|gfx/gl/GLContext.h}} | *{{moz-central|gfx/gl/GLContext.h}} | ||
Line 38: | Line 38: | ||
===Implementing the Extension=== | ===Implementing the Extension=== | ||
Finally, let's implement what this extension actually does. The spec describes that. | Finally, let's implement what this extension actually does. The spec describes that. | ||
The file you have to edit to do that, is {{moz-central|content/canvas/src/WebGLContextGL.cpp}}, though you might also need to make some more edits to GLContext, or elsewhere in WebGLContext. | The file you have to edit to do that, is {{moz-central|content/canvas/src/WebGLContextGL.cpp}}, though you might also need to make some more edits to <code>GLContext</code>, or elsewhere in <code>WebGLContext</code>. | ||
Sometimes, what this extension does is modify the behavior of some existing methods, it should be straightforward to see what to do there. The only thing is that you'll need to use these new symbolic constants, like TEXTURE_MAX_ANISOTROPY. Rather than trying to use the constants from the extension class, add #defines for them in {{moz-central|gfx/gl/GLDefs.h}}. | Sometimes, what this extension does is modify the behavior of some existing methods, it should be straightforward to see what to do there. The only thing is that you'll need to use these new symbolic constants, like <code>TEXTURE_MAX_ANISOTROPY</code>. Rather than trying to use the constants from the extension class, add #defines for them in {{moz-central|gfx/gl/GLDefs.h}}. | ||
(Notice we use LOCAL_GL_ prefixes there to avoid some conflicts) | (Notice we use <code>LOCAL_GL_</code> prefixes there to avoid some conflicts) | ||
===Adding Tests=== | ===Adding Tests=== |
Revision as of 00:30, 24 March 2012
(Adapted from bug 728354)
Extension drafts for WebGL are found at the Khronos WebGL Extension Registry.
Good models for how to add support for new WebGL extensions are: bug 684853 and bug 728354
General Approach
For the purposes of this page, we will pretend there is a WebGL extension named WEBGL_foo_bar
that we're trying to implement.
Adding the IDL
Add the IDL from the spec to mozilla-central/dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl, with a new UUID.
Let's call this interface, nsIWebGLExtensionFooBar
. A C++ header will be auto-generated from that IDL, and will define a nsIWebGLExtensionFooBar
class. But that's just a base class. Below we'll manually define a WebGLExtensionFooBar
(notice: no nsI prefix) class, inheriting nsIWebGLExtensionFooBar
.
The Goop
Edit these files, add goop similar to what there is for WebGLExtensionStandardDerivatives
/ nsIWebGLExtensionStandardDerivatives
:
- mozilla-central/dom/base/nsDOMClassInfo.cpp
- mozilla-central/dom/base/nsDOMClassInfoClasses.h
- mozilla-central/js/src/xpconnect/src/dom_quickstubs.qsconf
The Extension Class
Edit mozilla-central/content/canvas/src/WebGLExtensions.h and define the WebGLExtensionFooBar
class, inheriting nsIWebGLExtensionFooBar
, similar to what's being done for WebGLExtensionStandardDerivatives
.
You shouldn't have to do anything nontrivial there, as this class only has to expose the constants that were already defined in the IDL, so it's already inheriting them. I would implement the (empty) constructor and destructor inline there, to save the hassle of having to add a new .cpp file just for them.
Exposing the Extension
Now let's do the work to actually expose this extension, in WebGL getExtension
and getSupportedExtensions
methods.
The file to edit is mozilla-central/content/canvas/src/WebGLContext.cpp
The functions exposed to scripts are WebGLContext::GetExtension
and WebGLContext::GetSupportedExtensions
. They call another internal function that you'll have to edit as well: WebGLContext::IsExtensionSupported
. That's where you'll have to decide whether this extension is supported or not by the client. If you have to query the GL_EXTENSIONS
string of the underlying OpenGL context, call gl->IsExtensionSupported(enum value)
. Indeed, we are checking for a list of extensions when we create a OpenGL context, so that subsequent checking for them is really fast. If the OpenGL extensions you need to check for haven't yet been added to the list that we check for, you'll have to edit these files in a straightforward way (search for IsExtensionSupported
):
Implementing the Extension
Finally, let's implement what this extension actually does. The spec describes that.
The file you have to edit to do that, is mozilla-central/content/canvas/src/WebGLContextGL.cpp, though you might also need to make some more edits to GLContext
, or elsewhere in WebGLContext
.
Sometimes, what this extension does is modify the behavior of some existing methods, it should be straightforward to see what to do there. The only thing is that you'll need to use these new symbolic constants, like TEXTURE_MAX_ANISOTROPY
. Rather than trying to use the constants from the extension class, add #defines for them in mozilla-central/gfx/gl/GLDefs.h.
(Notice we use LOCAL_GL_
prefixes there to avoid some conflicts)
Adding Tests
Unfortunately, odds are fairly high that we don't have a test case for this particular extension! It would be very useful to write one, and even more useful to write one that can be added to the conformance test suite.
Other Remarks
- General info about getting started with Gfx hacking: Platform/GFX/Contribute
- Test your code by running the WebGL conformance test suite. (compare to a test run without your patch)
- Or as a mozilla mochitest: (assuming that you are in your mozilla-central directory, and that obj-firefox-debug is your object directory)
TEST_PATH=content/canvas/test/webgl/test_webgl_conformance_test_suite.html make -C obj-firefox-debug/ mochitest-plain
- Or as a mozilla mochitest: (assuming that you are in your mozilla-central directory, and that obj-firefox-debug is your object directory)