1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "gles_render_backend.h"
17
18 #include "egl_manager.h"
19 #include "drawing_utils.h"
20 #include "surface_ohos_gl.h"
21
22 namespace OHOS {
23 namespace Rosen {
GLESRenderBackend()24 GLESRenderBackend::GLESRenderBackend() noexcept
25 {
26 eglManager_ = new EGLManager();
27 }
28
~GLESRenderBackend()29 GLESRenderBackend::~GLESRenderBackend()
30 {
31 if (eglManager_) {
32 delete eglManager_;
33 eglManager_ = nullptr;
34 }
35 }
36
InitDrawContext()37 void GLESRenderBackend::InitDrawContext()
38 {
39 if (eglManager_ == nullptr) {
40 LOGE("eglManager_ is nullptr, can not InitDrawContext");
41 return;
42 }
43 eglManager_->Init();
44 }
45
SetUpGrContext()46 bool GLESRenderBackend::SetUpGrContext()
47 {
48 if (grContext_ != nullptr) {
49 LOGD("grContext has already created!!");
50 return true;
51 }
52
53 sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
54 if (glInterface.get() == nullptr) {
55 LOGE("SetUpGrContext failed to make native interface");
56 return false;
57 }
58
59 GrContextOptions options;
60 options.fPreferExternalImagesOverES3 = true;
61 options.fDisableDistanceFieldPaths = true;
62 #if defined(USE_CANVASKIT0310_SKIA)
63 sk_sp<GrDirectContext> grContext(GrDirectContext::MakeGL(std::move(glInterface), options));
64 if (grContext == nullptr) {
65 LOGE("SetUpGrContext grContext is null");
66 return false;
67 }
68 #else
69 options.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
70 sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
71 if (grContext == nullptr) {
72 LOGE("SetUpGrContext grContext is null");
73 return false;
74 }
75 #endif
76 grContext_ = std::move(grContext);
77 LOGI("SetUpGrContext done");
78 return true;
79 }
80
MakeCurrent()81 void GLESRenderBackend::MakeCurrent()
82 {
83 if (eglManager_ == nullptr) {
84 LOGE("eglManager_ is nullptr, can not MakeCurrent");
85 return;
86 }
87 eglManager_->MakeCurrent();
88 }
89
SwapBuffers()90 void GLESRenderBackend::SwapBuffers()
91 {
92 if (eglManager_ == nullptr) {
93 LOGE("eglManager_ is nullptr, can not SwapBuffers");
94 return;
95 }
96 eglManager_->SwapBuffers();
97 }
98
CreateSurface(void * window)99 void* GLESRenderBackend::CreateSurface(void* window)
100 {
101 if (eglManager_ == nullptr) {
102 LOGE("eglManager_ is nullptr, can not CreateSurface");
103 return nullptr;
104 }
105 return static_cast<void*>(eglManager_->CreateSurface((EGLNativeWindowType)window));
106 }
107
SetDamageRegion(int32_t left,int32_t top,int32_t width,int32_t height)108 void GLESRenderBackend::SetDamageRegion(int32_t left, int32_t top, int32_t width, int32_t height)
109 {
110 if (eglManager_ == nullptr) {
111 LOGE("eglManager_ is nullptr, can not SetDamageRegion");
112 return;
113 }
114 eglManager_->SetDamageRegion(left, top, width, height);
115 }
116
Destroy()117 void GLESRenderBackend::Destroy()
118 {
119 grContext_ = nullptr;
120 skSurface_ = nullptr;
121 }
122
RenderFrame()123 void GLESRenderBackend::RenderFrame()
124 {
125 // flush commands
126 if (skSurface_->getCanvas() != nullptr) {
127 LOGD("RenderFrame: Canvas is %{public}p", skSurface_->getCanvas());
128 skSurface_->getCanvas()->flush();
129 } else {
130 LOGW("canvas is nullptr!!!");
131 }
132 }
133
AcquireCanvas(std::unique_ptr<SurfaceFrame> & frame)134 SkCanvas* GLESRenderBackend::AcquireCanvas(std::unique_ptr<SurfaceFrame>& frame)
135 {
136 if (!SetUpGrContext()) {
137 LOGE("GrContext is not ready!!!");
138 return nullptr;
139 }
140
141 SurfaceFrameOhosGl* framePtr = static_cast<SurfaceFrameOhosGl*>(frame.get());
142
143 if (GetGrContext() == nullptr) {
144 LOGE("GrContext is not ready!!!");
145 return nullptr;
146 }
147
148 GrGLFramebufferInfo framebufferInfo;
149 framebufferInfo.fFBOID = 0;
150 framebufferInfo.fFormat = GL_RGBA8;
151
152 SkColorType colorType = kRGBA_8888_SkColorType;
153
154 int32_t width = framePtr->GetWidth();
155 int32_t height = framePtr->GetHeight();
156 const int stencilBufferSize = 8;
157
158 GrBackendRenderTarget backendRenderTarget(width, height, 0, stencilBufferSize, framebufferInfo);
159 #if defined(USE_CANVASKIT0310_SKIA)
160 SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
161 #else
162 SkSurfaceProps surfaceProps = SkSurfaceProps::kLegacyFontHost_InitType;
163 #endif
164 skSurface_ = SkSurface::MakeFromBackendRenderTarget(
165 GetGrContext(), backendRenderTarget, kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &surfaceProps);
166 if (skSurface_ == nullptr) {
167 LOGW("skSurface is nullptr");
168 return nullptr;
169 }
170
171 LOGI("CreateCanvas successfully!!! (%{public}p)", skSurface_->getCanvas());
172
173 return skSurface_->getCanvas();
174 }
175 }
176 }