/*
 * 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.
 */

#define LOG_TAG "OpenGLRenderer"
#define ATRACE_TAG ATRACE_TAG_VIEW

#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(NULL) {
    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) {
        TessellationTask* t = static_cast<TessellationTask*>(task.get());
        ATRACE_NAME("shape tessellation");
        VertexBuffer* buffer = t->tessellator(t->description);
        t->setResult(buffer);
    }
};

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

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

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

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

private:
    void blockOnPrecache() {
        if (mTask != NULL) {
            mBuffer = mTask->getResult();
            LOG_ALWAYS_FATAL_IF(mBuffer == NULL, "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 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
    Vector<Vertex> casterVertices2d;
    const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value
    PathTessellator::approximatePathOutlineVertices(*casterPerimeter,
            casterRefinementThresholdSquared, casterVertices2d);
    if (!ShadowTessellator::isClockwisePath(*casterPerimeter)) {
        ShadowTessellator::reverseVertexArray(casterVertices2d.editArray(),
                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 = fmin(minZ, casterPolygon[i].z);
        maxZ = fmax(maxZ, casterPolygon[i].z);
    }

    // map the centroid of the caster into 3d
    Vector2 centroid =  ShadowTessellator::centroid2d(
            reinterpret_cast<const Vector2*>(casterVertices2d.array()),
            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,
            *drawTransform, lightCenter, lightRadius, casterBounds, *localClip,
            spotBuffer);

    // TODO: set ambientBuffer & spotBuffer's bounds for correct layer damage
}

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) {
        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, NULL) > 0) {
        INIT_LOGD("  Setting %s cache size to %sMB", name, property);
        setMaxSize(MB(atof(property)));
    } else {
        INIT_LOGD("  Using default %s cache size of %.2fMB", name, DEFAULT_VERTEX_CACHE_SIZE);
    }

    mCache.setOnEntryRemovedListener(&mBufferRemovedListener);
    mShadowCache.setOnEntryRemovedListener(&mBufferPairRemovedListener);
    mDebugEnabled = readDebugLevel() & 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);

    sp<ShadowTask> task = new ShadowTask(drawTransform, localClip, opaque,
            casterPerimeter, transformXY, transformZ, lightCenter, lightRadius);
    if (mShadowProcessor == NULL) {
        mShadowProcessor = new ShadowProcessor(Caches::getInstance());
    }
    mShadowProcessor->add(task);

    task->incStrong(NULL); // 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 == NULL, "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 == NULL) {
            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
