// Copyright 2014 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_SKIA_SOFTWARE_IMAGE_H_
#define COBALT_RENDERER_RASTERIZER_SKIA_SOFTWARE_IMAGE_H_

#include "base/memory/scoped_ptr.h"
#include "cobalt/math/size.h"
#include "cobalt/render_tree/image.h"
#include "cobalt/render_tree/resource_provider.h"
#include "cobalt/renderer/rasterizer/skia/image.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace skia {

class SoftwareImageData : public render_tree::ImageData {
 public:
  SoftwareImageData(const math::Size& size,
                    render_tree::PixelFormat pixel_format,
                    render_tree::AlphaFormat alpha_format);

  const render_tree::ImageDataDescriptor& GetDescriptor() const OVERRIDE;
  uint8_t* GetMemory() OVERRIDE;

  scoped_array<uint8_t> PassPixelData();

 private:
  render_tree::ImageDataDescriptor descriptor_;
  scoped_array<uint8_t> pixel_data_;
};

class SoftwareImage : public SinglePlaneImage {
 public:
  explicit SoftwareImage(scoped_ptr<SoftwareImageData> source_data);
  SoftwareImage(uint8_t* source_data,
                const render_tree::ImageDataDescriptor& descriptor);

  const math::Size& GetSize() const OVERRIDE { return size_; }

  const SkBitmap* GetBitmap() const OVERRIDE { return &bitmap_; }

  bool EnsureInitialized() OVERRIDE { return false; }

  bool IsOpaque() const OVERRIDE { return is_opaque_; }

 private:
  void Initialize(uint8_t* source_data,
                  const render_tree::ImageDataDescriptor& descriptor);

  scoped_array<uint8_t> owned_pixel_data_;
  SkBitmap bitmap_;
  math::Size size_;
  bool is_opaque_;
};

class SoftwareRawImageMemory : public render_tree::RawImageMemory {
 public:
  SoftwareRawImageMemory(size_t size_in_bytes, size_t alignment);

  size_t GetSizeInBytes() const OVERRIDE;
  uint8_t* GetMemory() OVERRIDE;

  scoped_ptr_malloc<uint8_t, base::ScopedPtrAlignedFree> PassPixelData();

 private:
  size_t size_in_bytes_;
  scoped_ptr_malloc<uint8_t, base::ScopedPtrAlignedFree> pixel_data_;
};

class SoftwareMultiPlaneImage : public MultiPlaneImage {
 public:
  SoftwareMultiPlaneImage(
      scoped_ptr<SoftwareRawImageMemory> raw_image_memory,
      const render_tree::MultiPlaneImageDataDescriptor& descriptor);

  const math::Size& GetSize() const OVERRIDE { return size_; }

  render_tree::MultiPlaneImageFormat GetFormat() const OVERRIDE {
    return format_;
  }
  const SkBitmap* GetBitmap(int plane_index) const OVERRIDE {
    return planes_[plane_index]->GetBitmap();
  }

  bool EnsureInitialized() OVERRIDE { return false; }

  // Currently, all supported multiplane images (e.g. mostly YUV) do not
  // support alpha, so multiplane images will always be opaque.
  bool IsOpaque() const OVERRIDE { return true; }

 private:
  math::Size size_;
  render_tree::MultiPlaneImageFormat format_;

  scoped_ptr_malloc<uint8_t, base::ScopedPtrAlignedFree> owned_pixel_data_;

  scoped_refptr<SoftwareImage>
      planes_[render_tree::MultiPlaneImageDataDescriptor::kMaxPlanes];
};

}  // namespace skia
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // COBALT_RENDERER_RASTERIZER_SKIA_SOFTWARE_IMAGE_H_
