// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/renderer/rasterizer/egl/shader_program.h"

#include <GLES2/gl2.h>

#include "base/logging.h"
#include "cobalt/renderer/backend/egl/utils.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace egl {

namespace {

void CompileShader(GLuint handle, const GLchar* source) {
  GLint source_length = strlen(source);
  GL_CALL(glShaderSource(handle, 1, &source, &source_length));
  GL_CALL(glCompileShader(handle));

  GLint compiled = GL_FALSE;
  GL_CALL(glGetShaderiv(handle, GL_COMPILE_STATUS, &compiled));
  if (compiled != GL_TRUE) {
    GLchar log[2048] = {0};
    glGetShaderInfoLog(handle, arraysize(log) - 1, NULL, log);
    DLOG(ERROR) << "shader compile error:\n" << log;
    DLOG(ERROR) << "shader source:\n" << source;
  }
  DCHECK(compiled == GL_TRUE);
}

}  // namespace

ShaderProgramBase::ShaderProgramBase() : handle_(0) {}

ShaderProgramBase::~ShaderProgramBase() { DCHECK_EQ(handle_, 0); }

void ShaderProgramBase::Create(ShaderBase* vertex_shader,
                               ShaderBase* fragment_shader) {
  handle_ = glCreateProgram();

  GLuint vertex_shader_handle = glCreateShader(GL_VERTEX_SHADER);
  CompileShader(vertex_shader_handle, vertex_shader->GetSource());
  GL_CALL(glAttachShader(handle_, vertex_shader_handle));

  GLuint fragment_shader_handle = glCreateShader(GL_FRAGMENT_SHADER);
  CompileShader(fragment_shader_handle, fragment_shader->GetSource());
  GL_CALL(glAttachShader(handle_, fragment_shader_handle));

  vertex_shader->InitializePreLink(handle_);
  fragment_shader->InitializePreLink(handle_);
  GL_CALL(glLinkProgram(handle_));

  GLint linked = GL_FALSE;
  GL_CALL(glGetProgramiv(handle_, GL_LINK_STATUS, &linked));
  if (linked != GL_TRUE) {
    GLchar log[2048] = {0};
    glGetProgramInfoLog(handle_, arraysize(log) - 1, NULL, log);
    DLOG(ERROR) << "shader link error:\n" << log;
    DLOG(ERROR) << "vertex source:\n" << vertex_shader->GetSource();
    DLOG(ERROR) << "fragment source:\n" << fragment_shader->GetSource();
  }
  DCHECK(linked == GL_TRUE);

  vertex_shader->InitializePostLink(handle_);
  fragment_shader->InitializePostLink(handle_);
  GL_CALL(glUseProgram(handle_));
  vertex_shader->InitializePostUse();
  fragment_shader->InitializePostUse();

  GL_CALL(glDeleteShader(vertex_shader_handle));
  GL_CALL(glDeleteShader(fragment_shader_handle));
}

void ShaderProgramBase::Destroy(ShaderBase* vertex_shader,
                                ShaderBase* fragment_shader) {
  DCHECK_NE(handle_, 0);
  GL_CALL(glDeleteProgram(handle_));
  handle_ = 0;
}

}  // namespace egl
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
