/*
 * Copyright 2019 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/SkSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/mtl/GrMtlGpu.h"
#include "tests/Test.h"

#import <Metal/Metal.h>
#import <MetalKit/MTKView.h>

#include "src/gpu/ganesh/mtl/GrMtlCaps.h"
#include "src/gpu/ganesh/mtl/GrMtlTextureRenderTarget.h"

DEF_GANESH_TEST_FOR_METAL_CONTEXT(MtlCopySurfaceTest, reporter, ctxInfo) {
    if (@available(macOS 11.0, iOS 9.0, *)) {
        static const int kWidth = 1024;
        static const int kHeight = 768;

        auto context = ctxInfo.directContext();

        // This is a bit weird, but it's the only way to get a framebufferOnly surface
        GrMtlGpu* gpu = (GrMtlGpu*) context->priv().getGpu();

        MTKView* view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, kWidth, kHeight)
                                                device:gpu->device()];
        id<CAMetalDrawable> drawable = [view currentDrawable];
        REPORTER_ASSERT(reporter, drawable.texture.framebufferOnly);
        REPORTER_ASSERT(reporter, drawable.texture.usage & MTLTextureUsageRenderTarget);

        // Test to see if we can initiate a copy via GrSurfaceProxys
        SkSurfaceProps props(0, kRGB_H_SkPixelGeometry);

        // TODO: check multisampled RT as well
        GrMtlTextureInfo fbInfo;
        fbInfo.fTexture.retain((__bridge const void*)(drawable.texture));
        GrBackendRenderTarget backendRT(kWidth, kHeight, fbInfo);

        GrProxyProvider* proxyProvider = context->priv().proxyProvider();
        sk_sp<GrSurfaceProxy> srcProxy = proxyProvider->wrapBackendRenderTarget(backendRT, nullptr);

        auto dstProxy = GrSurfaceProxy::Copy(context,
                                             srcProxy,
                                             kTopLeft_GrSurfaceOrigin,
                                             GrMipmapped::kNo,
                                             SkBackingFit::kExact,
                                             skgpu::Budgeted::kYes,
                                             /*label=*/{});

        // TODO: GrSurfaceProxy::Copy doesn't check to see if the framebufferOnly bit is set yet.
        // Update this when it does -- it should fail.
        if (!dstProxy) {
            ERRORF(reporter, "Expected copy to succeed");
        }

        // Try direct copy via GPU (should fail)
        GrBackendFormat backendFormat = GrBackendFormat::MakeMtl(drawable.texture.pixelFormat);
        GrSurface* src = srcProxy->peekSurface();
        sk_sp<GrTexture> dst =
                gpu->createTexture({kWidth, kHeight}, backendFormat, GrTextureType::k2D,
                                   GrRenderable::kNo, 1, GrMipmapped::kNo, skgpu::Budgeted::kNo,
                                   GrProtected::kNo, /*label=*/"MtlCopySurfaceTest");

        bool result = gpu->copySurface(dst.get(),
                                       SkIRect::MakeWH(kWidth, kHeight),
                                       src,
                                       SkIRect::MakeWH(kWidth, kHeight),
                                       GrSamplerState::Filter::kNearest);
        REPORTER_ASSERT(reporter, !result);
    }
}
