/*
 * 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_CACHED_SOFTWARE_RASTERIZER_H_
#define COBALT_RENDERER_RASTERIZER_BLITTER_CACHED_SOFTWARE_RASTERIZER_H_

#include "base/containers/linked_hash_map.h"
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "cobalt/base/c_val.h"
#include "cobalt/render_tree/node.h"
#include "cobalt/renderer/rasterizer/blitter/render_state.h"
#include "cobalt/renderer/rasterizer/common/offscreen_render_coordinate_mapping.h"
#include "cobalt/renderer/rasterizer/skia/software_rasterizer.h"
#include "starboard/blitter.h"

#if SB_HAS(BLITTER)

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

// This class is responsible for creating SbBlitterSurfaces and software
// rasterizing render tree nodes to them to be used by clients.  The class
// manages a cache of software surfaces in order to avoid duplicate work.  Its
// main public interface is for clients to construct
// CachedSoftwareRasterizer::SurfaceReference objects from which they can
// extract the software-rasterized surface.  Internally, software rasterization
// is handled via a skia::SoftwareRasterizer object.
class CachedSoftwareRasterizer {
 public:
  struct Surface {
    // The actual surface containing rendered data.
    SbBlitterSurface surface;

    // True if this surface was referenced at least once since the last time
    // OnStartNewFrame() was called.
    bool referenced;

#if defined(ENABLE_DEBUG_CONSOLE)
    // True if OnStartNewFrame() has not been called since this surface was
    // created.
    bool created;
#endif  // defined(ENABLE_DEBUG_CONSOLE)

    // Transform information detailing how the surface should be output to
    // the display such that sub-pixel alignments are respected.
    common::OffscreenRenderCoordinateMapping coord_mapping;

    // A duplicate of the key, though as a smart pointer, to keep a reference
    // to the node alive.
    scoped_refptr<render_tree::Node> node;

    // Is this surface cached or not.
    bool cached;

    // The scale used for rasterization when the surface was cached.
    math::Vector2dF scale;

    size_t GetEstimatedMemoryUsage() const;
  };

  CachedSoftwareRasterizer(SbBlitterDevice device, SbBlitterContext context,
                           int cache_capacity);
  ~CachedSoftwareRasterizer();

  // Should be called once per frame.  This method will remove from the cache
  // anything that hasn't been referenced in the last frame.
  void OnStartNewFrame();

  // A SurfaceReference is the mechanism through which clients can request
  // renders from the CachedSoftwareRasterizer.  The main reason that we don't
  // make GetSurface() the direct public interface is so that we can decide
  // to rasterize something without caching it, in which case it should be
  // cleaned up when the reference to it expires.
  class SurfaceReference {
   public:
    // The |transform| parameter should be the transform that the node will
    // ultimately have applied to it, and is used for ensuring that the rendered
    // result is sub-pixel aligned properly.
    SurfaceReference(CachedSoftwareRasterizer* rasterizer,
                     render_tree::Node* node, const Transform& transform)
        : surface_(rasterizer->GetSurface(node, transform)) {}
    ~SurfaceReference() {
      // If the surface returned to us was not actually cached, then destroy
      // it here when the surface reference is destroyed.
      if (!surface_.cached && SbBlitterIsSurfaceValid(surface_.surface)) {
        SbBlitterDestroySurface(surface_.surface);
      }
    }
    const Surface& surface() const { return surface_; }

   private:
    Surface surface_;

    DISALLOW_COPY_AND_ASSIGN(SurfaceReference);
  };

  Surface GetSurface(render_tree::Node* node, const Transform& transform);

  render_tree::ResourceProvider* GetResourceProvider() {
    return software_rasterizer_.GetResourceProvider();
  }

 private:
  typedef base::linked_hash_map<render_tree::Node*, Surface> CacheMap;

  // Release surfaces until we have |space_needed| free bytes in the cache.
  // This function will never release surfaces that were referenced this frame.
  // It is an error to call this function if it is impossible to purge
  // unreferenced surfaces until the desired amount of free space is available.
  void PurgeUntilSpaceAvailable(int space_needed);

  // The cache, mapping input render_tree::Node references to cached surfaces.
  CacheMap surface_map_;

  const int cache_capacity_;

  // The Blitter device/context that all image allocation/blitting operations
  // will occur within.
  SbBlitterDevice device_;
  SbBlitterContext context_;

  // The internal rasterizer used to actually render nodes.
  skia::SoftwareRasterizer software_rasterizer_;

  // The amount of memory currently consumed by the surfaces populating the
  // cache.
  base::CVal<base::cval::SizeInBytes> cache_memory_usage_;

  // Cache memory used this frame only.
  base::CVal<base::cval::SizeInBytes> cache_frame_usage_;
};

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

#endif  // #if SB_HAS(BLITTER)

#endif  // COBALT_RENDERER_RASTERIZER_BLITTER_CACHED_SOFTWARE_RASTERIZER_H_
