// Copyright 2016 The SwiftShader 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 sw_Blitter_hpp
#define sw_Blitter_hpp

#include "Memset.hpp"
#include "RoutineCache.hpp"
#include "Reactor/Reactor.hpp"
#include "Vulkan/VkFormat.hpp"

#include "marl/mutex.h"
#include "marl/tsa.h"

#include <cstring>

namespace vk {

class Image;
class ImageView;
class Buffer;

}  // namespace vk

namespace sw {

class Blitter
{
	struct Options
	{
		explicit Options() = default;
		explicit Options(bool filter, bool allowSRGBConversion)
		    : writeMask(0xF)
		    , clearOperation(false)
		    , filter(filter)
		    , allowSRGBConversion(allowSRGBConversion)
		    , clampToEdge(false)
		{}
		explicit Options(unsigned int writeMask)
		    : writeMask(writeMask)
		    , clearOperation(true)
		    , filter(false)
		    , allowSRGBConversion(true)
		    , clampToEdge(false)
		{}

		union
		{
			struct
			{
				bool writeRed : 1;
				bool writeGreen : 1;
				bool writeBlue : 1;
				bool writeAlpha : 1;
			};

			unsigned char writeMask;
		};

		bool clearOperation : 1;
		bool filter : 1;
		bool allowSRGBConversion : 1;
		bool clampToEdge : 1;
	};

	struct State : Memset<State>, Options
	{
		State()
		    : Memset(this, 0)
		{}
		State(const Options &options)
		    : Memset(this, 0)
		    , Options(options)
		{}
		State(vk::Format sourceFormat, vk::Format destFormat, int srcSamples, int destSamples, const Options &options)
		    : Memset(this, 0)
		    , Options(options)
		    , sourceFormat(sourceFormat)
		    , destFormat(destFormat)
		    , srcSamples(srcSamples)
		    , destSamples(destSamples)
		{}

		vk::Format sourceFormat;
		vk::Format destFormat;
		int srcSamples = 0;
		int destSamples = 0;
		bool filter3D = false;
	};
	friend std::hash<Blitter::State>;

	struct BlitData
	{
		const void *source;
		void *dest;
		uint32_t sPitchB;
		uint32_t dPitchB;
		uint32_t sSliceB;
		uint32_t dSliceB;

		float x0;
		float y0;
		float z0;
		float w;
		float h;
		float d;

		int x0d;
		int x1d;
		int y0d;
		int y1d;
		int z0d;
		int z1d;

		int sWidth;
		int sHeight;
		int sDepth;

		bool filter3D;
	};

	struct CubeBorderData
	{
		void *layers;
		uint32_t pitchB;
		uint32_t layerSize;
		uint32_t dim;
	};

public:
	Blitter();
	virtual ~Blitter();

	void clear(const void *clearValue, vk::Format clearFormat, vk::Image *dest, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea = nullptr);

	void blit(const vk::Image *src, vk::Image *dst, VkImageBlit2KHR region, VkFilter filter);
	void resolve(const vk::Image *src, vk::Image *dst, VkImageResolve2KHR region);
	void resolveDepthStencil(const vk::ImageView *src, vk::ImageView *dst, const VkSubpassDescriptionDepthStencilResolve &dsrDesc);
	void copy(const vk::Image *src, uint8_t *dst, unsigned int dstPitch);

	void updateBorders(const vk::Image *image, const VkImageSubresource &subresource);

private:
	enum Edge
	{
		TOP,
		BOTTOM,
		RIGHT,
		LEFT
	};

	bool fastClear(const void *clearValue, vk::Format clearFormat, vk::Image *dest, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea);
	bool fastResolve(const vk::Image *src, vk::Image *dst, VkImageResolve2KHR region);

	Float4 readFloat4(Pointer<Byte> element, const State &state);
	void write(Float4 &color, Pointer<Byte> element, const State &state);
	Int4 readInt4(Pointer<Byte> element, const State &state);
	void write(Int4 &color, Pointer<Byte> element, const State &state);
	static void ApplyScaleAndClamp(Float4 &value, const State &state, bool preScaled = false);
	static Int ComputeOffset(Int &x, Int &y, Int &pitchB, int bytes);
	static Int ComputeOffset(Int &x, Int &y, Int &z, Int &sliceB, Int &pitchB, int bytes);
	static Float4 LinearToSRGB(const Float4 &color);
	static Float4 sRGBtoLinear(const Float4 &color);

	using BlitFunction = FunctionT<void(const BlitData *)>;
	using BlitRoutineType = BlitFunction::RoutineType;
	BlitRoutineType getBlitRoutine(const State &state);
	BlitRoutineType generate(const State &state);
	Float4 sample(Pointer<Byte> &source, Float &x, Float &y, Float &z,
	              Int &sWidth, Int &sHeight, Int &sDepth,
	              Int &sSliceB, Int &sPitchB, const State &state);

	using CornerUpdateFunction = FunctionT<void(const CubeBorderData *)>;
	using CornerUpdateRoutineType = CornerUpdateFunction::RoutineType;
	CornerUpdateRoutineType getCornerUpdateRoutine(const State &state);
	CornerUpdateRoutineType generateCornerUpdate(const State &state);
	void computeCubeCorner(Pointer<Byte> &layer, Int &x0, Int &x1, Int &y0, Int &y1, Int &pitchB, const State &state);

	void copyCubeEdge(const vk::Image *image,
	                  const VkImageSubresource &dstSubresource, Edge dstEdge,
	                  const VkImageSubresource &srcSubresource, Edge srcEdge);

	marl::mutex blitMutex;
	RoutineCache<State, BlitFunction::CFunctionType> blitCache GUARDED_BY(blitMutex);

	marl::mutex cornerUpdateMutex;
	RoutineCache<State, CornerUpdateFunction::CFunctionType> cornerUpdateCache GUARDED_BY(cornerUpdateMutex);
};

}  // namespace sw

namespace std {

template<>
struct hash<sw::Blitter::State>
{
	uint64_t operator()(const sw::Blitter::State &state) const
	{
		uint64_t hash = state.sourceFormat;
		hash = hash * 31 + state.destFormat;
		hash = hash * 31 + state.srcSamples;
		hash = hash * 31 + state.destSamples;
		hash = hash * 31 + state.filter3D;
		return hash;
	}
};

}  // namespace std

#endif  // sw_Blitter_hpp
