// 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 "content/common/gpu/image_transport_surface_fbo_mac.h"

#include "content/common/gpu/gpu_messages.h"
#include "content/common/gpu/image_transport_surface_calayer_mac.h"
#include "content/common/gpu/image_transport_surface_iosurface_mac.h"
#include "ui/base/cocoa/remote_layer_api.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_surface_osmesa.h"

namespace content {

ImageTransportSurfaceFBO::ImageTransportSurfaceFBO(
    GpuChannelManager* manager,
    GpuCommandBufferStub* stub,
    gfx::PluginWindowHandle handle)
    : backbuffer_suggested_allocation_(true),
      frontbuffer_suggested_allocation_(true),
      fbo_id_(0),
      texture_id_(0),
      depth_stencil_renderbuffer_id_(0),
      has_complete_framebuffer_(false),
      context_(NULL),
      scale_factor_(1.f),
      made_current_(false),
      is_swap_buffers_pending_(false),
      did_unschedule_(false) {
  if (ui::RemoteLayerAPISupported())
    storage_provider_.reset(new CALayerStorageProvider(this));
  else
    storage_provider_.reset(new IOSurfaceStorageProvider(this));
  helper_.reset(new ImageTransportHelper(this, manager, stub, handle));
}

ImageTransportSurfaceFBO::~ImageTransportSurfaceFBO() {
}

bool ImageTransportSurfaceFBO::Initialize() {
  // Only support IOSurfaces if the GL implementation is the native desktop GL.
  // IO surfaces will not work with, for example, OSMesa software renderer
  // GL contexts.
  if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL &&
      gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL)
    return false;

  if (!helper_->Initialize())
    return false;

  helper_->stub()->AddDestructionObserver(this);
  return true;
}

void ImageTransportSurfaceFBO::Destroy() {
  DestroyFramebuffer();

  helper_->Destroy();
}

bool ImageTransportSurfaceFBO::DeferDraws() {
  // The command buffer hit a draw/clear command that could clobber the
  // IOSurface in use by an earlier SwapBuffers. If a Swap is pending, abort
  // processing of the command by returning true and unschedule until the Swap
  // Ack arrives.
  if(did_unschedule_)
    return true;  // Still unscheduled, so just return true.
  if (is_swap_buffers_pending_) {
    did_unschedule_ = true;
    helper_->SetScheduled(false);
    return true;
  }
  return false;
}

bool ImageTransportSurfaceFBO::IsOffscreen() {
  return false;
}

bool ImageTransportSurfaceFBO::OnMakeCurrent(gfx::GLContext* context) {
  context_ = context;

  if (made_current_)
    return true;

  OnResize(gfx::Size(1, 1), 1.f);

  made_current_ = true;
  return true;
}

unsigned int ImageTransportSurfaceFBO::GetBackingFrameBufferObject() {
  return fbo_id_;
}

bool ImageTransportSurfaceFBO::SetBackbufferAllocation(bool allocation) {
  if (backbuffer_suggested_allocation_ == allocation)
    return true;
  backbuffer_suggested_allocation_ = allocation;
  AdjustBufferAllocation();
  return true;
}

void ImageTransportSurfaceFBO::SetFrontbufferAllocation(bool allocation) {
  if (frontbuffer_suggested_allocation_ == allocation)
    return;
  frontbuffer_suggested_allocation_ = allocation;
  AdjustBufferAllocation();
}

void ImageTransportSurfaceFBO::AdjustBufferAllocation() {
  // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is
  // free'd when both the browser and gpu processes have Unref'd the IOSurface.
  if (!backbuffer_suggested_allocation_ &&
      !frontbuffer_suggested_allocation_ &&
      has_complete_framebuffer_) {
    DestroyFramebuffer();
    helper_->Suspend();
  } else if (backbuffer_suggested_allocation_ && !has_complete_framebuffer_) {
    CreateFramebuffer();
  }
}

bool ImageTransportSurfaceFBO::SwapBuffers() {
  DCHECK(backbuffer_suggested_allocation_);
  if (!frontbuffer_suggested_allocation_)
    return true;
  glFlush();

  GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
  params.surface_handle = storage_provider_->GetSurfaceHandle();
  params.size = GetSize();
  params.scale_factor = scale_factor_;
  params.latency_info.swap(latency_info_);
  helper_->SendAcceleratedSurfaceBuffersSwapped(params);

  DCHECK(!is_swap_buffers_pending_);
  is_swap_buffers_pending_ = true;

  storage_provider_->WillSwapBuffers();
  return true;
}

bool ImageTransportSurfaceFBO::PostSubBuffer(
    int x, int y, int width, int height) {
  // Mac does not support sub-buffer swaps.
  NOTREACHED();
  return false;
}

bool ImageTransportSurfaceFBO::SupportsPostSubBuffer() {
  return true;
}

gfx::Size ImageTransportSurfaceFBO::GetSize() {
  return size_;
}

void* ImageTransportSurfaceFBO::GetHandle() {
  return NULL;
}

void* ImageTransportSurfaceFBO::GetDisplay() {
  return NULL;
}

void ImageTransportSurfaceFBO::OnBufferPresented(
    const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
  context_->share_group()->SetRendererID(params.renderer_id);
  storage_provider_->CanFreeSwappedBuffer();
}

void ImageTransportSurfaceFBO::UnblockContextAfterPendingSwap() {
  DCHECK(is_swap_buffers_pending_);
  is_swap_buffers_pending_ = false;
  if (did_unschedule_) {
    did_unschedule_ = false;
    helper_->SetScheduled(true);
  }
}

void ImageTransportSurfaceFBO::OnResize(gfx::Size size,
                                        float scale_factor) {
  TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize",
               "old_width", size_.width(), "new_width", size.width());
  // Caching |context_| from OnMakeCurrent. It should still be current.
  DCHECK(context_->IsCurrent(this));

  size_ = size;
  scale_factor_ = scale_factor;

  CreateFramebuffer();
}

void ImageTransportSurfaceFBO::SetLatencyInfo(
    const std::vector<ui::LatencyInfo>& latency_info) {
  for (size_t i = 0; i < latency_info.size(); i++)
    latency_info_.push_back(latency_info[i]);
}

void ImageTransportSurfaceFBO::WakeUpGpu() {
  NOTIMPLEMENTED();
}

void ImageTransportSurfaceFBO::OnWillDestroyStub() {
  helper_->stub()->RemoveDestructionObserver(this);
  Destroy();
}

void ImageTransportSurfaceFBO::DestroyFramebuffer() {
  // If we have resources to destroy, then make sure that we have a current
  // context which we can use to delete the resources.
  if (context_ || fbo_id_ || texture_id_ || depth_stencil_renderbuffer_id_) {
    DCHECK(gfx::GLContext::GetCurrent() == context_);
    DCHECK(context_->IsCurrent(this));
    DCHECK(CGLGetCurrentContext());
  }

  if (fbo_id_) {
    glDeleteFramebuffersEXT(1, &fbo_id_);
    fbo_id_ = 0;
  }

  if (texture_id_) {
    glDeleteTextures(1, &texture_id_);
    texture_id_ = 0;
  }

  if (depth_stencil_renderbuffer_id_) {
    glDeleteRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_);
    depth_stencil_renderbuffer_id_ = 0;
  }

  storage_provider_->FreeColorBufferStorage();

  has_complete_framebuffer_ = false;
}

void ImageTransportSurfaceFBO::CreateFramebuffer() {
  gfx::Size new_rounded_size = storage_provider_->GetRoundedSize(size_);

  // Only recreate surface when the rounded up size has changed.
  if (has_complete_framebuffer_ && new_rounded_size == rounded_size_)
    return;

  TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::CreateFramebuffer",
               "width", new_rounded_size.width(),
               "height", new_rounded_size.height());

  rounded_size_ = new_rounded_size;

  // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
  // Mac OS X and is required for IOSurface interoperability.
  GLint previous_texture_id = 0;
  glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id);

  // Free the old IO Surface first to reduce memory fragmentation.
  DestroyFramebuffer();

  glGenFramebuffersEXT(1, &fbo_id_);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);

  glGenTextures(1, &texture_id_);

  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id_);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                  GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                  GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                            GL_COLOR_ATTACHMENT0_EXT,
                            GL_TEXTURE_RECTANGLE_ARB,
                            texture_id_,
                            0);

  // Search through the provided attributes; if the caller has
  // requested a stencil buffer, try to get one.

  int32 stencil_bits =
      helper_->stub()->GetRequestedAttribute(EGL_STENCIL_SIZE);
  if (stencil_bits > 0) {
    // Create and bind the stencil buffer
    bool has_packed_depth_stencil =
         GLSurface::ExtensionsContain(
             reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
                                            "GL_EXT_packed_depth_stencil");

    if (has_packed_depth_stencil) {
      glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_);
      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
                            depth_stencil_renderbuffer_id_);
      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
                              rounded_size_.width(), rounded_size_.height());
      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                                  GL_STENCIL_ATTACHMENT_EXT,
                                  GL_RENDERBUFFER_EXT,
                                  depth_stencil_renderbuffer_id_);
    }

    // If we asked for stencil but the extension isn't present,
    // it's OK to silently fail; subsequent code will/must check
    // for the presence of a stencil buffer before attempting to
    // do stencil-based operations.
  }

  bool allocated_color_buffer = storage_provider_->AllocateColorBufferStorage(
      static_cast<CGLContextObj>(context_->GetHandle()), texture_id_,
      rounded_size_, scale_factor_);
  if (!allocated_color_buffer) {
    DLOG(ERROR) << "Failed to allocate color buffer storage.";
    DestroyFramebuffer();
    return;
  }

  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
    DLOG(ERROR) << "Framebuffer was incomplete: " << status;
    DestroyFramebuffer();
    return;
  }

  has_complete_framebuffer_ = true;

  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_id);
  // The FBO remains bound for this GL context.
}

}  // namespace content
