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

#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "tests/Test.h"

static SkBitmap read_pixels(sk_sp<SkSurface> surface, SkColor initColor) {
    SkBitmap bmp;
    bmp.allocN32Pixels(surface->width(), surface->height());
    bmp.eraseColor(initColor);
    if (!surface->readPixels(bmp, 0, 0)) {
        SkDebugf("readPixels failed\n");
    }
    return bmp;
}

static sk_sp<SkSurface> make_surface(GrRecordingContext* rContext) {
    SkImageInfo info = SkImageInfo::Make(50, 50, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    return SkSurface::MakeRenderTarget(rContext, SkBudgeted::kNo, info, 4,
                                       kBottomLeft_GrSurfaceOrigin, nullptr);
}

static void test_bug_6653(GrDirectContext* dContext,
                          skiatest::Reporter* reporter,
                          const char* label) {
    SkRect rect = SkRect::MakeWH(50, 50);

    SkPaint paint;
    paint.setColor(SK_ColorWHITE);
    paint.setStrokeWidth(5);
    paint.setStyle(SkPaint::kStroke_Style);

    // The one device that fails this test (Galaxy S6) does so in a flaky fashion. Trying many
    // times makes it more likely to fail. Also, interacting with the phone (eg swiping between
    // different home screens) while the test is running makes it fail close to 100%.
    static const int kNumIterations = 50;

    for (int i = 0; i < kNumIterations; ++i) {
        auto s0 = make_surface(dContext);
        if (!s0) {
            // MSAA may not be supported
            return;
        }

        auto s1 = make_surface(dContext);
        s1->getCanvas()->clear(SK_ColorBLACK);
        s1->getCanvas()->drawOval(rect, paint);
        SkBitmap b1 = read_pixels(s1, SK_ColorBLACK);
        s1 = nullptr;

        // The bug requires that all three of the following surfaces are cleared to the same color
        auto s2 = make_surface(dContext);
        s2->getCanvas()->clear(SK_ColorBLUE);
        SkBitmap b2 = read_pixels(s2, SK_ColorBLACK);
        s2 = nullptr;

        auto s3 = make_surface(dContext);
        s3->getCanvas()->clear(SK_ColorBLUE);
        SkBitmap b3 = read_pixels(s3, SK_ColorBLACK);
        s0->getCanvas()->drawBitmap(b3, 0, 0);
        s3 = nullptr;

        auto s4 = make_surface(dContext);
        s4->getCanvas()->clear(SK_ColorBLUE);
        s4->getCanvas()->drawOval(rect, paint);

        // When this fails, b4 will "succeed", but return an empty bitmap (containing just the
        // clear color). Regardless, b5 will contain the oval that was just drawn, so diffing the
        // two bitmaps tests for the failure case. Initialize the bitmaps to different colors so
        // that if the readPixels doesn't work, this test will always fail.
        SkBitmap b4 = read_pixels(s4, SK_ColorRED);
        SkBitmap b5 = read_pixels(s4, SK_ColorGREEN);

        bool match = true;
        for (int y = 0; y < b4.height() && match; ++y) {
            for (int x = 0; x < b4.width() && match; ++x) {
                uint32_t pixelA = *b4.getAddr32(x, y);
                uint32_t pixelB = *b5.getAddr32(x, y);
                if (pixelA != pixelB) {
                    match = false;
                }
            }
        }

        REPORTER_ASSERT(reporter, match, label);
    }
}

// Tests that readPixels returns up-to-date results. This has failed on several GPUs,
// from multiple vendors, in MSAA mode.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(skbug6653, reporter, ctxInfo) {
    auto ctx = ctxInfo.directContext();
    test_bug_6653(ctx, reporter, "Default");
}

