// Copyright 2019 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 "starboard/shared/blittergles/blitter_internal.h"

#include <EGL/egl.h>
#include <GLES2/gl2.h>

#include <memory>

#include "starboard/common/log.h"
#include "starboard/memory.h"
#include "starboard/once.h"
#include "starboard/shared/blittergles/blitter_context.h"
#include "starboard/shared/blittergles/blitter_surface.h"
#include "starboard/shared/gles/gl_call.h"

namespace starboard {
namespace shared {
namespace blittergles {

namespace {
// Keep track of a global device registry that will be accessed by calls to
// create/destroy devices.
SbBlitterDeviceRegistry* s_device_registry = NULL;
SbOnceControl s_device_registry_once_control = SB_ONCE_INITIALIZER;

void EnsureDeviceRegistryInitialized() {
  s_device_registry = new SbBlitterDeviceRegistry();
  s_device_registry->default_device = NULL;
}

void SetChannelOffsets(SbBlitterPixelDataFormat format, int (&channel)[4]) {
  switch (format) {
    case kSbBlitterPixelDataFormatRGBA8: {
      channel[0] = 3;
      channel[1] = 2;
      channel[2] = 1;
      channel[3] = 0;
      break;
    }
    case kSbBlitterPixelDataFormatARGB8: {
      channel[0] = 0;
      channel[1] = 3;
      channel[2] = 2;
      channel[3] = 1;
      break;
    }
    case kSbBlitterPixelDataFormatBGRA8: {
      channel[0] = 3;
      channel[1] = 0;
      channel[2] = 1;
      channel[3] = 2;
      break;
    }
    default: {
      SB_DLOG(ERROR) << ": Unexpected pixel data format.";
      SB_NOTREACHED();
    }
  }
}

void SwizzlePixels(SbBlitterPixelDataFormat in_format,
                   SbBlitterPixelDataFormat out_format,
                   int pitch_in_bytes,
                   int height,
                   uint8_t* data) {
  int index, in_channel[4], out_channel[4];
  uint8_t r_channel, g_channel, b_channel, a_channel;
  SetChannelOffsets(in_format, in_channel);
  SetChannelOffsets(out_format, out_channel);
  for (int i = 0; i < height; ++i) {
    for (int j = 0; j < pitch_in_bytes; j += 4) {
      index = pitch_in_bytes * i + j;
      r_channel = data[index + in_channel[0]];
      g_channel = data[index + in_channel[1]];
      b_channel = data[index + in_channel[2]];
      a_channel = data[index + in_channel[3]];
      data[index + out_channel[0]] = r_channel;
      data[index + out_channel[1]] = g_channel;
      data[index + out_channel[2]] = b_channel;
      data[index + out_channel[3]] = a_channel;
    }
  }
}

}  // namespace

const EGLint kContextAttributeList[] = {EGL_CONTEXT_CLIENT_VERSION, 2,
                                        EGL_NONE};

const EGLint kConfigAttributeList[] = {EGL_RED_SIZE,
                                       8,
                                       EGL_GREEN_SIZE,
                                       8,
                                       EGL_BLUE_SIZE,
                                       8,
                                       EGL_ALPHA_SIZE,
                                       8,
                                       EGL_BUFFER_SIZE,
                                       32,
                                       EGL_SURFACE_TYPE,
                                       EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
                                       EGL_COLOR_BUFFER_TYPE,
                                       EGL_RGB_BUFFER,
                                       EGL_CONFORMANT,
                                       EGL_OPENGL_ES2_BIT,
                                       EGL_RENDERABLE_TYPE,
                                       EGL_OPENGL_ES2_BIT,
                                       EGL_NONE};

SbBlitterDeviceRegistry* GetBlitterDeviceRegistry() {
  SbOnce(&s_device_registry_once_control, &EnsureDeviceRegistryInitialized);

  return s_device_registry;
}

void ChangeDataFormat(SbBlitterPixelDataFormat in_format,
                      SbBlitterPixelDataFormat out_format,
                      int pitch_in_bytes,
                      int height,
                      void* data) {
  uint8_t* data_bytes = static_cast<uint8_t*>(data);
  std::unique_ptr<uint8_t[]> temp_array(new uint8_t[pitch_in_bytes]);
  for (int i = 0; i < height / 2; ++i) {
    uint8_t* current_row = data_bytes + i * pitch_in_bytes;
    uint8_t* flip_row = data_bytes + pitch_in_bytes * (height - 1 - i);
    SbMemoryCopy(temp_array.get(), current_row, pitch_in_bytes);
    SbMemoryCopy(current_row, flip_row, pitch_in_bytes);
    SbMemoryCopy(flip_row, temp_array.get(), pitch_in_bytes);
  }

  if (in_format != out_format && in_format != kSbBlitterPixelDataFormatA8) {
    SwizzlePixels(in_format, out_format, pitch_in_bytes, height, data_bytes);
  }
}

}  // namespace blittergles
}  // namespace shared
}  // namespace starboard

bool SbBlitterRenderTargetPrivate::SetFramebuffer() {
  if (surface->color_texture_handle == 0) {
    return false;
  }
  SbBlitterContextPrivate::ScopedCurrentContext scoped_current_context;
  glGenFramebuffers(1, &framebuffer_handle);
  if (framebuffer_handle == 0) {
    SB_DLOG(ERROR) << ": Error creating new framebuffer.";
    return false;
  }
  glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_handle);
  if (glGetError() != GL_NO_ERROR) {
    GL_CALL(glDeleteFramebuffers(1, &framebuffer_handle));
    framebuffer_handle = 0;
    SB_DLOG(ERROR) << ": Error binding framebuffer.";
    return false;
  }
  GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->color_texture_handle));
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                         surface->color_texture_handle, 0);
  if (glGetError() != GL_NO_ERROR) {
    GL_CALL(glDeleteFramebuffers(1, &framebuffer_handle));
    GL_CALL(glDeleteTextures(1, &surface->color_texture_handle));
    framebuffer_handle = 0;
    surface->color_texture_handle = 0;
    SB_DLOG(ERROR) << ": Error drawing empty image to framebuffer.";
    return false;
  }

  GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));
  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    GL_CALL(glDeleteFramebuffers(1, &framebuffer_handle));
    GL_CALL(glDeleteTextures(1, &surface->color_texture_handle));
    framebuffer_handle = 0;
    surface->color_texture_handle = 0;
    SB_DLOG(ERROR) << ": Failed to create framebuffer.";
    return false;
  }
  GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
  return true;
}
