1// LAF OS Library
2// Copyright (C) 2022 Igara Studio S.A.
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include "base/log.h"
12#include "os/skia/skia_gl.h"
13
14#if SK_SUPPORT_GPU
15
16#include "include/core/SkSurface.h"
17#include "include/core/SkSurfaceCharacterization.h"
18#include "src/gpu/gl/GrGLDefines.h"
19
20namespace os {
21
22SkiaGL::SkiaGL()
23{
24}
25
26bool SkiaGL::attachGL()
27{
28 if (m_grCtx)
29 return true;
30
31 try {
32 m_glInterfaces = GrGLMakeNativeInterface();
33 if (!m_glInterfaces) {
34 LOG(ERROR, "OS: Cannot get native GL interface\n");
35 detachGL();
36 return false;
37 }
38
39 m_grCtx = GrDirectContext::MakeGL(m_glInterfaces);
40 if (!m_grCtx) {
41 LOG(ERROR, "OS: Cannot create GrContext\n");
42 detachGL();
43 return false;
44 }
45
46 LOG("OS: Using OpenGL backend\n");
47 }
48 catch (const std::exception& ex) {
49 LOG(ERROR, "OS: Cannot create GL context: %s\n", ex.what());
50 detachGL();
51 return false;
52 }
53 return true;
54}
55
56void SkiaGL::detachGL()
57{
58 if (m_grCtx) {
59 m_grCtx->abandonContext();
60 m_grCtx.reset(nullptr);
61 }
62 m_glInterfaces.reset(nullptr);
63}
64
65bool SkiaGL::createRenderTarget(const gfx::Size& size,
66 const int scale,
67 sk_sp<SkColorSpace> colorSpace)
68{
69 // Create of a SkSurface (m_backbufferSurface) connected to the
70 // OpenGL framebuffer.
71
72 GrGLint buffer;
73 m_glInterfaces->fFunctions.fGetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer);
74
75 GrGLFramebufferInfo info;
76 info.fFBOID = (GrGLuint)buffer;
77 info.fFormat = GR_GL_RGBA8;
78
79 GrGLint stencil = 0;
80 m_glInterfaces->fFunctions.fGetIntegerv(GR_GL_STENCIL_BITS, &stencil);
81
82 GrBackendRenderTarget target(size.w, size.h, 0, stencil, info);
83
84 m_surface.reset(nullptr);
85 m_backbufferSurface =
86 SkSurface::MakeFromBackendRenderTarget(
87 m_grCtx.get(), target,
88 kBottomLeft_GrSurfaceOrigin,
89 kRGBA_8888_SkColorType,
90 colorSpace,
91 nullptr);
92
93 if (!m_backbufferSurface)
94 return false;
95
96 if (scale == 1 && m_backbufferSurface) {
97 m_surface = m_backbufferSurface;
98 }
99 else {
100 SkImageInfo info = SkImageInfo::Make(
101 std::max(1, size.w / scale),
102 std::max(1, size.h / scale),
103 kN32_SkColorType,
104 kOpaque_SkAlphaType,
105 colorSpace);
106
107 SkSurfaceCharacterization ch;
108 m_backbufferSurface->characterize(&ch);
109
110 m_surface =
111 SkSurface::MakeRenderTarget(
112 m_grCtx.get(), SkBudgeted::kNo,
113 info, ch.sampleCount(), nullptr);
114 }
115
116 return true;
117}
118
119} // namespace os
120
121#endif
122