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/GrDirectContext.h" 10#include "src/gpu/ganesh/GrDirectContextPriv.h" 11#include "src/gpu/ganesh/GrProxyProvider.h" 12#include "src/gpu/ganesh/mtl/GrMtlGpu.h" 13#include "tests/Test.h" 14 15#import <Metal/Metal.h> 16#import <MetalKit/MTKView.h> 17 18#include "src/gpu/ganesh/mtl/GrMtlCaps.h" 19#include "src/gpu/ganesh/mtl/GrMtlTextureRenderTarget.h" 20 21DEF_GANESH_TEST_FOR_METAL_CONTEXT(MtlCopySurfaceTest, reporter, ctxInfo) { 22 if (@available(macOS 11.0, iOS 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(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 GrMipmapped::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 = GrBackendFormat::MakeMtl(drawable.texture.pixelFormat); 64 GrSurface* src = srcProxy->peekSurface(); 65 sk_sp<GrTexture> dst = 66 gpu->createTexture({kWidth, kHeight}, backendFormat, GrTextureType::k2D, 67 GrRenderable::kNo, 1, GrMipmapped::kNo, skgpu::Budgeted::kNo, 68 GrProtected::kNo, /*label=*/"MtlCopySurfaceTest"); 69 70 bool result = gpu->copySurface(dst.get(), 71 SkIRect::MakeWH(kWidth, kHeight), 72 src, 73 SkIRect::MakeWH(kWidth, kHeight), 74 GrSamplerState::Filter::kNearest); 75 REPORTER_ASSERT(reporter, !result); 76 } 77} 78