/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkLinearBitmapPipeline_DEFINED
#define SkLinearBitmapPipeline_DEFINED

#include "SkColor.h"
#include "SkImageInfo.h"
#include "SkMatrix.h"
#include "SkShader.h"
#include "SkSmallAllocator.h"

class SkEmbeddableLinearPipeline;

enum SkGammaType {
    kLinear_SkGammaType,
    kSRGB_SkGammaType,
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// SkLinearBitmapPipeline - encapsulates all the machinery for doing floating point pixel
// processing in a linear color space.
// Note: this class has unusual alignment requirements due to its use of SIMD instructions. The
// class SkEmbeddableLinearPipeline below manages these requirements.
class SkLinearBitmapPipeline {
public:
    SkLinearBitmapPipeline(
        const SkMatrix& inverse,
        SkFilterQuality filterQuality,
        SkShader::TileMode xTile, SkShader::TileMode yTile,
        SkColor paintColor,
        const SkPixmap& srcPixmap);

    SkLinearBitmapPipeline(
        const SkLinearBitmapPipeline& pipeline,
        const SkPixmap& srcPixmap,
        SkBlendMode,
        const SkImageInfo& dstInfo);

    static bool ClonePipelineForBlitting(
        SkEmbeddableLinearPipeline* pipelineStorage,
        const SkLinearBitmapPipeline& pipeline,
        SkMatrix::TypeMask matrixMask,
        SkShader::TileMode xTileMode,
        SkShader::TileMode yTileMode,
        SkFilterQuality filterQuality,
        const SkPixmap& srcPixmap,
        float finalAlpha,
        SkBlendMode,
        const SkImageInfo& dstInfo);

    ~SkLinearBitmapPipeline();

    void shadeSpan4f(int x, int y, SkPM4f* dst, int count);
    void blitSpan(int32_t x, int32_t y, void* dst, int count);

    template<typename Base, size_t kSize, typename Next = void>
    class Stage {
    public:
        Stage() : fIsInitialized{false} {}
        ~Stage();

        template<typename Variant, typename... Args>
        void initStage(Next* next, Args&& ... args);

        template<typename Variant, typename... Args>
        void initSink(Args&& ... args);

        Base* get() const { return reinterpret_cast<Base*>(fSpace); }
        Base* operator->() const { return this->get(); }
        Base& operator*() const { return *(this->get()); }

    private:
        mutable char                       fSpace[kSize];
        bool                               fIsInitialized;
    };

    class PointProcessorInterface;
    class SampleProcessorInterface;
    class BlendProcessorInterface;
    class DestinationInterface;
    class PixelAccessorInterface;

    // These values were generated by the assert above in Stage::init{Sink|Stage}.
    using SampleStage  = Stage<SampleProcessorInterface,   160, BlendProcessorInterface>;
    using BlenderStage = Stage<BlendProcessorInterface,     48>;

private:
    using MemoryAllocator = SkSmallAllocator<128, 4>;
    using MatrixCloner =
        std::function<PointProcessorInterface* (PointProcessorInterface*, MemoryAllocator*)>;
    using TilerCloner =
        std::function<PointProcessorInterface* (SampleProcessorInterface*, MemoryAllocator*)>;

    PointProcessorInterface* chooseMatrix(
        PointProcessorInterface* next,
        const SkMatrix& inverse);

    template <typename Tiler>
    PointProcessorInterface* createTiler(SampleProcessorInterface* next, SkISize dimensions);

    template <typename XStrategy>
    PointProcessorInterface* chooseTilerYMode(
        SampleProcessorInterface* next, SkShader::TileMode yMode, SkISize dimensions);

    PointProcessorInterface* chooseTiler(
        SampleProcessorInterface* next,
        SkISize dimensions,
        SkShader::TileMode xMode, SkShader::TileMode yMode,
        SkFilterQuality filterQuality,
        SkScalar dx);

    template <SkColorType colorType>
    PixelAccessorInterface* chooseSpecificAccessor(const SkPixmap& srcPixmap);

    PixelAccessorInterface* choosePixelAccessor(
        const SkPixmap& srcPixmap,
        const SkColor A8TintColor);

    SampleProcessorInterface* chooseSampler(
        BlendProcessorInterface* next,
        SkFilterQuality filterQuality,
        SkShader::TileMode xTile, SkShader::TileMode yTile,
        const SkPixmap& srcPixmap,
        const SkColor A8TintColor);

    MemoryAllocator          fMemory;
    PointProcessorInterface* fFirstStage;
    MatrixCloner             fMatrixStageCloner;
    TilerCloner              fTileStageCloner;
    BlenderStage             fBlenderStage;
    DestinationInterface*    fLastStage;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// SkEmbeddableLinearPipeline - manage stricter alignment needs for SkLinearBitmapPipeline.
class SkEmbeddableLinearPipeline {
public:
    SkEmbeddableLinearPipeline() { }
    ~SkEmbeddableLinearPipeline() {
        if (fInitialized) {
            get()->~SkLinearBitmapPipeline();
        }
    }

    template <typename... Args>
    void init(Args&&... args) {
        new (fPipelineStorage) SkLinearBitmapPipeline{std::forward<Args>(args)...};
        fInitialized = true;
    }

    SkLinearBitmapPipeline* get() const {
        return reinterpret_cast<SkLinearBitmapPipeline*>(fPipelineStorage);
    }
    SkLinearBitmapPipeline& operator*()  const { return *this->get(); }
    SkLinearBitmapPipeline* operator->() const { return  this->get(); }

private:
    alignas(SkLinearBitmapPipeline) mutable char fPipelineStorage[sizeof(SkLinearBitmapPipeline)];
    bool                                         fInitialized {false};
};

#endif  // SkLinearBitmapPipeline_DEFINED
