Skip to content

Commit 4f98055

Browse files
authored
Update SharedBuffer.md
1 parent 4113f8d commit 4f98055

File tree

1 file changed

+47
-39
lines changed

1 file changed

+47
-39
lines changed

specs/SharedBuffer.md

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ as part of the app. Some examples:
1111
code to print. See https://github.com/MicrosoftEdge/WebView2Feedback/issues/89.
1212
- Native side generates a large amount of data for the web side to consume. The data
1313
might or might not come directly from files. For example the native side has generated
14-
terrabytes of data to produce different graphs on the web side.
14+
terabytes of data to produce different graphs on the web side.
1515
See https://github.com/MicrosoftEdge/WebView2Feedback/issues/1005.
1616

1717
To support these scenarios, we are adding an Edge WebView2 API to support sharing
@@ -30,7 +30,7 @@ from native side via an IStream* object that you can get from the shared buffer
3030
When the application code calls `PostSharedBufferToScript`, the script side will
3131
receive a `SharedBufferReceived` event containing the buffer as an `ArrayBuffer` object.
3232
After receiving the shared buffer object, it can access it the same way as any other
33-
ArrayBuffer object, including transering to a web worker to process the data on
33+
ArrayBuffer object, including transferring to a web worker to process the data on
3434
the worker thread.
3535

3636
As shared buffer normally represent a large memory, instead of waiting for garbage
@@ -53,19 +53,19 @@ The example below illustrates how to send data from application to script for on
5353
The script code will look like this:
5454
```
5555
window.onload = function () {
56-
window.chrome.webview.addEventListener("SharedBufferReceived", e => {
56+
window.chrome.webview.addEventListener("sharedbufferreceived", e => {
5757
SharedBufferReceived(e);
5858
});
5959
}
6060
6161
function SharedBufferReceived(e) {
62-
if (e.data && e.data.readOnly) {
63-
// This is the one time read only buffer
64-
let oneTimeSharedBuffer = e.sharedBuffer;
65-
// Consume the data from the buffer
66-
DisplaySharedBufferData(oneTimeSharedBuffer);
62+
if (e.additionalData && e.additionalData.contosoBufferKind == "contosoDisplayBuffer") {
63+
let displayBuffer = e.getBuffer();
64+
// Consume the data from the buffer (in the form of an ArrayBuffer)
65+
let view = new UInt32Array(displayBuffer);
66+
DisplaySharedBufferData(view);
6767
// Release the buffer after consuming the data.
68-
chrome.webview.releaseBuffer(oneTimeSharedBuffer);
68+
chrome.webview.releaseBuffer(displayBuffer);
6969
}
7070
}
7171
```
@@ -76,18 +76,18 @@ The script code will look like this:
7676
CHECK_FAILURE(webviewEnvironment->CreateSharedBuffer(bufferSize, &sharedBuffer));
7777
// Fill data into the shared memory via IStream.
7878
wil::com_ptr<IStream> stream;
79-
CHECK_FAILURE(sharedBuffer->GetStream(&stream));
79+
CHECK_FAILURE(sharedBuffer->OpenStream(&stream));
8080
CHECK_FAILURE(stream->Write(data, dataSize, nullptr));
81-
PCWSTR additionalDataAsJson = L"{\"readOnly\":true}";
81+
PCWSTR additionalDataAsJson = L"{\"contosoBufferKind\":\"contosoDisplayBuffer\"}";
8282
if (forFrame)
8383
{
8484
m_webviewFrame->PostSharedBufferToScript(
85-
sharedBuffer.get(), /*isReadOnlyToScript*/TRUE, additionalDataAsJson);
85+
sharedBuffer.get(), COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY, additionalDataAsJson);
8686
}
8787
else
8888
{
8989
m_webView->PostSharedBufferToScript(
90-
sharedBuffer.get(), /*isReadOnlyToScript*/TRUE, additionalDataAsJson);
90+
sharedBuffer.get(), COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY, additionalDataAsJson);
9191
}
9292
// Explicitly close the one time shared buffer to ensure that the resource is released timely.
9393
sharedBuffer->Close();
@@ -98,21 +98,21 @@ The script code will look like this:
9898
using (CoreWebView2SharedBuffer sharedBuffer = WebViewEnvironment.CreateSharedBuffer(bufferSize))
9999
{
100100
// Fill data using access Stream
101-
using (Stream stream = sharedBuffer.GetStream())
101+
using (Stream stream = sharedBuffer.OpenStream())
102102
{
103103
using (StreamWriter writer = new StreamWriter(stream))
104104
{
105105
writer.Write(data);
106106
}
107107
}
108-
string additionalDataAsJson = "{\"readOnly\":true}";
108+
string additionalDataAsJson = "{\"contosoBufferKind\":\"contosoDisplayBuffer\"}";
109109
if (forFrame)
110110
{
111-
m_webviewFrame.PostSharedBufferToScript(sharedBuffer, /*isReadOnlyToScript*/true, additionalDataAsJson);
111+
m_webviewFrame.PostSharedBufferToScript(sharedBuffer, CoreWebView2SharedBufferAccess.ReadOnly, additionalDataAsJson);
112112
}
113113
else
114114
{
115-
m_webview.PostSharedBufferToScript(sharedBuffer, /*isReadOnlyToScript*/true, additionalDataAsJson);
115+
m_webview.PostSharedBufferToScript(sharedBuffer, CoreWebView2SharedBufferAccess.ReadOnly, additionalDataAsJson);
116116
}
117117
}
118118
```
@@ -127,7 +127,6 @@ interface ICoreWebView2Environment11 : IUnknown {
127127
/// Once shared, the same content of the buffer will be accessible from both
128128
/// the app process and script in WebView. Modification to the content will be visible
129129
/// to all parties that have access to the buffer.
130-
/// For 32bit application, the creation will fail with E_INVALIDARG if `size` is larger than 4GB.
131130
HRESULT CreateSharedBuffer(
132131
[in] UINT64 size,
133132
[out, retval] ICoreWebView2SharedBuffer** shared_buffer);
@@ -141,15 +140,17 @@ interface ICoreWebView2SharedBuffer : IUnknown {
141140
[propget] HRESULT Buffer([out, retval] BYTE** value);
142141
143142
/// Get an IStream object that can be used to access the shared buffer.
144-
HRESULT GetStream([out, retval] IStream** value);
143+
HRESULT OpenStream([out, retval] IStream** value);
145144
146-
/// The file mapping handle of the shared memory of the buffer.
145+
/// Returns a handle to the file mapping object that backs this shared buffer.
146+
/// The returned handle is owned by the shared buffer object. You should not
147+
/// call CloseHandle on it.
147148
/// Normal app should use `Buffer` or `GetStream` to get memory address
148149
/// or IStream object to access the buffer.
149-
/// For advanced scenarios, you could duplicate this handle to another application
150-
/// process and create a mapping from the duplicated handle in that process to access
151-
/// the buffer from that separate process.
152-
[propget] HRESULT Handle([out, retval] HANDLE* value);
150+
/// For advanced scenarios, you could use file-mapping APIs to obtain other views
151+
/// or duplicate this handle to another application process and create a view from
152+
/// the duplicated handle in that process to access the buffer from that separate process.
153+
[propget] HRESULT FileMappingHandle([out, retval] HANDLE* value);
153154
154155
/// Release the backing shared memory. The application should call this API when no
155156
/// access to the buffer is needed any more, to ensure that the underlying resources
@@ -174,17 +175,24 @@ interface ICoreWebView2SharedBuffer : IUnknown {
174175
HRESULT Close();
175176
}
176177
178+
typedef enum COREWEBVIEW2_SHARED_BUFFER_ACCESS {
179+
// The script only has read access to the shared buffer
180+
COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY,
181+
// The script has read and write access to the shared buffer
182+
COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_WRITE
183+
} COREWEBVIEW2_SHARED_BUFFER_ACCESS;
184+
177185
interface ICoreWebView2_14 : IUnknown {
178186
/// Share a shared buffer object with script of the main frame in the WebView.
179187
/// The script will receive a `SharedBufferReceived` event from chrome.webview.
180-
/// The event arg for that event will have the following properties:
181-
/// `sharedBuffer`: an ArrayBuffer object with the backing content from the shared buffer.
182-
/// `data`: an object as the result of parsing `additionalDataAsJson` as JSON string.
188+
/// The event arg for that event will have the following methods and properties:
189+
/// `getBuffer()`: returns an ArrayBuffer object with the backing content from the shared buffer.
190+
/// `additionalData`: an object as the result of parsing `additionalDataAsJson` as JSON string.
183191
/// This property will be `undefined` if `additionalDataAsJson` is nullptr or empty string.
184192
/// `source`: with a value set as `chrome.webview` object.
185193
/// If a string is provided as `additionalDataAsJson` but it is not a valid JSON string,
186194
/// the API will fail with `E_INVALIDARG`.
187-
/// If `isReadOnlyToScript` is true, the script will only have read access to the buffer.
195+
/// If `access` is COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY, the script will only have read access to the buffer.
188196
/// If the script tries to modify the content in a read only buffer, it will cause an access
189197
/// violation in WebView renderer process and crash the renderer process.
190198
/// If the shared buffer is already closed, the API will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
@@ -199,7 +207,7 @@ interface ICoreWebView2_14 : IUnknown {
199207
/// it could result in corrupted data that might even crash the application.
200208
HRESULT PostSharedBufferToScript(
201209
[in] ICoreWebView2SharedBuffer* sharedBuffer,
202-
[in] BOOL isReadOnlyToScript,
210+
[in] COREWEBVIEW2_SHARED_BUFFER_ACCESS access,
203211
[in] LPCWSTR additionalDataAsJson);
204212
}
205213
@@ -213,7 +221,7 @@ interface ICoreWebView2Frame4 : IUnknown {
213221
/// `source`: with a value set as `chrome.webview` object.
214222
/// If a string is provided as `additionalDataAsJson` but it is not a valid JSON string,
215223
/// the API will fail with `E_INVALIDARG`.
216-
/// If `isReadOnlyToScript` is true, the script will only have read access to the buffer.
224+
/// If `access` is COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY, the script will only have read access to the buffer.
217225
/// If the script tries to modify the content in a read only buffer, it will cause an access
218226
/// violation in WebView renderer process and crash the renderer process.
219227
/// If the shared buffer is already closed, the API will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
@@ -228,7 +236,7 @@ interface ICoreWebView2Frame4 : IUnknown {
228236
/// it could result in corrupted data that might even crash the application.
229237
HRESULT PostSharedBufferToScript(
230238
[in] ICoreWebView2SharedBuffer* sharedBuffer,
231-
[in] BOOL isReadOnlyToScript,
239+
[in] COREWEBVIEW2_SHARED_BUFFER_ACCESS access,
232240
[in] LPCWSTR additionalDataAsJson);
233241
}
234242
@@ -255,27 +263,27 @@ namespace Microsoft.Web.WebView2.Core
255263
public IntPtr Buffer { get; };
256264

257265
/// The native file mapping handle of the shared memory of the buffer.
258-
/// Normal app should use `GetStream` to get a Stream object to access the buffer.
266+
/// Normal app should use `OpenStream` to get a Stream object to access the buffer.
259267
/// For advanced scenario, you could use native APIs to duplicate this handle to
260268
/// another application process and create a mapping from the duplicated handle in
261269
/// that process to access the buffer from that separate process.
262-
public IntPtr Handle { get; };
270+
public System.Runtime.InteropServices.SafeHandle FileMappingHandle { get; };
263271

264-
public Stream GetStream();
272+
public Stream OpenStream();
265273

266274
void Close();
267275
}
268276

269277
runtimeclass CoreWebView2
270278
{
271279
public void PostSharedBufferToScript(
272-
CoreWebView2SharedBuffer sharedBuffer, bool isReadOnlyToScript, string additionalDataAsJson);
280+
CoreWebView2SharedBuffer sharedBuffer, CoreWebView2SharedBufferAccess access, string additionalDataAsJson);
273281
}
274282

275283
class CoreWebView2Frame
276284
{
277285
public void PostSharedBufferToScript(
278-
CoreWebView2SharedBuffer sharedBuffer, bool isReadOnlyToScript, string additionalDataAsJson);
286+
CoreWebView2SharedBuffer sharedBuffer, CoreWebView2SharedBufferAccess access, string additionalDataAsJson);
279287
}
280288
}
281289

@@ -297,7 +305,7 @@ namespace Microsoft.Web.WebView2.Core
297305
{
298306
UInt64 Size { get; };
299307

300-
Windows.Storage.Streams.IRandomAccessStream GetStream();
308+
Windows.Storage.Streams.IRandomAccessStream OpenStream();
301309

302310
[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2SharedBuffer_Manual")]
303311
{
@@ -316,7 +324,7 @@ namespace Microsoft.Web.WebView2.Core
316324
[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_14")]
317325
{
318326
void PostSharedBufferToScript(
319-
CoreWebView2SharedBuffer sharedBuffer, Boolean isReadOnlyToScript, String additionalDataAsJson);
327+
CoreWebView2SharedBuffer sharedBuffer, CoreWebView2SharedBufferAccess access, String additionalDataAsJson);
320328
}
321329
}
322330

@@ -325,7 +333,7 @@ namespace Microsoft.Web.WebView2.Core
325333
[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Frame4")]
326334
{
327335
void PostSharedBufferToScript(
328-
CoreWebView2SharedBuffer sharedBuffer, Boolean isReadOnlyToScript, String additionalDataAsJson);
336+
CoreWebView2SharedBuffer sharedBuffer, CoreWebView2SharedBufferAccess access, String additionalDataAsJson);
329337
}
330338
}
331339
}

0 commit comments

Comments
 (0)