WebAssembly Migration Guide
(P)NaCl Deprecation Announcements
Given the momentum of cross-browser WebAssembly support, we plan to focus our
native code efforts on WebAssembly going forward and plan to remove support for
PNaCl in Q1 2018 (except for Chrome Apps). We believe that the vibrant
ecosystem around WebAssembly
makes it a better fit for new and existing high-performance
web apps and that usage of PNaCl is sufficiently low to warrant deprecation.
We also recently announced the deprecation Q1 2018 of
Chrome Apps
outside of ChromeOS.
For the majority of (P)NaCl uses cases we recommend transitioning
from the NaCl SDK to Emscripten.
Migration is likely to be reasonably straightforward
if your application is portable to Linux, uses
SDL, or POSIX APIs.
While direct support for NaCl / Pepper APIs in not available,
we’ve attempted to list Web API equivalents.
For more challenging porting cases, please reach out on
native-client-discuss@googlegroups.com
API Migration
We’ve outlined here the status of Web Platform substitutes for each
of the APIs exposed to (P)NaCl.
Additionally, the table lists the library or option in Emscripten
that offers the closest substitute.
We expect to add shared memory threads support to WebAssembly in 2017,
as threads are crucial to matching (P)NaCl’s most interesting use
cases. Migration items which assume forthcoming threads support
are marked below. If your application’s flow control relies heavily on blocking
APIs, you may also find threads support is required for convenient porting.
While we’ve tried to be accurate in this table,
there are no doubt errors or omissions.
If you encounter one, please reach out to us on
native-client-discuss@googlegroups.com
PPAPI
PPB_Audio
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
x |
SDL (partial) |
GAP (partial) - AudioWorkletNode ROUGHLY equivalent |
Still being standardized. |
| GetCurrentConfig |
|
SDL |
AudioContext.* (gets back settings passed in) |
|
| StartPlayback |
|
SDL |
AudioBufferSourceNode.start |
|
| StopPlayback |
|
SDL |
AudioBufferSourceNode.stop |
|
PPB_AudioBuffer
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetTimestamp |
|
SDL |
AudioBufferSourceNode.start (parameter) |
Passed in each time instead of attached to the buffer. |
| SetTimestamp |
|
SDL |
AudioBufferSourceNode.start (parameter) |
|
| GetSampleRate |
|
SDL |
AudioBuffer.sampleRate |
|
| GetSampleSize |
|
GAP |
GAP - WebAudio only uses 32-bit float, PPAPI does 16-bit int. |
PPAPI theoretically supports multiple sampling sizes. In practice, it only supports 16-bit samples. Unfortunately, developers have requested 16-bit sample sizes to save on memory use. |
| GetNumberOfChannels |
|
SDL |
AudioBuffer.numberOfChannels |
|
| GetDataBuffer |
|
SDL |
AudioBuffer.getChannelData |
|
| GetBufferSize |
|
SDL |
AudioBuffer.length |
|
PPB_AudioConfig
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| CreateStereo16Bit |
|
GAP |
GAP - Only 32-bit float samples supported |
|
| GetSampleRate |
|
SDL |
AudioContext.sampleRate |
|
| GetSampleFrameCount |
|
SDL |
AudioBuffer.length |
|
| RecommendSampleRate |
|
SDL |
AudioContext.sampleRate (from default construct) |
An AudioContext will have the preferred sampling rate by default. |
| RecommendSampleFrameCount |
|
GAP |
GAP - No mechanism to get a recomended buffer size. |
|
PPB_Console
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Log |
|
utime |
console.log/warn/error/... |
|
| LogWithSource |
|
GAP |
GAP |
PPAPI provides a way to override the source filename and line number in a console message.
(Though JS API provides way to style text). |
PPB_Core
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| getTime |
|
utime |
new Date().getTime() |
|
| getTimeTicks |
|
utime |
new Date().getTime() |
|
| IsMainThread |
|
GAP |
window.document !== undefined |
|
| CallOnMainThread |
|
GAP |
Worker.postMessage + Atomics.wait |
Equivalent synchronization can be built. |
PPB_FileIO
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
FS (partial) |
FileReader / FileWrite (Entry.createReader / Entry.createWriter) |
Create and open are used differently, but the pieces are of equal power. |
| Open |
|
FS (partial) |
FileReader / FileWrite (Entry.createReader / Entry.createWriter) |
|
| Query |
|
FS (partial) |
Entry.getMetadata |
|
| Touch |
|
FS (partial) |
GAP (partial) - No direct equivalent, but no access time either. |
Modify time can be bumped by writing. |
| Read |
|
FS (partial) |
Entry.getFile + Blob.slice + FileReader.getBinaryData |
Note, this API requires an extra copy to get a read into linear memory, and may be worse than that if Blob slices are not optimizes to use mmap. |
| Write |
|
FS (partial) |
FileWriter.seek + FileWriter.write 'write*' Events |
|
| SetLength |
|
FS (partial) |
FileWriter.truncate + 'write*' Events |
|
| Flush |
|
GAP |
GAP - No equivalent, no way to flush. |
|
| Close |
|
FS (partial) |
No equivalent, open files and directories are implicitly closed. |
|
| ReadToArray |
|
GAP |
GAP - No equivalent. |
Allows multiple subrange reads in parallel. |
PPB_FileRef
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
FS (partial) |
Entry.getFile(..., {create:true}) |
|
| GetFileSystemType |
|
FS (partial) |
FileSystem.type |
|
| GetName |
|
FS (partial) |
Entry.name |
|
| GetPath |
|
FS (partial) |
Entry.fullPath |
|
| GetParent |
|
FS (partial) |
Entry.getParent |
|
| MakeDirectory |
|
FS (partial) |
Entry.getDirectory(..., {create:true}) |
|
| Touch |
|
FS (partial) |
GAP (partial) - No direct equivalent, but no access time either. |
Modify time can be bumped by writing. |
| Delete |
|
FS (partial) |
Entry.remove |
|
| Rename |
|
FS (partial) |
Entry.moveTo |
|
| Query |
|
GAP |
Entry.getMetadata |
GAP - JS API has file size and last modified date, but doesn't have creation date and last accessed date. |
| ReadDirectoryEntries |
|
FS (partial) |
Directory.readEntries |
|
PPB_FileSystem
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
FS (partial) |
window.requestFileSystem |
JS API does both in one step |
| Open |
|
GAP |
window.requestFileSystem |
GAP - Filesystems API is chrome only. IndexedDB has additional performance limitations around subrange writes. |
| GetType |
|
GAP |
FileSystem.type |
|
PPB_Fullscreen
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| IsFullScreen |
|
html5.h |
Document.fullscreenEnabled |
|
| SetFullscreen |
|
html5.h |
Document.requestFullscreen |
|
| GetScreenSize |
|
html5.h |
Document.exitFullscreen |
|
PPB_Gamepad
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Sample |
|
SDL |
Gamepad.* |
GAP - PPAPI exposes a timestamp value, but the JS API doesn't provide this (though it is spec'd). |
PPB_Graphics2D
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
Canvas.getContext('2d') |
|
| Describe |
|
SDL |
Canvas.clientWidth + Canvas.clientHeight |
|
| PaintImageData |
|
SDL |
CanvasRenderingContext2d.putImageData |
|
| Scroll |
|
GAP |
CanvasRenderingContext2d.scrollIntoView |
GAP (partial) - Not an exact match (might have to resort to getImageData + putImageData which will be slow). Not a cross-browser standard. |
| ReplaceContents |
|
SDL |
CanvasRenderingContext2d.drawImage |
|
| Flush |
|
GAP |
GAP - Only returning to the event loop triggers the flush. |
|
| SetScale |
|
SDL |
CanvasRenderingContext2d.scale |
|
| GetScale |
|
SDL |
CanvasRenderingContext2d.currentTransform |
|
| SetLayerTransform |
|
SDL |
CanvasRenderingContext2d.setTransform
CanvasRenderingContext2d.scale
CanvasRenderingContext2d.translate |
|
PPB_Graphics3D
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetAttribMaxValue |
|
GAP |
GAP - Canvas.getContext lets you set booleans requesting depth / stencil buffers of certain sizes, but does not have a way to query what's possible (or get anything other than on or off for each) |
|
| Create |
|
SDL |
Canvas.getContext |
|
| GetAttribs |
|
SDL |
WebGLRenderingContext.getContextAttributes |
|
| SetAttribs |
|
SDL |
Canvas.getContext(.., OPTIONS) |
|
| GetError |
|
SDL |
WebGLRenderingContext.getError |
|
| ResizeBuffers |
|
SDL |
Canvas.width = w; Canvas.height = h; |
|
| SwapBuffers |
|
GAP |
GAP - No way to explicitly flip a frame, must return to the event loop. |
|
PPB_ImageData
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetNativeImageDataFormat |
|
SDL |
ImageData mandates RGBA order |
|
| IsImageDataFormatSupported |
|
SDL |
ImageData mandates RGBA order |
|
| Create |
|
SDL |
CanvasRenderingContext2d.createImageData |
|
| Describe |
|
SDL |
ImageData never has a stride |
|
| Map |
|
SDL |
ImageData.data |
|
| Unmap |
|
SDL |
ImageData.data |
|
PPB_InputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| RequestInputEvents |
|
SDL |
No direct equivalent |
The lack of this feature is probably less relevant as JS / Wasm runs on the main thread and can more cheaply filter events without incurring a cross process round-trip. |
| RequestFilteringInputEvents |
|
SDL |
mouse* key* wheel* touch* composition* Events |
|
| |
|
SDL |
Element.addEventListener |
|
| ClearInputEventRequest |
|
SDL |
Element.removeEventListener |
|
| GetType |
|
SDL |
Event class descendants |
|
| GetTimeStamp |
|
SDL |
Event.timeStamp |
|
| GetModifiers |
|
SDL |
*Event.altKey/shiftKey/metaKey/ctrlKey |
|
PPB_MouseInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
MouseEvent |
|
| GetButton |
|
SDL |
MouseEvent.button |
|
| GetPosition |
|
SDL |
MouseEvent.client*/page*/offset* |
|
| GetClickCount |
|
SDL |
dblclick' vs 'mousedown' Events |
|
| GetMovement |
|
SDL |
MouseEvent.movement* |
|
PPB_WheelInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
WheelEvent |
|
| GetDelta |
|
SDL |
WheelEvent.delta* |
|
| GetTicks |
|
GAP |
GAP - deltaMode kinda of contains this info, but incompletely. |
|
| GetScrollByPage |
|
GAP |
GAP - deltaMode kinda of contains this info, but incompletely. |
|
PPB_KeyboardInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
KeyboardEvent |
|
| GetKeyCode |
|
SDL |
KeyboardEvent.keyCode |
|
| GetCharacterText |
|
SDL |
KeyboardEvent.key |
|
| GetCode |
|
SDL |
KeyboardEvent.code |
|
PPB_TouchInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
TouchEvent |
|
| AddTouchPoint |
|
SDL |
TouchEvent.touches.push |
|
| GetTouchCount |
|
SDL |
TouchEvent.touches.length |
|
| GetTouchByIndex |
|
SDL |
TouchEvent.touches[i] |
|
| GetTouchById |
|
SDL |
Touch.indentifer (to figure this out yourself) |
|
PPB_IMEInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
CompositionEvent |
|
| GetText |
|
GAP |
CompositionEvent.data |
|
| GetSegmentNumber |
|
GAP |
GAP - No direct equivalent |
|
| GetSegmentOffset |
|
GAP |
GAP - No direct equivalent |
|
| GetTargetSegment |
|
GAP |
GAP - No direct equivalent |
|
| GetSelection |
|
GAP |
GAP - No direct equivalent |
|
PPB_Instance
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| BindGraphics |
|
SDL |
Canvas.getContext (moot as binding is automatic). |
|
| IsFullFrame |
|
GAP |
GAP - No equivalent to mime type handlers. |
NaCl apps can be registered to handle a particular mime type and own the whole document. |
PPB_MediaStreamAudioTrack
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Configure |
|
GAP |
GAP - No equivalent |
|
| GetAttrib |
|
GAP |
MediaStreamSettings.channelCount |
|
| |
|
GAP |
MediaStreamSettings.sampleSize |
|
| |
|
GAP |
MediaStreamSettings.sampleRate |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION |
|
| GetId |
|
GAP |
MediaStream.id |
|
| HasEnded |
|
GAP |
MediaStream.ended |
|
| GetBuffer |
|
GAP |
GAP - No equivalent |
|
| RecycleBuffer |
|
GAP |
GAP - No equivalent |
|
| Close |
|
GAP |
GAP - No equivalent |
|
PPB_MediaStreamVideoTrack
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
GAP - No equivalent |
Ability to create synthetic stream. |
| Configure |
|
GAP |
GAP - No equivalent |
|
| GetAttrib |
|
GAP |
MediaStreamSettings.width |
|
| |
|
GAP |
MediaStreamSettings.height |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_BUFFERED_FRAMES |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT |
|
| GetId |
|
GAP |
MediaStream.id |
|
| HasEnded |
|
GAP |
MediaStream.ended |
|
| GetFrame |
|
GAP |
GAP - No equivalent |
|
| RecycleFrame |
|
GAP |
GAP - No equivalent |
|
| Close |
|
GAP |
GAP - No equivalent |
|
| GetEmptyFrame |
|
GAP |
GAP - No equivalent |
|
| PutFrame |
|
GAP |
GAP - No equivalent |
|
PPB_MessageLoop
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| GetForMainThread |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| GetCurrent |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| AttachToCurrentThread |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| Run |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| PostWork |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| PostQuit |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
PPB_Messaging
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| PostMessage |
|
N/A |
Window.postMessage |
|
| RegisterMessageHandler |
|
N/A |
Window.addEventListener |
|
| UnregisterMessageHandler |
|
N/A |
Window.removeEventListener |
|
PPB_MouseCursor
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| SetCursor |
|
SDL |
Element.style.cursor |
Same set of stock cursors are supported.
Custom cursors can be done with url(..).
Dynamic custom cursors can be done with data URIs.
CSS3 supports specifying the hotspot. |
PPB_MouseLock
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| LockMouse |
|
SDL |
Element.requestPointerLock |
|
| UnlockMouse |
|
SDL |
Element.exitPointerLock |
|
PPB_OpenGLES2
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Several Methods |
|
OpenGLES |
Close to WebGL 1.0 in functionality. |
|
| |
x |
|
GAP - Without offscreen canvas, rendering must be done on the main thread. |
|
PPB_TextInputController
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| SetTextInputType |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
Some developers would like to either be able to hint in this fashion, or preferrably the ability to intercept and display IME events / output inline inside a canvas. |
| UpdateCaretPosition |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
|
| CancelCompositionText |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
|
| UpdateSurroundingText |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
|
PPB_URLLoader
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
new XMLHttpRequest(); |
|
| Open |
|
embind |
XMLHttpRequest.open |
|
| FollowRedirect |
|
embind |
Request.redirect |
|
| |
|
GAP |
GAP - No XMLHTTPRequest equivalent |
|
| GetUploadProgress |
|
embind |
XMLHttpRequest 'progress' Event |
|
| |
|
GAP |
GAP - No Fetch API equivalent |
|
| GetDownloadProgress |
|
embind |
XMLHttpRequest 'progress' Event |
|
| |
|
GAP |
GAP - No Fetch API equivalent |
|
| GetResponseInfo |
|
embind |
XMLHttpRequest.getAllResponseHeaders |
|
| |
|
embind |
Fetch Response.* |
|
| ReadResponseBody |
|
embind |
XMLHttpRequest.response |
|
| |
|
embind |
Body.* (Response is a Body) |
|
| FinishStreamingToFile |
|
embind |
GAP - No direct equivalent |
XMLHttpRequest and Fetch both assume streaming to memory, rather than directly to a storage. |
| Close |
|
embind |
XMLHttpRequest.abort |
|
| |
|
GAP |
GAP - No Fetch API equivalent |
|
PPB_URLRequestInfo
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
XMLHttpRequest |
|
| |
|
embind |
Fetch Request |
No way to stream to a file. |
| SetProperty |
|
GAP |
GAP - No direct equivalent for XMLHttpRequest |
XMLHttpRequest doesn't provide direct ways to per-request limit following redirects, stream to a file, set referrer or credentials policy. |
| |
|
embind |
Request.* |
|
| AppendDataToBody |
|
embind |
XMLHttpRequest.send |
GAP - Both must have the whole body, rather than a chunk. |
| |
|
embind |
fetch(.., options:body) |
|
| AppendFileToBody |
|
GAP |
GAP - No direct equivalent |
|
| |
|
N/A |
<form> |
You can also read with FileReader and upload, but that's more like AppendDataToBody |
PPB_URLResponseInfo
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetProperty |
|
embind |
XMLHttpRequest.getAllResponseHeaders + others |
|
| |
|
embind |
Fetch Response.* |
|
| GetBodyAsFileRef |
|
embind |
Fetch Response (Body) .blob() |
Assumes storage layer optimizes transfer. |
PPB_Var
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| VarFromUtf8 |
|
embind |
TextDecoder.decode |
|
| VarToUtf8 |
|
embind |
TextEncoder.encode |
|
| VarFromResource |
|
N/A |
N/A |
|
| VarToResource |
|
N/A |
N/A |
|
PPB_VarArray
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Get |
|
embind |
Array[i] |
|
| Set |
|
embind |
Array[i] = x |
|
| GetLength |
|
embind |
Array.length |
|
| SetLength |
|
embind |
Array.length = n |
|
PPB_VarArrayBuffer
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
new ArrayBuffer(n) |
|
| ByteLength |
|
embind |
ArrayBuffer.byteLength |
|
| Map |
|
GAP |
GAP - No direct equivalent |
Asm.js / Wasm modules are unable to map regions of an ArrayBuffer other than their single linear memory heap.
Future multiple memories or memory mapping might improve this. |
| Unmap |
|
GAP |
GAP - No direct equivalent |
|
PPB_VarDictionary
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
{} |
|
| Get |
|
embind |
<Object>[i] |
|
| Set |
|
embind |
<Object>[i] = x |
|
| Delete |
|
embind |
delete <Object>[i] |
|
| HasKey |
|
embind |
x in <Object> |
|
| GetKeys |
|
embind |
for (k in <Object>) {} |
No literal equivalent, but it can be built. |
PPB_VideoDecoder
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
GAP - No equivalent |
|
| Initialize |
|
GAP |
GAP - No equivalent |
|
| Decode |
|
GAP |
GAP - No equivalent |
|
| GetPicture |
|
GAP |
GAP - No equivalent |
|
| RecyclePicture |
|
GAP |
GAP - No equivalent |
|
| Flush |
|
GAP |
GAP - No equivalent |
|
| Reset |
|
GAP |
GAP - No equivalent |
|
PPB_VideoEncoder
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
GAP - No equivalent |
Overlap with MediaRecorder API, but not exact. |
| GetSupportedProfiles |
|
GAP |
GAP - No equivalent |
|
| Initialize |
|
GAP |
GAP - No equivalent |
|
| GetFramesRequired |
|
GAP |
GAP - No equivalent |
|
| GetFrameCodedSize |
|
GAP |
GAP - No equivalent |
|
| GetVideoFrame |
|
GAP |
GAP - No equivalent |
|
| Encode |
|
GAP |
GAP - No equivalent |
|
| GetBitstreamBuffer |
|
GAP |
GAP - No equivalent |
|
| RecycleBitstreamBuffer |
|
GAP |
GAP - No equivalent |
|
| RequestEncodingParametersChange |
|
GAP |
GAP - No equivalent |
|
| Close |
|
GAP |
GAP - No equivalent |
|
PPB_VideoFrame
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetTimestamp |
|
GAP |
GAP - No equivalent |
|
| SetTimestamp |
|
GAP |
GAP - No equivalent |
|
| GetFormat |
|
GAP |
GAP - No equivalent |
|
| GetSize |
|
GAP |
GAP - No equivalent |
|
| GetDataBuffer |
|
GAP |
GAP - No equivalent |
|
| GetDataBufferSize |
|
GAP |
GAP - No equivalent |
|
PPB_View
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetRect |
|
embind |
Element.getBoundingClientRect |
|
| IsFullscreen |
|
embind |
Document.fullScreenEnabled |
Pertains to document instead of just single element. |
| IsVisible |
|
embind |
IntersectionObserver |
|
| IsPageVisible |
|
embind |
document.visibilityState |
|
| GetClipRect |
|
embind |
IntersectionObserver |
|
| GetDeviceScale |
|
embind |
window.devicePixelRatio |
|
| GetCSSScale |
|
embind |
<Element>.getBoundingClientRect().width / <Element>.offsetWidth |
|
| GetScrollOffset |
|
embind |
<Element>.scrollTop / <Element>.scrollLeft |
|
PPB_WebSocket
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
WebSocket.WebSocket |
|
| Connect |
|
GAP |
WebSocket.WebSocket(url, ...)
WebSocket 'open' Event |
|
| Close |
|
GAP |
WebSocket.close |
|
| ReceiveMessage |
|
GAP |
WebSocket 'message' Event
WebSocket 'error' Event
WebSocket 'close' Event |
|
| SendMessage |
|
GAP |
WebSocket.send |
|
| GetBufferedAmount |
|
GAP |
WebSocket.bufferedAmount |
|
| GetCloseCode |
|
GAP |
CloseEvent.code |
|
| GetCloseReason |
|
GAP |
CloseEvent.reason |
|
| GetCloseWasClean |
|
GAP |
CloseEvent.wasClean |
|
| GetExtensions |
|
GAP |
WebSocket.extensions |
|
| GetProtocol |
|
GAP |
WebSocket.protocol |
|
| GetReadyState |
|
GAP |
WebSocket.readyState |
|
| GetURL |
|
GAP |
WebSocket.url |
|
PPP_Graphics3D
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Graphics3DContextLost |
|
SDL |
Canvas 'webglcontextlost' Event |
|
PPP_InputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| HandleInputEvent |
|
SDL |
Element.addEventListener |
|
PPP_Instance
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| DidCreate |
|
N/A |
<Element>[key] |
General DOM access lets you fish out tag attributes |
| DidDestroy |
|
N/A |
N/A |
Not triggered for NaCl |
| DidChangeView |
|
N/A |
Element 'resize' Event |
|
| DidChangeFocus |
|
N/A |
Element 'focus', 'focusin', 'focusout' Events |
|
| HandleDocumentLoad |
|
N/A |
GAP - No way to register as a mime type handler |
NaCl modules via apps + a manifest entry can be set up to handle particular mime types. |
PPP_MessageHandler
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| HandleMessage |
|
embind |
MessagePort 'message' Event
Window 'message' Event |
|
| HandleBlockingMessage |
|
N/A |
GAP - No direct equivalent |
Similar synchronization can be done off main thread with Atomics.wait. This was added to support emulation of synchronous plugin APIs. |
PPP_Messaging
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| HandleMessage |
|
embind |
MessagePort 'message' Event
Window 'message' Event |
|
PPP_MouseLock
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| MouseLockLost |
|
SDL |
Element 'pointerlockchange', 'pointerlockerror' Events |
|
IRT
PPB_Audio
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
x |
SDL (partial) |
GAP (partial) - AudioWorkletNode ROUGHLY equivalent |
Still being standardized. |
| GetCurrentConfig |
|
SDL |
AudioContext.* (gets back settings passed in) |
|
| StartPlayback |
|
SDL |
AudioBufferSourceNode.start |
|
| StopPlayback |
|
SDL |
AudioBufferSourceNode.stop |
|
PPB_AudioBuffer
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetTimestamp |
|
SDL |
AudioBufferSourceNode.start (parameter) |
Passed in each time instead of attached to the buffer. |
| SetTimestamp |
|
SDL |
AudioBufferSourceNode.start (parameter) |
|
| GetSampleRate |
|
SDL |
AudioBuffer.sampleRate |
|
| GetSampleSize |
|
GAP |
GAP - WebAudio only uses 32-bit float, PPAPI does 16-bit int. |
PPAPI theoretically supports multiple sampling sizes. In practice, it only supports 16-bit samples. Unfortunately, developers have requested 16-bit sample sizes to save on memory use. |
| GetNumberOfChannels |
|
SDL |
AudioBuffer.numberOfChannels |
|
| GetDataBuffer |
|
SDL |
AudioBuffer.getChannelData |
|
| GetBufferSize |
|
SDL |
AudioBuffer.length |
|
PPB_AudioConfig
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| CreateStereo16Bit |
|
GAP |
GAP - Only 32-bit float samples supported |
|
| GetSampleRate |
|
SDL |
AudioContext.sampleRate |
|
| GetSampleFrameCount |
|
SDL |
AudioBuffer.length |
|
| RecommendSampleRate |
|
SDL |
AudioContext.sampleRate (from default construct) |
An AudioContext will have the preferred sampling rate by default. |
| RecommendSampleFrameCount |
|
GAP |
GAP - No mechanism to get a recomended buffer size. |
|
PPB_Console
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Log |
|
utime |
console.log/warn/error/... |
|
| LogWithSource |
|
GAP |
GAP |
PPAPI provides a way to override the source filename and line number in a console message.
(Though JS API provides way to style text). |
PPB_Core
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| getTime |
|
utime |
new Date().getTime() |
|
| getTimeTicks |
|
utime |
new Date().getTime() |
|
| IsMainThread |
|
GAP |
window.document !== undefined |
|
| CallOnMainThread |
|
GAP |
Worker.postMessage + Atomics.wait |
Equivalent synchronization can be built. |
PPB_FileIO
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
FS (partial) |
FileReader / FileWrite (Entry.createReader / Entry.createWriter) |
Create and open are used differently, but the pieces are of equal power. |
| Open |
|
FS (partial) |
FileReader / FileWrite (Entry.createReader / Entry.createWriter) |
|
| Query |
|
FS (partial) |
Entry.getMetadata |
|
| Touch |
|
FS (partial) |
GAP (partial) - No direct equivalent, but no access time either. |
Modify time can be bumped by writing. |
| Read |
|
FS (partial) |
Entry.getFile + Blob.slice + FileReader.getBinaryData |
Note, this API requires an extra copy to get a read into linear memory, and may be worse than that if Blob slices are not optimizes to use mmap. |
| Write |
|
FS (partial) |
FileWriter.seek + FileWriter.write 'write*' Events |
|
| SetLength |
|
FS (partial) |
FileWriter.truncate + 'write*' Events |
|
| Flush |
|
GAP |
GAP - No equivalent, no way to flush. |
|
| Close |
|
FS (partial) |
No equivalent, open files and directories are implicitly closed. |
|
| ReadToArray |
|
GAP |
GAP - No equivalent. |
Allows multiple subrange reads in parallel. |
PPB_FileRef
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
FS (partial) |
Entry.getFile(..., {create:true}) |
|
| GetFileSystemType |
|
FS (partial) |
FileSystem.type |
|
| GetName |
|
FS (partial) |
Entry.name |
|
| GetPath |
|
FS (partial) |
Entry.fullPath |
|
| GetParent |
|
FS (partial) |
Entry.getParent |
|
| MakeDirectory |
|
FS (partial) |
Entry.getDirectory(..., {create:true}) |
|
| Touch |
|
FS (partial) |
GAP (partial) - No direct equivalent, but no access time either. |
Modify time can be bumped by writing. |
| Delete |
|
FS (partial) |
Entry.remove |
|
| Rename |
|
FS (partial) |
Entry.moveTo |
|
| Query |
|
GAP |
Entry.getMetadata |
GAP - JS API has file size and last modified date, but doesn't have creation date and last accessed date. |
| ReadDirectoryEntries |
|
FS (partial) |
Directory.readEntries |
|
PPB_FileSystem
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
FS (partial) |
window.requestFileSystem |
JS API does both in one step |
| Open |
|
GAP |
window.requestFileSystem |
GAP - Filesystems API is chrome only. IndexedDB has additional performance limitations around subrange writes. |
| GetType |
|
GAP |
FileSystem.type |
|
PPB_Fullscreen
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| IsFullScreen |
|
html5.h |
Document.fullscreenEnabled |
|
| SetFullscreen |
|
html5.h |
Document.requestFullscreen |
|
| GetScreenSize |
|
html5.h |
Document.exitFullscreen |
|
PPB_Gamepad
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Sample |
|
SDL |
Gamepad.* |
GAP - PPAPI exposes a timestamp value, but the JS API doesn't provide this (though it is spec'd). |
PPB_Graphics2D
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
Canvas.getContext('2d') |
|
| Describe |
|
SDL |
Canvas.clientWidth + Canvas.clientHeight |
|
| PaintImageData |
|
SDL |
CanvasRenderingContext2d.putImageData |
|
| Scroll |
|
GAP |
CanvasRenderingContext2d.scrollIntoView |
GAP (partial) - Not an exact match (might have to resort to getImageData + putImageData which will be slow). Not a cross-browser standard. |
| ReplaceContents |
|
SDL |
CanvasRenderingContext2d.drawImage |
|
| Flush |
|
GAP |
GAP - Only returning to the event loop triggers the flush. |
|
| SetScale |
|
SDL |
CanvasRenderingContext2d.scale |
|
| GetScale |
|
SDL |
CanvasRenderingContext2d.currentTransform |
|
| SetLayerTransform |
|
SDL |
CanvasRenderingContext2d.setTransform
CanvasRenderingContext2d.scale
CanvasRenderingContext2d.translate |
|
PPB_Graphics3D
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetAttribMaxValue |
|
GAP |
GAP - Canvas.getContext lets you set booleans requesting depth / stencil buffers of certain sizes, but does not have a way to query what's possible (or get anything other than on or off for each) |
|
| Create |
|
SDL |
Canvas.getContext |
|
| GetAttribs |
|
SDL |
WebGLRenderingContext.getContextAttributes |
|
| SetAttribs |
|
SDL |
Canvas.getContext(.., OPTIONS) |
|
| GetError |
|
SDL |
WebGLRenderingContext.getError |
|
| ResizeBuffers |
|
SDL |
Canvas.width = w; Canvas.height = h; |
|
| SwapBuffers |
|
GAP |
GAP - No way to explicitly flip a frame, must return to the event loop. |
|
PPB_ImageData
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetNativeImageDataFormat |
|
SDL |
ImageData mandates RGBA order |
|
| IsImageDataFormatSupported |
|
SDL |
ImageData mandates RGBA order |
|
| Create |
|
SDL |
CanvasRenderingContext2d.createImageData |
|
| Describe |
|
SDL |
ImageData never has a stride |
|
| Map |
|
SDL |
ImageData.data |
|
| Unmap |
|
SDL |
ImageData.data |
|
PPB_InputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| RequestInputEvents |
|
SDL |
No direct equivalent |
The lack of this feature is probably less relevant as JS / Wasm runs on the main thread and can more cheaply filter events without incurring a cross process round-trip. |
| RequestFilteringInputEvents |
|
SDL |
mouse* key* wheel* touch* composition* Events |
|
| |
|
SDL |
Element.addEventListener |
|
| ClearInputEventRequest |
|
SDL |
Element.removeEventListener |
|
| GetType |
|
SDL |
Event class descendants |
|
| GetTimeStamp |
|
SDL |
Event.timeStamp |
|
| GetModifiers |
|
SDL |
*Event.altKey/shiftKey/metaKey/ctrlKey |
|
PPB_MouseInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
MouseEvent |
|
| GetButton |
|
SDL |
MouseEvent.button |
|
| GetPosition |
|
SDL |
MouseEvent.client*/page*/offset* |
|
| GetClickCount |
|
SDL |
dblclick' vs 'mousedown' Events |
|
| GetMovement |
|
SDL |
MouseEvent.movement* |
|
PPB_WheelInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
WheelEvent |
|
| GetDelta |
|
SDL |
WheelEvent.delta* |
|
| GetTicks |
|
GAP |
GAP - deltaMode kinda of contains this info, but incompletely. |
|
| GetScrollByPage |
|
GAP |
GAP - deltaMode kinda of contains this info, but incompletely. |
|
PPB_KeyboardInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
KeyboardEvent |
|
| GetKeyCode |
|
SDL |
KeyboardEvent.keyCode |
|
| GetCharacterText |
|
SDL |
KeyboardEvent.key |
|
| GetCode |
|
SDL |
KeyboardEvent.code |
|
PPB_TouchInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
SDL |
TouchEvent |
|
| AddTouchPoint |
|
SDL |
TouchEvent.touches.push |
|
| GetTouchCount |
|
SDL |
TouchEvent.touches.length |
|
| GetTouchByIndex |
|
SDL |
TouchEvent.touches[i] |
|
| GetTouchById |
|
SDL |
Touch.indentifer (to figure this out yourself) |
|
PPB_IMEInputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
CompositionEvent |
|
| GetText |
|
GAP |
CompositionEvent.data |
|
| GetSegmentNumber |
|
GAP |
GAP - No direct equivalent |
|
| GetSegmentOffset |
|
GAP |
GAP - No direct equivalent |
|
| GetTargetSegment |
|
GAP |
GAP - No direct equivalent |
|
| GetSelection |
|
GAP |
GAP - No direct equivalent |
|
PPB_Instance
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| BindGraphics |
|
SDL |
Canvas.getContext (moot as binding is automatic). |
|
| IsFullFrame |
|
GAP |
GAP - No equivalent to mime type handlers. |
NaCl apps can be registered to handle a particular mime type and own the whole document. |
PPB_MediaStreamAudioTrack
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Configure |
|
GAP |
GAP - No equivalent |
|
| GetAttrib |
|
GAP |
MediaStreamSettings.channelCount |
|
| |
|
GAP |
MediaStreamSettings.sampleSize |
|
| |
|
GAP |
MediaStreamSettings.sampleRate |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION |
|
| GetId |
|
GAP |
MediaStream.id |
|
| HasEnded |
|
GAP |
MediaStream.ended |
|
| GetBuffer |
|
GAP |
GAP - No equivalent |
|
| RecycleBuffer |
|
GAP |
GAP - No equivalent |
|
| Close |
|
GAP |
GAP - No equivalent |
|
PPB_MediaStreamVideoTrack
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
GAP - No equivalent |
Ability to create synthetic stream. |
| Configure |
|
GAP |
GAP - No equivalent |
|
| GetAttrib |
|
GAP |
MediaStreamSettings.width |
|
| |
|
GAP |
MediaStreamSettings.height |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_BUFFERED_FRAMES |
|
| |
|
GAP |
GAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT |
|
| GetId |
|
GAP |
MediaStream.id |
|
| HasEnded |
|
GAP |
MediaStream.ended |
|
| GetFrame |
|
GAP |
GAP - No equivalent |
|
| RecycleFrame |
|
GAP |
GAP - No equivalent |
|
| Close |
|
GAP |
GAP - No equivalent |
|
| GetEmptyFrame |
|
GAP |
GAP - No equivalent |
|
| PutFrame |
|
GAP |
GAP - No equivalent |
|
PPB_MessageLoop
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| GetForMainThread |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| GetCurrent |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| AttachToCurrentThread |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| Run |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| PostWork |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
| PostQuit |
|
N/A |
Mostly moot, workers get an implicit event loop. |
|
PPB_Messaging
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| PostMessage |
|
N/A |
Window.postMessage |
|
| RegisterMessageHandler |
|
N/A |
Window.addEventListener |
|
| UnregisterMessageHandler |
|
N/A |
Window.removeEventListener |
|
PPB_MouseCursor
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| SetCursor |
|
SDL |
Element.style.cursor |
Same set of stock cursors are supported.
Custom cursors can be done with url(..).
Dynamic custom cursors can be done with data URIs.
CSS3 supports specifying the hotspot. |
PPB_MouseLock
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| LockMouse |
|
SDL |
Element.requestPointerLock |
|
| UnlockMouse |
|
SDL |
Element.exitPointerLock |
|
PPB_OpenGLES2
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Several Methods |
|
OpenGLES |
Close to WebGL 1.0 in functionality. |
|
| |
x |
|
GAP - Without offscreen canvas, rendering must be done on the main thread. |
|
PPB_TextInputController
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| SetTextInputType |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
Some developers would like to either be able to hint in this fashion, or preferrably the ability to intercept and display IME events / output inline inside a canvas. |
| UpdateCaretPosition |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
|
| CancelCompositionText |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
|
| UpdateSurroundingText |
|
GAP |
GAP - No equivalent hints to browser about canvas containing input. |
|
PPB_URLLoader
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
new XMLHttpRequest(); |
|
| Open |
|
embind |
XMLHttpRequest.open |
|
| FollowRedirect |
|
embind |
Request.redirect |
|
| |
|
GAP |
GAP - No XMLHTTPRequest equivalent |
|
| GetUploadProgress |
|
embind |
XMLHttpRequest 'progress' Event |
|
| |
|
GAP |
GAP - No Fetch API equivalent |
|
| GetDownloadProgress |
|
embind |
XMLHttpRequest 'progress' Event |
|
| |
|
GAP |
GAP - No Fetch API equivalent |
|
| GetResponseInfo |
|
embind |
XMLHttpRequest.getAllResponseHeaders |
|
| |
|
embind |
Fetch Response.* |
|
| ReadResponseBody |
|
embind |
XMLHttpRequest.response |
|
| |
|
embind |
Body.* (Response is a Body) |
|
| FinishStreamingToFile |
|
embind |
GAP - No direct equivalent |
XMLHttpRequest and Fetch both assume streaming to memory, rather than directly to a storage. |
| Close |
|
embind |
XMLHttpRequest.abort |
|
| |
|
GAP |
GAP - No Fetch API equivalent |
|
PPB_URLRequestInfo
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
XMLHttpRequest |
|
| |
|
embind |
Fetch Request |
No way to stream to a file. |
| SetProperty |
|
GAP |
GAP - No direct equivalent for XMLHttpRequest |
XMLHttpRequest doesn't provide direct ways to per-request limit following redirects, stream to a file, set referrer or credentials policy. |
| |
|
embind |
Request.* |
|
| AppendDataToBody |
|
embind |
XMLHttpRequest.send |
GAP - Both must have the whole body, rather than a chunk. |
| |
|
embind |
fetch(.., options:body) |
|
| AppendFileToBody |
|
GAP |
GAP - No direct equivalent |
|
| |
|
N/A |
<form> |
You can also read with FileReader and upload, but that's more like AppendDataToBody |
PPB_URLResponseInfo
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetProperty |
|
embind |
XMLHttpRequest.getAllResponseHeaders + others |
|
| |
|
embind |
Fetch Response.* |
|
| GetBodyAsFileRef |
|
embind |
Fetch Response (Body) .blob() |
Assumes storage layer optimizes transfer. |
PPB_Var
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| VarFromUtf8 |
|
embind |
TextDecoder.decode |
|
| VarToUtf8 |
|
embind |
TextEncoder.encode |
|
| VarFromResource |
|
N/A |
N/A |
|
| VarToResource |
|
N/A |
N/A |
|
PPB_VarArray
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Get |
|
embind |
Array[i] |
|
| Set |
|
embind |
Array[i] = x |
|
| GetLength |
|
embind |
Array.length |
|
| SetLength |
|
embind |
Array.length = n |
|
PPB_VarArrayBuffer
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
new ArrayBuffer(n) |
|
| ByteLength |
|
embind |
ArrayBuffer.byteLength |
|
| Map |
|
GAP |
GAP - No direct equivalent |
Asm.js / Wasm modules are unable to map regions of an ArrayBuffer other than their single linear memory heap.
Future multiple memories or memory mapping might improve this. |
| Unmap |
|
GAP |
GAP - No direct equivalent |
|
PPB_VarDictionary
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
embind |
{} |
|
| Get |
|
embind |
<Object>[i] |
|
| Set |
|
embind |
<Object>[i] = x |
|
| Delete |
|
embind |
delete <Object>[i] |
|
| HasKey |
|
embind |
x in <Object> |
|
| GetKeys |
|
embind |
for (k in <Object>) {} |
No literal equivalent, but it can be built. |
PPB_VideoDecoder
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
GAP - No equivalent |
|
| Initialize |
|
GAP |
GAP - No equivalent |
|
| Decode |
|
GAP |
GAP - No equivalent |
|
| GetPicture |
|
GAP |
GAP - No equivalent |
|
| RecyclePicture |
|
GAP |
GAP - No equivalent |
|
| Flush |
|
GAP |
GAP - No equivalent |
|
| Reset |
|
GAP |
GAP - No equivalent |
|
PPB_VideoEncoder
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
GAP - No equivalent |
Overlap with MediaRecorder API, but not exact. |
| GetSupportedProfiles |
|
GAP |
GAP - No equivalent |
|
| Initialize |
|
GAP |
GAP - No equivalent |
|
| GetFramesRequired |
|
GAP |
GAP - No equivalent |
|
| GetFrameCodedSize |
|
GAP |
GAP - No equivalent |
|
| GetVideoFrame |
|
GAP |
GAP - No equivalent |
|
| Encode |
|
GAP |
GAP - No equivalent |
|
| GetBitstreamBuffer |
|
GAP |
GAP - No equivalent |
|
| RecycleBitstreamBuffer |
|
GAP |
GAP - No equivalent |
|
| RequestEncodingParametersChange |
|
GAP |
GAP - No equivalent |
|
| Close |
|
GAP |
GAP - No equivalent |
|
PPB_VideoFrame
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetTimestamp |
|
GAP |
GAP - No equivalent |
|
| SetTimestamp |
|
GAP |
GAP - No equivalent |
|
| GetFormat |
|
GAP |
GAP - No equivalent |
|
| GetSize |
|
GAP |
GAP - No equivalent |
|
| GetDataBuffer |
|
GAP |
GAP - No equivalent |
|
| GetDataBufferSize |
|
GAP |
GAP - No equivalent |
|
PPB_View
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetRect |
|
embind |
Element.getBoundingClientRect |
|
| IsFullscreen |
|
embind |
Document.fullScreenEnabled |
Pertains to document instead of just single element. |
| IsVisible |
|
embind |
IntersectionObserver |
|
| IsPageVisible |
|
embind |
document.visibilityState |
|
| GetClipRect |
|
embind |
IntersectionObserver |
|
| GetDeviceScale |
|
embind |
window.devicePixelRatio |
|
| GetCSSScale |
|
embind |
<Element>.getBoundingClientRect().width / <Element>.offsetWidth |
|
| GetScrollOffset |
|
embind |
<Element>.scrollTop / <Element>.scrollLeft |
|
PPB_WebSocket
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
|
GAP |
WebSocket.WebSocket |
|
| Connect |
|
GAP |
WebSocket.WebSocket(url, ...)
WebSocket 'open' Event |
|
| Close |
|
GAP |
WebSocket.close |
|
| ReceiveMessage |
|
GAP |
WebSocket 'message' Event
WebSocket 'error' Event
WebSocket 'close' Event |
|
| SendMessage |
|
GAP |
WebSocket.send |
|
| GetBufferedAmount |
|
GAP |
WebSocket.bufferedAmount |
|
| GetCloseCode |
|
GAP |
CloseEvent.code |
|
| GetCloseReason |
|
GAP |
CloseEvent.reason |
|
| GetCloseWasClean |
|
GAP |
CloseEvent.wasClean |
|
| GetExtensions |
|
GAP |
WebSocket.extensions |
|
| GetProtocol |
|
GAP |
WebSocket.protocol |
|
| GetReadyState |
|
GAP |
WebSocket.readyState |
|
| GetURL |
|
GAP |
WebSocket.url |
|
PPP_Graphics3D
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Graphics3DContextLost |
|
SDL |
Canvas 'webglcontextlost' Event |
|
PPP_InputEvent
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| HandleInputEvent |
|
SDL |
Element.addEventListener |
|
PPP_Instance
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| DidCreate |
|
N/A |
<Element>[key] |
General DOM access lets you fish out tag attributes |
| DidDestroy |
|
N/A |
N/A |
Not triggered for NaCl |
| DidChangeView |
|
N/A |
Element 'resize' Event |
|
| DidChangeFocus |
|
N/A |
Element 'focus', 'focusin', 'focusout' Events |
|
| HandleDocumentLoad |
|
N/A |
GAP - No way to register as a mime type handler |
NaCl modules via apps + a manifest entry can be set up to handle particular mime types. |
PPP_MessageHandler
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| HandleMessage |
|
embind |
MessagePort 'message' Event
Window 'message' Event |
|
| HandleBlockingMessage |
|
N/A |
GAP - No direct equivalent |
Similar synchronization can be done off main thread with Atomics.wait. This was added to support emulation of synchronous plugin APIs. |
PPP_Messaging
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| HandleMessage |
|
embind |
MessagePort 'message' Event
Window 'message' Event |
|
PPP_MouseLock
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| MouseLockLost |
|
SDL |
Element 'pointerlockchange', 'pointerlockerror' Events |
|
PPAPI (Apps)
PPB_HostResolver
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| Resolve |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| GetCanonicalName |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| GetNetAddressCount |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| GetNetAddress |
x |
GAP |
GAP (partial) - No direct equivalent |
|
PPB_NetAddress
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| CreateFromIPv4Address |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| CreateFromIPv6Address |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| GetFamily |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| DescribeAsString |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| DescribeAsIPv4Address |
x |
GAP |
GAP (partial) - No direct equivalent |
|
| DescribeAsIPv6Address |
x |
GAP |
GAP (partial) - No direct equivalent |
|
PPB_NetworkList
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetCount |
x |
GAP |
GAP - No direct equivalent |
|
| GetName |
x |
GAP |
GAP - No direct equivalent |
|
| GetType |
x |
GAP |
GAP - No direct equivalent |
|
| GetState |
x |
GAP |
GAP - No direct equivalent |
|
| GetIpAddress |
x |
GAP |
GAP - No direct equivalent |
|
| GetDisplayName |
x |
GAP |
GAP - No direct equivalent |
|
| GetMTU |
x |
GAP |
GAP - No direct equivalent |
|
PPB_NetworkMonitor
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
x |
GAP |
GAP - No direct equivalent |
|
| UpdateNetworkList |
x |
GAP |
GAP - No direct equivalent |
|
PPB_NetworkProxy
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| GetProxyForURL |
x |
GAP |
GAP - No direct equivalent |
|
PPB_TCPSocket
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
x |
GAP |
chrome.sockets.tcp.create |
WebSockets / WebRTC closest practical equivalent on open Web. |
| |
x |
GAP |
chrome.sockets.tcpServer.create |
|
| Bind |
x |
GAP |
chrome.sockets.tcpServer.create |
|
| Connect |
x |
GAP |
chrome.sockets.tcp.connect |
|
| GetLocalAddress |
x |
GAP |
chrome.sockets.udp.SocketInfo |
|
| GetRemoteAddress |
x |
GAP |
chrome.sockets.udp.SocketInfo |
|
| Read |
x |
GAP |
onReceive* Events |
|
| Write |
x |
GAP |
chrome.sockets.tcp.send |
|
| Listen |
x |
GAP |
chrome.sockets.tcpServer.listen |
|
| Accept |
x |
GAP |
onAccept* Events |
|
| Close |
x |
GAP |
chrome.sockets.tcp.close |
|
| |
x |
GAP |
chrome.sockets.tcpServer.close |
|
| SetOption |
x |
GAP |
chrome.sockets.tcp.update |
|
| |
x |
GAP |
chrome.sockets.tcpServer.update |
|
PPB_UDPSocket
| PPAPI Method |
Assumes Threads |
Emscripten |
Web API |
Limitations |
| Create |
x |
GAP |
chrome.sockets.udp.create |
GAP (partial) - WebRTC closest practical open Web equivalent |
| Bind |
x |
GAP |
chrome.sockets.udp.bind |
|
| GetBoundAddress |
x |
GAP |
chrome.sockets.udp.SocketInfo |
|
| RecvFrom |
x |
GAP |
onReceive* Events |
|
| SendTo |
x |
GAP |
chrome.sockets.udp.send |
|
| Close |
x |
GAP |
chrome.sockets.udp.close |
|
| SetOption |
x |
GAP |
chrome.sockets.udp.update |
|
| JoinGroup |
x |
GAP |
chrome.sockets.udp.joinGroup |
|
| LeaveGroup |
x |
GAP |
chrome.sockets.udp.leaveGroup |
|