// 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_SHELL_PLATFORM_DARWIN_IOS_IOS_RESOURCE_CONTEXT_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_RESOURCE_CONTEXT_H_

#include <memory>

#include "flutter/common/graphics/gl_context_switch.h"
#include "flutter/common/graphics/msaa_sample_count.h"
#include "flutter/common/graphics/texture.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
#import "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"

namespace impeller {
class Context;
}  // namespace impeller

namespace flutter {

//------------------------------------------------------------------------------
/// @brief      Manages the lifetime of the on-screen and off-screen rendering
///             contexts on iOS. On-screen contexts are used by Flutter for
///             rendering into the surface. The lifecycle of this context may be
///             tied to the lifecycle of the surface. On the other hand, the
///             lifecycle of the off-screen context it tied to that of the
///             platform view. This one object used to manage both context
///             because GPU handles may need to be shared between the two
///             context. To achieve this, context may need references to one
///             another at creation time. This one object manages the creation,
///             use and collection of both contexts in a client rendering API
///             agnostic manner.
///
class IOSContext {
 public:
  //----------------------------------------------------------------------------
  /// @brief      Create an iOS context object capable of creating the on-screen
  ///             and off-screen GPU context for use by Skia.
  ///
  ///             In case the engine does not support the specified client
  ///             rendering API, this a `nullptr` may be returned.
  ///
  /// @param[in]  api       A client rendering API supported by the
  ///                       engine/platform.
  /// @param[in]  backend   A client rendering backend supported by the
  ///                       engine/platform.
  /// @param[in]  msaa_samples
  ///                       The number of MSAA samples to use. Only supplied to
  ///                       Skia, must be either 0, 1, 2, 4, or 8.
  ///
  /// @return     A valid context on success. `nullptr` on failure.
  ///
  static std::unique_ptr<IOSContext> Create(IOSRenderingAPI api,
                                            IOSRenderingBackend backend,
                                            MsaaSampleCount msaa_samples);

  //----------------------------------------------------------------------------
  /// @brief      Collects the context object. This must happen on the thread on
  ///             which this object was created.
  ///
  virtual ~IOSContext();

  //----------------------------------------------------------------------------
  /// @brief      Get the rendering backend used by this context.
  ///
  /// @return     The rendering backend.
  ///
  virtual IOSRenderingBackend GetBackend() const;

  //----------------------------------------------------------------------------
  /// @brief      Create a resource context for use on the IO task runner. This
  ///             resource context is used by Skia to upload texture to
  ///             asynchronously and collect resources that are no longer needed
  ///             on the render task runner.
  ///
  /// @attention  Client rendering APIs for which a GrDirectContext cannot be realized
  ///             (software rendering), this method will always return null.
  ///
  /// @return     A non-null Skia context on success. `nullptr` on failure.
  ///
  virtual sk_sp<GrDirectContext> CreateResourceContext() = 0;

  //----------------------------------------------------------------------------
  /// @brief      When using client rendering APIs whose contexts need to be
  ///             bound to a specific thread, the engine will call this method
  ///             to give the on-screen context a chance to bind to the current
  ///             thread.
  ///
  /// @attention  Client rendering APIs that have no-concept of thread local
  ///             bindings (anything that is not OpenGL) will always return
  ///             `true`.
  ///
  /// @attention  Client rendering APIs for which a GrDirectContext cannot be created
  ///             (software rendering) will always return `false`.
  ///
  /// @attention  This binds the on-screen context to the current thread. To
  ///             bind the off-screen context to the thread, use the
  ///             `ResoruceMakeCurrent` method instead.
  ///
  /// @attention  Only one context may be bound to a thread at any given time.
  ///             Making a binding on a thread, clears the old binding.
  ///
  /// @return     A GLContextResult that represents the result of the method.
  ///             The GetResult() returns a bool that indicates If the on-screen context could be
  ///             bound to the current
  /// thread.
  ///
  virtual std::unique_ptr<GLContextResult> MakeCurrent() = 0;

  //----------------------------------------------------------------------------
  /// @brief      Creates an external texture proxy of the appropriate client
  ///             rendering API.
  ///
  /// @param[in]  texture_id  The texture identifier
  /// @param[in]  texture     The texture
  ///
  /// @return     The texture proxy if the rendering backend supports embedder
  ///             provided external textures.
  ///
  virtual std::unique_ptr<Texture> CreateExternalTexture(
      int64_t texture_id,
      fml::scoped_nsobject<NSObject<FlutterTexture>> texture) = 0;

  //----------------------------------------------------------------------------
  /// @brief      Accessor for the Skia context associated with IOSSurfaces and
  ///             the raster thread.
  /// @details    There can be any number of resource contexts but this is the
  ///             one context that will be used by surfaces to draw to the
  ///             screen from the raster thread.
  /// @returns    `nullptr` on failure.
  /// @attention  The software context doesn't have a Skia context, so this
  ///             value will be nullptr.
  /// @see        For contexts which are used for offscreen work like loading
  ///             textures see IOSContext::CreateResourceContext.
  ///
  virtual sk_sp<GrDirectContext> GetMainContext() const = 0;

  virtual std::shared_ptr<impeller::Context> GetImpellerContext() const;

  MsaaSampleCount GetMsaaSampleCount() const { return msaa_samples_; }

 protected:
  explicit IOSContext(MsaaSampleCount msaa_samples);

 private:
  MsaaSampleCount msaa_samples_ = MsaaSampleCount::kNone;
  FML_DISALLOW_COPY_AND_ASSIGN(IOSContext);
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_RESOURCE_CONTEXT_H_
