/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

#include <utils/JenkinsHash.h>
#include <utils/Trace.h>

#include "Caches.h"
#include "OpenGLRenderer.h"
#include "PathTessellator.h"
#include "ShadowTessellator.h"
#include "TessellationCache.h"

#include "thread/Signal.h"
#include "thread/Task.h"
#include "thread/TaskProcessor.h"

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Cache entries
///////////////////////////////////////////////////////////////////////////////

TessellationCache::Description::Description()
        : type(kNone)
        , scaleX(1.0f)
        , scaleY(1.0f)
        , aa(false)
        , cap(SkPaint::kDefault_Cap)
        , style(SkPaint::kFill_Style)
        , strokeWidth(1.0f) {
    memset(&shape, 0, sizeof(Shape));
}

TessellationCache::Description::Description(Type type, const Matrix4& transform, const SkPaint& paint)
        : type(type)
        , aa(paint.isAntiAlias())
        , cap(paint.getStrokeCap())
        , style(paint.getStyle())
        , strokeWidth(paint.getStrokeWidth()) {
    PathTessellator::extractTessellationScales(transform, &scaleX, &scaleY);
    memset(&shape, 0, sizeof(Shape));
}

hash_t TessellationCache::Description::hash() const {
    uint32_t hash = JenkinsHashMix(0, type);
    hash = JenkinsHashMix(hash, aa);
    hash = JenkinsHashMix(hash, cap);
    hash = JenkinsHashMix(hash, style);
    hash = JenkinsHashMix(hash, android::hash_type(strokeWidth));
    hash = JenkinsHashMix(hash, android::hash_type(scaleX));
    hash = JenkinsHashMix(hash, android::hash_type(scaleY));
    hash = JenkinsHashMixBytes(hash, (uint8_t*) &shape, sizeof(Shape));
    return JenkinsHashWhiten(hash);
}

void TessellationCache::Description::setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const {
    matrix->loadScale(scaleX, scaleY, 1.0f);
    paint->setAntiAlias(aa);
    paint->setStrokeCap(cap);
    paint->setStyle(style);
    paint->setStrokeWidth(strokeWidth);
}

TessellationCache::ShadowDescription::ShadowDescription()
        : nodeKey(nullptr) {
    memset(&matrixData, 0, 16 * sizeof(float));
}

TessellationCache::ShadowDescription::ShadowDescription(const void* nodeKey, const Matrix4* drawTransform)
        : nodeKey(nodeKey) {
    memcpy(&matrixData, drawTransform->data, 16 * sizeof(float));
}

hash_t TessellationCache::ShadowDescription::hash() const {
    uint32_t hash = JenkinsHashMixBytes(0, (uint8_t*) &nodeKey, sizeof(const void*));
    hash = JenkinsHashMixBytes(hash, (uint8_t*) &matrixData, 16 * sizeof(float));
    return JenkinsHashWhiten(hash);
}

///////////////////////////////////////////////////////////////////////////////
// General purpose tessellation task processing
///////////////////////////////////////////////////////////////////////////////

class TessellationCache::TessellationTask : public Task<VertexBuffer*> {
public:
    TessellationTask(Tessellator tessellator, const Description& description)
        : tessellator(tessellator)
        , description(description) {
    }

    ~TessellationTask() {}

    Tessellator tessellator;
    Description description;
};

class TessellationCache::TessellationProcessor : public TaskProcessor<VertexBuffer*> {
public:
    TessellationProcessor(Caches& caches)
            : TaskProcessor<VertexBuffer*>(&caches.tasks) {}
    ~TessellationProcessor() {}

    virtual void onProcess(const sp<Task<VertexBuffer*> >& task) override {
        TessellationTask* t = static_cast<TessellationTask*>(task.get());
        ATRACE_NAME("shape tessellation");
        VertexBuffer* buffer = t->tessellator(t->description);
        t->setResult(buffer);
    }
};

class TessellationCache::Buffer {
public:
    Buffer(const sp<Task<VertexBuffer*> >& task)
            : mTask(task)
            , mBuffer(nullptr) {
    }

    ~Buffer() {
        mTask.clear();
        delete mBuffer;
    }

    unsigned int getSize() {
        blockOnPrecache();
        return mBuffer->getSize();
    }

    const VertexBuffer* getVertexBuffer() {
        blockOnPrecache();
        return mBuffer;
    }

private:
    void blockOnPrecache() {
        if (mTask != nullptr) {
            mBuffer = mTask->getResult();
            LOG_ALWAYS_FATAL_IF(mBuffer == nullptr, "Failed to precache");
            mTask.clear();
        }
    }
    sp<Task<VertexBuffer*> > mTask;
    VertexBuffer* mBuffer;
};

///////////////////////////////////////////////////////////////////////////////
// Shadow tessellation task processing
///////////////////////////////////////////////////////////////////////////////

class ShadowTask : public Task<TessellationCache::vertexBuffer_pair_t*> {
public:
    ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
            const SkPath* casterPerimeter, const Matrix4* transformXY, const Matrix4* transformZ,
            const Vector3& lightCenter, float lightRadius)
        : drawTransform(*drawTransform)
        , localClip(localClip)
        , opaque(opaque)
        , casterPerimeter(*casterPerimeter)
        , transformXY(*transformXY)
        , transformZ(*transformZ)
        , lightCenter(lightCenter)
        , lightRadius(lightRadius) {
    }

    ~ShadowTask() {
        TessellationCache::vertexBuffer_pair_t* bufferPair = getResult();
        delete bufferPair->getFirst();
        delete bufferPair->getSecond();
        delete bufferPair;
    }

    /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
     * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
     * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
     *
     * These deep copies could be avoided, long term, by cancelling or flushing outstanding tasks
     * before tearning down single-frame LinearAllocators.
     */
    const Matrix4 drawTransform;
    const Rect localClip;
    bool opaque;
    const SkPath casterPerimeter;
    const Matrix4 transformXY;
    const Matrix4 transformZ;
    const Vector3 lightCenter;
    const float lightRadius;
};

static void mapPointFakeZ(Vector3& point, const mat4* transformXY, const mat4* transformZ) {
    // map z coordinate with true 3d matrix
    point.z = transformZ->mapZ(point);

    // map x,y coordinates with draw/Skia matrix
    transformXY->mapPoint(point.x, point.y);
}

static void reverseVertexArray(Vertex* polygon, int len) {
    int n = len / 2;
    for (int i = 0; i < n; i++) {
        Vertex tmp = polygon[i];
        int k = len - 1 - i;
        polygon[i] = polygon[k];
        polygon[k] = tmp;
    }
}

void tessellateShadows(
        const Matrix4* drawTransform, const Rect* localClip,
        bool isCasterOpaque, const SkPath* casterPerimeter,
        const Matrix4* casterTransformXY, const Matrix4* casterTransformZ,
        const Vector3& lightCenter, float lightRadius,
        VertexBuffer& ambientBuffer, VertexBuffer& spotBuffer) {

    // tessellate caster outline into a 2d polygon
    std::vector<Vertex> casterVertices2d;
    const float casterRefinementThreshold = 2.0f;
    PathTessellator::approximatePathOutlineVertices(*casterPerimeter,
            casterRefinementThreshold, casterVertices2d);

    // Shadow requires CCW for now. TODO: remove potential double-reverse
    reverseVertexArray(&casterVertices2d.front(), casterVertices2d.size());

    if (casterVertices2d.size() == 0) return;

    // map 2d caster poly into 3d
    const int casterVertexCount = casterVertices2d.size();
    Vector3 casterPolygon[casterVertexCount];
    float minZ = FLT_MAX;
    float maxZ = -FLT_MAX;
    for (int i = 0; i < casterVertexCount; i++) {
        const Vertex& point2d = casterVertices2d[i];
        casterPolygon[i] = (Vector3){point2d.x, point2d.y, 0};
        mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ);
        minZ = std::min(minZ, casterPolygon[i].z);
        maxZ = std::max(maxZ, casterPolygon[i].z);
    }

    // map the centroid of the caster into 3d
    Vector2 centroid =  ShadowTessellator::centroid2d(
            reinterpret_cast<const Vector2*>(&casterVertices2d.front()),
            casterVertexCount);
    Vector3 centroid3d = {centroid.x, centroid.y, 0};
    mapPointFakeZ(centroid3d, casterTransformXY, casterTransformZ);

    // if the caster intersects the z=0 plane, lift it in Z so it doesn't
    if (minZ < SHADOW_MIN_CASTER_Z) {
        float casterLift = SHADOW_MIN_CASTER_Z - minZ;
        for (int i = 0; i < casterVertexCount; i++) {
            casterPolygon[i].z += casterLift;
        }
        centroid3d.z += casterLift;
    }

    // Check whether we want to draw the shadow at all by checking the caster's bounds against clip.
    // We only have ortho projection, so we can just ignore the Z in caster for
    // simple rejection calculation.
    Rect casterBounds(casterPerimeter->getBounds());
    casterTransformXY->mapRect(casterBounds);

    // actual tessellation of both shadows
    ShadowTessellator::tessellateAmbientShadow(
            isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
            casterBounds, *localClip, maxZ, ambientBuffer);

    ShadowTessellator::tessellateSpotShadow(
            isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
            *drawTransform, lightCenter, lightRadius, casterBounds, *localClip,
            spotBuffer);
}

class ShadowProcessor : public TaskProcessor<TessellationCache::vertexBuffer_pair_t*> {
public:
    ShadowProcessor(Caches& caches)
            : TaskProcessor<TessellationCache::vertexBuffer_pair_t*>(&caches.tasks) {}
    ~ShadowProcessor() {}

    virtual void onProcess(const sp<Task<TessellationCache::vertexBuffer_pair_t*> >& task) override {
        ShadowTask* t = static_cast<ShadowTask*>(task.get());
        ATRACE_NAME("shadow tessellation");

        VertexBuffer* ambientBuffer = new VertexBuffer;
        VertexBuffer* spotBuffer = new VertexBuffer;
        tessellateShadows(&t->drawTransform, &t->localClip, t->opaque, &t->casterPerimeter,
                &t->transformXY, &t->transformZ, t->lightCenter, t->lightRadius,
                *ambientBuffer, *spotBuffer);

        t->setResult(new TessellationCache::vertexBuffer_pair_t(ambientBuffer, spotBuffer));
    }
};

///////////////////////////////////////////////////////////////////////////////
// Cache constructor/destructor
///////////////////////////////////////////////////////////////////////////////

TessellationCache::TessellationCache()
        : mSize(0)
        , mMaxSize(MB(DEFAULT_VERTEX_CACHE_SIZE))
        , mCache(LruCache<Description, Buffer*>::kUnlimitedCapacity)
        , mShadowCache(LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*>::kUnlimitedCapacity) {
    char property[PROPERTY_VALUE_MAX];
    if (property_get(PROPERTY_VERTEX_CACHE_SIZE, property, nullptr) > 0) {
        INIT_LOGD("  Setting tessellation cache size to %sMB", property);
        setMaxSize(MB(atof(property)));
    } else {
        INIT_LOGD("  Using default tessellation cache size of %.2fMB", DEFAULT_VERTEX_CACHE_SIZE);
    }

    mCache.setOnEntryRemovedListener(&mBufferRemovedListener);
    mShadowCache.setOnEntryRemovedListener(&mBufferPairRemovedListener);
    mDebugEnabled = Properties::debugLevel & kDebugCaches;
}

TessellationCache::~TessellationCache() {
    mCache.clear();
}

///////////////////////////////////////////////////////////////////////////////
// Size management
///////////////////////////////////////////////////////////////////////////////

uint32_t TessellationCache::getSize() {
    LruCache<Description, Buffer*>::Iterator iter(mCache);
    uint32_t size = 0;
    while (iter.next()) {
        size += iter.value()->getSize();
    }
    return size;
}

uint32_t TessellationCache::getMaxSize() {
    return mMaxSize;
}

void TessellationCache::setMaxSize(uint32_t maxSize) {
    mMaxSize = maxSize;
    while (mSize > mMaxSize) {
        mCache.removeOldest();
    }
}

///////////////////////////////////////////////////////////////////////////////
// Caching
///////////////////////////////////////////////////////////////////////////////


void TessellationCache::trim() {
    uint32_t size = getSize();
    while (size > mMaxSize) {
        size -= mCache.peekOldestValue()->getSize();
        mCache.removeOldest();
    }
    mShadowCache.clear();
}

void TessellationCache::clear() {
    mCache.clear();
    mShadowCache.clear();
}

///////////////////////////////////////////////////////////////////////////////
// Callbacks
///////////////////////////////////////////////////////////////////////////////

void TessellationCache::BufferRemovedListener::operator()(Description& description,
        Buffer*& buffer) {
    delete buffer;
}

///////////////////////////////////////////////////////////////////////////////
// Shadows
///////////////////////////////////////////////////////////////////////////////

void TessellationCache::precacheShadows(const Matrix4* drawTransform, const Rect& localClip,
        bool opaque, const SkPath* casterPerimeter,
        const Matrix4* transformXY, const Matrix4* transformZ,
        const Vector3& lightCenter, float lightRadius) {
    ShadowDescription key(casterPerimeter, drawTransform);

    if (mShadowCache.get(key)) return;
    sp<ShadowTask> task = new ShadowTask(drawTransform, localClip, opaque,
            casterPerimeter, transformXY, transformZ, lightCenter, lightRadius);
    if (mShadowProcessor == nullptr) {
        mShadowProcessor = new ShadowProcessor(Caches::getInstance());
    }
    mShadowProcessor->add(task);
    task->incStrong(nullptr); // not using sp<>s, so manually ref while in the cache
    mShadowCache.put(key, task.get());
}

void TessellationCache::getShadowBuffers(const Matrix4* drawTransform, const Rect& localClip,
        bool opaque, const SkPath* casterPerimeter,
        const Matrix4* transformXY, const Matrix4* transformZ,
        const Vector3& lightCenter, float lightRadius, vertexBuffer_pair_t& outBuffers) {
    ShadowDescription key(casterPerimeter, drawTransform);
    ShadowTask* task = static_cast<ShadowTask*>(mShadowCache.get(key));
    if (!task) {
        precacheShadows(drawTransform, localClip, opaque, casterPerimeter,
                transformXY, transformZ, lightCenter, lightRadius);
        task = static_cast<ShadowTask*>(mShadowCache.get(key));
    }
    LOG_ALWAYS_FATAL_IF(task == nullptr, "shadow not precached");
    outBuffers = *(task->getResult());
}

///////////////////////////////////////////////////////////////////////////////
// Tessellation precaching
///////////////////////////////////////////////////////////////////////////////

TessellationCache::Buffer* TessellationCache::getOrCreateBuffer(
        const Description& entry, Tessellator tessellator) {
    Buffer* buffer = mCache.get(entry);
    if (!buffer) {
        // not cached, enqueue a task to fill the buffer
        sp<TessellationTask> task = new TessellationTask(tessellator, entry);
        buffer = new Buffer(task);

        if (mProcessor == nullptr) {
            mProcessor = new TessellationProcessor(Caches::getInstance());
        }
        mProcessor->add(task);
        mCache.put(entry, buffer);
    }
    return buffer;
}

static VertexBuffer* tessellatePath(const TessellationCache::Description& description,
        const SkPath& path) {
    Matrix4 matrix;
    SkPaint paint;
    description.setupMatrixAndPaint(&matrix, &paint);
    VertexBuffer* buffer = new VertexBuffer();
    PathTessellator::tessellatePath(path, &paint, matrix, *buffer);
    return buffer;
}

///////////////////////////////////////////////////////////////////////////////
// RoundRect
///////////////////////////////////////////////////////////////////////////////

static VertexBuffer* tessellateRoundRect(const TessellationCache::Description& description) {
    SkRect rect = SkRect::MakeWH(description.shape.roundRect.width,
            description.shape.roundRect.height);
    float rx = description.shape.roundRect.rx;
    float ry = description.shape.roundRect.ry;
    if (description.style == SkPaint::kStrokeAndFill_Style) {
        float outset = description.strokeWidth / 2;
        rect.outset(outset, outset);
        rx += outset;
        ry += outset;
    }
    SkPath path;
    path.addRoundRect(rect, rx, ry);
    return tessellatePath(description, path);
}

TessellationCache::Buffer* TessellationCache::getRoundRectBuffer(
        const Matrix4& transform, const SkPaint& paint,
        float width, float height, float rx, float ry) {
    Description entry(Description::kRoundRect, transform, paint);
    entry.shape.roundRect.width = width;
    entry.shape.roundRect.height = height;
    entry.shape.roundRect.rx = rx;
    entry.shape.roundRect.ry = ry;
    return getOrCreateBuffer(entry, &tessellateRoundRect);
}
const VertexBuffer* TessellationCache::getRoundRect(const Matrix4& transform, const SkPaint& paint,
        float width, float height, float rx, float ry) {
    return getRoundRectBuffer(transform, paint, width, height, rx, ry)->getVertexBuffer();
}

}; // namespace uirenderer
}; // namespace android
