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

/*
 * This is a straightforward test of using packed pixel configs (4444, 565).
 * This test will make sure that these RGBA_4444 and RGB_565 are always supported
 * as valid texturing configs.
 */

#include "Test.h"

#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "GrTexture.h"

static const int DEV_W = 10, DEV_H = 10;
static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
static const uint8_t TOL = 0x4;

static void check_component(skiatest::Reporter* reporter, uint8_t control, uint8_t test) {
    uint8_t diff = 0;
    if (control >= test) {
        diff = control - test;
    } else {
        diff = test - control;
    }
    REPORTER_ASSERT(reporter, diff < TOL);
}

static uint8_t expand_value(uint8_t original, int sigBits) {
    SkASSERT(sigBits >= 4);
    uint8_t inSigBitShift = 8 - sigBits;
    uint8_t duplBitShift = sigBits - inSigBitShift;
    return (original << inSigBitShift) + (original >> duplBitShift);
}

static void check_4444(skiatest::Reporter* reporter,
                       const SkTDArray<uint16_t>& controlData,
                       const SkTDArray<uint32_t>& readBuffer) {
    for (int j = 0; j < DEV_H; ++j) {
        for (int i = 0; i < DEV_W; ++i) {
            uint16_t control = controlData[i + j * DEV_H];
            uint32_t test = readBuffer[i + j * DEV_H];

            // Test alpha component
            uint8_t ctrlComp = expand_value(control & 0xF, 4);
            uint8_t testComp = GrColorUnpackA(test);
            check_component(reporter, ctrlComp, testComp);

            // Test blue component
            ctrlComp = expand_value((control >> 4) & 0xF, 4);
            testComp = GrColorUnpackB(test);
            check_component(reporter, ctrlComp, testComp);

            // Test green component
            ctrlComp = expand_value((control >> 8) & 0xF, 4);
            testComp = GrColorUnpackG(test);
            check_component(reporter, ctrlComp, testComp);

            // Test red component
            ctrlComp = expand_value((control >> 12) & 0xF, 4);
            testComp = GrColorUnpackR(test);
            check_component(reporter, ctrlComp, testComp);
        }
    }
}

static void check_565(skiatest::Reporter* reporter,
                      const SkTDArray<uint16_t>& controlData,
                      const SkTDArray<GrColor>& readBuffer) {
    for (int j = 0; j < DEV_H; ++j) {
        for (int i = 0; i < DEV_W; ++i) {
            uint16_t control = controlData[i + j * DEV_H];
            GrColor test = readBuffer[i + j * DEV_H];
            // Test blue component (5 bit control)
            uint8_t ctrlComp = expand_value(control & 0x1F, 5);
            uint8_t testComp = GrColorUnpackB(test);
            check_component(reporter, ctrlComp, testComp);

            // Test green component (6 bit control)
            ctrlComp = expand_value((control >> 5) & 0x3F, 6);
            testComp = GrColorUnpackG(test);
            check_component(reporter, ctrlComp, testComp);

            // Test red component (5 bit control)
            ctrlComp = expand_value((control >> 11) & 0x1F, 5);
            testComp = GrColorUnpackR(test);
            check_component(reporter, ctrlComp, testComp);
        }
    }
}

template <typename T>
void runTest(skiatest::Reporter* reporter, GrContext* context,
             T val1, T val2, int arraySize, GrPixelConfig config) {
    SkTDArray<T> controlPixelData;
    // We will read back into an 8888 buffer since 565/4444 read backes aren't supported
    SkTDArray<GrColor> readBuffer;
    controlPixelData.setCount(arraySize);
    readBuffer.setCount(arraySize);

    for (int i = 0; i < arraySize; i += 2) {
        controlPixelData[i] = val1;
        controlPixelData[i + 1] = val2;
    }

    for (int origin = 0; origin < 2; ++origin) {
        GrSurfaceDesc desc;
        desc.fFlags = kNone_GrSurfaceFlags;
        desc.fWidth = DEV_W;
        desc.fHeight = DEV_H;
        desc.fConfig = config;
        desc.fOrigin = 0 == origin ?
            kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
        sk_sp<GrTexture> fpTexture(context->textureProvider()->createTexture(
            desc, SkBudgeted::kNo, controlPixelData.begin(), 0));
        SkASSERT(fpTexture);
        fpTexture->readPixels(0, 0, DEV_W, DEV_H, kRGBA_8888_GrPixelConfig, readBuffer.begin(), 0);
        if (kRGBA_4444_GrPixelConfig == config) {
            check_4444(reporter, controlPixelData, readBuffer);
        } else {
            SkASSERT(kRGB_565_GrPixelConfig == config);
            check_565(reporter, controlPixelData, readBuffer);
        }
    }
}

static const int CONTROL_ARRAY_SIZE = DEV_W * DEV_H;

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RGBA4444TextureTest, reporter, ctxInfo) {
    runTest<uint16_t>(reporter, ctxInfo.grContext(), 0xFF00, 0xFA62,
                      CONTROL_ARRAY_SIZE, kRGBA_4444_GrPixelConfig);
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RGB565TextureTest, reporter, ctxInfo) {
    runTest<uint16_t>(reporter, ctxInfo.grContext(), 0xFF00, 0xFA62,
                      CONTROL_ARRAY_SIZE, kRGB_565_GrPixelConfig);
}

#endif
