// Copyright 2017 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 "modules/xr/XRWebGLLayer.h"

#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "core/imagebitmap/ImageBitmap.h"
#include "modules/webgl/WebGL2RenderingContext.h"
#include "modules/webgl/WebGLFramebuffer.h"
#include "modules/webgl/WebGLRenderingContext.h"
#include "modules/xr/XRDevice.h"
#include "modules/xr/XRFrameProvider.h"
#include "modules/xr/XRPresentationContext.h"
#include "modules/xr/XRSession.h"
#include "modules/xr/XRView.h"
#include "modules/xr/XRViewport.h"
#include "platform/geometry/DoubleSize.h"
#include "platform/geometry/IntSize.h"

namespace blink {

namespace {

const double kFramebufferMinScale = 0.2;
const double kFramebufferMaxScale = 1.2;

const double kViewportMinScale = 0.2;
const double kViewportMaxScale = 1.0;

// Because including base::ClampToRange would be a dependency violation
double ClampToRange(const double value, const double min, const double max) {
  return std::min(std::max(value, min), max);
}

}  // namespace

XRWebGLLayer* XRWebGLLayer::Create(
    XRSession* session,
    const WebGLRenderingContextOrWebGL2RenderingContext& context,
    const XRWebGLLayerInit& initializer,
    ExceptionState& exception_state) {
  if (session->ended()) {
    exception_state.ThrowDOMException(kInvalidStateError,
                                      "Cannot create an XRWebGLLayer for an "
                                      "XRSession which has already ended.");
    return nullptr;
  }

  WebGLRenderingContextBase* webgl_context;
  if (context.IsWebGL2RenderingContext()) {
    webgl_context = context.GetAsWebGL2RenderingContext();
  } else {
    webgl_context = context.GetAsWebGLRenderingContext();
  }

  if (webgl_context->isContextLost()) {
    exception_state.ThrowDOMException(kInvalidStateError,
                                      "Cannot create an XRWebGLLayer with a "
                                      "lost WebGL context.");
    return nullptr;
  }

  bool want_antialiasing = initializer.antialias();
  bool want_depth_buffer = initializer.depth();
  bool want_stencil_buffer = initializer.stencil();
  bool want_alpha_channel = initializer.alpha();
  bool want_multiview = initializer.multiview();

  double framebuffer_scale = session->DefaultFramebufferScale();

  if (initializer.hasFramebufferScaleFactor() &&
      initializer.framebufferScaleFactor() != 0.0) {
    // Clamp the developer-requested framebuffer size to ensure it's not too
    // small to see or unreasonably large.
    framebuffer_scale =
        ClampToRange(initializer.framebufferScaleFactor(), kFramebufferMinScale,
                     kFramebufferMaxScale);
  }

  DoubleSize framebuffers_size = session->IdealFramebufferSize();

  IntSize desired_size(framebuffers_size.Width() * framebuffer_scale,
                       framebuffers_size.Height() * framebuffer_scale);

  // Create an opaque WebGL Framebuffer
  WebGLFramebuffer* framebuffer = WebGLFramebuffer::CreateOpaque(webgl_context);

  XRWebGLDrawingBuffer* drawing_buffer = XRWebGLDrawingBuffer::Create(
      webgl_context->GetDrawingBuffer(), framebuffer->Object(), desired_size,
      want_alpha_channel, want_depth_buffer, want_stencil_buffer,
      want_antialiasing, want_multiview);

  if (!drawing_buffer) {
    exception_state.ThrowDOMException(kOperationError,
                                      "Unable to create a framebuffer.");
    return nullptr;
  }

  return new XRWebGLLayer(session, webgl_context, drawing_buffer, framebuffer,
                          framebuffer_scale);
}

XRWebGLLayer::XRWebGLLayer(XRSession* session,
                           WebGLRenderingContextBase* webgl_context,
                           XRWebGLDrawingBuffer* drawing_buffer,
                           WebGLFramebuffer* framebuffer,
                           double framebuffer_scale)
    : XRLayer(session, kXRWebGLLayerType),
      webgl_context_(webgl_context),
      drawing_buffer_(drawing_buffer),
      framebuffer_(framebuffer),
      framebuffer_scale_(framebuffer_scale) {
  DCHECK(drawing_buffer);
  UpdateViewports();
}

XRWebGLLayer::~XRWebGLLayer() {}

void XRWebGLLayer::getXRWebGLRenderingContext(
    WebGLRenderingContextOrWebGL2RenderingContext& result) const {
  if (webgl_context_->Version() == 2) {
    result.SetWebGL2RenderingContext(
        static_cast<WebGL2RenderingContext*>(webgl_context_.Get()));
  } else {
    result.SetWebGLRenderingContext(
        static_cast<WebGLRenderingContext*>(webgl_context_.Get()));
  }
}

void XRWebGLLayer::requestViewportScaling(double scale_factor) {
  if (!session()->exclusive()) {
    // TODO(bajones): For the moment we're just going to ignore viewport changes
    // in non-exclusive mode. This is legal, but probably not what developers
    // would like to see. Look into making viewport scale apply properly.
    scale_factor = 1.0;
  } else {
    // Clamp the developer-requested viewport size to ensure it's not too
    // small to see or larger than the framebuffer.
    scale_factor =
        ClampToRange(scale_factor, kViewportMinScale, kViewportMaxScale);
  }

  if (viewport_scale_ != scale_factor) {
    viewport_scale_ = scale_factor;
    viewports_dirty_ = true;
  }
}

XRViewport* XRWebGLLayer::GetViewport(XRView::Eye eye) {
  if (viewports_dirty_)
    UpdateViewports();

  if (eye == XRView::kEyeLeft)
    return left_viewport_;

  return right_viewport_;
}

void XRWebGLLayer::UpdateViewports() {
  long framebuffer_width = framebufferWidth();
  long framebuffer_height = framebufferHeight();

  viewports_dirty_ = false;

  if (session()->exclusive()) {
    left_viewport_ =
        new XRViewport(0, 0, framebuffer_width * 0.5 * viewport_scale_,
                       framebuffer_height * viewport_scale_);
    right_viewport_ =
        new XRViewport(framebuffer_width * 0.5 * viewport_scale_, 0,
                       framebuffer_width * 0.5 * viewport_scale_,
                       framebuffer_height * viewport_scale_);

    session()->device()->frameProvider()->UpdateWebGLLayerViewports(this);
  } else {
    left_viewport_ = new XRViewport(0, 0, framebuffer_width * viewport_scale_,
                                    framebuffer_height * viewport_scale_);
  }
}

void XRWebGLLayer::OnFrameStart() {
  framebuffer_->MarkOpaqueBufferComplete(true);
  framebuffer_->SetContentsChanged(false);
}

void XRWebGLLayer::OnFrameEnd() {
  framebuffer_->MarkOpaqueBufferComplete(false);
  // Exit early if the framebuffer contents have not changed.
  if (!framebuffer_->HaveContentsChanged())
    return;

  // Submit the frame to the XR compositor.
  if (session()->exclusive()) {
    session()->device()->frameProvider()->SubmitWebGLLayer(this);
  } else if (session()->outputContext()) {
    ImageBitmap* image_bitmap =
        ImageBitmap::Create(TransferToStaticBitmapImage());
    session()->outputContext()->SetImage(image_bitmap);
  }
}

void XRWebGLLayer::OnResize() {
  DoubleSize framebuffers_size = session()->IdealFramebufferSize();

  IntSize desired_size(framebuffers_size.Width() * framebuffer_scale_,
                       framebuffers_size.Height() * framebuffer_scale_);
  drawing_buffer_->Resize(desired_size);
  viewports_dirty_ = true;
}

scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage() {
  return drawing_buffer_->TransferToStaticBitmapImage();
}

void XRWebGLLayer::Trace(blink::Visitor* visitor) {
  visitor->Trace(left_viewport_);
  visitor->Trace(right_viewport_);
  visitor->Trace(webgl_context_);
  visitor->Trace(framebuffer_);
  XRLayer::Trace(visitor);
}

void XRWebGLLayer::TraceWrappers(const ScriptWrappableVisitor* visitor) const {
  visitor->TraceWrappers(webgl_context_);
  XRLayer::TraceWrappers(visitor);
}

}  // namespace blink
