// Copyright 2016 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 "third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h"

#include "gpu/command_buffer/client/gles2_interface.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/skia_texture_holder.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/skia/include/gpu/GrContext.h"

namespace blink {

namespace {

void ReleaseTexture(
    bool is_converted_from_skia_texture,
    unsigned texture_id,
    std::unique_ptr<gpu::Mailbox> mailbox,
    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider,
    std::unique_ptr<gpu::SyncToken> sync_token) {
  if (!is_converted_from_skia_texture && texture_id && context_provider) {
    context_provider->ContextProvider()->ContextGL()->WaitSyncTokenCHROMIUM(
        sync_token->GetData());
    context_provider->ContextProvider()->ContextGL()->DeleteTextures(
        1, &texture_id);
  }
}

}  // namespace

MailboxTextureHolder::MailboxTextureHolder(
    const gpu::Mailbox& mailbox,
    const gpu::SyncToken& sync_token,
    unsigned texture_id_to_delete_after_mailbox_consumed,
    base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
        context_provider_wrapper,
    IntSize mailbox_size)
    : TextureHolder(std::move(context_provider_wrapper)),
      mailbox_(mailbox),
      sync_token_(sync_token),
      texture_id_(texture_id_to_delete_after_mailbox_consumed),
      size_(mailbox_size),
      is_converted_from_skia_texture_(false),
      thread_id_(0) {
  InitCommon();
}

MailboxTextureHolder::MailboxTextureHolder(
    std::unique_ptr<TextureHolder> texture_holder,
    GLenum filter)
    : TextureHolder(texture_holder->ContextProviderWrapper()),
      texture_id_(0),
      is_converted_from_skia_texture_(true),
      thread_id_(0) {
  DCHECK(texture_holder->IsSkiaTextureHolder());
  sk_sp<SkImage> image = texture_holder->GetSkImage();
  DCHECK(image);
  size_ = IntSize(image->width(), image->height());

  if (!ContextProviderWrapper())
    return;

  ContextProviderWrapper()->Utils()->GetMailboxForSkImage(mailbox_, image,
                                                          filter);

  InitCommon();
}

void MailboxTextureHolder::Sync(MailboxSyncMode mode) {
  if (IsCrossThread()) {
    // Was originally created on another thread. Should already have a sync
    // token from the original source context, already verified if needed.
    DCHECK(sync_token_.HasData());
    DCHECK(mode != kVerifiedSyncToken || sync_token_.verified_flush());
    return;
  }

  if (!ContextProviderWrapper() || IsAbandoned())
    return;

  TRACE_EVENT0("blink", "MailboxTextureHolder::Sync");

  gpu::gles2::GLES2Interface* gl =
      ContextProviderWrapper()->ContextProvider()->ContextGL();

  if (mode == kOrderingBarrier) {
    if (!did_issue_ordering_barrier_) {
      gl->OrderingBarrierCHROMIUM();
      did_issue_ordering_barrier_ = true;
    }
    return;
  }

  if (!sync_token_.HasData()) {
    if (mode == kVerifiedSyncToken) {
      gl->GenSyncTokenCHROMIUM(sync_token_.GetData());
    } else {
      gl->GenUnverifiedSyncTokenCHROMIUM(sync_token_.GetData());
    }
    return;
  }

  // At this point we have a pre-existing sync token. We just need to verify
  // it if needed.  Providing a verified sync token when unverified is requested
  // is fine.
  if (mode == kVerifiedSyncToken && !sync_token_.verified_flush()) {
    int8_t* token_data = sync_token_.GetData();
    // TODO(junov): Batch this verification in the case where there are multiple
    // offscreen canvases being committed.
    gl->ShallowFlushCHROMIUM();
    gl->VerifySyncTokensCHROMIUM(&token_data, 1);
    sync_token_.SetVerifyFlush();
  }
}

void MailboxTextureHolder::InitCommon() {
  Thread* thread = Thread::Current();
  thread_id_ = thread->ThreadId();
  texture_thread_task_runner_ = thread->GetTaskRunner();
}

bool MailboxTextureHolder::IsValid() const {
  if (IsCrossThread()) {
    // If context is is from another thread, validity cannot be verified.
    // Just assume valid. Potential problem will be detected later.
    return true;
  }
  return !IsAbandoned() && !!ContextProviderWrapper();
}

bool MailboxTextureHolder::IsCrossThread() const {
  return thread_id_ != Thread::Current()->ThreadId();
}

MailboxTextureHolder::~MailboxTextureHolder() {
  std::unique_ptr<gpu::SyncToken> passed_sync_token(
      new gpu::SyncToken(sync_token_));
  std::unique_ptr<gpu::Mailbox> passed_mailbox(new gpu::Mailbox(mailbox_));

  if (!IsAbandoned()) {
    if (texture_thread_task_runner_ &&
        thread_id_ != Thread::Current()->ThreadId()) {
      PostCrossThreadTask(
          *texture_thread_task_runner_, FROM_HERE,
          CrossThreadBind(&ReleaseTexture, is_converted_from_skia_texture_,
                          texture_id_, WTF::Passed(std::move(passed_mailbox)),
                          WTF::Passed(ContextProviderWrapper()),
                          WTF::Passed(std::move(passed_sync_token))));
    } else {
      ReleaseTexture(is_converted_from_skia_texture_, texture_id_,
                     std::move(passed_mailbox), ContextProviderWrapper(),
                     std::move(passed_sync_token));
    }
  }

  texture_id_ = 0u;  // invalidate the texture.
  texture_thread_task_runner_ = nullptr;
}

}  // namespace blink
