blob: f7277e18f87b2faea0e160fd676303d2a8eb248e [file] [log] [blame]
Jim Van Verth7bb0ff02021-09-30 16:27:30 -04001/*
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