// Copyright (c) 2013 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 "ui/accelerated_widget_mac/io_surface_context.h"

#include <OpenGL/gl.h>
#include <OpenGL/OpenGL.h>
#include <vector>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_switching_manager.h"

namespace ui {

// static
scoped_refptr<IOSurfaceContext>
IOSurfaceContext::Get(Type type) {
  TRACE_EVENT0("browser", "IOSurfaceContext::Get");

  // Return the context for this type, if it exists.
  TypeMap::iterator found = type_map()->find(type);
  if (found != type_map()->end()) {
    DCHECK(!found->second->poisoned_);
    return found->second;
  }

  base::ScopedTypeRef<CGLContextObj> cgl_context;
  CGLError error = kCGLNoError;

  // Create the pixel format object for the context.
  std::vector<CGLPixelFormatAttribute> attribs;
  attribs.push_back(kCGLPFADepthSize);
  attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
  if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
    attribs.push_back(kCGLPFAAllowOfflineRenderers);
  attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
  GLint number_virtual_screens = 0;
  base::ScopedTypeRef<CGLPixelFormatObj> pixel_format;
  error = CGLChoosePixelFormat(&attribs.front(),
                               pixel_format.InitializeInto(),
                               &number_virtual_screens);
  if (error != kCGLNoError) {
    LOG(ERROR) << "Failed to create pixel format object.";
    return NULL;
  }

  // Create all contexts in the same share group so that the textures don't
  // need to be recreated when transitioning contexts.
  CGLContextObj share_context = NULL;
  if (!type_map()->empty())
    share_context = type_map()->begin()->second->cgl_context();
  error = CGLCreateContext(
      pixel_format, share_context, cgl_context.InitializeInto());
  if (error != kCGLNoError) {
    LOG(ERROR) << "Failed to create context object.";
    return NULL;
  }

  return new IOSurfaceContext(type, cgl_context);
}

void IOSurfaceContext::PoisonContextAndSharegroup() {
  if (poisoned_)
    return;

  for (TypeMap::iterator it = type_map()->begin();
       it != type_map()->end();
       ++it) {
    it->second->poisoned_ = true;
  }
  type_map()->clear();
}

IOSurfaceContext::IOSurfaceContext(
    Type type, base::ScopedTypeRef<CGLContextObj> cgl_context)
    : type_(type), cgl_context_(cgl_context), poisoned_(false) {
  DCHECK(type_map()->find(type_) == type_map()->end());
  type_map()->insert(std::make_pair(type_, this));

  ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
}

IOSurfaceContext::~IOSurfaceContext() {
  ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);

  if (!poisoned_) {
    DCHECK(type_map()->find(type_) != type_map()->end());
    DCHECK(type_map()->find(type_)->second == this);
    type_map()->erase(type_);
  } else {
    TypeMap::const_iterator found = type_map()->find(type_);
    if (found != type_map()->end())
      DCHECK(found->second != this);
  }
}

void IOSurfaceContext::OnGpuSwitched() {
  // Recreate all browser-side GL contexts whenever the GPU switches. If this
  // is not done, performance will suffer.
  // http://crbug.com/361493
  PoisonContextAndSharegroup();
}

// static
IOSurfaceContext::TypeMap*
    IOSurfaceContext::type_map() {
  return type_map_.Pointer();
}

// static
base::LazyInstance<IOSurfaceContext::TypeMap>
    IOSurfaceContext::type_map_;

}  // namespace ui
