1 /*
2 * Copyright (c) 2023 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 "drawing_context.h"
17
18 #include "GLES3/gl32.h"
19
20 #include "include/core/SkCanvas.h"
21 #include "include/core/SkColorSpace.h"
22 #include "include/core/SkImageInfo.h"
23 #include "include/core/SkSurface.h"
24 #include "include/gpu/GrBackendSurface.h"
25 #include "include/gpu/gl/GrGLInterface.h"
26
27 #include "render_context/shader_cache.h"
28 #include "utils/log.h"
29 #include "render_context_base.h"
30
31 namespace OHOS {
32 namespace Rosen {
33 const int STENCIL_BUFFER_SIZE = 8;
34 const std::string UNIRENDER_CACHE_DIR = "/data/service/el0/render_service";
AcquireSurface(const std::shared_ptr<RSRenderSurfaceFrame> & frame)35 sk_sp<SkSurface> DrawingContext::AcquireSurface(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
36 {
37 if (frame == nullptr) {
38 LOGE("Failed to acquire Surface, frame is nullptr");
39 return nullptr;
40 }
41 if (renderType_ == RenderType::GLES) {
42 return AcquireSurfaceInGLES(frame);
43 } else if (renderType_ == RenderType::RASTER) {
44 return AcquireSurfaceInRaster(frame);
45 } else {
46 return AcquireSurfaceInVulkan(frame);
47 }
48 }
49
SetUpDrawingContext()50 bool DrawingContext::SetUpDrawingContext()
51 {
52 #if defined(RS_ENABLE_GL)
53 if (grContext_ != nullptr) {
54 LOGD("grContext has already initialized");
55 return true;
56 }
57
58 sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
59 if (glInterface.get() == nullptr) {
60 LOGE("SetUpDrawingContext failed to make native interface");
61 return false;
62 }
63
64 GrContextOptions options;
65 options.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
66 options.fPreferExternalImagesOverES3 = true;
67 options.fDisableDistanceFieldPaths = true;
68 options.fAllowPathMaskCaching = true;
69 auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
70 auto size = glesVersion ? strlen(glesVersion) : 0;
71 bool isUni = false;
72 auto &cache = ShaderCache::Instance();
73 #if defined(RS_ENABLE_UNI_RENDER)
74 isUni = true;
75 cache.SetFilePath(UNIRENDER_CACHE_DIR);
76 #endif
77 cache.InitShaderCache(glesVersion, size, isUni);
78 options.fPersistentCache = &cache;
79
80 #if defined(NEW_SKIA)
81 sk_sp<GrDirectContext> grContext(GrDirectContext::MakeGL(std::move(glInterface), options));
82 #else
83 sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
84 #endif
85 if (grContext == nullptr) {
86 LOGE("Failed to create grContext, grContext is nullptr");
87 return false;
88 }
89 grContext_ = std::move(grContext);
90 return true;
91 #else
92 return false;
93 #endif
94 }
95
96 #if defined(NEW_SKIA)
GetDrawingContext() const97 GrDirectContext* DrawingContext::GetDrawingContext() const
98 {
99 return grContext_.get();
100 }
101 #else
GetDrawingContext() const102 GrContext* DrawingContext::GetDrawingContext() const
103 {
104 return grContext_.get();
105 }
106 #endif
107
AcquireSurfaceInGLES(const std::shared_ptr<RSRenderSurfaceFrame> & frame)108 sk_sp<SkSurface> DrawingContext::AcquireSurfaceInGLES(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
109 {
110 #if defined(NEW_SKIA)
111 GrDirectContext* grContext = GetDrawingContext();
112 #else
113 GrContext* grContext = GetDrawingContext();
114 #endif
115 GrGLFramebufferInfo framebufferInfo;
116 framebufferInfo.fFBOID = 0;
117 framebufferInfo.fFormat = GL_RGBA8;
118
119 SkColorType colorType = kRGBA_8888_SkColorType;
120
121 std::shared_ptr<FrameConfig> frameConfig = frame->frameConfig;
122 if (frameConfig == nullptr) {
123 LOGE("Failed to acquire surface in gles, frameConfig is nullptr");
124 return nullptr;
125 }
126 GrBackendRenderTarget backendRenderTarget(frameConfig->width, frameConfig->height, 0, STENCIL_BUFFER_SIZE,
127 framebufferInfo);
128 #if defined(NEW_SKIA)
129 SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
130 #else
131 SkSurfaceProps surfaceProps = SkSurfaceProps::kLegacyFontHost_InitType;
132 #endif
133
134 sk_sp<SkColorSpace> skColorSpace = GetSkColorSpace(frame);
135 #if !defined(NEW_SKIA)
136 RSTagTracker tagTracker(grContext, RSTagTracker::TAGTYPE::TAG_ACQUIRE_SURFACE);
137 #endif
138 sk_sp<SkSurface> skSurface = SkSurface::MakeFromBackendRenderTarget(
139 grContext, backendRenderTarget, kBottomLeft_GrSurfaceOrigin, colorType,
140 skColorSpace, &surfaceProps);
141 if (skSurface == nullptr) {
142 LOGE("Failed to acquire surface in gles, skSurface is nullptr");
143 return nullptr;
144 }
145 LOGD("Acquire Surface In GLES Successfully!");
146 return skSurface;
147 }
148
AcquireSurfaceInRaster(const std::shared_ptr<RSRenderSurfaceFrame> & frame)149 sk_sp<SkSurface> DrawingContext::AcquireSurfaceInRaster(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
150 {
151 std::shared_ptr<FrameConfig> frameConfig = frame->frameConfig;
152 if (frameConfig == nullptr) {
153 LOGE("Failed to acquire surface in raster, frameConfig is nullptr");
154 return nullptr;
155 }
156 sptr<SurfaceBuffer> buffer = frameConfig->buffer;
157 if ((buffer == nullptr) || (buffer->GetWidth() <= 0) || (buffer->GetHeight() <= 0)) {
158 LOGE("Failed to acquire surface in raster, buffer is invalide");
159 return nullptr;
160 }
161
162 auto addr = static_cast<uint32_t*>(buffer->GetVirAddr());
163 if (addr == nullptr) {
164 LOGE("Failed to acquire surface in raster, buffer addr is invalid");
165 return nullptr;
166 }
167 SkImageInfo info =
168 SkImageInfo::Make(buffer->GetWidth(), buffer->GetHeight(), kRGBA_8888_SkColorType, kPremul_SkAlphaType);
169 sk_sp<SkSurface> skSurface = SkSurface::MakeRasterDirect(info, addr, buffer->GetStride());
170 LOGD("Acquire Surface In Raster Successfully!");
171 return skSurface;
172 }
173
AcquireSurfaceInVulkan(const std::shared_ptr<RSRenderSurfaceFrame> & frame)174 sk_sp<SkSurface> DrawingContext::AcquireSurfaceInVulkan(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
175 {
176 #ifdef RS_ENABLE_VK
177 VulkanState* vulkanState = frame->vulkanState;
178 if (vulkanState == nullptr) {
179 LOGE("Failed to acquire surface in vulkan, vulkanState is nullptr");
180 return nullptr;
181 }
182 std::shared_ptr<vulkan::VulkanWindow> vulkanWindow = vulkanState->vulkanWindow;
183 if (vulkanWindow == nullptr) {
184 LOGE("Failed to acquire surface in vulkan, vulkanWindow is nullptr");
185 return nullptr;
186 }
187 LOGD("Acquire Surface In Vulkan Successfully!");
188 return vulkanWindow->AcquireSurface();
189 #else
190 return nullptr;
191 #endif
192 }
193
GetSkColorSpace(const std::shared_ptr<RSRenderSurfaceFrame> & frame)194 sk_sp<SkColorSpace> DrawingContext::GetSkColorSpace(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
195 {
196 sk_sp<SkColorSpace> skColorSpace = nullptr;
197 std::shared_ptr<FrameConfig> frameConfig = frame->frameConfig;
198 if (frameConfig == nullptr) {
199 LOGE("Failed to get sk color space, frameConfig is nullptr");
200 return nullptr;
201 }
202
203 GraphicColorGamut colorSpace = frameConfig->colorSpace;
204 switch (colorSpace) {
205 // [planning] in order to stay consistant with the colorspace used before, we disabled
206 // GRAPHIC_COLOR_GAMUT_SRGB to let the branch to default, then skColorSpace is set to nullptr
207 case GRAPHIC_COLOR_GAMUT_DISPLAY_P3:
208 #if defined(NEW_SKIA)
209 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3);
210 #else
211 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
212 #endif
213 break;
214 case GRAPHIC_COLOR_GAMUT_ADOBE_RGB:
215 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB);
216 break;
217 case GRAPHIC_COLOR_GAMUT_BT2020:
218 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kRec2020);
219 break;
220 default:
221 break;
222 }
223 return skColorSpace;
224 }
225 }
226 }