// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/command_buffer/client/webgpu_implementation.h"

#include <algorithm>
#include <vector>

#include <dawn/dawn_proc.h>

#include "base/numerics/checked_math.h"
#include "base/run_loop.h"
#include "base/trace_event/trace_event.h"
#include "gpu/command_buffer/client/dawn_client_memory_transfer_service.h"
#include "gpu/command_buffer/client/dawn_client_serializer.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"

#define GPU_CLIENT_SINGLE_THREAD_CHECK()

namespace gpu {
namespace webgpu {

#if BUILDFLAG(USE_DAWN)
class DawnWireServices : public APIChannel {
 private:
  friend class base::RefCounted<DawnWireServices>;
  ~DawnWireServices() override = default;

 public:
  DawnWireServices(WebGPUImplementation* webgpu_implementation,
                   WebGPUCmdHelper* helper,
                   MappedMemoryManager* mapped_memory,
                   std::unique_ptr<TransferBuffer> transfer_buffer)
      : memory_transfer_service_(mapped_memory),
        serializer_(webgpu_implementation,
                    helper,
                    &memory_transfer_service_,
                    std::move(transfer_buffer)),
        wire_client_(dawn_wire::WireClientDescriptor{
            &serializer_,
            &memory_transfer_service_,
        }) {}

  const DawnProcTable& GetProcs() const override {
    return dawn_wire::client::GetProcs();
  }

  dawn_wire::WireClient* wire_client() { return &wire_client_; }
  DawnClientSerializer* serializer() { return &serializer_; }
  DawnClientMemoryTransferService* memory_transfer_service() {
    return &memory_transfer_service_;
  }

  void Disconnect() override {
    disconnected_ = true;
    wire_client_.Disconnect();
    serializer_.Disconnect();
    memory_transfer_service_.Disconnect();
  }

  bool IsDisconnected() const { return disconnected_; }

  void FreeMappedResources(WebGPUCmdHelper* helper) {
    memory_transfer_service_.FreeHandles(helper);
  }

 private:
  bool disconnected_ = false;
  DawnClientMemoryTransferService memory_transfer_service_;
  DawnClientSerializer serializer_;
  dawn_wire::WireClient wire_client_;
};
#endif

// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.
#include "gpu/command_buffer/client/webgpu_implementation_impl_autogen.h"

WebGPUImplementation::WebGPUImplementation(
    WebGPUCmdHelper* helper,
    TransferBufferInterface* transfer_buffer,
    GpuControl* gpu_control)
    : ImplementationBase(helper, transfer_buffer, gpu_control),
      helper_(helper) {}

WebGPUImplementation::~WebGPUImplementation() {
  LoseContext();

  // Before destroying WebGPUImplementation, all mappable buffers
  // must be destroyed first. This means that all shared memory mappings are
  // detached. If they are not destroyed, MappedMemoryManager (member of
  // base class ImplementationBase) will assert on destruction that some
  // memory blocks are in use. Calling |FreeMappedResources| marks all
  // blocks that are no longer in use as free.
#if BUILDFLAG(USE_DAWN)
  dawn_wire_->FreeMappedResources(helper_);
#endif

  // Wait for commands to finish before we continue destruction.
  // WebGPUImplementation no longer owns the WebGPU transfer buffer, but still
  // owns the GPU command buffer. We should not free shared memory that the
  // GPU process is using.
  helper_->Finish();
}

void WebGPUImplementation::LoseContext() {
  lost_ = true;
#if BUILDFLAG(USE_DAWN)
  dawn_wire_->Disconnect();

  auto request_adapter_callback_map = std::move(request_adapter_callback_map_);
  auto request_device_callback_map = std::move(request_device_callback_map_);
  for (auto& it : request_adapter_callback_map) {
    std::move(it.second).Run(-1, {}, "Context Lost");
  }
  for (auto& it : request_device_callback_map) {
    std::move(it.second).Run(false, nullptr, "Context Lost");
  }

  // After |lost_| is set to true, callbacks should not be enqueued anymore.
  DCHECK(request_adapter_callback_map_.empty());
  DCHECK(request_device_callback_map_.empty());
#endif
}

gpu::ContextResult WebGPUImplementation::Initialize(
    const SharedMemoryLimits& limits) {
  TRACE_EVENT0("gpu", "WebGPUImplementation::Initialize");
  auto result = ImplementationBase::Initialize(limits);
  if (result != gpu::ContextResult::kSuccess) {
    return result;
  }

  std::unique_ptr<TransferBuffer> transfer_buffer =
      std::make_unique<TransferBuffer>(helper_);
  if (!transfer_buffer->Initialize(limits.start_transfer_buffer_size,
                                   /* start offset */ 0,
                                   limits.min_transfer_buffer_size,
                                   limits.max_transfer_buffer_size,
                                   /* alignment */ 8)) {
    return gpu::ContextResult::kFatalFailure;
  }

#if BUILDFLAG(USE_DAWN)
  dawn_wire_ = base::MakeRefCounted<DawnWireServices>(
      this, helper_, mapped_memory_.get(), std::move(transfer_buffer));

  // TODO(senorblanco): Do this only once per process. Doing it once per
  // WebGPUImplementation is non-optimal but valid, since the returned
  // procs are always the same.
  dawnProcSetProcs(&dawn_wire::client::GetProcs());
#endif

  return gpu::ContextResult::kSuccess;
}

// ContextSupport implementation.
void WebGPUImplementation::SetAggressivelyFreeResources(
    bool aggressively_free_resources) {
  NOTIMPLEMENTED();
}
void WebGPUImplementation::Swap(uint32_t flags,
                                SwapCompletedCallback complete_callback,
                                PresentationCallback presentation_callback) {
  NOTIMPLEMENTED();
}
void WebGPUImplementation::SwapWithBounds(
    const std::vector<gfx::Rect>& rects,
    uint32_t flags,
    SwapCompletedCallback swap_completed,
    PresentationCallback presentation_callback) {
  NOTIMPLEMENTED();
}
void WebGPUImplementation::PartialSwapBuffers(
    const gfx::Rect& sub_buffer,
    uint32_t flags,
    SwapCompletedCallback swap_completed,
    PresentationCallback presentation_callback) {
  NOTIMPLEMENTED();
}
void WebGPUImplementation::CommitOverlayPlanes(
    uint32_t flags,
    SwapCompletedCallback swap_completed,
    PresentationCallback presentation_callback) {
  NOTREACHED();
}
void WebGPUImplementation::ScheduleOverlayPlane(
    int plane_z_order,
    gfx::OverlayTransform plane_transform,
    unsigned overlay_texture_id,
    const gfx::Rect& display_bounds,
    const gfx::RectF& uv_rect,
    bool enable_blend,
    unsigned gpu_fence_id) {
  NOTREACHED();
}
uint64_t WebGPUImplementation::ShareGroupTracingGUID() const {
  NOTIMPLEMENTED();
  return 0;
}
void WebGPUImplementation::SetErrorMessageCallback(
    base::RepeatingCallback<void(const char*, int32_t)> callback) {
  NOTIMPLEMENTED();
}
bool WebGPUImplementation::ThreadSafeShallowLockDiscardableTexture(
    uint32_t texture_id) {
  NOTREACHED();
  return false;
}
void WebGPUImplementation::CompleteLockDiscardableTexureOnContextThread(
    uint32_t texture_id) {
  NOTREACHED();
}
bool WebGPUImplementation::ThreadsafeDiscardableTextureIsDeletedForTracing(
    uint32_t texture_id) {
  NOTREACHED();
  return false;
}
void* WebGPUImplementation::MapTransferCacheEntry(uint32_t serialized_size) {
  NOTREACHED();
  return nullptr;
}
void WebGPUImplementation::UnmapAndCreateTransferCacheEntry(uint32_t type,
                                                            uint32_t id) {
  NOTREACHED();
}
bool WebGPUImplementation::ThreadsafeLockTransferCacheEntry(uint32_t type,
                                                            uint32_t id) {
  NOTREACHED();
  return false;
}
void WebGPUImplementation::UnlockTransferCacheEntries(
    const std::vector<std::pair<uint32_t, uint32_t>>& entries) {
  NOTREACHED();
}
void WebGPUImplementation::DeleteTransferCacheEntry(uint32_t type,
                                                    uint32_t id) {
  NOTREACHED();
}
unsigned int WebGPUImplementation::GetTransferBufferFreeSize() const {
  NOTREACHED();
  return 0;
}
bool WebGPUImplementation::IsJpegDecodeAccelerationSupported() const {
  NOTREACHED();
  return false;
}
bool WebGPUImplementation::IsWebPDecodeAccelerationSupported() const {
  NOTREACHED();
  return false;
}
bool WebGPUImplementation::CanDecodeWithHardwareAcceleration(
    const cc::ImageHeaderMetadata* image_metadata) const {
  NOTREACHED();
  return false;
}

// InterfaceBase implementation.
void WebGPUImplementation::GenSyncTokenCHROMIUM(GLbyte* sync_token) {
  // Need to commit the commands to the GPU command buffer first for SyncToken
  // to work.
#if BUILDFLAG(USE_DAWN)
  dawn_wire_->serializer()->Commit();
#endif
  ImplementationBase::GenSyncToken(sync_token);
}
void WebGPUImplementation::GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) {
  // Need to commit the commands to the GPU command buffer first for SyncToken
  // to work.
#if BUILDFLAG(USE_DAWN)
  dawn_wire_->serializer()->Commit();
#endif
  ImplementationBase::GenUnverifiedSyncToken(sync_token);
}
void WebGPUImplementation::VerifySyncTokensCHROMIUM(GLbyte** sync_tokens,
                                                    GLsizei count) {
  ImplementationBase::VerifySyncTokens(sync_tokens, count);
}
void WebGPUImplementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {
  // Need to commit the commands to the GPU command buffer first for SyncToken
  // to work.
#if BUILDFLAG(USE_DAWN)
  dawn_wire_->serializer()->Commit();
#endif
  ImplementationBase::WaitSyncToken(sync_token);
}
void WebGPUImplementation::ShallowFlushCHROMIUM() {
  FlushCommands();
}

bool WebGPUImplementation::HasGrContextSupport() const {
  return true;
}

// ImplementationBase implementation.
void WebGPUImplementation::IssueShallowFlush() {
  NOTIMPLEMENTED();
}

void WebGPUImplementation::SetGLError(GLenum error,
                                      const char* function_name,
                                      const char* msg) {
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] Client Synthesized Error: "
                     << gles2::GLES2Util::GetStringError(error) << ": "
                     << function_name << ": " << msg);
  NOTIMPLEMENTED();
}

// GpuControlClient implementation.
void WebGPUImplementation::OnGpuControlLostContext() {
  LoseContext();

  // This should never occur more than once.
  DCHECK(!lost_context_callback_run_);
  lost_context_callback_run_ = true;
  if (!lost_context_callback_.is_null()) {
    std::move(lost_context_callback_).Run();
  }
}
void WebGPUImplementation::OnGpuControlLostContextMaybeReentrant() {
  // If this function is called, we are guaranteed to also get a call
  // to |OnGpuControlLostContext| when the callstack unwinds. Thus, this
  // function only handles immediately setting state so that other operations
  // which occur while the callstack is unwinding are aware that the context
  // is lost.
  lost_ = true;
}
void WebGPUImplementation::OnGpuControlErrorMessage(const char* message,
                                                    int32_t id) {
  NOTIMPLEMENTED();
}
void WebGPUImplementation::OnGpuControlSwapBuffersCompleted(
    const SwapBuffersCompleteParams& params,
    gfx::GpuFenceHandle release_fence) {
  NOTIMPLEMENTED();
}
void WebGPUImplementation::OnSwapBufferPresented(
    uint64_t swap_id,
    const gfx::PresentationFeedback& feedback) {
  NOTIMPLEMENTED();
}
void WebGPUImplementation::OnGpuControlReturnData(
    base::span<const uint8_t> data) {
  if (lost_) {
    return;
  }
#if BUILDFLAG(USE_DAWN)

  static uint32_t return_trace_id = 0;
  TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"),
                         "DawnReturnCommands", TRACE_EVENT_FLAG_FLOW_IN,
                         return_trace_id++);

  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"),
               "WebGPUImplementation::OnGpuControlReturnData", "bytes",
               data.size());

  CHECK_GT(data.size(), sizeof(cmds::DawnReturnDataHeader));

  const cmds::DawnReturnDataHeader& dawnReturnDataHeader =
      *reinterpret_cast<const cmds::DawnReturnDataHeader*>(data.data());

  switch (dawnReturnDataHeader.return_data_type) {
    case DawnReturnDataType::kDawnCommands: {
      CHECK_GE(data.size(), sizeof(cmds::DawnReturnCommandsInfo));

      const cmds::DawnReturnCommandsInfo* dawn_return_commands_info =
          reinterpret_cast<const cmds::DawnReturnCommandsInfo*>(data.data());
      if (dawn_wire_->IsDisconnected()) {
        break;
      }
      // TODO(enga): Instead of a CHECK, this could generate a device lost
      // event on just that device. It doesn't seem worth doing right now
      // since a failure here is likely not recoverable.
      CHECK(dawn_wire_->wire_client()->HandleCommands(
          reinterpret_cast<const char*>(
              dawn_return_commands_info->deserialized_buffer),
          data.size() -
              offsetof(cmds::DawnReturnCommandsInfo, deserialized_buffer)));
    } break;
    case DawnReturnDataType::kRequestedDawnAdapterProperties: {
      CHECK_GE(data.size(),
               offsetof(cmds::DawnReturnAdapterInfo, deserialized_buffer));

      const cmds::DawnReturnAdapterInfo* returned_adapter_info =
          reinterpret_cast<const cmds::DawnReturnAdapterInfo*>(data.data());

      DawnRequestAdapterSerial request_adapter_serial =
          returned_adapter_info->header.request_adapter_serial;
      auto request_callback_iter =
          request_adapter_callback_map_.find(request_adapter_serial);
      CHECK(request_callback_iter != request_adapter_callback_map_.end());
      RequestAdapterCallback callback =
          std::move(request_callback_iter->second);
      // Remove the callback from the map immediately since the callback could
      // perform reentrant calls that modify the map.
      request_adapter_callback_map_.erase(request_callback_iter);

      GLuint adapter_service_id =
          returned_adapter_info->header.adapter_service_id;
      WGPUDeviceProperties adapter_properties = {};
      const volatile char* deserialized_buffer =
          reinterpret_cast<const volatile char*>(
              returned_adapter_info->deserialized_buffer);
      const char* error_message =
          returned_adapter_info->deserialized_buffer +
          returned_adapter_info->adapter_properties_size;
      if (strlen(error_message) == 0) {
        error_message = nullptr;
      }
      if (returned_adapter_info->adapter_properties_size > 0) {
        if (!dawn_wire::DeserializeWGPUDeviceProperties(
                &adapter_properties,
                deserialized_buffer,
                returned_adapter_info->adapter_properties_size)) {
          adapter_service_id = -1;
          adapter_properties = {};
          error_message = "Request adapter failed";
        }
      }
      std::move(callback).Run(adapter_service_id, adapter_properties,
                              error_message);
    } break;
    case DawnReturnDataType::kRequestedDeviceReturnInfo: {
      CHECK_GE(data.size(), offsetof(cmds::DawnReturnRequestDeviceInfo,
                                     deserialized_buffer));

      const cmds::DawnReturnRequestDeviceInfo* returned_request_device_info =
          reinterpret_cast<const cmds::DawnReturnRequestDeviceInfo*>(
              data.data());

      DawnRequestDeviceSerial request_device_serial =
          returned_request_device_info->request_device_serial;
      auto request_callback_iter =
          request_device_callback_map_.find(request_device_serial);
      CHECK(request_callback_iter != request_device_callback_map_.end());
      RequestDeviceCallback callback = std::move(request_callback_iter->second);
      // Remove the callback from the map immediately since the callback could
      // perform reentrant calls that modify the map.
      request_device_callback_map_.erase(request_callback_iter);

      bool success = returned_request_device_info->is_request_device_success &&
                     returned_request_device_info->limits_size > 0;

      WGPUSupportedLimits limits;
      limits.nextInChain = nullptr;

      const volatile char* deserialized_buffer =
          reinterpret_cast<const volatile char*>(
              returned_request_device_info->deserialized_buffer);
      const char* error_message =
          returned_request_device_info->deserialized_buffer +
          returned_request_device_info->limits_size;
      if (strlen(error_message) == 0) {
        error_message = nullptr;
      }
      if (success) {
        if (!dawn_wire::DeserializeWGPUSupportedLimits(
                &limits, deserialized_buffer,
                returned_request_device_info->limits_size)) {
          success = false;
          error_message = "Request device failed";
        }
      }

      std::move(callback).Run(success, &limits, error_message);
    } break;
    default:
      NOTREACHED();
  }
#endif
}

void WebGPUImplementation::FlushCommands() {
#if BUILDFLAG(USE_DAWN)
  dawn_wire_->serializer()->Commit();
  helper_->Flush();
#endif
}

void WebGPUImplementation::EnsureAwaitingFlush(bool* needs_flush) {
#if BUILDFLAG(USE_DAWN)
  // If there is already a flush waiting, we don't need to flush.
  // We only want to set |needs_flush| on state transition from
  // false -> true.
  if (dawn_wire_->serializer()->AwaitingFlush()) {
    *needs_flush = false;
    return;
  }

  // Set the state to waiting for flush, and then write |needs_flush|.
  // Could still be false if there's no data to flush.
  dawn_wire_->serializer()->SetAwaitingFlush(true);
  *needs_flush = dawn_wire_->serializer()->AwaitingFlush();
#else
  *needs_flush = false;
#endif
}

void WebGPUImplementation::FlushAwaitingCommands() {
#if BUILDFLAG(USE_DAWN)
  if (dawn_wire_->serializer()->AwaitingFlush()) {
    dawn_wire_->serializer()->Commit();
    helper_->Flush();
  }
#endif
}

scoped_refptr<APIChannel> WebGPUImplementation::GetAPIChannel() const {
#if BUILDFLAG(USE_DAWN)
  return dawn_wire_.get();
#else
  return nullptr;
#endif
}

ReservedTexture WebGPUImplementation::ReserveTexture(WGPUDevice device) {
#if BUILDFLAG(USE_DAWN)
  // Commit because we need to make sure messages that free a previously used
  // texture are seen first. ReserveTexture may reuse an existing ID.
  dawn_wire_->serializer()->Commit();

  auto reservation = dawn_wire_->wire_client()->ReserveTexture(device);
  ReservedTexture result;
  result.texture = reservation.texture;
  result.id = reservation.id;
  result.generation = reservation.generation;
  result.deviceId = reservation.deviceId;
  result.deviceGeneration = reservation.deviceGeneration;
  return result;
#else
  NOTREACHED();
  return {};
#endif
}

DawnRequestAdapterSerial WebGPUImplementation::NextRequestAdapterSerial() {
  return ++request_adapter_serial_;
}

void WebGPUImplementation::RequestAdapterAsync(
    PowerPreference power_preference,
    base::OnceCallback<void(int32_t, const WGPUDeviceProperties&, const char*)>
        request_adapter_callback) {
  if (lost_) {
    std::move(request_adapter_callback).Run(-1, {}, "Context Lost");
    return;
  }

  // Now that we declare request_adapter_serial as an uint64, it can't overflow
  // because we just increment an uint64 by one.
  DawnRequestAdapterSerial request_adapter_serial = NextRequestAdapterSerial();
  DCHECK(request_adapter_callback_map_.find(request_adapter_serial) ==
         request_adapter_callback_map_.end());

  request_adapter_callback_map_[request_adapter_serial] =
      std::move(request_adapter_callback);

  helper_->RequestAdapter(request_adapter_serial,
                          static_cast<uint32_t>(power_preference));
  helper_->Flush();
}

DawnRequestDeviceSerial WebGPUImplementation::NextRequestDeviceSerial() {
  return ++request_device_serial_;
}

void WebGPUImplementation::RequestDeviceAsync(
    uint32_t requested_adapter_id,
    const WGPUDeviceProperties& requested_device_properties,
    base::OnceCallback<void(WGPUDevice,
                            const WGPUSupportedLimits*,
                            const char*)> request_device_callback) {
#if BUILDFLAG(USE_DAWN)
  if (lost_) {
    std::move(request_device_callback)
        .Run(nullptr, nullptr, "GPU connection lost");
    return;
  }

  size_t serialized_device_properties_size =
      dawn_wire::SerializedWGPUDevicePropertiesSize(
          &requested_device_properties);
  DCHECK_NE(0u, serialized_device_properties_size);

  DCHECK_LE(serialized_device_properties_size, transfer_buffer_->GetMaxSize());

  ScopedTransferBufferPtr buffer(serialized_device_properties_size, helper_,
                                 transfer_buffer_);

  if (!buffer.valid() || buffer.size() < serialized_device_properties_size) {
    std::move(request_device_callback)
        .Run(nullptr, nullptr, "Failed to request device");
    return;
  }

  // We declare DawnRequestDeviceSerial as an uint64, so it can't overflow
  // because we just increment an uint64 by one.
  DawnRequestDeviceSerial request_device_serial = NextRequestDeviceSerial();
  DCHECK(request_device_callback_map_.find(request_device_serial) ==
         request_device_callback_map_.end());

  // Commit because we need to make sure messages that free a previously used
  // device are seen first. ReserveDevice may reuse an existing ID.
  dawn_wire_->serializer()->Commit();

  dawn_wire::ReservedDevice reservation =
      dawn_wire_->wire_client()->ReserveDevice();

  request_device_callback_map_[request_device_serial] = base::BindOnce(
      [](scoped_refptr<DawnWireServices> dawn_wire,
         dawn_wire::ReservedDevice reservation,
         base::OnceCallback<void(WGPUDevice, const WGPUSupportedLimits*,
                                 const char*)> callback,
         bool success, const WGPUSupportedLimits* limits,
         const char* error_message) {
        WGPUDevice device = reservation.device;
        if (!success) {
          dawn_wire->wire_client()->ReclaimDeviceReservation(reservation);
          device = nullptr;
        }
        std::move(callback).Run(device, limits, error_message);
      },
      dawn_wire_, reservation, std::move(request_device_callback));

  dawn_wire::SerializeWGPUDeviceProperties(
      &requested_device_properties, reinterpret_cast<char*>(buffer.address()));

  helper_->RequestDevice(request_device_serial, requested_adapter_id,
                         reservation.id, reservation.generation,
                         buffer.shm_id(), buffer.offset(),
                         serialized_device_properties_size);
  buffer.Release();
  helper_->Flush();
#endif
}

WGPUDevice WebGPUImplementation::DeprecatedEnsureDefaultDeviceSync() {
  if (deprecated_default_device_ != nullptr) {
    return deprecated_default_device_;
  }

  DLOG(WARNING) << "Using deprecated WebGPU device initialization";

  base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
  RequestAdapterAsync(
      PowerPreference::kDefault,
      base::BindOnce(
          [](WebGPUImplementation* self, WGPUDevice* result,
             base::OnceCallback<void()> done, int32_t adapter_id,
             const WGPUDeviceProperties& properties, const char* name) {
            if (adapter_id < 0) {
              std::move(done).Run();
              return;
            }
            self->RequestDeviceAsync(
                static_cast<uint32_t>(adapter_id), properties,
                base::BindOnce(
                    [](WGPUDevice* result, base::OnceCallback<void()> done,
                       WGPUDevice device, const WGPUSupportedLimits*,
                       const char*) {
                      *result = device;
                      std::move(done).Run();
                    },
                    result, std::move(done)));
          },
          this, &deprecated_default_device_, run_loop.QuitClosure()));
  run_loop.Run();

  return deprecated_default_device_;
}

void WebGPUImplementation::AssociateMailbox(GLuint device_id,
                                            GLuint device_generation,
                                            GLuint texture_id,
                                            GLuint texture_generation,
                                            GLuint usage,
                                            MailboxFlags flags,
                                            const GLbyte* mailbox) {
#if BUILDFLAG(USE_DAWN)
  // Commit previous Dawn commands as they may manipulate texture object IDs
  // and need to be resolved prior to the AssociateMailbox command. Otherwise
  // the service side might not know, for example that the previous texture
  // using that ID has been released.
  dawn_wire_->serializer()->Commit();
  helper_->AssociateMailboxImmediate(device_id, device_generation, texture_id,
                                     texture_generation, usage, flags, mailbox);
#endif
}

void WebGPUImplementation::DissociateMailbox(GLuint texture_id,
                                             GLuint texture_generation) {
#if BUILDFLAG(USE_DAWN)
  // Commit previous Dawn commands that might be rendering to the texture, prior
  // to Dissociating the shared image from that texture.
  dawn_wire_->serializer()->Commit();
  helper_->DissociateMailbox(texture_id, texture_generation);
#endif
}

void WebGPUImplementation::DissociateMailboxForPresent(
    GLuint device_id,
    GLuint device_generation,
    GLuint texture_id,
    GLuint texture_generation) {
#if BUILDFLAG(USE_DAWN)
  // Commit previous Dawn commands that might be rendering to the texture, prior
  // to Dissociating the shared image from that texture.
  dawn_wire_->serializer()->Commit();
  helper_->DissociateMailboxForPresent(device_id, device_generation, texture_id,
                                       texture_generation);
#endif
}

}  // namespace webgpu
}  // namespace gpu
