// 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/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;
    }
  }

  // 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;
}

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
