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
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
74 grContext_ = std::move(grContext);
75 LOGI("SetUpGrContext done");
76 return true;
77 }
78
SetUpDrContext()79 bool GLESRenderBackend::SetUpDrContext()
80 {
81 if (drGPUContext_ != nullptr) {
82 LOGD("Drawing GPUContext has already created!!");
83 return true;
84 }
85
86 Drawing::GPUContextOptions options;
87
88 auto drGPUContext = std::make_shared<Drawing::GPUContext>();
89 if (!drGPUContext->BuildFromGL(options)) {
90 LOGE("SetUpGrContext drGPUContext is null");
91 return false;
92 }
93 drGPUContext_ = std::move(drGPUContext);
94 return true;
95 }
96
MakeCurrent()97 void GLESRenderBackend::MakeCurrent()
98 {
99 if (eglManager_ == nullptr) {
100 LOGE("eglManager_ is nullptr, can not MakeCurrent");
101 return;
102 }
103 eglManager_->MakeCurrent();
104 }
105
SwapBuffers()106 void GLESRenderBackend::SwapBuffers()
107 {
108 if (eglManager_ == nullptr) {
109 LOGE("eglManager_ is nullptr, can not SwapBuffers");
110 return;
111 }
112 eglManager_->SwapBuffers();
113 }
114
CreateSurface(void * window)115 void* GLESRenderBackend::CreateSurface(void* window)
116 {
117 if (eglManager_ == nullptr) {
118 LOGE("eglManager_ is nullptr, can not CreateSurface");
119 return nullptr;
120 }
121 return static_cast<void*>(eglManager_->CreateSurface((EGLNativeWindowType)window));
122 }
123
SetDamageRegion(int32_t left,int32_t top,int32_t width,int32_t height)124 void GLESRenderBackend::SetDamageRegion(int32_t left, int32_t top, int32_t width, int32_t height)
125 {
126 if (eglManager_ == nullptr) {
127 LOGE("eglManager_ is nullptr, can not SetDamageRegion");
128 return;
129 }
130 eglManager_->SetDamageRegion(left, top, width, height);
131 }
132
Destroy()133 void GLESRenderBackend::Destroy()
134 {
135 grContext_ = nullptr;
136 skSurface_ = nullptr;
137 }
138
RenderFrame()139 void GLESRenderBackend::RenderFrame()
140 {
141 // flush commands
142 if (pSkSurface_->getCanvas() != nullptr) {
143 LOGD("RenderFrame: Canvas");
144 std::cout << "GLESRenderBackend::RenderFrame flushing" << std::endl;
145 pSkSurface_->getCanvas()->flush();
146 } else {
147 LOGW("canvas is nullptr!!!");
148 }
149 }
150
AcquireSkCanvas(std::unique_ptr<SurfaceFrame> & frame)151 SkCanvas* GLESRenderBackend::AcquireSkCanvas(std::unique_ptr<SurfaceFrame>& frame)
152 {
153 if (!SetUpGrContext()) {
154 LOGE("GrContext is not ready!!!");
155 return nullptr;
156 }
157
158 SurfaceFrameOhosGl* framePtr = static_cast<SurfaceFrameOhosGl*>(frame.get());
159
160 if (GetGrContext() == nullptr) {
161 LOGE("GrContext is not ready!!!");
162 return nullptr;
163 }
164
165 GrGLFramebufferInfo framebufferInfo;
166 framebufferInfo.fFBOID = 0;
167 framebufferInfo.fFormat = GL_RGBA8;
168
169 SkColorType colorType = kRGBA_8888_SkColorType;
170
171 int32_t width = framePtr->GetWidth();
172 int32_t height = framePtr->GetHeight();
173 const int stencilBufferSize = 8;
174
175 GrBackendRenderTarget backendRenderTarget(width, height, 0, stencilBufferSize, framebufferInfo);
176 SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
177 skSurface_ = SkSurface::MakeFromBackendRenderTarget(
178 GetGrContext(), backendRenderTarget, kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &surfaceProps);
179 if (skSurface_ == nullptr) {
180 LOGW("skSurface is nullptr");
181 return nullptr;
182 }
183 pSkSurface_ = skSurface_.get();
184 LOGI("CreateCanvas successfully!!!");
185
186 return skSurface_->getCanvas();
187 }
188
AcquireDrCanvas(std::unique_ptr<SurfaceFrame> & frame)189 Drawing::Canvas* GLESRenderBackend::AcquireDrCanvas(std::unique_ptr<SurfaceFrame>& frame)
190 {
191 if (!SetUpDrContext()) {
192 LOGE("GrContext is not ready!!!");
193 return nullptr;
194 }
195
196 SurfaceFrameOhosGl* framePtr = static_cast<SurfaceFrameOhosGl*>(frame.get());
197
198 int32_t width = framePtr->GetWidth();
199 int32_t height = framePtr->GetHeight();
200
201 std::shared_ptr<Drawing::ColorSpace> colorSpace = nullptr;
202
203 colorSpace = Drawing::ColorSpace::CreateRGB(Drawing::CMSTransferFuncType::SRGB,
204 Drawing::CMSMatrixType::DCIP3);
205
206 struct Drawing::FrameBuffer bufferInfo;
207 bufferInfo.width = width;
208 bufferInfo.height = height;
209 bufferInfo.FBOID = 0;
210 bufferInfo.Format = GL_RGBA8;
211 bufferInfo.colorType = Drawing::COLORTYPE_RGBA_8888;
212 bufferInfo.gpuContext = drGPUContext_;
213 bufferInfo.colorSpace = colorSpace;
214
215 drSurface_ = std::make_shared<Drawing::Surface>();
216 if (!drSurface_->Bind(bufferInfo)) {
217 LOGW("surface_ is nullptr");
218 drSurface_ = nullptr;
219 return nullptr;
220 }
221
222 LOGD("CreateCanvas successfully!!!");
223 pSkSurface_ = drSurface_->GetImpl<Drawing::SkiaSurface>()->GetSkSurface().get();
224 return drSurface_->GetCanvas().get();
225 }
226 }
227 }