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

#include "Test.h"
#if SK_SUPPORT_GPU

#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrGpu.h"
#include "GrTextureStripAtlas.h"
#include "GrTypes.h"

// This tests that GrTextureStripAtlas flushes pending IO on the texture it acquires.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    GrSurfaceDesc desc;
    desc.fWidth = 32;
    desc.fHeight = 32;
    desc.fConfig = kRGBA_8888_GrPixelConfig;

    sk_sp<GrSurfaceProxy> srcProxy;

    {
        SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight);
        memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight);

        srcProxy = GrSurfaceProxy::MakeDeferred(*context->caps(), context->textureProvider(),
                                                desc, SkBudgeted::kYes,
                                                pixels.get(), 0);
    }

    // Add a pending read to the src texture, and then make it available for reuse.
    sk_sp<GrSurfaceProxy> targetProxy;
    GrSurface* srcSurface;

    {
        GrSurfaceDesc targetDesc = desc;
        targetDesc.fFlags = kRenderTarget_GrSurfaceFlag;

        // We can't use GrSurfaceProxy::Copy bc we may be changing the dst proxy type
        sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
                                                                            targetDesc,
                                                                            SkBackingFit::kExact,
                                                                            SkBudgeted::kYes));
        REPORTER_ASSERT(reporter, dstContext);

        if (!dstContext->copy(srcProxy.get())) {
            return;
        }

        targetProxy = sk_ref_sp(dstContext->asDeferredSurface());

        srcSurface = srcProxy->instantiate(context->textureProvider());
        srcProxy.reset();
    }

    // Create an atlas with parameters that allow it to reuse the texture.
    GrTextureStripAtlas* atlas;

    {
        GrTextureStripAtlas::Desc atlasDesc;
        atlasDesc.fContext = context;
        atlasDesc.fConfig = desc.fConfig;
        atlasDesc.fWidth = desc.fWidth;
        atlasDesc.fHeight = desc.fHeight;
        atlasDesc.fRowHeight = 1;
        atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
    }

    // Write to the atlas' texture.
    int lockedRow;

    {
        SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
        size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
        SkBitmap bitmap;
        bitmap.allocPixels(info, rowBytes);
        memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight);
        lockedRow = atlas->lockRow(bitmap);
    }

    // The atlas' use of its texture shouldn't change which pixels got copied to the target.
    {
        SkAutoTMalloc<uint8_t> actualPixels(sizeof(uint32_t) * desc.fWidth * desc.fHeight);

        // TODO: move readPixels to GrSurfaceProxy?
        GrSurface* surf = targetProxy->instantiate(context->textureProvider());

        bool success = surf->readPixels(0, 0, desc.fWidth, desc.fHeight,
                                        kRGBA_8888_GrPixelConfig, actualPixels.get());
        REPORTER_ASSERT(reporter, success);

        bool good = true;

        const uint8_t* bytes = actualPixels.get();
        for (size_t i = 0; i < sizeof(uint32_t) * desc.fWidth * desc.fHeight; ++i, ++bytes) {
            if (0xFF != *bytes) {
                good = false;
                break;
            }
        }

        REPORTER_ASSERT(reporter, good);
    }

    if (!context->caps()->preferVRAMUseOverFlushes()) {
        // This is kindof dodgy since we released it!
        REPORTER_ASSERT(reporter, srcSurface == atlas->getTexture());
    }

    atlas->unlockRow(lockedRow);
}

#endif
