|
7 | 7 |
|
8 | 8 | #include <unordered_set> |
9 | 9 |
|
10 | | -#include "ExternalTexture.h" |
11 | 10 | #include "mozilla/PodOperations.h" |
12 | 11 | #include "mozilla/ScopeExit.h" |
13 | 12 | #include "mozilla/dom/WebGPUBinding.h" |
@@ -172,18 +171,6 @@ extern void wgpu_server_remove_shared_texture(WGPUWebGPUParentPtr aParent, |
172 | 171 | parent->RemoveSharedTexture(aId); |
173 | 172 | } |
174 | 173 |
|
175 | | -extern void wgpu_parent_destroy_external_texture_source( |
176 | | - WGPUWebGPUParentPtr aParent, WGPUExternalTextureSourceId aId) { |
177 | | - auto* const parent = static_cast<WebGPUParent*>(aParent); |
178 | | - parent->DestroyExternalTextureSource(aId); |
179 | | -} |
180 | | - |
181 | | -extern void wgpu_parent_drop_external_texture_source( |
182 | | - WGPUWebGPUParentPtr aParent, WGPUExternalTextureSourceId aId) { |
183 | | - auto* const parent = static_cast<WebGPUParent*>(aParent); |
184 | | - parent->DropExternalTextureSource(aId); |
185 | | -} |
186 | | - |
187 | 174 | extern void wgpu_server_dealloc_buffer_shmem(WGPUWebGPUParentPtr aParent, |
188 | 175 | WGPUBufferId aId) { |
189 | 176 | auto* parent = static_cast<WebGPUParent*>(aParent); |
@@ -371,60 +358,95 @@ extern void wgpu_parent_send_server_message(WGPUWebGPUParentPtr aParent, |
371 | 358 |
|
372 | 359 | } // namespace ffi |
373 | 360 |
|
374 | | -ErrorBuffer::ErrorBuffer() { mMessageUtf8[0] = 0; } |
| 361 | +// A fixed-capacity buffer for receiving textual error messages from |
| 362 | +// `wgpu_bindings`. |
| 363 | +// |
| 364 | +// The `ToFFI` method returns an `ffi::WGPUErrorBuffer` pointing to our |
| 365 | +// buffer, for you to pass to fallible FFI-visible `wgpu_bindings` |
| 366 | +// functions. These indicate failure by storing an error message in the |
| 367 | +// buffer, which you can retrieve by calling `GetError`. |
| 368 | +// |
| 369 | +// If you call `ToFFI` on this type, you must also call `GetError` to check for |
| 370 | +// an error. Otherwise, the destructor asserts. |
| 371 | +// |
| 372 | +// TODO: refactor this to avoid stack-allocating the buffer all the time. |
| 373 | +class ErrorBuffer { |
| 374 | + // if the message doesn't fit, it will be truncated |
| 375 | + static constexpr unsigned BUFFER_SIZE = 512; |
| 376 | + ffi::WGPUErrorBufferType mType = ffi::WGPUErrorBufferType_None; |
| 377 | + char mMessageUtf8[BUFFER_SIZE] = {}; |
| 378 | + bool mAwaitingGetError = false; |
| 379 | + RawId mDeviceId = 0; |
375 | 380 |
|
376 | | -ErrorBuffer::~ErrorBuffer() { MOZ_ASSERT(!mAwaitingGetError); } |
| 381 | + public: |
| 382 | + ErrorBuffer() { mMessageUtf8[0] = 0; } |
| 383 | + ErrorBuffer(const ErrorBuffer&) = delete; |
| 384 | + ~ErrorBuffer() { MOZ_ASSERT(!mAwaitingGetError); } |
| 385 | + |
| 386 | + ffi::WGPUErrorBuffer ToFFI() { |
| 387 | + mAwaitingGetError = true; |
| 388 | + ffi::WGPUErrorBuffer errorBuf = {&mType, mMessageUtf8, BUFFER_SIZE, |
| 389 | + &mDeviceId}; |
| 390 | + return errorBuf; |
| 391 | + } |
| 392 | + |
| 393 | + ffi::WGPUErrorBufferType GetType() { return mType; } |
| 394 | + |
| 395 | + static Maybe<dom::GPUErrorFilter> ErrorTypeToFilterType( |
| 396 | + ffi::WGPUErrorBufferType aType) { |
| 397 | + switch (aType) { |
| 398 | + case ffi::WGPUErrorBufferType_None: |
| 399 | + case ffi::WGPUErrorBufferType_DeviceLost: |
| 400 | + return {}; |
| 401 | + case ffi::WGPUErrorBufferType_Internal: |
| 402 | + return Some(dom::GPUErrorFilter::Internal); |
| 403 | + case ffi::WGPUErrorBufferType_Validation: |
| 404 | + return Some(dom::GPUErrorFilter::Validation); |
| 405 | + case ffi::WGPUErrorBufferType_OutOfMemory: |
| 406 | + return Some(dom::GPUErrorFilter::Out_of_memory); |
| 407 | + case ffi::WGPUErrorBufferType_Sentinel: |
| 408 | + break; |
| 409 | + } |
377 | 410 |
|
378 | | -ffi::WGPUErrorBuffer ErrorBuffer::ToFFI() { |
379 | | - mAwaitingGetError = true; |
380 | | - ffi::WGPUErrorBuffer errorBuf = {&mType, mMessageUtf8, BUFFER_SIZE, |
381 | | - &mDeviceId}; |
382 | | - return errorBuf; |
383 | | -} |
| 411 | + MOZ_CRASH("invalid `ErrorBufferType`"); |
| 412 | + } |
384 | 413 |
|
385 | | -ffi::WGPUErrorBufferType ErrorBuffer::GetType() { return mType; } |
| 414 | + struct Error { |
| 415 | + dom::GPUErrorFilter type; |
| 416 | + bool isDeviceLost; |
| 417 | + nsCString message; |
| 418 | + RawId deviceId; |
| 419 | + }; |
386 | 420 |
|
387 | | -Maybe<dom::GPUErrorFilter> ErrorBuffer::ErrorTypeToFilterType( |
388 | | - ffi::WGPUErrorBufferType aType) { |
389 | | - switch (aType) { |
390 | | - case ffi::WGPUErrorBufferType_None: |
391 | | - case ffi::WGPUErrorBufferType_DeviceLost: |
| 421 | + // Retrieve the error message was stored in this buffer. Asserts that |
| 422 | + // this instance actually contains an error (viz., that `GetType() != |
| 423 | + // ffi::WGPUErrorBufferType_None`). |
| 424 | + // |
| 425 | + // Mark this `ErrorBuffer` as having been handled, so its destructor |
| 426 | + // won't assert. |
| 427 | + Maybe<Error> GetError() { |
| 428 | + mAwaitingGetError = false; |
| 429 | + if (mType == ffi::WGPUErrorBufferType_DeviceLost) { |
| 430 | + // This error is for a lost device, so we return an Error struct |
| 431 | + // with the isDeviceLost bool set to true. It doesn't matter what |
| 432 | + // GPUErrorFilter type we use, so we just use Validation. The error |
| 433 | + // will not be reported. |
| 434 | + return Some(Error{dom::GPUErrorFilter::Validation, true, |
| 435 | + nsCString{mMessageUtf8}, mDeviceId}); |
| 436 | + } |
| 437 | + auto filterType = ErrorTypeToFilterType(mType); |
| 438 | + if (!filterType) { |
392 | 439 | return {}; |
393 | | - case ffi::WGPUErrorBufferType_Internal: |
394 | | - return Some(dom::GPUErrorFilter::Internal); |
395 | | - case ffi::WGPUErrorBufferType_Validation: |
396 | | - return Some(dom::GPUErrorFilter::Validation); |
397 | | - case ffi::WGPUErrorBufferType_OutOfMemory: |
398 | | - return Some(dom::GPUErrorFilter::Out_of_memory); |
399 | | - case ffi::WGPUErrorBufferType_Sentinel: |
400 | | - break; |
| 440 | + } |
| 441 | + return Some(Error{*filterType, false, nsCString{mMessageUtf8}, mDeviceId}); |
401 | 442 | } |
402 | 443 |
|
403 | | - MOZ_CRASH("invalid `ErrorBufferType`"); |
404 | | -} |
405 | | - |
406 | | -Maybe<ErrorBuffer::Error> ErrorBuffer::GetError() { |
407 | | - mAwaitingGetError = false; |
408 | | - if (mType == ffi::WGPUErrorBufferType_DeviceLost) { |
409 | | - // This error is for a lost device, so we return an Error struct |
410 | | - // with the isDeviceLost bool set to true. It doesn't matter what |
411 | | - // GPUErrorFilter type we use, so we just use Validation. The error |
412 | | - // will not be reported. |
413 | | - return Some(Error{dom::GPUErrorFilter::Validation, true, |
414 | | - nsCString{mMessageUtf8}, mDeviceId}); |
415 | | - } |
416 | | - auto filterType = ErrorTypeToFilterType(mType); |
417 | | - if (!filterType) { |
418 | | - return {}; |
419 | | - } |
420 | | - return Some(Error{*filterType, false, nsCString{mMessageUtf8}, mDeviceId}); |
421 | | -} |
422 | | - |
423 | | -void ErrorBuffer::CoerceValidationToInternal() { |
424 | | - if (mType == ffi::WGPUErrorBufferType_Validation) { |
425 | | - mType = ffi::WGPUErrorBufferType_Internal; |
| 444 | + void CoerceValidationToInternal() { |
| 445 | + if (mType == ffi::WGPUErrorBufferType_Validation) { |
| 446 | + mType = ffi::WGPUErrorBufferType_Internal; |
| 447 | + } |
426 | 448 | } |
427 | | -} |
| 449 | +}; |
428 | 450 |
|
429 | 451 | struct PendingSwapChainDrop { |
430 | 452 | layers::RemoteTextureTxnType mTxnType; |
@@ -792,28 +814,6 @@ void WebGPUParent::RemoveSharedTexture(RawId aTextureId) { |
792 | 814 | } |
793 | 815 | } |
794 | 816 |
|
795 | | -void WebGPUParent::DestroyExternalTextureSource(RawId aSourceId) { |
796 | | - auto it = mExternalTextureSources.find(aSourceId); |
797 | | - if (it != mExternalTextureSources.end()) { |
798 | | - for (const auto textureId : it->second.TextureIds()) { |
799 | | - ffi::wgpu_server_texture_destroy(mContext.get(), textureId); |
800 | | - } |
801 | | - } |
802 | | -} |
803 | | - |
804 | | -void WebGPUParent::DropExternalTextureSource(RawId aSourceId) { |
805 | | - auto it = mExternalTextureSources.find(aSourceId); |
806 | | - if (it != mExternalTextureSources.end()) { |
807 | | - for (const auto viewId : it->second.ViewIds()) { |
808 | | - ffi::wgpu_server_texture_view_drop(mContext.get(), viewId); |
809 | | - } |
810 | | - for (const auto textureId : it->second.TextureIds()) { |
811 | | - ffi::wgpu_server_texture_drop(mContext.get(), textureId); |
812 | | - } |
813 | | - mExternalTextureSources.erase(it); |
814 | | - } |
815 | | -} |
816 | | - |
817 | 817 | void WebGPUParent::QueueSubmit(RawId aQueueId, RawId aDeviceId, |
818 | 818 | Span<const RawId> aCommandBuffers, |
819 | 819 | Span<const RawId> aTextureIds) { |
@@ -1564,18 +1564,6 @@ ipc::IPCResult WebGPUParent::RecvMessages( |
1564 | 1564 | return IPC_OK(); |
1565 | 1565 | } |
1566 | 1566 |
|
1567 | | -ipc::IPCResult WebGPUParent::RecvCreateExternalTextureSource( |
1568 | | - RawId aDeviceId, RawId aQueueId, RawId aExternalTextureSourceId, |
1569 | | - const ExternalTextureSourceDescriptor& aDesc) { |
1570 | | - MOZ_RELEASE_ASSERT(mExternalTextureSources.find(aExternalTextureSourceId) == |
1571 | | - mExternalTextureSources.end()); |
1572 | | - mExternalTextureSources.emplace( |
1573 | | - aExternalTextureSourceId, |
1574 | | - ExternalTextureSourceHost::Create(this, aDeviceId, aQueueId, aDesc)); |
1575 | | - |
1576 | | - return IPC_OK(); |
1577 | | -} |
1578 | | - |
1579 | 1567 | void WebGPUParent::DevicePushErrorScope(RawId aDeviceId, |
1580 | 1568 | const dom::GPUErrorFilter aFilter) { |
1581 | 1569 | const auto& itr = mErrorScopeStackByDevice.find(aDeviceId); |
|
0 commit comments