/*
 * Copyright (C) 2015 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.
 */

#ifndef ANDROID_HWUI_RECORDED_OP_H
#define ANDROID_HWUI_RECORDED_OP_H

#include "RecordedOp.h"
#include "font/FontUtil.h"
#include "Matrix.h"
#include "Rect.h"
#include "RenderNode.h"
#include "TessellationCache.h"
#include "utils/LinearAllocator.h"
#include "Vector.h"

#include <androidfw/ResourceTypes.h>
#include <SkXfermode.h>

class SkBitmap;
class SkPaint;

namespace android {
namespace uirenderer {

struct ClipBase;
class OffscreenBuffer;
class RenderNode;
struct Vertex;

namespace VectorDrawable {
class Tree;
}

/**
 * Authoritative op list, used for generating the op ID enum, ID based LUTS, and
 * the functions to which they dispatch. Parameter macros are executed for each op,
 * in order, based on the op's type.
 *
 * There are 4 types of op, which defines dispatch/LUT capability:
 *
 *              | DisplayList |   Render    |    Merge    |
 * -------------|-------------|-------------|-------------|
 * PRE RENDER   |     Yes     |             |             |
 * RENDER ONLY  |             |     Yes     |             |
 * UNMERGEABLE  |     Yes     |     Yes     |             |
 * MERGEABLE    |     Yes     |     Yes     |     Yes     |
 *
 * PRE RENDER - These ops are recorded into DisplayLists, but can't be directly rendered. This
 *      may be because they need to be transformed into other op types (e.g. CirclePropsOp),
 *      be traversed to access multiple renderable ops within (e.g. RenderNodeOp), or because they
 *      modify renderbuffer lifecycle, instead of directly rendering content (the various LayerOps).
 *
 * RENDER ONLY - These ops cannot be recorded into DisplayLists, and are instead implicitly
 *      constructed from other commands/RenderNode properties. They cannot be merged.
 *
 * UNMERGEABLE - These ops can be recorded into DisplayLists and rendered directly, but do not
 *      support merged rendering.
 *
 * MERGEABLE - These ops can be recorded into DisplayLists and rendered individually, or merged
 *      under certain circumstances.
 */
#define MAP_OPS_BASED_ON_TYPE(PRE_RENDER_OP_FN, RENDER_ONLY_OP_FN, UNMERGEABLE_OP_FN, MERGEABLE_OP_FN) \
        PRE_RENDER_OP_FN(RenderNodeOp) \
        PRE_RENDER_OP_FN(CirclePropsOp) \
        PRE_RENDER_OP_FN(RoundRectPropsOp) \
        PRE_RENDER_OP_FN(BeginLayerOp) \
        PRE_RENDER_OP_FN(EndLayerOp) \
        PRE_RENDER_OP_FN(BeginUnclippedLayerOp) \
        PRE_RENDER_OP_FN(EndUnclippedLayerOp) \
        PRE_RENDER_OP_FN(VectorDrawableOp) \
        \
        RENDER_ONLY_OP_FN(ShadowOp) \
        RENDER_ONLY_OP_FN(LayerOp) \
        RENDER_ONLY_OP_FN(CopyToLayerOp) \
        RENDER_ONLY_OP_FN(CopyFromLayerOp) \
        \
        UNMERGEABLE_OP_FN(ArcOp) \
        UNMERGEABLE_OP_FN(BitmapMeshOp) \
        UNMERGEABLE_OP_FN(BitmapRectOp) \
        UNMERGEABLE_OP_FN(FunctorOp) \
        UNMERGEABLE_OP_FN(LinesOp) \
        UNMERGEABLE_OP_FN(OvalOp) \
        UNMERGEABLE_OP_FN(PathOp) \
        UNMERGEABLE_OP_FN(PointsOp) \
        UNMERGEABLE_OP_FN(RectOp) \
        UNMERGEABLE_OP_FN(RoundRectOp) \
        UNMERGEABLE_OP_FN(SimpleRectsOp) \
        UNMERGEABLE_OP_FN(TextOnPathOp) \
        UNMERGEABLE_OP_FN(TextureLayerOp) \
        \
        MERGEABLE_OP_FN(BitmapOp) \
        MERGEABLE_OP_FN(PatchOp) \
        MERGEABLE_OP_FN(TextOp)

/**
 * LUT generators, which will insert nullptr for unsupported ops
 */
#define NULLPTR_OP_FN(Type) nullptr,

#define BUILD_DEFERRABLE_OP_LUT(OP_FN) \
        { MAP_OPS_BASED_ON_TYPE(OP_FN, NULLPTR_OP_FN, OP_FN, OP_FN) }

#define BUILD_MERGEABLE_OP_LUT(OP_FN) \
        { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, NULLPTR_OP_FN, NULLPTR_OP_FN, OP_FN) }

#define BUILD_RENDERABLE_OP_LUT(OP_FN) \
        { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, OP_FN, OP_FN, OP_FN) }

#define BUILD_FULL_OP_LUT(OP_FN) \
        { MAP_OPS_BASED_ON_TYPE(OP_FN, OP_FN, OP_FN, OP_FN) }

/**
 * Op mapping functions, which skip unsupported ops.
 *
 * Note: Do not use for LUTS, since these do not preserve ID order.
 */
#define NULL_OP_FN(Type)

#define MAP_DEFERRABLE_OPS(OP_FN) \
        MAP_OPS_BASED_ON_TYPE(OP_FN, NULL_OP_FN, OP_FN, OP_FN)

#define MAP_MERGEABLE_OPS(OP_FN) \
        MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, NULL_OP_FN, NULL_OP_FN, OP_FN)

#define MAP_RENDERABLE_OPS(OP_FN) \
        MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, OP_FN, OP_FN, OP_FN)

// Generate OpId enum
#define IDENTITY_FN(Type) Type,
namespace RecordedOpId {
    enum {
        MAP_OPS_BASED_ON_TYPE(IDENTITY_FN, IDENTITY_FN, IDENTITY_FN, IDENTITY_FN)
        Count,
    };
}
static_assert(RecordedOpId::RenderNodeOp == 0,
        "First index must be zero for LUTs to work");

#define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint
#define BASE_PARAMS_PAINTLESS const Rect& unmappedBounds, const Matrix4& localMatrix, const ClipBase* localClip
#define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, paint)
#define SUPER_PAINTLESS(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, nullptr)

struct RecordedOp {
    /* ID from RecordedOpId - generally used for jumping into function tables */
    const int opId;

    /* bounds in *local* space, without accounting for DisplayList transformation, or stroke */
    const Rect unmappedBounds;

    /* transform in recording space (vs DisplayList origin) */
    const Matrix4 localMatrix;

    /* clip in recording space - nullptr if not clipped */
    const ClipBase* localClip;

    /* optional paint, stored in base object to simplify merging logic */
    const SkPaint* paint;
protected:
    RecordedOp(unsigned int opId, BASE_PARAMS)
            : opId(opId)
            , unmappedBounds(unmappedBounds)
            , localMatrix(localMatrix)
            , localClip(localClip)
            , paint(paint) {}
};

struct RenderNodeOp : RecordedOp {
    RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode)
            : SUPER_PAINTLESS(RenderNodeOp)
            , renderNode(renderNode) {}
    RenderNode * renderNode; // not const, since drawing modifies it

    /**
     * Holds the transformation between the projection surface ViewGroup and this RenderNode
     * drawing instance. Represents any translations / transformations done within the drawing of
     * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this
     * DisplayList draw instance.
     *
     * Note: doesn't include transformation within the RenderNode, or its properties.
     */
    Matrix4 transformFromCompositingAncestor;
    bool skipInOrderDraw = false;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Standard Ops
////////////////////////////////////////////////////////////////////////////////////////////////////

struct ArcOp : RecordedOp {
    ArcOp(BASE_PARAMS, float startAngle, float sweepAngle, bool useCenter)
            : SUPER(ArcOp)
            , startAngle(startAngle)
            , sweepAngle(sweepAngle)
            , useCenter(useCenter) {}
    const float startAngle;
    const float sweepAngle;
    const bool useCenter;
};

struct BitmapOp : RecordedOp {
    BitmapOp(BASE_PARAMS, const SkBitmap* bitmap)
            : SUPER(BitmapOp)
            , bitmap(bitmap) {}
    const SkBitmap* bitmap;
    // TODO: asset atlas/texture id lookup?
};

struct BitmapMeshOp : RecordedOp {
    BitmapMeshOp(BASE_PARAMS, const SkBitmap* bitmap, int meshWidth, int meshHeight,
            const float* vertices, const int* colors)
            : SUPER(BitmapMeshOp)
            , bitmap(bitmap)
            , meshWidth(meshWidth)
            , meshHeight(meshHeight)
            , vertices(vertices)
            , colors(colors) {}
    const SkBitmap* bitmap;
    const int meshWidth;
    const int meshHeight;
    const float* vertices;
    const int* colors;
};

struct BitmapRectOp : RecordedOp {
    BitmapRectOp(BASE_PARAMS, const SkBitmap* bitmap, const Rect& src)
            : SUPER(BitmapRectOp)
            , bitmap(bitmap)
            , src(src) {}
    const SkBitmap* bitmap;
    const Rect src;
};

struct CirclePropsOp : RecordedOp {
    CirclePropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
            float* x, float* y, float* radius)
            : RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClip, paint)
            , x(x)
            , y(y)
            , radius(radius) {}
    const float* x;
    const float* y;
    const float* radius;
};

struct FunctorOp : RecordedOp {
    // Note: undefined record-time bounds, since this op fills the clip
    // TODO: explicitly define bounds
    FunctorOp(const Matrix4& localMatrix, const ClipBase* localClip, Functor* functor)
            : RecordedOp(RecordedOpId::FunctorOp, Rect(), localMatrix, localClip, nullptr)
            , functor(functor) {}
    Functor* functor;
};

struct LinesOp : RecordedOp {
    LinesOp(BASE_PARAMS, const float* points, const int floatCount)
            : SUPER(LinesOp)
            , points(points)
            , floatCount(floatCount) {}
    const float* points;
    const int floatCount;
};

struct OvalOp : RecordedOp {
    OvalOp(BASE_PARAMS)
            : SUPER(OvalOp) {}
};

struct PatchOp : RecordedOp {
    PatchOp(BASE_PARAMS, const SkBitmap* bitmap, const Res_png_9patch* patch)
            : SUPER(PatchOp)
            , bitmap(bitmap)
            , patch(patch) {}
    const SkBitmap* bitmap;
    const Res_png_9patch* patch;
};

struct PathOp : RecordedOp {
    PathOp(BASE_PARAMS, const SkPath* path)
            : SUPER(PathOp)
            , path(path) {}
    const SkPath* path;
};

struct PointsOp : RecordedOp {
    PointsOp(BASE_PARAMS, const float* points, const int floatCount)
            : SUPER(PointsOp)
            , points(points)
            , floatCount(floatCount) {}
    const float* points;
    const int floatCount;
};

struct RectOp : RecordedOp {
    RectOp(BASE_PARAMS)
            : SUPER(RectOp) {}
};

struct RoundRectOp : RecordedOp {
    RoundRectOp(BASE_PARAMS, float rx, float ry)
            : SUPER(RoundRectOp)
            , rx(rx)
            , ry(ry) {}
    const float rx;
    const float ry;
};

struct RoundRectPropsOp : RecordedOp {
    RoundRectPropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
            float* left, float* top, float* right, float* bottom, float *rx, float *ry)
            : RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClip, paint)
            , left(left)
            , top(top)
            , right(right)
            , bottom(bottom)
            , rx(rx)
            , ry(ry) {}
    const float* left;
    const float* top;
    const float* right;
    const float* bottom;
    const float* rx;
    const float* ry;
};

struct VectorDrawableOp : RecordedOp {
    VectorDrawableOp(VectorDrawable::Tree* tree, BASE_PARAMS_PAINTLESS)
            : SUPER_PAINTLESS(VectorDrawableOp)
            , vectorDrawable(tree) {}
    VectorDrawable::Tree* vectorDrawable;
};

/**
 * Real-time, dynamic-lit shadow.
 *
 * Uses invalid/empty bounds and matrix since ShadowOp bounds aren't known at defer time,
 * and are resolved dynamically, and transform isn't needed.
 *
 * State construction handles these properties specially, ignoring matrix/bounds.
 */
struct ShadowOp : RecordedOp {
    ShadowOp(sp<TessellationCache::ShadowTask>& shadowTask, float casterAlpha)
            : RecordedOp(RecordedOpId::ShadowOp, Rect(), Matrix4::identity(), nullptr, nullptr)
            , shadowTask(shadowTask)
            , casterAlpha(casterAlpha) {
    };
    sp<TessellationCache::ShadowTask> shadowTask;
    const float casterAlpha;
};

struct SimpleRectsOp : RecordedOp { // Filled, no AA (TODO: better name?)
    SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount)
            : SUPER(SimpleRectsOp)
            , vertices(vertices)
            , vertexCount(vertexCount) {}
    Vertex* vertices;
    const size_t vertexCount;
};

struct TextOp : RecordedOp {
    TextOp(BASE_PARAMS, const glyph_t* glyphs, const float* positions, int glyphCount,
            float x, float y)
            : SUPER(TextOp)
            , glyphs(glyphs)
            , positions(positions)
            , glyphCount(glyphCount)
            , x(x)
            , y(y) {}
    const glyph_t* glyphs;
    const float* positions;
    const int glyphCount;
    const float x;
    const float y;
};

struct TextOnPathOp : RecordedOp {
    // TODO: explicitly define bounds
    TextOnPathOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
            const glyph_t* glyphs, int glyphCount, const SkPath* path, float hOffset, float vOffset)
            : RecordedOp(RecordedOpId::TextOnPathOp, Rect(), localMatrix, localClip, paint)
            , glyphs(glyphs)
            , glyphCount(glyphCount)
            , path(path)
            , hOffset(hOffset)
            , vOffset(vOffset) {}
    const glyph_t* glyphs;
    const int glyphCount;

    const SkPath* path;
    const float hOffset;
    const float vOffset;
};

struct TextureLayerOp : RecordedOp {
    TextureLayerOp(BASE_PARAMS_PAINTLESS, Layer* layer)
            : SUPER_PAINTLESS(TextureLayerOp)
            , layer(layer) {}
    Layer* layer;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Layers
////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * Stateful operation! denotes the creation of an off-screen layer,
 * and that commands following will render into it.
 */
struct BeginLayerOp : RecordedOp {
    BeginLayerOp(BASE_PARAMS)
            : SUPER(BeginLayerOp) {}
};

/**
 * Stateful operation! Denotes end of off-screen layer, and that
 * commands since last BeginLayerOp should be drawn into parent FBO.
 *
 * State in this op is empty, it just serves to signal that a layer has been finished.
 */
struct EndLayerOp : RecordedOp {
    EndLayerOp()
            : RecordedOp(RecordedOpId::EndLayerOp, Rect(), Matrix4::identity(), nullptr, nullptr) {}
};

struct BeginUnclippedLayerOp : RecordedOp {
    BeginUnclippedLayerOp(BASE_PARAMS)
            : SUPER(BeginUnclippedLayerOp) {}
};

struct EndUnclippedLayerOp : RecordedOp {
    EndUnclippedLayerOp()
            : RecordedOp(RecordedOpId::EndUnclippedLayerOp, Rect(), Matrix4::identity(), nullptr, nullptr) {}
};

struct CopyToLayerOp : RecordedOp {
    CopyToLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle)
            : RecordedOp(RecordedOpId::CopyToLayerOp,
                    op.unmappedBounds,
                    op.localMatrix,
                    nullptr, // clip intentionally ignored
                    op.paint)
            , layerHandle(layerHandle) {}

    // Records a handle to the Layer object, since the Layer itself won't be
    // constructed until after this operation is constructed.
    OffscreenBuffer** layerHandle;
};


// draw the parameter layer underneath
struct CopyFromLayerOp : RecordedOp {
    CopyFromLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle)
            : RecordedOp(RecordedOpId::CopyFromLayerOp,
                    op.unmappedBounds,
                    op.localMatrix,
                    nullptr, // clip intentionally ignored
                    op.paint)
            , layerHandle(layerHandle) {}

    // Records a handle to the Layer object, since the Layer itself won't be
    // constructed until after this operation is constructed.
    OffscreenBuffer** layerHandle;
};

/**
 * Draws an OffscreenBuffer.
 *
 * Alpha, mode, and colorfilter are embedded, since LayerOps are always dynamically generated,
 * when creating/tracking a SkPaint* during defer isn't worth the bother.
 */
struct LayerOp : RecordedOp {
    // Records a one-use (saveLayer) layer for drawing. Once drawn, the layer will be destroyed.
    LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle)
            : SUPER_PAINTLESS(LayerOp)
            , layerHandle(layerHandle)
            , alpha(paint ? paint->getAlpha() / 255.0f : 1.0f)
            , mode(PaintUtils::getXfermodeDirect(paint))
            , colorFilter(paint ? paint->getColorFilter() : nullptr)
            , destroy(true) {}

    LayerOp(RenderNode& node)
            : RecordedOp(RecordedOpId::LayerOp, Rect(node.getWidth(), node.getHeight()), Matrix4::identity(), nullptr, nullptr)
            , layerHandle(node.getLayerHandle())
            , alpha(node.properties().layerProperties().alpha() / 255.0f)
            , mode(node.properties().layerProperties().xferMode())
            , colorFilter(node.properties().layerProperties().colorFilter())
            , destroy(false) {}

    // Records a handle to the Layer object, since the Layer itself won't be
    // constructed until after this operation is constructed.
    OffscreenBuffer** layerHandle;
    const float alpha;
    const SkXfermode::Mode mode;

    // pointer to object owned by either LayerProperties, or a recorded Paint object in a
    // BeginLayerOp. Lives longer than LayerOp in either case, so no skia ref counting is used.
    SkColorFilter* colorFilter;

    // whether to destroy the layer, once rendered
    const bool destroy;
};

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

#endif // ANDROID_HWUI_RECORDED_OP_H
