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