// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_FLOW_GL_CONTEXT_SWITCH_H_
#define FLUTTER_FLOW_GL_CONTEXT_SWITCH_H_

#include <functional>
#include <memory>
#include <vector>

#include "flutter/fml/logging.h"
#include "flutter/fml/macros.h"

namespace flutter {

// This interface represents a gl context that can be switched by
// |GLContextSwitch|.
//
// The implementation should wrap a "Context" object inside this class. For
// example, in iOS while using a GL rendering surface, the implementation should
// wrap an |EAGLContext|.
class SwitchableGLContext {
 public:
  SwitchableGLContext();

  virtual ~SwitchableGLContext();

  // Implement this to set the context wrapped by this |SwitchableGLContext|
  // object to the current context.
  virtual bool SetCurrent() = 0;

  // Implement this to remove the context wrapped by this |SwitchableGLContext|
  // object from current context;
  virtual bool RemoveCurrent() = 0;

  FML_DISALLOW_COPY_AND_ASSIGN(SwitchableGLContext);
};

// Represents the result of setting a gl context.
//
// This class exists because context results are used in places applies to all
// the platforms. On certain platforms(for example lower end iOS devices that
// uses gl), a |GLContextSwitch| is required to protect flutter's gl contect
// from being polluted by other programs(embedded platform views). A
// |GLContextSwitch| is a subclass of |GLContextResult|, which can be returned
// on platforms that requires context switching. A |GLContextDefaultResult| is
// also a subclass of |GLContextResult|, which can be returned on platforms
// that doesn't require context switching.
class GLContextResult {
 public:
  GLContextResult();
  virtual ~GLContextResult();

  //----------------------------------------------------------------------------
  // Returns true if the gl context is set successfully.
  bool GetResult();

 protected:
  GLContextResult(bool static_result);
  bool result_;

  FML_DISALLOW_COPY_AND_ASSIGN(GLContextResult);
};

//------------------------------------------------------------------------------
/// The default implementation of |GLContextResult|.
///
/// Use this class on platforms that doesn't require gl context switching.
/// * See also |GLContextSwitch| if the platform requires gl context switching.
class GLContextDefaultResult : public GLContextResult {
 public:
  //----------------------------------------------------------------------------
  /// Constructs a |GLContextDefaultResult| with a static result.
  ///
  /// Used this on platforms that doesn't require gl context switching. (For
  /// example, metal on iOS)
  ///
  /// @param  static_result a static value that will be returned from
  /// |GetResult|
  GLContextDefaultResult(bool static_result);

  ~GLContextDefaultResult() override;

  FML_DISALLOW_COPY_AND_ASSIGN(GLContextDefaultResult);
};

//------------------------------------------------------------------------------
/// Switches the gl context to the a context that is passed in the
/// constructor.
///
/// In destruction, it should restore the current context to what was
/// before the construction of this switch.
class GLContextSwitch final : public GLContextResult {
 public:
  //----------------------------------------------------------------------------
  /// Constructs a |GLContextSwitch|.
  ///
  /// @param  context The context that is going to be set as the current
  /// context. The |GLContextSwitch| should not outlive the owner of the gl
  /// context wrapped inside the `context`.
  GLContextSwitch(std::unique_ptr<SwitchableGLContext> context);

  ~GLContextSwitch() override;

 private:
  std::unique_ptr<SwitchableGLContext> context_;

  FML_DISALLOW_COPY_AND_ASSIGN(GLContextSwitch);
};

}  // namespace flutter

#endif  // FLUTTER_FLOW_GL_CONTEXT_SWITCH_H_
