// 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 "examples/ganesh_app/texture_uploader.h"

#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif

#include "base/bind.h"
#include "gpu/GLES2/gl2chromium.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "mojo/public/c/gles2/gles2.h"
#include "mojo/public/cpp/application/connect.h"
#include "mojo/public/interfaces/application/shell.mojom.h"
#include "mojo/services/geometry/public/cpp/geometry_util.h"
#include "mojo/services/surfaces/public/cpp/surfaces_utils.h"

namespace examples {

TextureUploader::Client::~Client() {
}

TextureUploader::TextureUploader(Client* client,
                                 mojo::Shell* shell,
                                 base::WeakPtr<mojo::GLContext> context)
    : client_(client),
      context_(context),
      next_resource_id_(0u),
      id_namespace_(0u),
      local_id_(0u),
      weak_factory_(this) {
  context_->AddObserver(this);

  mojo::ServiceProviderPtr surfaces_service_provider;
  shell->ConnectToApplication("mojo:surfaces_service",
                              mojo::GetProxy(&surfaces_service_provider),
                              nullptr);
  mojo::ConnectToService(surfaces_service_provider.get(), &surface_);
  surface_.set_client(this);
}

TextureUploader::~TextureUploader() {
  if (context_.get())
    context_->RemoveObserver(this);
}

void TextureUploader::Upload(scoped_ptr<mojo::GLTexture> texture) {
  if (!surface_) {
    pending_upload_ = texture.Pass();
    return;
  }

  mojo::Size size = texture->size();
  EnsureSurfaceForSize(size);

  mojo::FramePtr frame = mojo::Frame::New();
  frame->resources.resize(0u);

  mojo::Rect bounds;
  bounds.width = size.width;
  bounds.height = size.height;
  mojo::PassPtr pass = mojo::CreateDefaultPass(1, bounds);
  pass->quads.resize(0u);
  pass->shared_quad_states.push_back(mojo::CreateDefaultSQS(size));

  context_->MakeCurrent();
  glBindTexture(GL_TEXTURE_2D, texture->texture_id());
  GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
  glGenMailboxCHROMIUM(mailbox);
  glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
  GLuint sync_point = glInsertSyncPointCHROMIUM();

  mojo::TransferableResourcePtr resource = mojo::TransferableResource::New();
  resource->id = next_resource_id_++;
  resource_to_texture_map_[resource->id] = texture.release();
  resource->format = mojo::RESOURCE_FORMAT_RGBA_8888;
  resource->filter = GL_LINEAR;
  resource->size = size.Clone();
  mojo::MailboxHolderPtr mailbox_holder = mojo::MailboxHolder::New();
  mailbox_holder->mailbox = mojo::Mailbox::New();
  for (int i = 0; i < GL_MAILBOX_SIZE_CHROMIUM; ++i)
    mailbox_holder->mailbox->name.push_back(mailbox[i]);
  mailbox_holder->texture_target = GL_TEXTURE_2D;
  mailbox_holder->sync_point = sync_point;
  resource->mailbox_holder = mailbox_holder.Pass();
  resource->is_repeated = false;
  resource->is_software = false;

  mojo::QuadPtr quad = mojo::Quad::New();
  quad->material = mojo::MATERIAL_TEXTURE_CONTENT;

  mojo::RectPtr rect = mojo::Rect::New();
  rect->width = size.width;
  rect->height = size.height;
  quad->rect = rect.Clone();
  quad->opaque_rect = rect.Clone();
  quad->visible_rect = rect.Clone();
  quad->needs_blending = true;
  quad->shared_quad_state_index = 0u;

  mojo::TextureQuadStatePtr texture_state = mojo::TextureQuadState::New();
  texture_state->resource_id = resource->id;
  texture_state->premultiplied_alpha = true;
  texture_state->uv_top_left = mojo::PointF::New();
  texture_state->uv_bottom_right = mojo::PointF::New();
  texture_state->uv_bottom_right->x = 1.f;
  texture_state->uv_bottom_right->y = 1.f;
  texture_state->background_color = mojo::Color::New();
  texture_state->background_color->rgba = 0;
  for (int i = 0; i < 4; ++i)
    texture_state->vertex_opacity.push_back(1.f);
  texture_state->flipped = false;

  frame->resources.push_back(resource.Pass());
  quad->texture_quad_state = texture_state.Pass();
  pass->quads.push_back(quad.Pass());

  frame->passes.push_back(pass.Pass());
  surface_->SubmitFrame(local_id_, frame.Pass(), mojo::Closure());
}

void TextureUploader::EnsureSurfaceForSize(const mojo::Size& size) {
  if (local_id_ != 0u && size == surface_size_)
    return;

  if (local_id_ != 0u) {
    surface_->DestroySurface(local_id_);
  }

  local_id_++;
  surface_->CreateSurface(local_id_);
  surface_size_ = size;
  if (id_namespace_ != 0u)
    SendFullyQualifiedID();
}
void TextureUploader::SendFullyQualifiedID() {
  auto qualified_id = mojo::SurfaceId::New();
  qualified_id->id_namespace = id_namespace_;
  qualified_id->local = local_id_;
  client_->OnSurfaceIdAvailable(qualified_id.Pass());
}

void TextureUploader::OnContextLost() {
  LOG(FATAL) << "Context lost.";
}

void TextureUploader::SetIdNamespace(uint32_t id_namespace) {
  id_namespace_ = id_namespace;
  if (local_id_ != 0u)
    SendFullyQualifiedID();
}

void TextureUploader::ReturnResources(
    mojo::Array<mojo::ReturnedResourcePtr> resources) {
  if (!resources.size())
    return;
  context_->MakeCurrent();
  for (size_t i = 0u; i < resources.size(); ++i) {
    mojo::ReturnedResourcePtr resource = resources[i].Pass();
    DCHECK_EQ(1, resource->count);
    glWaitSyncPointCHROMIUM(resource->sync_point);
    mojo::GLTexture* texture = resource_to_texture_map_[resource->id];
    DCHECK_NE(0u, texture->texture_id());
    resource_to_texture_map_.erase(resource->id);
    delete texture;
  }
}

}  // namespace examples
