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