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

#include "DebugCanvas.h"
#include "SkCanvas.h"
#include "SkPicture.h"
#include "SkPictureFlat.h"
#include "SkPictureRecord.h"
#include "Test.h"

// This test exercises the Matrix/Clip State collapsing system. It generates
// example skps and the compares the actual stored operations to the expected
// operations. The test works by emitting canvas operations at three levels:
// overall structure, bodies that draw something and model/clip state changes.
//
// Structure methods only directly emit save and restores but call the
// ModelClip and Body helper methods to fill in the structure. Since they only
// emit saves and restores the operations emitted by the structure methods will
// be completely removed by the matrix/clip collapse. Note: every save in
// a structure method is followed by a call to a ModelClip helper.
//
// Body methods only directly emit draw ops and saveLayer/restore pairs but call
// the ModelClip helper methods. Since the body methods emit the ops that cannot
// be collapsed (i.e., draw ops, saveLayer/restore) they also generate the
// expected result information. Note: every saveLayer in a body method is
// followed by a call to a ModelClip helper.
//
// The ModelClip methods output matrix and clip ops in various orders and
// combinations. They contribute to the expected result by outputting the
// expected matrix & clip ops. Note that, currently, the entire clip stack
// is output for each MC state so the clip operations accumulate down the
// save/restore stack.

// TODOs:
//   check on clip offsets
//      - not sure if this is possible. The desire is to verify that the clip
//        operations' offsets point to the correct follow-on operations. This
//        could be difficult since there is no good way to communicate the
//        offset stored in the SkPicture to the debugger's clip objects
//   add comparison of rendered before & after images?
//      - not sure if this would be useful since it somewhat duplicates the
//        correctness test of running render_pictures in record mode and
//        rendering before and after images. Additionally the matrix/clip collapse
//        is sure to cause some small differences so an automated test might
//        yield too many false positives.
//   run the matrix/clip collapse system on the 10K skp set
//      - this should give us warm fuzzies that the matrix clip collapse
//        system is ready for prime time
//   bench the recording times with/without matrix/clip collapsing

#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE

// Enable/disable debugging helper code
//#define TEST_COLLAPSE_MATRIX_CLIP_STATE 1

// Extract the command ops from the input SkPicture
static void gets_ops(SkPicture& input, SkTDArray<DrawType>* ops) {
    DebugCanvas debugCanvas(input.width(), input.height());
    debugCanvas.setBounds(input.width(), input.height());
    input.draw(&debugCanvas);

    ops->setCount(debugCanvas.getSize());
    for (int i = 0; i < debugCanvas.getSize(); ++i) {
        (*ops)[i] = debugCanvas.getDrawCommandAt(i)->getType();
    }
}

enum ClipType {
    kNone_ClipType,
    kRect_ClipType,
    kRRect_ClipType,
    kPath_ClipType,
    kRegion_ClipType,

    kLast_ClipType = kRRect_ClipType
};

static const int kClipTypeCount = kLast_ClipType + 1;

enum MatType {
    kNone_MatType,
    kTranslate_MatType,
    kScale_MatType,
    kSkew_MatType,
    kRotate_MatType,
    kConcat_MatType,
    kSetMatrix_MatType,

    kLast_MatType = kScale_MatType
};

static const int kMatTypeCount = kLast_MatType + 1;

// TODO: implement the rest of the draw ops
enum DrawOpType {
    kNone_DrawOpType,
#if 0
    kBitmap_DrawOpType,
    kBitmapMatrix_DrawOpType,
    kBitmapNone_DrawOpType,
    kBitmapRectToRect_DrawOpType,
#endif
    kClear_DrawOpType,
#if 0
    kData_DrawOpType,
#endif
    kOval_DrawOpType,
#if 0
    kPaint_DrawOpType,
    kPath_DrawOpType,
    kPicture_DrawOpType,
    kPoints_DrawOpType,
    kPosText_DrawOpType,
    kPosTextTopBottom_DrawOpType,
    kPosTextH_DrawOpType,
    kPosTextHTopBottom_DrawOpType,
#endif
    kRect_DrawOpType,
    kRRect_DrawOpType,
#if 0
    kSprite_DrawOpType,
    kText_DrawOpType,
    kTextOnPath_DrawOpType,
    kTextTopBottom_DrawOpType,
    kDrawVertices_DrawOpType,
#endif

    kLastNonSaveLayer_DrawOpType = kRect_DrawOpType,

    // saveLayer's have to handled apart from the other draw operations
    // since they also alter the save/restore structure.
    kSaveLayer_DrawOpType,
};

static const int kNonSaveLayerDrawOpTypeCount = kLastNonSaveLayer_DrawOpType + 1;

typedef void (*PFEmitMC)(SkCanvas* canvas, MatType mat, ClipType clip,
                         DrawOpType draw, SkTDArray<DrawType>* expected,
                         int accumulatedClips);
typedef void (*PFEmitBody)(SkCanvas* canvas, PFEmitMC emitMC, MatType mat,
                           ClipType clip, DrawOpType draw,
                           SkTDArray<DrawType>* expected, int accumulatedClips);
typedef void (*PFEmitStruct)(SkCanvas* canvas, PFEmitMC emitMC, MatType mat,
                             ClipType clip, PFEmitBody emitBody, DrawOpType draw,
                             SkTDArray<DrawType>* expected);

//////////////////////////////////////////////////////////////////////////////

// TODO: expand the testing to include the different ops & AA types!
static void emit_clip(SkCanvas* canvas, ClipType clip) {
    switch (clip) {
        case kNone_ClipType:
            break;
        case kRect_ClipType: {
            SkRect r = SkRect::MakeLTRB(10, 10, 90, 90);
            canvas->clipRect(r, SkRegion::kIntersect_Op, true);
            break;
        }
        case kRRect_ClipType: {
            SkRect r = SkRect::MakeLTRB(10, 10, 90, 90);
            SkRRect rr;
            rr.setRectXY(r, 10, 10);
            canvas->clipRRect(rr, SkRegion::kIntersect_Op, true);
            break;
        }
        case kPath_ClipType: {
            SkPath p;
            p.moveTo(5.0f, 5.0f);
            p.lineTo(50.0f, 50.0f);
            p.lineTo(100.0f, 5.0f);
            p.close();
            canvas->clipPath(p, SkRegion::kIntersect_Op, true);
            break;
        }
        case kRegion_ClipType: {
            SkIRect rects[2] = {
                { 1, 1, 55, 55 },
                { 45, 45, 99, 99 },
            };
            SkRegion r;
            r.setRects(rects, 2);
            canvas->clipRegion(r, SkRegion::kIntersect_Op);
            break;
        }
        default:
            SkASSERT(0);
    }
}

static void add_clip(ClipType clip, MatType mat, SkTDArray<DrawType>* expected) {
    if (nullptr == expected) {
        // expected is nullptr if this clip will be fused into later clips
        return;
    }

    switch (clip) {
        case kNone_ClipType:
            break;
        case kRect_ClipType:
            *expected->append() = CONCAT;
            *expected->append() = CLIP_RECT;
            break;
        case kRRect_ClipType:
            *expected->append() = CONCAT;
            *expected->append() = CLIP_RRECT;
            break;
        case kPath_ClipType:
            *expected->append() = CONCAT;
            *expected->append() = CLIP_PATH;
            break;
        case kRegion_ClipType:
            *expected->append() = CONCAT;
            *expected->append() = CLIP_REGION;
            break;
        default:
            SkASSERT(0);
    }
}

static void emit_mat(SkCanvas* canvas, MatType mat) {
    switch (mat) {
    case kNone_MatType:
        break;
    case kTranslate_MatType:
        canvas->translate(5.0f, 5.0f);
        break;
    case kScale_MatType:
        canvas->scale(1.1f, 1.1f);
        break;
    case kSkew_MatType:
        canvas->skew(1.1f, 1.1f);
        break;
    case kRotate_MatType:
        canvas->rotate(1.0f);
        break;
    case kConcat_MatType: {
        SkMatrix m;
        m.setTranslate(1.0f, 1.0f);
        canvas->concat(m);
        break;
    }
    case kSetMatrix_MatType: {
        SkMatrix m;
        m.setTranslate(1.0f, 1.0f);
        canvas->setMatrix(m);
        break;
    }
    default:
        SkASSERT(0);
    }
}

static void add_mat(MatType mat, SkTDArray<DrawType>* expected) {
    if (nullptr == expected) {
        // expected is nullptr if this matrix call will be fused into later ones
        return;
    }

    switch (mat) {
    case kNone_MatType:
        break;
    case kTranslate_MatType:    // fall thru
    case kScale_MatType:        // fall thru
    case kSkew_MatType:         // fall thru
    case kRotate_MatType:       // fall thru
    case kConcat_MatType:       // fall thru
    case kSetMatrix_MatType:
        // TODO: this system currently converts a setMatrix to concat. If we wanted to
        // really preserve the setMatrix semantics we should keep it a setMatrix. I'm
        // not sure if this is a good idea though since this would keep things like pinch
        // zoom from working.
        *expected->append() = CONCAT;
        break;
    default:
        SkASSERT(0);
    }
}

static void emit_draw(SkCanvas* canvas, DrawOpType draw, SkTDArray<DrawType>* expected) {
    switch (draw) {
        case kNone_DrawOpType:
            break;
        case kClear_DrawOpType:
            canvas->clear(SK_ColorRED);
            *expected->append() = DRAW_CLEAR;
            break;
        case kOval_DrawOpType: {
            SkRect r = SkRect::MakeLTRB(10, 10, 90, 90);
            SkPaint p;
            canvas->drawOval(r, p);
            *expected->append() = DRAW_OVAL;
            break;
        }
        case kRect_DrawOpType: {
            SkRect r = SkRect::MakeLTRB(10, 10, 90, 90);
            SkPaint p;
            canvas->drawRect(r, p);
            *expected->append() = DRAW_RECT;
            break;
        }
        case kRRect_DrawOpType: {
            SkRect r = SkRect::MakeLTRB(10.0f, 10.0f, 90.0f, 90.0f);
            SkRRect rr;
            rr.setRectXY(r, 5.0f, 5.0f);
            SkPaint p;
            canvas->drawRRect(rr, p);
            *expected->append() = DRAW_RRECT;
            break;
        }
        default:
            SkASSERT(0);
    }
}

//////////////////////////////////////////////////////////////////////////////

// Emit:
//  clip
//  matrix
// Simple case - the clip isn't effect by the matrix
static void emit_clip_and_mat(SkCanvas* canvas, MatType mat, ClipType clip,
                              DrawOpType draw, SkTDArray<DrawType>* expected,
                              int accumulatedClips) {
    emit_clip(canvas, clip);
    emit_mat(canvas, mat);

    if (kNone_DrawOpType == draw) {
        return;
    }

    for (int i = 0; i < accumulatedClips; ++i) {
        add_clip(clip, mat, expected);
    }
    add_mat(mat, expected);
}

// Emit:
//  matrix
//  clip
// Emitting the matrix first is more challenging since the matrix has to be
// pushed across (i.e., applied to) the clip.
static void emit_mat_and_clip(SkCanvas* canvas, MatType mat, ClipType clip,
                              DrawOpType draw, SkTDArray<DrawType>* expected,
                              int accumulatedClips) {
    emit_mat(canvas, mat);
    emit_clip(canvas, clip);

    if (kNone_DrawOpType == draw) {
        return;
    }

    // the matrix & clip order will be reversed once collapsed!
    for (int i = 0; i < accumulatedClips; ++i) {
        add_clip(clip, mat, expected);
    }
    add_mat(mat, expected);
}

// Emit:
//  matrix
//  clip
//  matrix
//  clip
// This tests that the matrices and clips coalesce when collapsed
static void emit_double_mat_and_clip(SkCanvas* canvas, MatType mat, ClipType clip,
                                     DrawOpType draw, SkTDArray<DrawType>* expected,
                                     int accumulatedClips) {
    emit_mat(canvas, mat);
    emit_clip(canvas, clip);
    emit_mat(canvas, mat);
    emit_clip(canvas, clip);

    if (kNone_DrawOpType == draw) {
        return;
    }

    for (int i = 0; i < accumulatedClips; ++i) {
        add_clip(clip, mat, expected);
        add_clip(clip, mat, expected);
    }
    add_mat(mat, expected);
}

// Emit:
//  matrix
//  clip
//  clip
// This tests accumulation of clips in same transform state. It also tests pushing
// of the matrix across both the clips.
static void emit_mat_clip_clip(SkCanvas* canvas, MatType mat, ClipType clip,
                               DrawOpType draw, SkTDArray<DrawType>* expected,
                               int accumulatedClips) {
    emit_mat(canvas, mat);
    emit_clip(canvas, clip);
    emit_clip(canvas, clip);

    if (kNone_DrawOpType == draw) {
        return;
    }

    for (int i = 0; i < accumulatedClips; ++i) {
        add_clip(clip, mat, expected);
        add_clip(clip, mat, expected);
    }
    add_mat(mat, expected);
}

//////////////////////////////////////////////////////////////////////////////

// Emit:
//  matrix & clip calls
//  draw op
static void emit_body0(SkCanvas* canvas, PFEmitMC emitMC, MatType mat,
                       ClipType clip, DrawOpType draw,
                       SkTDArray<DrawType>* expected, int accumulatedClips) {
    bool needsSaveRestore = kNone_DrawOpType != draw &&
                            (kNone_MatType != mat || kNone_ClipType != clip);

    if (needsSaveRestore) {
        *expected->append() = SAVE;
    }
    (*emitMC)(canvas, mat, clip, draw, expected, accumulatedClips+1);
    emit_draw(canvas, draw, expected);
    if (needsSaveRestore) {
        *expected->append() = RESTORE;
    }
}

// Emit:
//  matrix & clip calls
//  draw op
//  matrix & clip calls
//  draw op
static void emit_body1(SkCanvas* canvas, PFEmitMC emitMC, MatType mat,
                       ClipType clip, DrawOpType draw,
                       SkTDArray<DrawType>* expected, int accumulatedClips) {
    bool needsSaveRestore = kNone_DrawOpType != draw &&
                            (kNone_MatType != mat || kNone_ClipType != clip);

    if (needsSaveRestore) {
        *expected->append() = SAVE;
    }
    (*emitMC)(canvas, mat, clip, draw, expected, accumulatedClips+1);
    emit_draw(canvas, draw, expected);
    if (needsSaveRestore) {
        *expected->append() = RESTORE;
        *expected->append() = SAVE;
    }
    (*emitMC)(canvas, mat, clip, draw, expected, accumulatedClips+2);
    emit_draw(canvas, draw, expected);
    if (needsSaveRestore) {
        *expected->append() = RESTORE;
    }
}

// Emit:
//  matrix & clip calls
//  SaveLayer
//      matrix & clip calls
//      draw op
//  Restore
static void emit_body2(SkCanvas* canvas, PFEmitMC emitMC, MatType mat,
                       ClipType clip, DrawOpType draw,
                       SkTDArray<DrawType>* expected, int accumulatedClips) {
    bool needsSaveRestore = kNone_DrawOpType != draw &&
                            (kNone_MatType != mat || kNone_ClipType != clip);

    if (kNone_MatType != mat || kNone_ClipType != clip) {
        *expected->append() = SAVE;
    }
    (*emitMC)(canvas, mat, clip, kSaveLayer_DrawOpType, expected, accumulatedClips+1);
    *expected->append() = SAVE_LAYER;
    // TODO: widen testing to exercise saveLayer's parameters
    canvas->saveLayer(nullptr, nullptr);
        if (needsSaveRestore) {
            *expected->append() = SAVE;
        }
        (*emitMC)(canvas, mat, clip, draw, expected, 1);
        emit_draw(canvas, draw, expected);
        if (needsSaveRestore) {
            *expected->append() = RESTORE;
        }
    canvas->restore();
    *expected->append() = RESTORE;
    if (kNone_MatType != mat || kNone_ClipType != clip) {
        *expected->append() = RESTORE;
    }
}

// Emit:
//  matrix & clip calls
//  SaveLayer
//      matrix & clip calls
//      SaveLayer
//          matrix & clip calls
//          draw op
//      Restore
//      matrix & clip calls (will be ignored)
//  Restore
static void emit_body3(SkCanvas* canvas, PFEmitMC emitMC, MatType mat,
                       ClipType clip, DrawOpType draw,
                       SkTDArray<DrawType>* expected, int accumulatedClips) {
    bool needsSaveRestore = kNone_DrawOpType != draw &&
                            (kNone_MatType != mat || kNone_ClipType != clip);

    if (kNone_MatType != mat || kNone_ClipType != clip) {
        *expected->append() = SAVE;
    }
    (*emitMC)(canvas, mat, clip, kSaveLayer_DrawOpType, expected, accumulatedClips+1);
    *expected->append() = SAVE_LAYER;
    // TODO: widen testing to exercise saveLayer's parameters
    canvas->saveLayer(nullptr, nullptr);
        (*emitMC)(canvas, mat, clip, kSaveLayer_DrawOpType, expected, 1);
        if (kNone_MatType != mat || kNone_ClipType != clip) {
            *expected->append() = SAVE;
        }
        *expected->append() = SAVE_LAYER;
        // TODO: widen testing to exercise saveLayer's parameters
        canvas->saveLayer(nullptr, nullptr);
            if (needsSaveRestore) {
                *expected->append() = SAVE;
            }
            (*emitMC)(canvas, mat, clip, draw, expected, 1);
            emit_draw(canvas, draw, expected);
            if (needsSaveRestore) {
                *expected->append() = RESTORE;
            }
        canvas->restore();             // for saveLayer
        *expected->append() = RESTORE; // for saveLayer
        if (kNone_MatType != mat || kNone_ClipType != clip) {
            *expected->append() = RESTORE;
        }
    canvas->restore();
    // required to match forced SAVE_LAYER
    *expected->append() = RESTORE;
    if (kNone_MatType != mat || kNone_ClipType != clip) {
        *expected->append() = RESTORE;
    }
}

//////////////////////////////////////////////////////////////////////////////

// Emit:
//  Save
//      some body
//  Restore
// Note: the outer save/restore are provided by beginRecording/endRecording
static void emit_struct0(SkCanvas* canvas,
                         PFEmitMC emitMC, MatType mat, ClipType clip,
                         PFEmitBody emitBody, DrawOpType draw,
                         SkTDArray<DrawType>* expected) {
    (*emitBody)(canvas, emitMC, mat, clip, draw, expected, 0);
}

// Emit:
//  Save
//      matrix & clip calls
//      Save
//          some body
//      Restore
//      matrix & clip calls (will be ignored)
//  Restore
// Note: the outer save/restore are provided by beginRecording/endRecording
static void emit_struct1(SkCanvas* canvas,
                         PFEmitMC emitMC, MatType mat, ClipType clip,
                         PFEmitBody emitBody, DrawOpType draw,
                         SkTDArray<DrawType>* expected) {
    (*emitMC)(canvas, mat, clip, draw, nullptr, 0); // these get fused into later ops
    canvas->save();
        (*emitBody)(canvas, emitMC, mat, clip, draw, expected, 1);
    canvas->restore();
    (*emitMC)(canvas, mat, clip, draw, nullptr, 0); // these will get removed
}

// Emit:
//  Save
//      matrix & clip calls
//      Save
//          some body
//      Restore
//      Save
//          some body
//      Restore
//      matrix & clip calls (will be ignored)
//  Restore
// Note: the outer save/restore are provided by beginRecording/endRecording
static void emit_struct2(SkCanvas* canvas,
                         PFEmitMC emitMC, MatType mat, ClipType clip,
                         PFEmitBody emitBody, DrawOpType draw,
                         SkTDArray<DrawType>* expected) {
    (*emitMC)(canvas, mat, clip, draw, nullptr, 1); // these will get fused into later ops
    canvas->save();
        (*emitBody)(canvas, emitMC, mat, clip, draw, expected, 1);
    canvas->restore();
    canvas->save();
        (*emitBody)(canvas, emitMC, mat, clip, draw, expected, 1);
    canvas->restore();
    (*emitMC)(canvas, mat, clip, draw, nullptr, 1); // these will get removed
}

// Emit:
//  Save
//      matrix & clip calls
//      Save
//          some body
//      Restore
//      Save
//          matrix & clip calls
//          Save
//              some body
//          Restore
//      Restore
//      matrix & clip calls (will be ignored)
//  Restore
// Note: the outer save/restore are provided by beginRecording/endRecording
static void emit_struct3(SkCanvas* canvas,
                         PFEmitMC emitMC, MatType mat, ClipType clip,
                         PFEmitBody emitBody, DrawOpType draw,
                         SkTDArray<DrawType>* expected) {
    (*emitMC)(canvas, mat, clip, draw, nullptr, 0); // these will get fused into later ops
    canvas->save();
        (*emitBody)(canvas, emitMC, mat, clip, draw, expected, 1);
    canvas->restore();
    canvas->save();
        (*emitMC)(canvas, mat, clip, draw, nullptr, 1); // these will get fused into later ops
        canvas->save();
            (*emitBody)(canvas, emitMC, mat, clip, draw, expected, 2);
        canvas->restore();
    canvas->restore();
    (*emitMC)(canvas, mat, clip, draw, nullptr, 0); // these will get removed
}

//////////////////////////////////////////////////////////////////////////////

#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
static void print(const SkTDArray<DrawType>& expected, const SkTDArray<DrawType>& actual) {
    SkDebugf("\n\nexpected %d --- actual %d\n", expected.count(), actual.count());
    int max = SkMax32(expected.count(), actual.count());

    for (int i = 0; i < max; ++i) {
        if (i < expected.count()) {
            SkDebugf("%16s,    ", DrawCommand::GetCommandString(expected[i]));
        } else {
            SkDebugf("%16s,    ", " ");
        }

        if (i < actual.count()) {
            SkDebugf("%s\n", DrawCommand::GetCommandString(actual[i]));
        } else {
            SkDebugf("\n");
        }
    }
    SkDebugf("\n\n");
    SkASSERT(0);
}
#endif

static void test_collapse(skiatest::Reporter* reporter) {
    PFEmitStruct gStructure[] = { emit_struct0, emit_struct1, emit_struct2, emit_struct3 };
    PFEmitBody gBody[] = { emit_body0, emit_body1, emit_body2, emit_body3 };
    PFEmitMC gMCs[] = { emit_clip_and_mat, emit_mat_and_clip,
                        emit_double_mat_and_clip, emit_mat_clip_clip };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gStructure); ++i) {
        for (size_t j = 0; j < SK_ARRAY_COUNT(gBody); ++j) {
            for (size_t k = 0; k < SK_ARRAY_COUNT(gMCs); ++k) {
                for (int l = 0; l < kMatTypeCount; ++l) {
                    for (int m = 0; m < kClipTypeCount; ++m) {
                        for (int n = 0; n < kNonSaveLayerDrawOpTypeCount; ++n) {
#ifdef TEST_COLLAPSE_MATRIX_CLIP_STATE
                            static int testID = -1;
                            ++testID;
                            if (testID < -1) {
                                continue;
                            }
                            SkDebugf("test: %d\n", testID);
#endif

                            SkTDArray<DrawType> expected, actual;

                            SkPicture picture;

                            // Note: beginRecording/endRecording add a save/restore pair
                            SkCanvas* canvas = picture.beginRecording(100, 100);
                            (*gStructure[i])(canvas,
                                             gMCs[k],
                                             (MatType) l,
                                             (ClipType) m,
                                             gBody[j],
                                             (DrawOpType) n,
                                             &expected);
                            picture.endRecording();

                            gets_ops(picture, &actual);

                            REPORTER_ASSERT(reporter, expected.count() == actual.count());

                            if (expected.count() != actual.count()) {
#ifdef TEST_COLLAPSE_MATRIX_CLIP_STATE
                                print(expected, actual);
#endif
                                continue;
                            }

                            for (int i = 0; i < expected.count(); ++i) {
                                REPORTER_ASSERT(reporter, expected[i] == actual[i]);
#ifdef TEST_COLLAPSE_MATRIX_CLIP_STATE
                                if (expected[i] != actual[i]) {
                                    print(expected, actual);
                                }
#endif
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
}

DEF_TEST(MatrixClipCollapse, reporter) {
    test_collapse(reporter);
}

#endif
