1/* 2 * Copyright 2019 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "include/core/SkSurface.h" 9#include "include/gpu/ganesh/GrDirectContext.h" 10#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h" 11#include "src/gpu/ganesh/GrDirectContextPriv.h" 12#include "src/gpu/ganesh/GrProxyProvider.h" 13#include "src/gpu/ganesh/mtl/GrMtlCaps.h" 14#include "src/gpu/ganesh/mtl/GrMtlGpu.h" 15#include "src/gpu/ganesh/mtl/GrMtlTextureRenderTarget.h" 16#include "tests/Test.h" 17 18#import <Metal/Metal.h> 19#import <MetalKit/MTKView.h> 20 21DEF_GANESH_TEST_FOR_METAL_CONTEXT(MtlCopySurfaceTest, reporter, ctxInfo) { 22 if (@available(macOS 11.0, iOS 9.0, tvOS 9.0, *)) { 23 static const int kWidth = 1024; 24 static const int kHeight = 768; 25 26 auto context = ctxInfo.directContext(); 27 28 // This is a bit weird, but it's the only way to get a framebufferOnly surface 29 GrMtlGpu* gpu = (GrMtlGpu*) context->priv().getGpu(); 30 31 MTKView* view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, kWidth, kHeight) 32 device:gpu->device()]; 33 id<CAMetalDrawable> drawable = [view currentDrawable]; 34 REPORTER_ASSERT(reporter, drawable.texture.framebufferOnly); 35 REPORTER_ASSERT(reporter, drawable.texture.usage & MTLTextureUsageRenderTarget); 36 37 // Test to see if we can initiate a copy via GrSurfaceProxys 38 SkSurfaceProps props(0, kRGB_H_SkPixelGeometry); 39 40 // TODO: check multisampled RT as well 41 GrMtlTextureInfo fbInfo; 42 fbInfo.fTexture.retain((__bridge const void*)(drawable.texture)); 43 GrBackendRenderTarget backendRT = GrBackendRenderTargets::MakeMtl(kWidth, kHeight, fbInfo); 44 45 GrProxyProvider* proxyProvider = context->priv().proxyProvider(); 46 sk_sp<GrSurfaceProxy> srcProxy = proxyProvider->wrapBackendRenderTarget(backendRT, nullptr); 47 48 auto dstProxy = GrSurfaceProxy::Copy(context, 49 srcProxy, 50 kTopLeft_GrSurfaceOrigin, 51 skgpu::Mipmapped::kNo, 52 SkBackingFit::kExact, 53 skgpu::Budgeted::kYes, 54 /*label=*/{}); 55 56 // TODO: GrSurfaceProxy::Copy doesn't check to see if the framebufferOnly bit is set yet. 57 // Update this when it does -- it should fail. 58 if (!dstProxy) { 59 ERRORF(reporter, "Expected copy to succeed"); 60 } 61 62 // Try direct copy via GPU (should fail) 63 GrBackendFormat backendFormat = GrBackendFormats::MakeMtl(drawable.texture.pixelFormat); 64 GrSurface* src = srcProxy->peekSurface(); 65 sk_sp<GrTexture> dst = gpu->createTexture({kWidth, kHeight}, 66 backendFormat, 67 GrTextureType::k2D, 68 GrRenderable::kNo, 69 1, 70 skgpu::Mipmapped::kNo, 71 skgpu::Budgeted::kNo, 72 GrProtected::kNo, 73 /*label=*/"MtlCopySurfaceTest"); 74 75 bool result = gpu->copySurface(dst.get(), 76 SkIRect::MakeWH(kWidth, kHeight), 77 src, 78 SkIRect::MakeWH(kWidth, kHeight), 79 GrSamplerState::Filter::kNearest); 80 REPORTER_ASSERT(reporter, !result); 81 } 82} 83