xref: /aosp_15_r20/external/skia/src/gpu/ganesh/gl/GrGLDirectContext.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 "include/gpu/ganesh/gl/GrGLDirectContext.h"
9 
10 #include "include/gpu/ganesh/GrContextOptions.h"
11 #include "include/gpu/ganesh/GrDirectContext.h"
12 #include "include/gpu/ganesh/GrTypes.h"
13 #include "include/gpu/ganesh/gl/GrGLConfig.h"
14 #include "include/gpu/ganesh/gl/GrGLFunctions.h"
15 #include "include/gpu/ganesh/gl/GrGLInterface.h"
16 #include "include/gpu/ganesh/gl/GrGLTypes.h"
17 
18 #include "src/gpu/ganesh/GrContextThreadSafeProxyPriv.h"
19 #include "src/gpu/ganesh/GrDirectContextPriv.h"
20 #include "src/gpu/ganesh/gl/GrGLDefines.h"
21 #include "src/gpu/ganesh/gl/GrGLGpu.h"
22 
23 #include <utility>
24 
25 #if defined(GPU_TEST_UTILS)
26 #   include "src/base/SkRandom.h"
27 #   if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
28 #       include <sanitizer/lsan_interface.h>
29 #   endif
30 #endif
31 
32 #if defined(SK_DISABLE_LEGACY_GL_MAKE_NATIVE_INTERFACE)
33 #include "include/private/base/SkAssert.h"
34 #endif
35 
36 namespace GrDirectContexts {
37 
MakeGL(sk_sp<const GrGLInterface> glInterface)38 sk_sp<GrDirectContext> MakeGL(sk_sp<const GrGLInterface> glInterface) {
39     GrContextOptions defaultOptions;
40     return MakeGL(std::move(glInterface), defaultOptions);
41 }
42 
43 #if !defined(SK_DISABLE_LEGACY_GL_MAKE_NATIVE_INTERFACE)
MakeGL(const GrContextOptions & options)44 sk_sp<GrDirectContext> MakeGL(const GrContextOptions& options) {
45     return MakeGL(nullptr, options);
46 }
47 
MakeGL()48 sk_sp<GrDirectContext> MakeGL() {
49     GrContextOptions defaultOptions;
50     return MakeGL(nullptr, defaultOptions);
51 }
52 #endif
53 
54 #if defined(GPU_TEST_UTILS)
make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original)55 GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
56     // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
57     // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
58     // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
59     // on the thing it captures. So we leak the context.
60     struct GetErrorContext {
61         SkRandom fRandom;
62         GrGLFunction<GrGLGetErrorFn> fGetError;
63     };
64 
65     auto errorContext = new GetErrorContext;
66 
67 #if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
68     __lsan_ignore_object(errorContext);
69 #endif
70 
71     errorContext->fGetError = original;
72 
73     return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
74         GrGLenum error = errorContext->fGetError();
75         if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
76             error = GR_GL_OUT_OF_MEMORY;
77         }
78         return error;
79     });
80 }
81 #endif
82 
MakeGL(sk_sp<const GrGLInterface> glInterface,const GrContextOptions & options)83 sk_sp<GrDirectContext> MakeGL(sk_sp<const GrGLInterface> glInterface,
84                               const GrContextOptions& options) {
85 #if defined(SK_DISABLE_LEGACY_GL_MAKE_NATIVE_INTERFACE)
86     SkASSERT(glInterface);
87 #endif
88     auto direct = GrDirectContextPriv::Make(
89             GrBackendApi::kOpenGL,
90             options,
91             GrContextThreadSafeProxyPriv::Make(GrBackendApi::kOpenGL, options));
92 #if defined(GPU_TEST_UTILS)
93     if (options.fRandomGLOOM) {
94         auto copy = sk_make_sp<GrGLInterface>(*glInterface);
95         copy->fFunctions.fGetError =
96                 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
97 #if GR_GL_CHECK_ERROR
98         // Suppress logging GL errors since we'll be synthetically generating them.
99         copy->suppressErrorLogging();
100 #endif
101         glInterface = std::move(copy);
102     }
103 #endif
104     GrDirectContextPriv::SetGpu(direct,
105                                 GrGLGpu::Make(std::move(glInterface), options, direct.get()));
106     if (!GrDirectContextPriv::Init(direct)) {
107         return nullptr;
108     }
109     return direct;
110 }
111 
112 }  // namespace GrDirectContexts
113