// Copyright 2015 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.

#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif
#include <GLES2/gl2extmojo.h>

#include "mojo/gpu/gl_context.h"
#include "mojo/gpu/gl_texture.h"
#include "mojo/gpu/texture_cache.h"
#include "mojo/services/geometry/public/interfaces/geometry.mojom.h"

namespace mojo {

TextureCache::TextureInfo::TextureInfo() : texture_(), resource_id_(0u) {
}
TextureCache::TextureInfo::TextureInfo(scoped_ptr<mojo::GLTexture> texture,
                                       uint32_t resource_id)
    : texture_(texture.Pass()), resource_id_(resource_id) {
}
TextureCache::TextureInfo::~TextureInfo() {
}

TextureCache::TextureCache(base::WeakPtr<mojo::GLContext> gl_context,
                           mojo::ResourceReturnerPtr* out_resource_returner)
    : gl_context_(gl_context), returner_binding_(this), next_resource_id_(0u) {
  if (out_resource_returner) {
    returner_binding_.Bind(GetProxy(out_resource_returner));
  }
}

TextureCache::~TextureCache() {
}

scoped_ptr<TextureCache::TextureInfo> TextureCache::GetTexture(
    const mojo::Size& requested_size) {
  // Sift through our available textures to find one the correct size.  If one
  // exists use it.  As we find textures of the wrong size, clean them up.
  while (!available_textures_.empty()) {
    // Get the next available texture's resource id.
    uint32_t available_resource_id = available_textures_.front();
    available_textures_.pop_front();

    // Get the texture information from the texture map.
    auto texture_iterator =
        resource_to_texture_map_.find(available_resource_id);
    mojo::Size texture_size = texture_iterator->second->size();
    scoped_ptr<TextureInfo> texture_info(new TextureInfo(
        texture_iterator->second.Pass(), texture_iterator->first));
    resource_to_texture_map_.erase(texture_iterator);

    // Get the sync point from the sync point map.
    auto sync_point_iterator =
        resource_to_sync_point_map_.find(available_resource_id);
    int sync_point = sync_point_iterator->second;
    resource_to_sync_point_map_.erase(sync_point_iterator);

    // If the texture is the right size, use it.
    if (texture_size.width == requested_size.width &&
        texture_size.height == requested_size.height) {
      glWaitSyncPointCHROMIUM(sync_point);
      return texture_info.Pass();
    }
  }

  // If our context is invalid return an empty scoped ptr.
  if (!gl_context_) {
    return scoped_ptr<TextureInfo>();
  }

  // We couldn't find an existing texture to reuse, create a new one!
  scoped_ptr<mojo::GLTexture> new_texture(
      new mojo::GLTexture(gl_context_, requested_size));
  next_resource_id_++;
  scoped_ptr<TextureInfo> texture_info(
      new TextureInfo(new_texture.Pass(), next_resource_id_));
  return texture_info.Pass();
}

void TextureCache::NotifyPendingResourceReturn(
    uint32_t resource_id,
    scoped_ptr<mojo::GLTexture> texture) {
  resource_to_texture_map_[resource_id] = texture.Pass();
}

// mojo::ResourceReturner
void TextureCache::ReturnResources(
    mojo::Array<mojo::ReturnedResourcePtr> resources) {
  if (!gl_context_) {
    return;
  }
  gl_context_->MakeCurrent();
  for (size_t i = 0u; i < resources.size(); ++i) {
    mojo::ReturnedResourcePtr resource = resources[i].Pass();
    DCHECK_EQ(1, resource->count);
    auto it = resource_to_texture_map_.find(resource->id);
    // Ignore the returned resource if we haven't been notified of its pending
    // return.
    if (it != resource_to_texture_map_.end()) {
      available_textures_.push_back(resource->id);
      resource_to_sync_point_map_[resource->id] = resource->sync_point;
    }
  }
}
}  // namespace mojo
