| 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 |
| 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 |
| 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 recommended buffer size. |
| 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). |
| 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. |
| 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. |
| 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 |
| 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 |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| IsFullScreen | html5.h | Document.fullscreenEnabled | ||
| SetFullscreen | html5.h | Document.requestFullscreen | ||
| GetScreenSize | html5.h | Document.exitFullscreen |
| 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). |
| 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 |
| 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. |
| 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 |
| 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 |
| 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* |
| 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. |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| Create | SDL | KeyboardEvent | ||
| GetKeyCode | SDL | KeyboardEvent.keyCode | ||
| GetCharacterText | SDL | KeyboardEvent.key | ||
| GetCode | SDL | KeyboardEvent.code |
| 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) |
| 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 |
| 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. |
| 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 |
| 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 |
| 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. |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| PostMessage | N/A | Window.postMessage | ||
| RegisterMessageHandler | N/A | Window.addEventListener | ||
| UnregisterMessageHandler | N/A | Window.removeEventListener |
| 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. |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| LockMouse | SDL | Element.requestPointerLock | ||
| UnlockMouse | SDL | Element.exitPointerLock |
| 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. |
| 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 preferably 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. |
| 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 |
| 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 |
| 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. |
| 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 |
| 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 |
| 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 |
| 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. |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| Graphics3DContextLost | SDL | Canvas 'webglcontextlost' Event |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| HandleInputEvent | SDL | Element.addEventListener |
| 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. |
| 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. |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| HandleMessage | embind | MessagePort 'message' Event Window 'message' Event |
| PPAPI Method | Assumes Threads | Emscripten | Web API | Limitations |
| MouseLockLost | SDL | Element 'pointerlockchange', 'pointerlockerror' Events |