// 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/ipc/service/shared_image_stub.h"

#include "base/trace_event/trace_event.h"
#include "gpu/command_buffer/service/scheduler.h"
#include "gpu/command_buffer/service/shared_image_factory.h"
#include "gpu/ipc/common/command_buffer_id.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/service/gpu_channel.h"
#include "gpu/ipc/service/gpu_channel_manager.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "ui/gl/gl_context.h"

namespace gpu {

SharedImageStub::SharedImageStub(GpuChannel* channel, int32_t route_id)
    : channel_(channel),
      sequence_(channel->scheduler()->CreateSequence(SchedulingPriority::kLow)),
      sync_point_client_state_(
          channel->sync_point_manager()->CreateSyncPointClientState(
              CommandBufferNamespace::GPU_IO,
              CommandBufferIdFromChannelAndRoute(channel->client_id(),
                                                 route_id),
              sequence_)) {}

SharedImageStub::~SharedImageStub() {
  channel_->scheduler()->DestroySequence(sequence_);
  sync_point_client_state_->Destroy();
  if (factory_ && factory_->HasImages()) {
    bool have_context = MakeContextCurrentAndCreateFactory();
    factory_->DestroyAllSharedImages(have_context);
  }
}

bool SharedImageStub::OnMessageReceived(const IPC::Message& msg) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(SharedImageStub, msg)
    IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateSharedImage, OnCreateSharedImage)
    IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroySharedImage, OnDestroySharedImage)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void SharedImageStub::OnCreateSharedImage(
    const GpuChannelMsg_CreateSharedImage_Params& params) {
  TRACE_EVENT2("gpu", "SharedImageStub::OnCreateSharedImage", "width",
               params.size.width(), "height", params.size.height());
  if (!MakeContextCurrentAndCreateFactory())
    return;

  if (!factory_->CreateSharedImage(params.mailbox, params.format, params.size,
                                   params.color_space, params.usage)) {
    LOG(ERROR) << "SharedImageStub: Unable to create shared image";
    OnError();
    return;
  }
  sync_point_client_state_->ReleaseFenceSync(params.release_id);
}

void SharedImageStub::OnDestroySharedImage(const Mailbox& mailbox) {
  TRACE_EVENT0("gpu", "SharedImageStub::OnDestroySharedImage");
  if (!MakeContextCurrentAndCreateFactory())
    return;

  if (!factory_->DestroySharedImage(mailbox)) {
    LOG(ERROR) << "SharedImageStub: Unable to destroy shared image";
    OnError();
    return;
  }
}

bool SharedImageStub::MakeContextCurrentAndCreateFactory() {
  if (!factory_) {
    auto* channel_manager = channel_->gpu_channel_manager();
    DCHECK(!context_state_);
    ContextResult result;
    context_state_ = channel_manager->GetRasterDecoderContextState(&result);
    if (result != ContextResult::kSuccess) {
      LOG(ERROR) << "SharedImageStub: unable to create context";
      OnError();
      return false;
    }
    DCHECK(context_state_);
    DCHECK(!context_state_->context_lost);
    DCHECK(context_state_->context->IsCurrent(nullptr));
    gpu::GpuMemoryBufferFactory* gmb_factory =
        channel_manager->gpu_memory_buffer_factory();
    factory_ = std::make_unique<SharedImageFactory>(
        channel_manager->gpu_preferences(),
        channel_manager->gpu_driver_bug_workarounds(),
        channel_manager->gpu_feature_info(), channel_manager->mailbox_manager(),
        gmb_factory ? gmb_factory->AsImageFactory() : nullptr, this);
    return true;
  } else {
    DCHECK(context_state_);
    if (context_state_->context_lost) {
      LOG(ERROR) << "SharedImageStub: context already lost";
      OnError();
      return false;
    } else {
      if (context_state_->context->MakeCurrent(context_state_->surface.get()))
        return true;
      context_state_->context_lost = true;
      LOG(ERROR) << "SharedImageStub: MakeCurrent failed";
      OnError();
      return false;
    }
  }
}

void SharedImageStub::OnError() {
  channel_->OnChannelError();
}

void SharedImageStub::TrackMemoryAllocatedChange(uint64_t delta) {
  size_ += delta;
}

uint64_t SharedImageStub::GetSize() const {
  return size_;
}

uint64_t SharedImageStub::ClientTracingId() const {
  return channel_->client_tracing_id();
}

int SharedImageStub::ClientId() const {
  return channel_->client_id();
}

uint64_t SharedImageStub::ContextGroupTracingId() const {
  return sync_point_client_state_->command_buffer_id().GetUnsafeValue();
}

}  // namespace gpu
