xref: /aosp_15_r20/external/skia/tools/window/GLWindowContext.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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