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/GrDirectContextPriv.h" 11#include "src/gpu/GrProxyProvider.h" 12#include "src/gpu/mtl/GrMtlGpu.h" 13#include "tests/Test.h" 14 15#import <Metal/Metal.h> 16#import <MetalKit/MTKView.h> 17 18#include "src/gpu/mtl/GrMtlCaps.h" 19#include "src/gpu/mtl/GrMtlTextureRenderTarget.h" 20 21DEF_GPUTEST_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 SkBudgeted::kYes); 54 55 // TODO: GrSurfaceProxy::Copy doesn't check to see if the framebufferOnly bit is set yet. 56 // Update this when it does -- it should fail. 57 if (!dstProxy) { 58 ERRORF(reporter, "Expected copy to succeed"); 59 } 60 61 // Try direct copy via GPU (should fail) 62 GrBackendFormat backendFormat = GrBackendFormat::MakeMtl(drawable.texture.pixelFormat); 63 GrSurface* src = srcProxy->peekSurface(); 64 sk_sp<GrTexture> dst = 65 gpu->createTexture({kWidth, kHeight}, backendFormat, GrTextureType::k2D, 66 GrRenderable::kNo, 1, GrMipmapped::kNo, SkBudgeted::kNo, 67 GrProtected::kNo); 68 69 bool result = gpu->copySurface(dst.get(), src, SkIRect::MakeXYWH(0, 0, kWidth, kHeight), 70 SkIPoint::Make(0, 0)); 71 REPORTER_ASSERT(reporter, !result); 72 } 73} 74