// Copyright 2015 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/backend/egl/resource_context.h"

#include "base/bind.h"
#include "base/synchronization/waitable_event.h"
#include "cobalt/renderer/backend/egl/texture.h"
#include "cobalt/renderer/backend/egl/utils.h"

namespace cobalt {
namespace renderer {
namespace backend {

ResourceContext::ResourceContext(EGLDisplay display, EGLConfig config)
    : display_(display), config_(config), thread_("GL Texture Resource") {
  context_ = CreateGLES3Context(display, config, EGL_NO_CONTEXT);

  // Create a dummy EGLSurface object to be assigned as the target surface
  // when we need to make OpenGL calls that do not depend on a surface (e.g.
  // creating a texture).
  EGLint null_surface_attrib_list[] = {
      EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE,
  };
  null_surface_ =
      eglCreatePbufferSurface(display, config, null_surface_attrib_list);
  CHECK_EQ(EGL_SUCCESS, eglGetError());

  // Start the resource context thread and immediately make the resource context
  // current on that thread, so that subsequent calls to
  // RunSynchronouslyWithinResourceContext() can assume it is current already.
  thread_.Start();
  thread_.message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&ResourceContext::MakeCurrent, base::Unretained(this)));
}

ResourceContext::~ResourceContext() {
  thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &ResourceContext::ShutdownOnResourceThread, base::Unretained(this)));
}

namespace {
void RunAndSignal(const base::Closure& function, base::WaitableEvent* event) {
  function.Run();
  event->Signal();
}
}

void ResourceContext::RunSynchronouslyWithinResourceContext(
    const base::Closure& function) {
  DCHECK_NE(thread_.message_loop(), MessageLoop::current()) <<
      "This method should not be called within the resource context thread.";

  base::WaitableEvent event(true, false);
  thread_.message_loop()->PostTask(FROM_HERE,
                                   base::Bind(&RunAndSignal, function, &event));
  event.Wait();
}

void ResourceContext::AssertWithinResourceContext() {
  DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
}

void ResourceContext::MakeCurrent() {
  DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
  EGL_CALL(eglMakeCurrent(display_, null_surface_, null_surface_, context_));
}

void ResourceContext::ShutdownOnResourceThread() {
  EGL_CALL(eglMakeCurrent(
      display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

  EGL_CALL(eglDestroySurface(display_, null_surface_));
  EGL_CALL(eglDestroyContext(display_, context_));
}

}  // namespace backend
}  // namespace renderer
}  // namespace cobalt
