// Copyright 2016 Google Inc. 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.

#ifndef COBALT_RENDERER_RASTERIZER_BLITTER_SURFACE_CACHE_DELEGATE_H_
#define COBALT_RENDERER_RASTERIZER_BLITTER_SURFACE_CACHE_DELEGATE_H_

#include <string>

#include "base/callback.h"
#include "base/optional.h"
#if defined(ENABLE_DEBUG_CONSOLE)
#include "cobalt/base/console_commands.h"
#endif
#include "cobalt/renderer/rasterizer/blitter/render_state.h"
#include "cobalt/renderer/rasterizer/common/offscreen_render_coordinate_mapping.h"
#include "cobalt/renderer/rasterizer/common/surface_cache.h"
#include "starboard/blitter.h"

#if SB_HAS(BLITTER)

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace blitter {

// Implements blitter-specific cache recording and playback surface management
// in order to provide blitter-support for the render tree surface caching
// system.
class SurfaceCacheDelegate : public common::SurfaceCache::Delegate {
 private:
  class CachedSurface : public common::SurfaceCache::CachedSurface {
   public:
    CachedSurface(SbBlitterSurface surface,
                  const math::Vector2dF& output_post_scale,
                  const math::Vector2dF& output_pre_translate,
                  const math::Rect& output_bounds)
        : surface_(surface),
          output_post_scale_(output_post_scale),
          output_pre_translate_(output_pre_translate),
          output_bounds_(output_bounds) {}
    ~CachedSurface() OVERRIDE { SbBlitterDestroySurface(surface_); }

    SbBlitterSurface surface() const { return surface_; }
    const math::Vector2dF& output_post_scale() const {
      return output_post_scale_;
    }
    const math::Vector2dF& output_pre_translate() const {
      return output_pre_translate_;
    }
    const math::Rect& output_bounds() const { return output_bounds_; }

   private:
    // The actual surface representing the cached render tree.
    SbBlitterSurface surface_;

    // When applying |surface_| to another render target, the current
    // transformation should be post-multiplied by |output_post_scale_|, and
    // pre-multiplied by |output_pre_translate_|.
    math::Vector2dF output_post_scale_;
    math::Vector2dF output_pre_translate_;
    // The rectangle coordinates into which |surface_| should be rendered.
    math::Rect output_bounds_;
  };

 public:
  typedef base::Callback<RenderState*(const RenderState&)>
      SetRenderStateFunction;

  // Creating a ScopedContext object declares a render tree visitor context,
  // and so there should be one ScopedContext per render tree visitor.  Since
  // it is typical to recursively create sub render tree visitors, this class
  // is designed to be instantiated multiple times on the same
  // SurfaceCacheDelegate object.
  class ScopedContext {
   public:
    ScopedContext(SurfaceCacheDelegate* delegate, RenderState* render_state,
                  const SetRenderStateFunction& set_render_state_function)
        : delegate_(delegate),
          old_render_state_(delegate_->render_state_),
          old_set_render_state_function_(
              delegate_->set_render_state_function_) {
      // Setup our new render target to the provided one.  Remember a new method
      // to set the render target for the current rendering context in case we
      // need to start recording on a offscreen surface.
      delegate_->render_state_ = render_state;
      delegate_->set_render_state_function_ = set_render_state_function;
    }
    ~ScopedContext() {
      // Restore the render target to the old setting.
      delegate_->set_render_state_function_ = old_set_render_state_function_;
      delegate_->render_state_ = old_render_state_;
    }

   private:
    SurfaceCacheDelegate* delegate_;
    RenderState* old_render_state_;
    SetRenderStateFunction old_set_render_state_function_;
  };

  SurfaceCacheDelegate(SbBlitterDevice device, SbBlitterContext context);

  void ApplySurface(common::SurfaceCache::CachedSurface* surface) OVERRIDE;
  void StartRecording(const math::RectF& local_bounds) OVERRIDE;
  common::SurfaceCache::CachedSurface* EndRecording() OVERRIDE;
  void ReleaseSurface(common::SurfaceCache::CachedSurface* surface) OVERRIDE;
  math::Size GetRenderSize(const math::SizeF& local_size) OVERRIDE;
  math::Size MaximumSurfaceSize() OVERRIDE;

 private:
  // Defines a set of data that is relevant only while recording.
  struct RecordingData {
    RecordingData(const RenderState& original_render_state,
                  const common::OffscreenRenderCoordinateMapping& coord_mapping,
                  SbBlitterSurface surface)
        : original_render_state(original_render_state),
          coord_mapping(coord_mapping),
          surface(surface) {}

    // The original render state that the recorded draw calls would have
    // otherwise targeted if we were not recording.
    RenderState original_render_state;

    // Information about how to map the offscreen cached surface to the main
    // render target.
    common::OffscreenRenderCoordinateMapping coord_mapping;

    // The offscreen cached surface that we are recording to.
    SbBlitterSurface surface;
  };

#if defined(ENABLE_DEBUG_CONSOLE)
  void OnToggleCacheHighlights(const std::string& message);
#endif

  SbBlitterDevice device_;
  SbBlitterContext context_;

  // A function that can be used to change the current render state in order to
  // affect subsequent blitter render tree node visitor rasterization commands
  // to an offscreen cached surface with a custom transform and clip stack.
  SetRenderStateFunction set_render_state_function_;

  // The current render state that is being used, whether it is cached surface
  // recording state (e.g. render to an offscreen surface) or the normal
  // render state currently in use by a render tree node visitor client.
  RenderState* render_state_;

  // If we are currently recording, this will contain all of the data relevant
  // to that recording.
  base::optional<RecordingData> recording_data_;

#if defined(ENABLE_DEBUG_CONSOLE)
  // Debug command to toggle cache highlights to help visualize which nodes
  // are being cached.
  bool toggle_cache_highlights_;
  base::ConsoleCommandManager::CommandHandler
      toggle_cache_highlights_command_handler_;
#endif
};

}  // namespace blitter
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // #if SB_HAS(BLITTER)

#endif  // COBALT_RENDERER_RASTERIZER_BLITTER_SURFACE_CACHE_DELEGATE_H_
