1/* 2 * Copyright 2021 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 "src/core/SkMathPriv.h" 10#include "tools/sk_app/GraphiteMetalWindowContext.h" 11 12#include "experimental/graphite/include/Context.h" 13#include "experimental/graphite/include/mtl/MtlBackendContext.h" 14 15using sk_app::DisplayParams; 16using sk_app::GraphiteMetalWindowContext; 17 18namespace sk_app { 19 20GraphiteMetalWindowContext::GraphiteMetalWindowContext(const DisplayParams& params) 21 : WindowContext(params) 22 , fValid(false) 23 , fDrawableHandle(nil) { 24 fDisplayParams.fMSAASampleCount = GrNextPow2(fDisplayParams.fMSAASampleCount); 25} 26 27void GraphiteMetalWindowContext::initializeContext() { 28 SkASSERT(!fContext); 29 SkASSERT(!fGraphiteContext); 30 31 fDevice.reset(MTLCreateSystemDefaultDevice()); 32 fQueue.reset([*fDevice newCommandQueue]); 33 34 if (fDisplayParams.fMSAASampleCount > 1) { 35 if (@available(macOS 10.11, iOS 9.0, *)) { 36 if (![*fDevice supportsTextureSampleCount:fDisplayParams.fMSAASampleCount]) { 37 return; 38 } 39 } else { 40 return; 41 } 42 } 43 fSampleCount = fDisplayParams.fMSAASampleCount; 44 fStencilBits = 8; 45 46 fValid = this->onInitializeContext(); 47 48 skgpu::mtl::BackendContext backendContext = {}; 49 backendContext.fDevice.retain((GrMTLHandle)fDevice.get()); 50 backendContext.fQueue.retain((GrMTLHandle)fQueue.get()); 51 fGraphiteContext = skgpu::Context::MakeMetal(backendContext); 52 // TODO 53// if (!fGraphiteContext && fDisplayParams.fMSAASampleCount > 1) { 54// fDisplayParams.fMSAASampleCount /= 2; 55// this->initializeContext(); 56// return; 57// } 58} 59 60void GraphiteMetalWindowContext::destroyContext() { 61 if (fGraphiteContext) { 62 // TODO? 63 // in case we have outstanding refs to this (lua?) 64 // fGraphiteContext->abandonContext(); 65 fGraphiteContext.reset(); 66 } 67 68 this->onDestroyContext(); 69 70 fMetalLayer = nil; 71 fValid = false; 72 73#if GR_METAL_SDK_VERSION >= 230 74 if (@available(macOS 11.0, iOS 14.0, *)) { 75 [fPipelineArchive release]; 76 } 77#endif 78 fQueue.reset(); 79 fDevice.reset(); 80} 81 82sk_sp<SkSurface> GraphiteMetalWindowContext::getBackbufferSurface() { 83 sk_sp<SkSurface> surface; 84 id<CAMetalDrawable> currentDrawable = [fMetalLayer nextDrawable]; 85 86 // TODO 87// GrMtlTextureInfo fbInfo; 88// fbInfo.fTexture.retain(currentDrawable.texture); 89// 90// GrBackendRenderTarget backendRT(fWidth, 91// fHeight, 92// fSampleCount, 93// fbInfo); 94// 95// surface = SkSurface::MakeFromBackendRenderTarget(fContext.get(), backendRT, 96// kTopLeft_GrSurfaceOrigin, 97// kBGRA_8888_SkColorType, 98// fDisplayParams.fColorSpace, 99// &fDisplayParams.fSurfaceProps); 100 101 fDrawableHandle = CFRetain((GrMTLHandle) currentDrawable); 102 103 return surface; 104} 105 106void GraphiteMetalWindowContext::swapBuffers() { 107 id<CAMetalDrawable> currentDrawable = (id<CAMetalDrawable>)fDrawableHandle; 108 109 id<MTLCommandBuffer> commandBuffer([*fQueue commandBuffer]); 110 commandBuffer.label = @"Present"; 111 112 [commandBuffer presentDrawable:currentDrawable]; 113 [commandBuffer commit]; 114 // ARC is off in sk_app, so we need to release the CF ref manually 115 CFRelease(fDrawableHandle); 116 fDrawableHandle = nil; 117} 118 119void GraphiteMetalWindowContext::setDisplayParams(const DisplayParams& params) { 120 this->destroyContext(); 121 fDisplayParams = params; 122 this->initializeContext(); 123} 124 125void GraphiteMetalWindowContext::activate(bool isActive) {} 126 127} //namespace sk_app 128