1 /*
2 * Copyright 2023 Google LLC
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 "tools/window/GLWindowContext.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkSurface.h"
11 #include "include/gpu/GrBackendSurface.h"
12 #include "include/gpu/GrDirectContext.h"
13 #include "include/gpu/ganesh/SkSurfaceGanesh.h"
14 #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
15 #include "src/base/SkMathPriv.h"
16 #include "src/gpu/ganesh/GrCaps.h"
17 #include "src/gpu/ganesh/GrDirectContextPriv.h"
18 #include "src/gpu/ganesh/gl/GrGLDefines.h"
19 #include "src/gpu/ganesh/gl/GrGLUtil.h"
20 #include "include/gpu/ganesh/gl/GrGLDirectContext.h"
21 #include "src/image/SkImage_Base.h"
22
23 namespace skwindow::internal {
24
GLWindowContext(const DisplayParams & params)25 GLWindowContext::GLWindowContext(const DisplayParams& params)
26 : WindowContext(params)
27 , fBackendContext(nullptr)
28 , fSurface(nullptr) {
29 fDisplayParams.fMSAASampleCount = GrNextPow2(fDisplayParams.fMSAASampleCount);
30 }
31
initializeContext()32 void GLWindowContext::initializeContext() {
33 SkASSERT(!fContext);
34
35 fBackendContext = this->onInitializeContext();
36
37 fContext = GrDirectContexts::MakeGL(fBackendContext, fDisplayParams.fGrContextOptions);
38 if (!fContext && fDisplayParams.fMSAASampleCount > 1) {
39 fDisplayParams.fMSAASampleCount /= 2;
40 this->initializeContext();
41 return;
42 }
43 }
44
destroyContext()45 void GLWindowContext::destroyContext() {
46 fSurface.reset(nullptr);
47
48 if (fContext) {
49 // in case we have outstanding refs to this (lua?)
50 fContext->abandonContext();
51 fContext.reset();
52 }
53
54 fBackendContext.reset(nullptr);
55
56 this->onDestroyContext();
57 }
58
getBackbufferSurface()59 sk_sp<SkSurface> GLWindowContext::getBackbufferSurface() {
60 if (nullptr == fSurface) {
61 if (fContext) {
62 GrGLint buffer;
63 GR_GL_CALL(fBackendContext.get(), GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer));
64
65 GrGLFramebufferInfo fbInfo;
66 fbInfo.fFBOID = buffer;
67 fbInfo.fFormat = GR_GL_RGBA8;
68 fbInfo.fProtected = skgpu::Protected(fDisplayParams.fCreateProtectedNativeBackend);
69
70 auto backendRT = GrBackendRenderTargets::MakeGL(fWidth,
71 fHeight,
72 fSampleCount,
73 fStencilBits,
74 fbInfo);
75
76 fSurface = SkSurfaces::WrapBackendRenderTarget(fContext.get(),
77 backendRT,
78 kBottomLeft_GrSurfaceOrigin,
79 kRGBA_8888_SkColorType,
80 fDisplayParams.fColorSpace,
81 &fDisplayParams.fSurfaceProps);
82 }
83 }
84
85 return fSurface;
86 }
87
resize(int w,int h)88 void GLWindowContext::resize(int w, int h) {
89 this->destroyContext();
90 this->initializeContext();
91 }
92
setDisplayParams(const DisplayParams & params)93 void GLWindowContext::setDisplayParams(const DisplayParams& params) {
94 fDisplayParams = params;
95 this->destroyContext();
96 this->initializeContext();
97 }
98
99 } // namespace skwindow::internal
100