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 "skia_adapter/skia_surface.h"
21 #include "surface_ohos_gl.h"
22 #include "iostream"
23
24 namespace OHOS {
25 namespace Rosen {
GLESRenderBackend()26 GLESRenderBackend::GLESRenderBackend() noexcept
27 {
28 eglManager_ = new EGLManager();
29 }
30
~GLESRenderBackend()31 GLESRenderBackend::~GLESRenderBackend()
32 {
33 if (eglManager_) {
34 delete eglManager_;
35 eglManager_ = nullptr;
36 }
37 }
38
InitDrawContext()39 void GLESRenderBackend::InitDrawContext()
40 {
41 if (eglManager_ == nullptr) {
42 LOGE("eglManager_ is nullptr, can not InitDrawContext");
43 return;
44 }
45 eglManager_->Init();
46 }
47
SetUpGrContext()48 bool GLESRenderBackend::SetUpGrContext()
49 {
50 if (grContext_ != nullptr) {
51 LOGD("grContext has already created!!");
52 return true;
53 }
54
55 sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
56 if (glInterface.get() == nullptr) {
57 LOGE("SetUpGrContext failed to make native interface");
58 return false;
59 }
60
61 GrContextOptions options;
62 options.fPreferExternalImagesOverES3 = true;
63 options.fDisableDistanceFieldPaths = true;
64 options.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
65 // fix svg antialiasing bug
66 options.fGpuPathRenderers &= ~GpuPathRenderers::kAtlas;
67 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
68 sk_sp<GrDirectContext> grContext(GrDirectContext::MakeGL(std::move(glInterface), options));
69 if (grContext == nullptr) {
70 LOGE("SetUpGrContext grContext is null");
71 return false;
72 }
73 #else
74 sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
75 if (grContext == nullptr) {
76 LOGE("SetUpGrContext grContext is null");
77 return false;
78 }
79 #endif
80 grContext_ = std::move(grContext);
81 LOGI("SetUpGrContext done");
82 return true;
83 }
84
SetUpDrContext()85 bool GLESRenderBackend::SetUpDrContext()
86 {
87 if (drGPUContext_ != nullptr) {
88 LOGD("Drawing GPUContext has already created!!");
89 return true;
90 }
91
92 Drawing::GPUContextOptions options;
93
94 auto drGPUContext = std::make_shared<Drawing::GPUContext>();
95 if (!drGPUContext->BuildFromGL(options)) {
96 LOGE("SetUpGrContext drGPUContext is null");
97 return false;
98 }
99 drGPUContext_ = std::move(drGPUContext);
100 return true;
101 }
102
MakeCurrent()103 void GLESRenderBackend::MakeCurrent()
104 {
105 if (eglManager_ == nullptr) {
106 LOGE("eglManager_ is nullptr, can not MakeCurrent");
107 return;
108 }
109 eglManager_->MakeCurrent();
110 }
111
SwapBuffers()112 void GLESRenderBackend::SwapBuffers()
113 {
114 if (eglManager_ == nullptr) {
115 LOGE("eglManager_ is nullptr, can not SwapBuffers");
116 return;
117 }
118 eglManager_->SwapBuffers();
119 }
120
CreateSurface(void * window)121 void* GLESRenderBackend::CreateSurface(void* window)
122 {
123 if (eglManager_ == nullptr) {
124 LOGE("eglManager_ is nullptr, can not CreateSurface");
125 return nullptr;
126 }
127 return static_cast<void*>(eglManager_->CreateSurface((EGLNativeWindowType)window));
128 }
129
SetDamageRegion(int32_t left,int32_t top,int32_t width,int32_t height)130 void GLESRenderBackend::SetDamageRegion(int32_t left, int32_t top, int32_t width, int32_t height)
131 {
132 if (eglManager_ == nullptr) {
133 LOGE("eglManager_ is nullptr, can not SetDamageRegion");
134 return;
135 }
136 eglManager_->SetDamageRegion(left, top, width, height);
137 }
138
Destroy()139 void GLESRenderBackend::Destroy()
140 {
141 grContext_ = nullptr;
142 skSurface_ = nullptr;
143 }
144
RenderFrame()145 void GLESRenderBackend::RenderFrame()
146 {
147 // flush commands
148 if (pSkSurface_->getCanvas() != nullptr) {
149 LOGD("RenderFrame: Canvas");
150 std::cout << "GLESRenderBackend::RenderFrame flushing" << std::endl;
151 pSkSurface_->getCanvas()->flush();
152 } else {
153 LOGW("canvas is nullptr!!!");
154 }
155 }
156
AcquireSkCanvas(std::unique_ptr<SurfaceFrame> & frame)157 SkCanvas* GLESRenderBackend::AcquireSkCanvas(std::unique_ptr<SurfaceFrame>& frame)
158 {
159 if (!SetUpGrContext()) {
160 LOGE("GrContext is not ready!!!");
161 return nullptr;
162 }
163
164 SurfaceFrameOhosGl* framePtr = static_cast<SurfaceFrameOhosGl*>(frame.get());
165
166 if (GetGrContext() == nullptr) {
167 LOGE("GrContext is not ready!!!");
168 return nullptr;
169 }
170
171 GrGLFramebufferInfo framebufferInfo;
172 framebufferInfo.fFBOID = 0;
173 framebufferInfo.fFormat = GL_RGBA8;
174
175 SkColorType colorType = kRGBA_8888_SkColorType;
176
177 int32_t width = framePtr->GetWidth();
178 int32_t height = framePtr->GetHeight();
179 const int stencilBufferSize = 8;
180
181 GrBackendRenderTarget backendRenderTarget(width, height, 0, stencilBufferSize, framebufferInfo);
182 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
183 SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
184 #else
185 SkSurfaceProps surfaceProps = SkSurfaceProps::kLegacyFontHost_InitType;
186 #endif
187 skSurface_ = SkSurface::MakeFromBackendRenderTarget(
188 GetGrContext(), backendRenderTarget, kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &surfaceProps);
189 if (skSurface_ == nullptr) {
190 LOGW("skSurface is nullptr");
191 return nullptr;
192 }
193 pSkSurface_ = skSurface_.get();
194 LOGI("CreateCanvas successfully!!!");
195
196 return skSurface_->getCanvas();
197 }
198
AcquireDrCanvas(std::unique_ptr<SurfaceFrame> & frame)199 Drawing::Canvas* GLESRenderBackend::AcquireDrCanvas(std::unique_ptr<SurfaceFrame>& frame)
200 {
201 if (!SetUpDrContext()) {
202 LOGE("GrContext is not ready!!!");
203 return nullptr;
204 }
205
206 SurfaceFrameOhosGl* framePtr = static_cast<SurfaceFrameOhosGl*>(frame.get());
207
208 int32_t width = framePtr->GetWidth();
209 int32_t height = framePtr->GetHeight();
210
211 std::shared_ptr<Drawing::ColorSpace> colorSpace = nullptr;
212
213 colorSpace = Drawing::ColorSpace::CreateRGB(Drawing::CMSTransferFuncType::SRGB,
214 Drawing::CMSMatrixType::DCIP3);
215
216 struct Drawing::FrameBuffer bufferInfo;
217 bufferInfo.width = width;
218 bufferInfo.height = height;
219 bufferInfo.FBOID = 0;
220 bufferInfo.Format = GL_RGBA8;
221 bufferInfo.colorType = Drawing::COLORTYPE_RGBA_8888;
222 bufferInfo.gpuContext = drGPUContext_;
223 bufferInfo.colorSpace = colorSpace;
224
225 drSurface_ = std::make_shared<Drawing::Surface>();
226 if (!drSurface_->Bind(bufferInfo)) {
227 LOGW("surface_ is nullptr");
228 drSurface_ = nullptr;
229 return nullptr;
230 }
231
232 LOGD("CreateCanvas successfully!!!");
233 pSkSurface_ = drSurface_->GetImpl<Drawing::SkiaSurface>()->GetSkSurface().get();
234 return drSurface_->GetCanvas().get();
235 }
236 }
237 }