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 Q4 2019 (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.

As of Chrome 76, PNaCl on the open web has been moved behind an Origin Trial, which is a mechanism for web developers to register and get access to a feature that isn’t on by default. This is usually a new proposed feature but in this case it’s a feature being deprecated. A developer can register on the Origin Trial Console and receive a token, which can be embedded into a page and will enable the feature without the user needing to use a flag. (For more details see the linked guide). The trial is scheduled to last through Chrome 78, approximately until December 2019. This change is not intended to affect NaCl or PNaCl in Chrome Apps or extensions, and the “enable-nacl” flag in chrome://flags can also be used to enable PNaCl locally for testing (this flag also retains its current function of enabling non-PNaCl “native” NaCl on any page).

We also recently announced the deprecation Q1 2018 of Chrome Apps outside of Chrome OS.

Toolchain Migration

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 MethodAssumes ThreadsEmscriptenWeb APILimitations
CreatexSDL (partial)GAP (partial) - AudioWorkletNode ROUGHLY equivalentThe AudioWorkletSpec is done, but AudioDeviceClient may be a better fit for this API. The AudioDeviceClient is still being specified by the community. The worklet may not be the rough equivalent for this API.
GetCurrentConfigSDLAudioContext.* (gets back settings passed in)
StartPlaybackSDLAudioBufferSourceNode.start
StopPlaybackSDLAudioBufferSourceNode.stop

PPB_AudioBuffer

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetTimestampSDLAudioBufferSourceNode.start (parameter)Passed in each time instead of attached to the buffer.
SetTimestampSDLAudioBufferSourceNode.start (parameter)
GetSampleRateSDLAudioBuffer.sampleRate
GetSampleSizeGAPGAP - 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. The next version of the Web Audio spec will implement support for 16-bit samples. An optimization for AudioBuffer could be implemented similar to Firefox by using 16-bit buffer for audio that comes from decodeAudioData
GetNumberOfChannelsSDLAudioBuffer.numberOfChannels
GetDataBufferSDLAudioBuffer.getChannelData
GetBufferSizeSDLAudioBuffer.length

PPB_AudioConfig

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateStereo16BitGAPGAP - Only 32-bit float samples supportedThe next version of the Web Audio spec will implement support for 16-bit samples.
GetSampleRateSDLAudioContext.sampleRate
GetSampleFrameCountSDLAudioBuffer.length
RecommendSampleRateSDLAudioContext.sampleRate (from default construct)An AudioContext will have the preferred sampling rate that matchs the actual sample rate of the hardware audio device by default.
RecommendSampleFrameCountGAPGAP - Would be handled with the planned AudioDeviceClientThere is an open issue to allow a user-specified size, but that is still being defined. This is probably best handled with AudioDeviceClient which can tell you what the appropriate size would be for the given hardware.

PPB_Console

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Logutimeconsole.log/warn/error/...
LogWithSourceGAPGAPThe Console API is regarded as a sufficiently complete replacement, unless there are specific use cases raised by developers for the functionality provided by LogWithSource. DevTools Source Maps can be used to debug transpiled JavaScript in their original source language.

PPB_Core

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
getTimeutimenew Date().getTime()
getTimeTicksutimenew Date().getTime()
IsMainThreadGAPwindow.document !== undefined
CallOnMainThreadGAPWorker.postMessage + Atomics.waitEquivalent synchronization can be built.

PPB_FileIO

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateFS (partial)window.chooseFileSystemEntries()Create and open are used differently, but the pieces are of equal power.
OpenFS (partial)window.chooseFileSystemEntries()
QueryFS (partial)Blob.size, FileSystemHandle.getFile(), FileSystemHandle.getDirectory(), File.lastModifiedGAP (partial) - Blob.type can also be used to check the MIME type. The file system type, creation time, and last access time can not be determined with the Native File System API.
TouchFS (partial)FileSystemDirectoryHandle.getFile("name", {create: true})
ReadFS (partial)Blob.slice().arrayBuffer()
WriteFS (partial)FileSystemWriter.write()
SetLengthFS (partial)FileSystemWriter.truncate()
FlushGAP (partial)GAP (partial) - Files are flushed when FileSystemWrite.close() is calledThis is intended by design because the Native File System API files are exposed to the OS, therefore a Safe Browsing check needs to be performed before data is shown to the OS.
CloseFS (partial)FileSystemWriter.close()Does not cancel pending operations, but flushes any data written so far to disk.
ReadToArrayGAPBlob.slice().arrayBuffer() or Blob.arrayBuffer()Allows multiple subrange reads in parallel.

PPB_FileRef

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateFS (partial)FileSystemDirectoryHandle.getFile("name", {create: true})
GetFileSystemTypeFS (partial)FileSystem.type
GetNameFS (partial)File.name
GetPathFS (partial)GAP (partial) - With the Native File System API, the relative path of a file can be determined from reference to a directory that contains the file using FileSystemHandle.resolve(FileSystemHandle)The absolute path of a file cannot be determined, and the user has to grant permission to access the directory containing the file.
GetParentFS (partial)GAP (partial) - With the Native File System API, the relative path of a file can be determined from reference to a directory that contains the file using FileSystemHandle.resolve(FileSystemHandle)The user has to grant permission to access the directory containing the file.
MakeDirectoryFS (partial)FileSystemHandle.getDirectory(..., {createIfNotExists: true})
TouchFS (partial)FileSystemDirectoryHandle.getFile("name", {create: true})Modify time can be bumped by writing.
DeleteFS (partial)FileSystemDirectoryHandle.removeEntry()Unlike the PPAPI, directories do not have to be empty.
RenameFS (partial)GAP (partial) - With the Native File System API, the file can be written with the new name using a combination of FileSystemFileHandle.getFile() for the new name and FileSystemFileHandle.createWriter().write() with the contents of the old file. Then FileSystemDirectoryHandle.removeEntry() to delete the old file.There is not a direct API that will do this in one step in the Native File System API.
QueryGAP (partial)Blob.size, FileSystemHandle.getFile(), FileSystemHandle.getDirectory(), File.lastModifiedGAP (partial) - Blob.type can also be used to check the MIME type. The file system type, creation time, and last access time can not be determined with the Native File System API.
ReadDirectoryEntriesFS (partial)FileSystemDirectoryHandle.getEntries()

PPB_FileSystem

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateFS (partial)window.requestFileSystemJS API does both in one step
OpenGAPwindow.requestFileSystemJS API does both in one step
GetTypeGAPFileSystem.type

PPB_Fullscreen

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
IsFullScreenhtml5.hDocument.fullscreenEnabled
SetFullscreenhtml5.hDocument.requestFullscreen
GetScreenSizehtml5.hDocument.exitFullscreen

PPB_Gamepad

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
SampleSDLGamepad.*The Gamepad object exposes a timestamp relative to navigationStart. It is updated when data is received from the hardware https://www.w3.org/TR/gamepad/#gamepad-interface

PPB_Graphics2D

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLCanvas.getContext('2d')
DescribeSDLCanvas.clientWidth + Canvas.clientHeight
PaintImageDataSDLCanvasRenderingContext2D.putImageData
ScrollGAPCanvasRenderingContext2D.scrollIntoView, CanvasRenderingContext2D.drawImageGAP (partial) - Can be implemented by drawing the canvas onto itself, with an offset, using drawImage, and then filling in the rest.
ReplaceContentsSDLCanvasRenderingContext2D.drawImage
FlushGAPNo direct equivalentGAP (partial) - There is always an implicit flush at the end of draw code; this is unlikely to change. However, the combination of OffscreenCanvas and ImageBitmapRenderingContext provide similar functionality.
SetScaleSDLCanvasRenderingContext2D.scale
GetScaleSDLCanvasRenderingContext2D.currentTransform
SetLayerTransformSDLCanvasRenderingContext2D.setTransform CanvasRenderingContext2D.scale CanvasRenderingContext2D.translate

PPB_Graphics3D

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetAttribMaxValueOpenGL ES 3.0WebGL 2.0GAP (partial) - WebGL 2.0 and Emscripten's exposure of OpenGL ES 3.0 support user-defined multisampled framebuffers, in which all of the parameters configurable via PPAPI can be set.
CreateSDLCanvas.getContext
GetAttribsSDLWebGLRenderingContext.getContextAttributes
SetAttribsSDLCanvas.getContext(.., OPTIONS)
GetErrorSDLWebGLRenderingContext.getError
ResizeBuffersSDLCanvas.width = w; Canvas.height = h;
SwapBuffersGAPNo direct equivalentGAP (partial) - There is always an implicit flush at the end of draw code; this is unlikely to change. However, the combination of OffscreenCanvas and ImageBitmapRenderingContext provide similar functionality.

PPB_ImageData

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetNativeImageDataFormatSDLImageData mandates RGBA order
IsImageDataFormatSupportedSDLImageData mandates RGBA order
CreateSDLCanvasRenderingContext2d.createImageData
DescribeSDLImageData never has a stride
MapSDLImageData.data
UnmapSDLImageData.data

PPB_InputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
RequestInputEventsSDLNo direct equivalentThe 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.
RequestFilteringInputEventsSDLmouse* key* wheel* touch* composition* Events
SDLElement.addEventListener
ClearInputEventRequestSDLElement.removeEventListener
GetTypeSDLEvent class descendants
GetTimeStampSDLEvent.timeStamp
GetModifiersSDL*Event.altKey/shiftKey/metaKey/ctrlKey

PPB_MouseInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLMouseEvent
GetButtonSDLMouseEvent.button
GetPositionSDLMouseEvent.client*/page*/offset*
GetClickCountSDLdblclick' vs 'mousedown' Events
GetMovementSDLMouseEvent.movement*

PPB_WheelInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLWheelEvent
GetDeltaSDLWheelEvent.delta*
GetTicksGAPGAP - deltaMode kind of contains this info, but incompletely.There is discussion on implementing a WheelEvent.deltaMode API: https://github.com/w3c/uievents/issues/181#issuecomment-537811017
GetScrollByPageGAPGAP - deltaMode kind of contains this info, but incompletely.There is discussion on implementing a WheelEvent.deltaMode API: https://github.com/w3c/uievents/issues/181#issuecomment-537811017

PPB_KeyboardInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLKeyboardEvent
GetKeyCodeSDLKeyboardEvent.keyCode
GetCharacterTextSDLKeyboardEvent.key
GetCodeSDLKeyboardEvent.code

PPB_TouchInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLTouchEvent
AddTouchPointSDLTouchEvent.touches.push
GetTouchCountSDLTouchEvent.touches.length
GetTouchByIndexSDLTouchEvent.touches[i]
GetTouchByIdSDLTouch.indentifer (to figure this out yourself)

PPB_IMEInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPCompositionEvent
GetTextGAPCompositionEvent.data
GetSegmentNumberGAPGAP - No direct equivalentThis data can potentially be retrieved from CompositionEvent.data.
GetSegmentOffsetGAPGAP - No direct equivalent
GetTargetSegmentGAPGAP - No direct equivalent
GetSelectionGAPGAP - No direct equivalent

PPB_Instance

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
BindGraphicsSDLCanvas.getContext (moot as binding is automatic).
IsFullFrameGAPGAP - No equivalent to mime type handlers.NaCl apps can be registered to handle a particular mime type and own the whole document.
DidCreateN/A<Element>[key]General DOM access lets you fish out tag attributes
DidDestroyN/AN/ANot triggered for NaCl
DidChangeViewN/AElement 'resize' Event
DidChangeFocusN/AElement 'focus', 'focusin', 'focusout' Events
HandleDocumentLoadN/AGAP - No way to register as a mime type handlerNaCl modules via apps + a manifest entry can be set up to handle particular mime types.

PPB_MediaStreamAudioTrack

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
ConfigureGAPgetUserMedia()The constraints from getUserMedia() can provide the configuration values to use in MediaStreamTrack.
GetAttribGAPMediaStreamTrack.getSettings()
GetIdGAPMediaStreamTrack.id
HasEndedGAPMediaStreamTrack.readyState
GetBufferGAPGAP - No equivalent
RecycleBufferGAPGAP - No equivalent
CloseGAPMediaStreamTrack.stop()

PPB_MediaStreamVideoTrack

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPCanvas CaptureCanvas Capture provides the ability to introduce video frames programatically.
ConfigureGAPapplyConstraints(), getUserMedia()GAP (partial) - The extent of configurations available in the Web API may differ from the PPAPI.
GetAttribGAPMediaStreamSettings.width
GAPMediaStreamSettings.height
GAPGAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_BUFFERED_FRAMESMediaStream cannot be preloaded, so it will never buffer: https://www.w3.org/TR/mediacapture-streams/#mediastreams-in-media-elements
GAPGAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT
GetIdGAPMediaStreamTrack.id
HasEndedGAPMediaStreamTrack.readyState
GetFrameGAPGAP - No equivalent
RecycleFrameGAPGAP - No equivalent
CloseGAPMediaStreamTrack.stop()
GetEmptyFrameGAPGAP - No equivalent
PutFrameGAPGAP - No equivalent

PPB_MessageLoop

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateN/AMostly moot, workers get an implicit event loop.
GetForMainThreadN/AMostly moot, workers get an implicit event loop.
GetCurrentN/AMostly moot, workers get an implicit event loop.
AttachToCurrentThreadN/AMostly moot, workers get an implicit event loop.
RunN/AMostly moot, workers get an implicit event loop.
PostWorkN/AMostly moot, workers get an implicit event loop.
PostQuitN/AMostly moot, workers get an implicit event loop.

PPB_Messaging

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
PostMessageN/AWindow.postMessage
RegisterMessageHandlerN/AWindow.addEventListener
UnregisterMessageHandlerN/AWindow.removeEventListener

PPB_MouseCursor

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
SetCursorSDLElement.style.cursorSame 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 MethodAssumes ThreadsEmscriptenWeb APILimitations
LockMouseSDLElement.requestPointerLock
UnlockMouseSDLElement.exitPointerLock

PPB_OpenGLES2

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Several MethodsOpenGLESClose to WebGL 1.0 in functionality.
xOffscreenCanvas

PPB_TextInputController

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
SetTextInputTypeGAPGAP - Potentially filled by Input Method Editor APISome 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.
UpdateCaretPositionGAPGAP - Potentially filled by Input Method Editor APIhttps://www.w3.org/TR/ime-api/
CancelCompositionTextGAPGAP - Potentially filled by Input Method Editor APIhttps://www.w3.org/TR/ime-api/
UpdateSurroundingTextGAPGAP - Potentially filled by Input Method Editor APIhttps://www.w3.org/TR/ime-api/

PPB_URLLoader

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Createembindnew XMLHttpRequest();
OpenembindXMLHttpRequest.open
FollowRedirectembindRequest.redirect
GAPGAP - No XMLHTTPRequest equivalent
GetUploadProgressembindXMLHttpRequest 'progress' Event
GAPFetchObserverNot specced or implemented yet; https://github.com/whatwg/fetch/issues/607
GetDownloadProgressembindXMLHttpRequest 'progress' Event
GAPFetchObserverNot specced or implemented yet; https://github.com/whatwg/fetch/issues/607
GetResponseInfoembindXMLHttpRequest.getAllResponseHeaders
embindFetch Response.*
ReadResponseBodyembindXMLHttpRequest.response
embindBody.* (Response is a Body)
FinishStreamingToFileembindGAP - No direct equivalentXMLHttpRequest and Fetch both assume streaming to memory, rather than directly to a storage.
CloseembindXMLHttpRequest.abort
GAPFetch API: AbortSignal and AbortController

PPB_URLRequestInfo

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateembindXMLHttpRequest
embindFetch Request
SetPropertyGAPGAP - No direct equivalent for XMLHttpRequestXMLHttpRequest doesn't provide direct ways to per-request limit following redirects, stream to a file, set referrer or credentials policy.
embindRequest.*
AppendDataToBodyembindXMLHttpRequest.sendGAP - Both must have the whole body, rather than a chunk.
embindfetch(.., options:body)
AppendFileToBodyGAPfetch() upload streaminghttps://www.chromestatus.com/features/5274139738767360
N/A<form>You can also read with FileReader and upload, but that's more like AppendDataToBody

PPB_URLResponseInfo

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetPropertyembindXMLHttpRequest.getAllResponseHeaders + others
embindFetch Response.*
GetBodyAsFileRefembindFetch Response (Body) .blob()Assumes storage layer optimizes transfer.

PPB_Var

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
VarFromUtf8embindTextDecoder.decode
VarToUtf8embindTextEncoder.encode
VarFromResourceN/AN/A
VarToResourceN/AN/A

PPB_VarArray

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetembindArray[i]
SetembindArray[i] = x
GetLengthembindArray.length
SetLengthembindArray.length = n

PPB_VarArrayBuffer

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Createembindnew ArrayBuffer(n)
ByteLengthembindArrayBuffer.byteLength
MapGAPGAP - No direct equivalentAsm.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.
UnmapGAPGAP - No direct equivalent

PPB_VarDictionary

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Createembind{}
Getembind<Object>[i]
Setembind<Object>[i] = x
Deleteembinddelete <Object>[i]
HasKeyembindx in <Object>
GetKeysembindfor (k in <Object>) {}No literal equivalent, but it can be built.

PPB_VideoDecoder

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPGAP - Would be handled with the proposed WebCodecs API using VideoDecoder()https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
InitializeGAPGAP - Would be handled with the proposed WebCodecs API using VideoDecoder() initialization parameters (VideoDecoderInitParameters)https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
DecodeGAPGAP - Would be handled with the proposed WebCodecs API using ReadableStream.pipeThrough(VideoDecoder)https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
GetPictureGAPGAP - Would be handled with the proposed WebCodecs API using ReadableStream.pipeThrough(VideoDecoder).pipeTo(VideoTrackWriter().writable)https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
RecyclePictureGAPGAP - Would be handled with the proposed WebCodecs API. The current design will automatically recycle the pictures and keep the decoding process going.https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
FlushGAPGAP - Would be handled with the proposed WebCodecs API. The API will be called Flush(), however there is still discussion on how it will be sequenced in relation to decode calls.https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
ResetGAPGAP - Would be handled with the proposed WebCodecs API by destroying the VideoDecoder instance and creating a new one. This won't be as efficient as a dedicated reset method, but the semantics for a Reset() API is still being discussed.https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming

PPB_VideoEncoder

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPGAP - Would be handled with the proposed WebCodecs API using VideoEncoder()
GetSupportedProfilesGAPGAP (partial) - navigator.mediaCapabilities.encodingInfo()The supported profiles have to be checked one by one.
InitializeGAPGAP - Would be handled with the proposed WebCodecs API using VideoEncoder() initialization parameters
GetFramesRequiredGAPGAP - No equivalentIt is unlikely that the frame pool used internally by the Web Codecs API is exposed.
GetFrameCodedSizeGAPGAP - No equivalentIt is unlikely that the frame pool used internally by the Web Codecs API is exposed.
GetVideoFrameGAPGAP - Would be handled with the proposed WebCodecs API by using ReadableStream.pipeThrough(VideoEncoder). This would directly encode the data in the Readable stream instead of grabbing a single frame to fill with data before encoding.
EncodeGAPGAP - Would be handled with the proposed WebCodecs API using ReadableStream.pipeThrough(VideoEncoder)
GetBitstreamBufferGAPGAP - Would be handled with the proposed WebCodecs API. The current design will automatically go through the encoded bitstream buffer that is piped through.The WebCodecs API currently assumes that bitstream buffer can be copied rather than pooled, so it will not need to be recycled.
RecycleBitstreamBufferGAPGAP - Would be handled with the proposed WebCodecs API. The current design will automatically recycle the buffer to keep the encoding process going.This is unlikely to change in the future as performance implications are smaller.
RequestEncodingParametersChangeGAPGAP - Would be handled by the proposed Web Codecs API. Certain parameters will have the capability of being changed on the fly, while others will require the encoder to be torn down.
CloseGAPGAP - Would be handled with the proposed WebCodecs API by using VideoEncoder.Close()

PPB_VideoFrame

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetTimestampGAPGAP - Would be handled with the proposed WebCodecs API.
SetTimestampGAPGAP - Would be handled with the proposed WebCodecs API.
GetFormatGAPGAP - Would be handled with the proposed WebCodecs API.
GetSizeGAPGAP - Would be handled with the proposed WebCodecs API.
GetDataBufferGAPGAP - Would be handled with the proposed WebCodecs API.
GetDataBufferSizeGAPGAP - Would be handled with the proposed WebCodecs API.

PPB_View

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetRectembindElement.getBoundingClientRect
IsFullscreenembindDocument.fullScreenEnabledPertains to document instead of just single element.
IsVisibleembindIntersectionObserver
IsPageVisibleembinddocument.visibilityState
GetClipRectembindIntersectionObserver
GetDeviceScaleembindwindow.devicePixelRatio
GetCSSScaleembind<Element>.getBoundingClientRect().width / <Element>.offsetWidth
GetScrollOffsetembind<Element>.scrollTop / <Element>.scrollLeft

PPB_WebSocket

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPWebSocket.WebSocket
ConnectGAPWebSocket.WebSocket(url, ...) WebSocket 'open' Event
CloseGAPWebSocket.close
ReceiveMessageGAPWebSocket 'message' Event WebSocket 'error' Event WebSocket 'close' Event
SendMessageGAPWebSocket.send
GetBufferedAmountGAPWebSocket.bufferedAmount
GetCloseCodeGAPCloseEvent.code
GetCloseReasonGAPCloseEvent.reason
GetCloseWasCleanGAPCloseEvent.wasClean
GetExtensionsGAPWebSocket.extensions
GetProtocolGAPWebSocket.protocol
GetReadyStateGAPWebSocket.readyState
GetURLGAPWebSocket.url

PPP_Graphics3D

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Graphics3DContextLostSDLCanvas 'webglcontextlost' Event

PPP_InputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
HandleInputEventSDLElement.addEventListener

PPP_Instance

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
DidCreateN/A<Element>[key]General DOM access lets you fish out tag attributes
DidDestroyN/AN/ANot triggered for NaCl
DidChangeViewN/AElement 'resize' Event
DidChangeFocusN/AElement 'focus', 'focusin', 'focusout' Events
HandleDocumentLoadN/AGAP - No way to register as a mime type handlerNaCl Modules via apps + a manifest entry can be set up to handle particular mime types.

PPP_MessageHandler

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
HandleMessageembindMessagePort 'message' Event Window 'message' Event
HandleBlockingMessageN/AGAP - No direct equivalentSimilar synchronization can be done off main thread with Atomics.wait. This was added to support emulation of synchronous plugin APIs.

PPP_Messaging

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
HandleMessageembindMessagePort 'message' Event Window 'message' Event

PPP_MouseLock

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
MouseLockLostSDLElement 'pointerlockchange', 'pointerlockerror' Events

IRT

PPB_Audio

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreatexSDL (partial)GAP (partial) - AudioWorkletNode ROUGHLY equivalentThe AudioWorkletSpec is done, but AudioDeviceClient may be a better fit for this API. The AudioDeviceClient is still being specified by the community. The worklet may not be the rough equivalent for this API.
GetCurrentConfigSDLAudioContext.* (gets back settings passed in)
StartPlaybackSDLAudioBufferSourceNode.start
StopPlaybackSDLAudioBufferSourceNode.stop

PPB_AudioBuffer

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetTimestampSDLAudioBufferSourceNode.start (parameter)Passed in each time instead of attached to the buffer.
SetTimestampSDLAudioBufferSourceNode.start (parameter)
GetSampleRateSDLAudioBuffer.sampleRate
GetSampleSizeGAPGAP - 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. The next version of the Web Audio spec will implement support for 16-bit samples. An optimization for AudioBuffer could be implemented similar to Firefox by using 16-bit buffer for audio that comes from decodeAudioData
GetNumberOfChannelsSDLAudioBuffer.numberOfChannels
GetDataBufferSDLAudioBuffer.getChannelData
GetBufferSizeSDLAudioBuffer.length

PPB_AudioConfig

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateStereo16BitGAPGAP - Only 32-bit float samples supportedThe next version of the Web Audio spec will implement support for 16-bit samples.
GetSampleRateSDLAudioContext.sampleRate
GetSampleFrameCountSDLAudioBuffer.length
RecommendSampleRateSDLAudioContext.sampleRate (from default construct)An AudioContext will have the preferred sampling rate that matchs the actual sample rate of the hardware audio device by default.
RecommendSampleFrameCountGAPGAP - Would be handled with the planned AudioDeviceClientThere is an open issue to allow a user-specified size, but that is still being defined. This is probably best handled with AudioDeviceClient which can tell you what the appropriate size would be for the given hardware.

PPB_Console

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Logutimeconsole.log/warn/error/...
LogWithSourceGAPGAPThe Console API is regarded as a sufficiently complete replacement, unless there are specific use cases raised by developers for the functionality provided by LogWithSource. DevTools Source Maps can be used to debug transpiled JavaScript in their original source language.

PPB_Core

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
getTimeutimenew Date().getTime()
getTimeTicksutimenew Date().getTime()
IsMainThreadGAPwindow.document !== undefined
CallOnMainThreadGAPWorker.postMessage + Atomics.waitEquivalent synchronization can be built.

PPB_FileIO

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateFS (partial)window.chooseFileSystemEntries()Create and open are used differently, but the pieces are of equal power.
OpenFS (partial)window.chooseFileSystemEntries()
QueryFS (partial)Blob.size, FileSystemHandle.getFile(), FileSystemHandle.getDirectory(), File.lastModifiedGAP (partial) - Blob.type can also be used to check the MIME type. The file system type, creation time, and last access time can not be determined with the Native File System API.
TouchFS (partial)FileSystemDirectoryHandle.getFile("name", {create: true})
ReadFS (partial)Blob.slice().arrayBuffer()
WriteFS (partial)FileSystemWriter.write()
SetLengthFS (partial)FileSystemWriter.truncate()
FlushGAP (partial)GAP (partial) - Files are flushed when FileSystemWrite.close() is calledThis is intended by design because the Native File System API files are exposed to the OS, therefore a Safe Browsing check needs to be performed before data is shown to the OS.
CloseFS (partial)FileSystemWriter.close()Does not cancel pending operations, but flushes any data written so far to disk.
ReadToArrayGAPBlob.slice().arrayBuffer() or Blob.arrayBuffer()Allows multiple subrange reads in parallel.

PPB_FileRef

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateFS (partial)FileSystemDirectoryHandle.getFile("name", {create: true})
GetFileSystemTypeFS (partial)FileSystem.type
GetNameFS (partial)File.name
GetPathFS (partial)GAP (partial) - With the Native File System API, the relative path of a file can be determined from reference to a directory that contains the file using FileSystemHandle.resolve(FileSystemHandle)The absolute path of a file cannot be determined, and the user has to grant permission to access the directory containing the file.
GetParentFS (partial)GAP (partial) - With the Native File System API, the relative path of a file can be determined from reference to a directory that contains the file using FileSystemHandle.resolve(FileSystemHandle)The user has to grant permission to access the directory containing the file.
MakeDirectoryFS (partial)FileSystemHandle.getDirectory(..., {createIfNotExists: true})
TouchFS (partial)FileSystemDirectoryHandle.getFile("name", {create: true})Modify time can be bumped by writing.
DeleteFS (partial)FileSystemDirectoryHandle.removeEntry()Unlike the PPAPI, directories do not have to be empty.
RenameFS (partial)GAP (partial) - With the Native File System API, the file can be written with the new name using a combination of FileSystemFileHandle.getFile() for the new name and FileSystemFileHandle.createWriter().write() with the contents of the old file. Then FileSystemDirectoryHandle.removeEntry() to delete the old file.There is not a direct API that will do this in one step in the Native File System API.
QueryGAP (partial)Blob.size, FileSystemHandle.getFile(), FileSystemHandle.getDirectory(), File.lastModifiedGAP (partial) - Blob.type can also be used to check the MIME type. The file system type, creation time, and last access time can not be determined with the Native File System API.
ReadDirectoryEntriesFS (partial)FileSystemDirectoryHandle.getEntries()

PPB_FileSystem

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateFS (partial)window.requestFileSystemJS API does both in one step
OpenGAPwindow.requestFileSystemJS API does both in one step
GetTypeGAPFileSystem.type

PPB_Fullscreen

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
IsFullScreenhtml5.hDocument.fullscreenEnabled
SetFullscreenhtml5.hDocument.requestFullscreen
GetScreenSizehtml5.hDocument.exitFullscreen

PPB_Gamepad

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
SampleSDLGamepad.*The Gamepad object exposes a timestamp relative to navigationStart. It is updated when data is received from the hardware https://www.w3.org/TR/gamepad/#gamepad-interface

PPB_Graphics2D

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLCanvas.getContext('2d')
DescribeSDLCanvas.clientWidth + Canvas.clientHeight
PaintImageDataSDLCanvasRenderingContext2D.putImageData
ScrollGAPCanvasRenderingContext2D.scrollIntoView, CanvasRenderingContext2D.drawImageGAP (partial) - Can be implemented by drawing the canvas onto itself, with an offset, using drawImage, and then filling in the rest.
ReplaceContentsSDLCanvasRenderingContext2D.drawImage
FlushGAPNo direct equivalentGAP (partial) - There is always an implicit flush at the end of draw code; this is unlikely to change. However, the combination of OffscreenCanvas and ImageBitmapRenderingContext provide similar functionality.
SetScaleSDLCanvasRenderingContext2D.scale
GetScaleSDLCanvasRenderingContext2D.currentTransform
SetLayerTransformSDLCanvasRenderingContext2D.setTransform CanvasRenderingContext2D.scale CanvasRenderingContext2D.translate

PPB_Graphics3D

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetAttribMaxValueOpenGL ES 3.0WebGL 2.0GAP (partial) - WebGL 2.0 and Emscripten's exposure of OpenGL ES 3.0 support user-defined multisampled framebuffers, in which all of the parameters configurable via PPAPI can be set.
CreateSDLCanvas.getContext
GetAttribsSDLWebGLRenderingContext.getContextAttributes
SetAttribsSDLCanvas.getContext(.., OPTIONS)
GetErrorSDLWebGLRenderingContext.getError
ResizeBuffersSDLCanvas.width = w; Canvas.height = h;
SwapBuffersGAPNo direct equivalentGAP (partial) - There is always an implicit flush at the end of draw code; this is unlikely to change. However, the combination of OffscreenCanvas and ImageBitmapRenderingContext provide similar functionality.

PPB_ImageData

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetNativeImageDataFormatSDLImageData mandates RGBA order
IsImageDataFormatSupportedSDLImageData mandates RGBA order
CreateSDLCanvasRenderingContext2d.createImageData
DescribeSDLImageData never has a stride
MapSDLImageData.data
UnmapSDLImageData.data

PPB_InputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
RequestInputEventsSDLNo direct equivalentThe 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.
RequestFilteringInputEventsSDLmouse* key* wheel* touch* composition* Events
SDLElement.addEventListener
ClearInputEventRequestSDLElement.removeEventListener
GetTypeSDLEvent class descendants
GetTimeStampSDLEvent.timeStamp
GetModifiersSDL*Event.altKey/shiftKey/metaKey/ctrlKey

PPB_MouseInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLMouseEvent
GetButtonSDLMouseEvent.button
GetPositionSDLMouseEvent.client*/page*/offset*
GetClickCountSDLdblclick' vs 'mousedown' Events
GetMovementSDLMouseEvent.movement*

PPB_WheelInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLWheelEvent
GetDeltaSDLWheelEvent.delta*
GetTicksGAPGAP - deltaMode kind of contains this info, but incompletely.There is discussion on implementing a WheelEvent.deltaMode API: https://github.com/w3c/uievents/issues/181#issuecomment-537811017
GetScrollByPageGAPGAP - deltaMode kind of contains this info, but incompletely.There is discussion on implementing a WheelEvent.deltaMode API: https://github.com/w3c/uievents/issues/181#issuecomment-537811017

PPB_KeyboardInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLKeyboardEvent
GetKeyCodeSDLKeyboardEvent.keyCode
GetCharacterTextSDLKeyboardEvent.key
GetCodeSDLKeyboardEvent.code

PPB_TouchInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateSDLTouchEvent
AddTouchPointSDLTouchEvent.touches.push
GetTouchCountSDLTouchEvent.touches.length
GetTouchByIndexSDLTouchEvent.touches[i]
GetTouchByIdSDLTouch.indentifer (to figure this out yourself)

PPB_IMEInputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPCompositionEvent
GetTextGAPCompositionEvent.data
GetSegmentNumberGAPGAP - No direct equivalentThis data can potentially be retrieved from CompositionEvent.data.
GetSegmentOffsetGAPGAP - No direct equivalent
GetTargetSegmentGAPGAP - No direct equivalent
GetSelectionGAPGAP - No direct equivalent

PPB_Instance

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
BindGraphicsSDLCanvas.getContext (moot as binding is automatic).
IsFullFrameGAPGAP - No equivalent to mime type handlers.NaCl apps can be registered to handle a particular mime type and own the whole document.
DidCreateN/A<Element>[key]General DOM access lets you fish out tag attributes
DidDestroyN/AN/ANot triggered for NaCl
DidChangeViewN/AElement 'resize' Event
DidChangeFocusN/AElement 'focus', 'focusin', 'focusout' Events
HandleDocumentLoadN/AGAP - No way to register as a mime type handlerNaCl modules via apps + a manifest entry can be set up to handle particular mime types.

PPB_MediaStreamAudioTrack

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
ConfigureGAPgetUserMedia()The constraints from getUserMedia() can provide the configuration values to use in MediaStreamTrack.
GetAttribGAPMediaStreamTrack.getSettings()
GetIdGAPMediaStreamTrack.id
HasEndedGAPMediaStreamTrack.readyState
GetBufferGAPGAP - No equivalent
RecycleBufferGAPGAP - No equivalent
CloseGAPMediaStreamTrack.stop()

PPB_MediaStreamVideoTrack

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPCanvas CaptureCanvas Capture provides the ability to introduce video frames programatically.
ConfigureGAPapplyConstraints(), getUserMedia()GAP (partial) - The extent of configurations available in the Web API may differ from the PPAPI.
GetAttribGAPMediaStreamSettings.width
GAPMediaStreamSettings.height
GAPGAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_BUFFERED_FRAMESMediaStream cannot be preloaded, so it will never buffer: https://www.w3.org/TR/mediacapture-streams/#mediastreams-in-media-elements
GAPGAP - no equivalent to PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT
GetIdGAPMediaStreamTrack.id
HasEndedGAPMediaStreamTrack.readyState
GetFrameGAPGAP - No equivalent
RecycleFrameGAPGAP - No equivalent
CloseGAPMediaStreamTrack.stop()
GetEmptyFrameGAPGAP - No equivalent
PutFrameGAPGAP - No equivalent

PPB_MessageLoop

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateN/AMostly moot, workers get an implicit event loop.
GetForMainThreadN/AMostly moot, workers get an implicit event loop.
GetCurrentN/AMostly moot, workers get an implicit event loop.
AttachToCurrentThreadN/AMostly moot, workers get an implicit event loop.
RunN/AMostly moot, workers get an implicit event loop.
PostWorkN/AMostly moot, workers get an implicit event loop.
PostQuitN/AMostly moot, workers get an implicit event loop.

PPB_Messaging

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
PostMessageN/AWindow.postMessage
RegisterMessageHandlerN/AWindow.addEventListener
UnregisterMessageHandlerN/AWindow.removeEventListener

PPB_MouseCursor

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
SetCursorSDLElement.style.cursorSame 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 MethodAssumes ThreadsEmscriptenWeb APILimitations
LockMouseSDLElement.requestPointerLock
UnlockMouseSDLElement.exitPointerLock

PPB_OpenGLES2

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Several MethodsOpenGLESClose to WebGL 1.0 in functionality.
xOffscreenCanvas

PPB_TextInputController

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
SetTextInputTypeGAPGAP - Potentially filled by Input Method Editor APISome 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.
UpdateCaretPositionGAPGAP - Potentially filled by Input Method Editor APIhttps://www.w3.org/TR/ime-api/
CancelCompositionTextGAPGAP - Potentially filled by Input Method Editor APIhttps://www.w3.org/TR/ime-api/
UpdateSurroundingTextGAPGAP - Potentially filled by Input Method Editor APIhttps://www.w3.org/TR/ime-api/

PPB_URLLoader

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Createembindnew XMLHttpRequest();
OpenembindXMLHttpRequest.open
FollowRedirectembindRequest.redirect
GAPGAP - No XMLHTTPRequest equivalent
GetUploadProgressembindXMLHttpRequest 'progress' Event
GAPFetchObserverNot specced or implemented yet; https://github.com/whatwg/fetch/issues/607
GetDownloadProgressembindXMLHttpRequest 'progress' Event
GAPFetchObserverNot specced or implemented yet; https://github.com/whatwg/fetch/issues/607
GetResponseInfoembindXMLHttpRequest.getAllResponseHeaders
embindFetch Response.*
ReadResponseBodyembindXMLHttpRequest.response
embindBody.* (Response is a Body)
FinishStreamingToFileembindGAP - No direct equivalentXMLHttpRequest and Fetch both assume streaming to memory, rather than directly to a storage.
CloseembindXMLHttpRequest.abort
GAPFetch API: AbortSignal and AbortController

PPB_URLRequestInfo

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateembindXMLHttpRequest
embindFetch Request
SetPropertyGAPGAP - No direct equivalent for XMLHttpRequestXMLHttpRequest doesn't provide direct ways to per-request limit following redirects, stream to a file, set referrer or credentials policy.
embindRequest.*
AppendDataToBodyembindXMLHttpRequest.sendGAP - Both must have the whole body, rather than a chunk.
embindfetch(.., options:body)
AppendFileToBodyGAPfetch() upload streaminghttps://www.chromestatus.com/features/5274139738767360
N/A<form>You can also read with FileReader and upload, but that's more like AppendDataToBody

PPB_URLResponseInfo

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetPropertyembindXMLHttpRequest.getAllResponseHeaders + others
embindFetch Response.*
GetBodyAsFileRefembindFetch Response (Body) .blob()Assumes storage layer optimizes transfer.

PPB_Var

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
VarFromUtf8embindTextDecoder.decode
VarToUtf8embindTextEncoder.encode
VarFromResourceN/AN/A
VarToResourceN/AN/A

PPB_VarArray

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetembindArray[i]
SetembindArray[i] = x
GetLengthembindArray.length
SetLengthembindArray.length = n

PPB_VarArrayBuffer

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Createembindnew ArrayBuffer(n)
ByteLengthembindArrayBuffer.byteLength
MapGAPGAP - No direct equivalentAsm.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.
UnmapGAPGAP - No direct equivalent

PPB_VarDictionary

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Createembind{}
Getembind<Object>[i]
Setembind<Object>[i] = x
Deleteembinddelete <Object>[i]
HasKeyembindx in <Object>
GetKeysembindfor (k in <Object>) {}No literal equivalent, but it can be built.

PPB_VideoDecoder

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPGAP - Would be handled with the proposed WebCodecs API using VideoDecoder()https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
InitializeGAPGAP - Would be handled with the proposed WebCodecs API using VideoDecoder() initialization parameters (VideoDecoderInitParameters)https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
DecodeGAPGAP - Would be handled with the proposed WebCodecs API using ReadableStream.pipeThrough(VideoDecoder)https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
GetPictureGAPGAP - Would be handled with the proposed WebCodecs API using ReadableStream.pipeThrough(VideoDecoder).pipeTo(VideoTrackWriter().writable)https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
RecyclePictureGAPGAP - Would be handled with the proposed WebCodecs API. The current design will automatically recycle the pictures and keep the decoding process going.https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
FlushGAPGAP - Would be handled with the proposed WebCodecs API. The API will be called Flush(), however there is still discussion on how it will be sequenced in relation to decode calls.https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming
ResetGAPGAP - Would be handled with the proposed WebCodecs API by destroying the VideoDecoder instance and creating a new one. This won't be as efficient as a dedicated reset method, but the semantics for a Reset() API is still being discussed.https://github.com/WICG/web-codecs/blob/master/explainer.md#example-of-decode-for-low-latency-live-streaming-or-cloud-gaming

PPB_VideoEncoder

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPGAP - Would be handled with the proposed WebCodecs API using VideoEncoder()
GetSupportedProfilesGAPGAP (partial) - navigator.mediaCapabilities.encodingInfo()The supported profiles have to be checked one by one.
InitializeGAPGAP - Would be handled with the proposed WebCodecs API using VideoEncoder() initialization parameters
GetFramesRequiredGAPGAP - No equivalentIt is unlikely that the frame pool used internally by the Web Codecs API is exposed.
GetFrameCodedSizeGAPGAP - No equivalentIt is unlikely that the frame pool used internally by the Web Codecs API is exposed.
GetVideoFrameGAPGAP - Would be handled with the proposed WebCodecs API by using ReadableStream.pipeThrough(VideoEncoder). This would directly encode the data in the Readable stream instead of grabbing a single frame to fill with data before encoding.
EncodeGAPGAP - Would be handled with the proposed WebCodecs API using ReadableStream.pipeThrough(VideoEncoder)
GetBitstreamBufferGAPGAP - Would be handled with the proposed WebCodecs API. The current design will automatically go through the encoded bitstream buffer that is piped through.The WebCodecs API currently assumes that bitstream buffer can be copied rather than pooled, so it will not need to be recycled.
RecycleBitstreamBufferGAPGAP - Would be handled with the proposed WebCodecs API. The current design will automatically recycle the buffer to keep the encoding process going.This is unlikely to change in the future as performance implications are smaller.
RequestEncodingParametersChangeGAPGAP - Would be handled by the proposed Web Codecs API. Certain parameters will have the capability of being changed on the fly, while others will require the encoder to be torn down.
CloseGAPGAP - Would be handled with the proposed WebCodecs API by using VideoEncoder.Close()

PPB_VideoFrame

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetTimestampGAPGAP - Would be handled with the proposed WebCodecs API.
SetTimestampGAPGAP - Would be handled with the proposed WebCodecs API.
GetFormatGAPGAP - Would be handled with the proposed WebCodecs API.
GetSizeGAPGAP - Would be handled with the proposed WebCodecs API.
GetDataBufferGAPGAP - Would be handled with the proposed WebCodecs API.
GetDataBufferSizeGAPGAP - Would be handled with the proposed WebCodecs API.

PPB_View

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetRectembindElement.getBoundingClientRect
IsFullscreenembindDocument.fullScreenEnabledPertains to document instead of just single element.
IsVisibleembindIntersectionObserver
IsPageVisibleembinddocument.visibilityState
GetClipRectembindIntersectionObserver
GetDeviceScaleembindwindow.devicePixelRatio
GetCSSScaleembind<Element>.getBoundingClientRect().width / <Element>.offsetWidth
GetScrollOffsetembind<Element>.scrollTop / <Element>.scrollLeft

PPB_WebSocket

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateGAPWebSocket.WebSocket
ConnectGAPWebSocket.WebSocket(url, ...) WebSocket 'open' Event
CloseGAPWebSocket.close
ReceiveMessageGAPWebSocket 'message' Event WebSocket 'error' Event WebSocket 'close' Event
SendMessageGAPWebSocket.send
GetBufferedAmountGAPWebSocket.bufferedAmount
GetCloseCodeGAPCloseEvent.code
GetCloseReasonGAPCloseEvent.reason
GetCloseWasCleanGAPCloseEvent.wasClean
GetExtensionsGAPWebSocket.extensions
GetProtocolGAPWebSocket.protocol
GetReadyStateGAPWebSocket.readyState
GetURLGAPWebSocket.url

PPP_Graphics3D

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
Graphics3DContextLostSDLCanvas 'webglcontextlost' Event

PPP_InputEvent

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
HandleInputEventSDLElement.addEventListener

PPP_Instance

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
DidCreateN/A<Element>[key]General DOM access lets you fish out tag attributes
DidDestroyN/AN/ANot triggered for NaCl
DidChangeViewN/AElement 'resize' Event
DidChangeFocusN/AElement 'focus', 'focusin', 'focusout' Events
HandleDocumentLoadN/AGAP - No way to register as a mime type handlerNaCl Modules via apps + a manifest entry can be set up to handle particular mime types.

PPP_MessageHandler

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
HandleMessageembindMessagePort 'message' Event Window 'message' Event
HandleBlockingMessageN/AGAP - No direct equivalentSimilar synchronization can be done off main thread with Atomics.wait. This was added to support emulation of synchronous plugin APIs.

PPP_Messaging

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
HandleMessageembindMessagePort 'message' Event Window 'message' Event

PPP_MouseLock

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
MouseLockLostSDLElement 'pointerlockchange', 'pointerlockerror' Events

PPAPI (Apps)

PPB_HostResolver

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreatexGAPGAP (partial) - No direct equivalent
ResolvexGAPGAP (partial) - No direct equivalent
GetCanonicalNamexGAPGAP (partial) - No direct equivalent
GetNetAddressCountxGAPGAP (partial) - No direct equivalent
GetNetAddressxGAPGAP (partial) - No direct equivalent

PPB_NetAddress

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreateFromIPv4AddressxGAPGAP (partial) - No direct equivalent
CreateFromIPv6AddressxGAPGAP (partial) - No direct equivalent
GetFamilyxGAPGAP (partial) - No direct equivalent
DescribeAsStringxGAPGAP (partial) - No direct equivalent
DescribeAsIPv4AddressxGAPGAP (partial) - No direct equivalent
DescribeAsIPv6AddressxGAPGAP (partial) - No direct equivalent

PPB_NetworkList

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetCountxGAPGAP - No direct equivalent
GetNamexGAPGAP - No direct equivalent
GetTypexGAPGAP - No direct equivalent
GetStatexGAPGAP - No direct equivalent
GetIpAddressxGAPGAP - No direct equivalent
GetDisplayNamexGAPGAP - No direct equivalent
GetMTUxGAPGAP - No direct equivalent

PPB_NetworkMonitor

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
CreatexGAPGAP - No direct equivalent
UpdateNetworkListxGAPGAP - No direct equivalent

PPB_NetworkProxy

PPAPI MethodAssumes ThreadsEmscriptenWeb APILimitations
GetProxyForURLxGAPGAP - No direct equivalent

PPB_TCPSocket and PPB_UDPSocket

There is not a direct 1:1 mapping for migration. Instead, we have outlined some user scenarios below and what the recommended migration path is.
Use CaseRecommendations
Screen sharinggetDisplayMedia and WebRTC ( demo)
Loading from a local server to minimize bandwidth usageXHR, Fetch, Streams, Service Worker, Cache APIs
Loading from a local instance of a web app / Connecting to a local instance of a web appWebRTC
ChatWebSocket*
Realtime audio/video communicationWebRTC
CollaborationWebSocket*
Realtime multiplayer gamesWebTransport** unless P2P in which case WebRTC (or WebTransport over RTCIceTransport)
Realtime interactive streamingWebTransport**
Communicating with legacy serverProxy server or middleware to do protocol conversion. Feedback to bit.ly/network-api-gaps
*: Or WebTransport in the future
**: See chromestatus for availability
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.