// Copyright 2014 The Cobalt Authors. 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_BACKEND_TEXTURE_STUB_H_
#define COBALT_RENDERER_BACKEND_TEXTURE_STUB_H_

#include <memory>

#include "base/memory/aligned_memory.h"
#include "cobalt/renderer/backend/pixel_data_stub.h"
#include "cobalt/renderer/backend/surface_info.h"
#include "cobalt/renderer/backend/texture.h"

namespace cobalt {
namespace renderer {
namespace backend {

// Maintains a scoped array of texture data.
class TextureDataStub : public TextureData {
 public:
  explicit TextureDataStub(const SurfaceInfo& surface_info) :
      pixel_data_(new PixelDataStub(surface_info)) {}

  const SurfaceInfo& GetSurfaceInfo() const override {
    return pixel_data_->surface_info();
  }
  int GetPitchInBytes() const override {
    return pixel_data_->surface_info().size.width() *
           SurfaceInfo::BytesPerPixel(pixel_data_->surface_info().format);
  }
  uint8_t* GetMemory() override { return pixel_data_->memory(); }

  const scoped_refptr<PixelDataStub>& pixel_data() const { return pixel_data_; }

 private:
  scoped_refptr<PixelDataStub> pixel_data_;
};

class RawTextureMemoryStub : public RawTextureMemory {
 public:
  RawTextureMemoryStub(size_t size_in_bytes, size_t alignment)
      : size_in_bytes_(size_in_bytes) {
    memory_.reset(
        static_cast<uint8_t*>(base::AlignedAlloc(size_in_bytes, alignment)));
  }

  // Returns the allocated size of the texture memory.
  size_t GetSizeInBytes() const override { return size_in_bytes_; }

  // Returns a CPU-accessible pointer to the allocated memory.
  uint8_t* GetMemory() override { return memory_.get(); }

  const uint8_t* GetMemory() const { return memory_.get(); }

 protected:
  void MakeConst() override {}

 private:
  size_t size_in_bytes_;

  // TODO: Store memory using a EGL PBuffer object which provides the
  //       implementation control over the memory.
  std::unique_ptr<uint8_t, base::AlignedFreeDeleter> memory_;
};

// Acts as a texture in the stub graphics system.  It does not store any pixel
// information and cannot redraw itself, but it does store surface information
// and so even the stub graphics system can query for texture metadata.
class TextureStub : public Texture {
 public:
  explicit TextureStub(scoped_refptr<PixelDataStub> pixel_data)
      : pixel_data_(pixel_data) {}

  TextureStub(const scoped_refptr<ConstRawTextureMemory>& raw_texture_memory,
              intptr_t offset, const SurfaceInfo& surface_info,
              int pitch_in_bytes)
      : pixel_data_(new PixelDataStub(surface_info)) {
    const RawTextureMemoryStub* raw_texture_memory_stub =
        base::polymorphic_downcast<const RawTextureMemoryStub*>(
            &(raw_texture_memory->raw_texture_memory()));
  }

  const SurfaceInfo& GetSurfaceInfo() const override {
    return pixel_data_->surface_info();
  }

  const scoped_refptr<PixelDataStub>& pixel_data() const {
    return pixel_data_;
  }

  Origin GetOrigin() const override { return kBottomLeft; }

  intptr_t GetPlatformHandle() override { return 0; }

 private:
  scoped_refptr<PixelDataStub> pixel_data_;
};

}  // namespace backend
}  // namespace renderer
}  // namespace cobalt

#endif  // COBALT_RENDERER_BACKEND_TEXTURE_STUB_H_
