// Copyright 2014 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/service/mailbox_synchronizer.h"

#include "base/bind.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "ui/gl/gl_implementation.h"

namespace gpu {
namespace gles2 {

namespace {

MailboxSynchronizer* g_instance = NULL;

}  // anonymous namespace

// static
bool MailboxSynchronizer::Initialize() {
  DCHECK(!g_instance);
  DCHECK(gfx::GetGLImplementation() != gfx::kGLImplementationNone)
      << "GL bindings not initialized";
  switch (gfx::GetGLImplementation()) {
    case gfx::kGLImplementationMockGL:
      break;
    case gfx::kGLImplementationEGLGLES2:
#if !defined(OS_MACOSX)
      {
        if (!gfx::g_driver_egl.ext.b_EGL_KHR_image_base ||
            !gfx::g_driver_egl.ext.b_EGL_KHR_gl_texture_2D_image ||
            !gfx::g_driver_gl.ext.b_GL_OES_EGL_image ||
            !gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
          LOG(WARNING) << "MailboxSync not supported due to missing EGL "
                          "image/fence support";
          return false;
        }
      }
      break;
#endif
    default:
      NOTREACHED();
      return false;
  }
  g_instance = new MailboxSynchronizer;
  return true;
}

// static
void MailboxSynchronizer::Terminate() {
  DCHECK(g_instance);
  delete g_instance;
  g_instance = NULL;
}

// static
MailboxSynchronizer* MailboxSynchronizer::GetInstance() {
  return g_instance;
}

MailboxSynchronizer::TargetName::TargetName(unsigned target,
                                            const Mailbox& mailbox)
    : target(target), mailbox(mailbox) {}

MailboxSynchronizer::TextureGroup::TextureGroup(
    const TextureDefinition& definition)
    : definition(definition) {}

MailboxSynchronizer::TextureGroup::~TextureGroup() {}

MailboxSynchronizer::TextureVersion::TextureVersion(
    linked_ptr<TextureGroup> group)
    : version(group->definition.version()), group(group) {}

MailboxSynchronizer::TextureVersion::~TextureVersion() {}

MailboxSynchronizer::MailboxSynchronizer() {}

MailboxSynchronizer::~MailboxSynchronizer() {
  DCHECK_EQ(0U, textures_.size());
}

void MailboxSynchronizer::ReassociateMailboxLocked(
    const TargetName& target_name,
    TextureGroup* group) {
  lock_.AssertAcquired();
  for (TextureMap::iterator it = textures_.begin(); it != textures_.end();
       it++) {
    std::set<TargetName>::iterator mb_it =
        it->second.group->mailboxes.find(target_name);
    if (it->second.group != group &&
        mb_it != it->second.group->mailboxes.end()) {
      it->second.group->mailboxes.erase(mb_it);
    }
  }
  group->mailboxes.insert(target_name);
}

linked_ptr<MailboxSynchronizer::TextureGroup>
MailboxSynchronizer::GetGroupForMailboxLocked(const TargetName& target_name) {
  lock_.AssertAcquired();
  for (TextureMap::iterator it = textures_.begin(); it != textures_.end();
       it++) {
    std::set<TargetName>::const_iterator mb_it =
        it->second.group->mailboxes.find(target_name);
    if (mb_it != it->second.group->mailboxes.end())
      return it->second.group;
  }
  return make_linked_ptr<MailboxSynchronizer::TextureGroup>(NULL);
}

Texture* MailboxSynchronizer::CreateTextureFromMailbox(unsigned target,
                                                       const Mailbox& mailbox) {
  base::AutoLock lock(lock_);
  TargetName target_name(target, mailbox);
  linked_ptr<TextureGroup> group = GetGroupForMailboxLocked(target_name);
  if (group.get()) {
    Texture* new_texture = group->definition.CreateTexture();
    if (new_texture)
      textures_.insert(std::make_pair(new_texture, TextureVersion(group)));
    return new_texture;
  }

  return NULL;
}

void MailboxSynchronizer::TextureDeleted(Texture* texture) {
  base::AutoLock lock(lock_);
  TextureMap::iterator it = textures_.find(texture);
  if (it != textures_.end()) {
    // TODO: We could avoid the update if this was the last ref.
    UpdateTextureLocked(it->first, it->second);
    textures_.erase(it);
  }
}

void MailboxSynchronizer::PushTextureUpdates(MailboxManager* manager) {
  base::AutoLock lock(lock_);
  for (MailboxManager::MailboxToTextureMap::const_iterator texture_it =
           manager->mailbox_to_textures_.begin();
       texture_it != manager->mailbox_to_textures_.end();
       texture_it++) {
    TargetName target_name(texture_it->first.target, texture_it->first.mailbox);
    Texture* texture = texture_it->second->first;
    // TODO(sievers): crbug.com/352274
    // Should probably only fail if it already *has* mipmaps, while allowing
    // incomplete textures here. Also reconsider how to fail otherwise.
    bool needs_mips = texture->min_filter() != GL_NEAREST &&
                      texture->min_filter() != GL_LINEAR;
    if (target_name.target != GL_TEXTURE_2D || needs_mips)
      continue;

    TextureMap::iterator it = textures_.find(texture);
    if (it != textures_.end()) {
      TextureVersion& texture_version = it->second;
      TextureGroup* group = texture_version.group.get();
      std::set<TargetName>::const_iterator mb_it =
          group->mailboxes.find(target_name);
      if (mb_it == group->mailboxes.end()) {
        // We previously did not associate this texture with the given mailbox.
        // Unlink other texture groups from the mailbox.
        ReassociateMailboxLocked(target_name, group);
      }
      UpdateTextureLocked(texture, texture_version);

    } else {
      // Skip compositor resources/tile textures.
      // TODO: Remove this, see crbug.com/399226.
      if (texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM)
        continue;

      linked_ptr<TextureGroup> group = make_linked_ptr(new TextureGroup(
          TextureDefinition(target_name.target, texture, 1, NULL)));

      // Unlink other textures from this mailbox in case the name is not new.
      ReassociateMailboxLocked(target_name, group.get());
      textures_.insert(std::make_pair(texture, TextureVersion(group)));
    }
  }
}

void MailboxSynchronizer::UpdateTextureLocked(Texture* texture,
                                              TextureVersion& texture_version) {
  lock_.AssertAcquired();
  gfx::GLImage* gl_image = texture->GetLevelImage(texture->target(), 0);
  TextureGroup* group = texture_version.group.get();
  scoped_refptr<NativeImageBuffer> image_buffer = group->definition.image();

  // Make sure we don't clobber with an older version
  if (!group->definition.IsOlderThan(texture_version.version))
    return;

  // Also don't push redundant updates. Note that it would break the
  // versioning.
  if (group->definition.Matches(texture))
    return;

  if (gl_image && !image_buffer->IsClient(gl_image)) {
    LOG(ERROR) << "MailboxSync: Incompatible attachment";
    return;
  }

  group->definition = TextureDefinition(texture->target(),
                                        texture,
                                        ++texture_version.version,
                                        gl_image ? image_buffer : NULL);
}

void MailboxSynchronizer::PullTextureUpdates(MailboxManager* manager) {
  base::AutoLock lock(lock_);
  for (MailboxManager::MailboxToTextureMap::const_iterator texture_it =
           manager->mailbox_to_textures_.begin();
       texture_it != manager->mailbox_to_textures_.end();
       texture_it++) {
    Texture* texture = texture_it->second->first;
    TextureMap::iterator it = textures_.find(texture);
    if (it != textures_.end()) {
      TextureDefinition& definition = it->second.group->definition;
      if (it->second.version == definition.version() ||
          definition.IsOlderThan(it->second.version))
        continue;
      it->second.version = definition.version();
      definition.UpdateTexture(texture);
    }
  }
}

}  // namespace gles2
}  // namespace gpu
