// 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_COMMON_SCRATCH_SURFACE_CACHE_H_
#define COBALT_RENDERER_RASTERIZER_COMMON_SCRATCH_SURFACE_CACHE_H_

#include <vector>

#include "base/callback.h"
#include "base/logging.h"
#include "cobalt/math/size.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace common {

// The ScratchSurfaceCache manages a set of platform-specific surface objects
// that can be used for offscreen rendering (e.g. by a RenderTreeNodeVisitor).
// In order to acquire surfaces from ScratchSurfaceCache, one should construct
// a CachedScratchSurface object, from which they can get a pointer to the
// Surface object.
// It is unique because it caters to RenderTreeNodeVisitor's scratch
// surface allocation pattern.  In particular, we don't mind handing out very
// large scratch surfaces when very small surfaces are requested, because
// typically only one surface is ever needed at a time.  When multiple surfaces
// are necessary, the subsequent ones tend to be smaller than the previous
// (because rendering is now happening within the previous ones), and so handing
// out textures in large to small order makes sense.
class ScratchSurfaceCache {
 public:
  class Surface {
   public:
    virtual ~Surface() {}
    virtual math::Size GetSize() const = 0;
  };
  class Delegate {
   public:
    virtual Surface* CreateSurface(const math::Size& size) = 0;
    virtual void DestroySurface(Surface* surface) = 0;
    virtual void PrepareForUse(Surface* surface, const math::Size& area) = 0;
  };

  ScratchSurfaceCache(Delegate* delegate, int cache_capacity_in_bytes);
  ~ScratchSurfaceCache();

 private:
  // Acquire (either via cache lookup or by creation if that fails) a scratch
  // surface.
  Surface* AcquireScratchSurface(const math::Size& size);
  void ReleaseScratchSurface(Surface* surface);

  // Searches through |unused_surfaces_| for one the one that best matches the
  // requested size, among all those cached surfaces that have at least the
  // requested size.
  Surface* FindBestCachedSurface(const math::Size& size);

  // Removes elements from the cache until we are below the cache limit.
  void Purge();

  // Allocate a new Surface and return it.
  Surface* CreateScratchSurface(const math::Size& size);

  // Implementation-specific details about how to create/destroy surfaces.
  Delegate* delegate_;

  // The maximum number of surface bytes that can be stored in the cache.
  int cache_capacity_in_bytes_;

  // We keep track of all surfaces we've handed out using |surface_stack_|.
  // This is mostly for debug checks to verify that surfaces returned to us
  // actually did come from us, and that they are returned in the expected
  // order.
  std::vector<Surface*> surface_stack_;

  // |unused_surfaces_| is the heart of the cache, as it stores the surfaces
  // that are unused but allocated and available to be handed out upon request.
  // Most recently used surfaces are found at the end of this vector.
  std::vector<Surface*> unused_surfaces_;

  // Tracks how much total memory we've allocated towards surfaces.
  size_t surface_memory_;

  friend class CachedScratchSurface;
};

// The primary interface to ScratchSurfaceCache is through CachedScratchSurface
// objects.  These effectively scope the acquisition of a cached surface, RAII
// style.
class CachedScratchSurface {
 public:
  CachedScratchSurface(ScratchSurfaceCache* cache, const math::Size& size)
      : cache_(cache) {
    surface_ = cache_->AcquireScratchSurface(size);
  }

  ~CachedScratchSurface() {
    if (surface_) {
      cache_->ReleaseScratchSurface(surface_);
    }
  }

  // Returns a pointer to the platform-specific surface.  The platform can then
  // downcast to the expected surface type.
  ScratchSurfaceCache::Surface* GetSurface() { return surface_; }

 private:
  ScratchSurfaceCache* cache_;
  ScratchSurfaceCache::Surface* surface_;
};

}  // namespace common
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // COBALT_RENDERER_RASTERIZER_COMMON_SCRATCH_SURFACE_CACHE_H_
