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 }
SetUpDrawingContext()49 bool DrawingContext::SetUpDrawingContext()
50 {
51 #if defined(RS_ENABLE_GL)
52 if (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) {
53 return false;
54 }
55 if (gpuContext_ != nullptr) {
56 LOGD("gpuContext_ has already initialized");
57 return true;
58 }
59
60 auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
61 auto size = glesVersion ? strlen(glesVersion) : 0;
62 bool isUni = false;
63 auto &cache = ShaderCache::Instance();
64 #if defined(RS_ENABLE_UNI_RENDER)
65 isUni = true;
66 cache.SetFilePath(UNIRENDER_CACHE_DIR);
67 #endif
68 cache.InitShaderCache(glesVersion, size, isUni);
69
70 Drawing::GPUContextOptions options;
71 options.SetPersistentCache(&cache);
72 auto gpuContext = std::make_shared<Drawing::GPUContext>();
73 if (!gpuContext->BuildFromGL(options)) {
74 LOGE("Failed to create gpuContext, gpuContext is nullptr");
75 return false;
76 }
77 gpuContext_ = std::move(gpuContext);
78 return true;
79 #else
80 return false;
81 #endif
82 }
83
GetDrawingContext() const84 GPUContext* DrawingContext::GetDrawingContext() const
85 {
86 return gpuContext_.get();
87 }
88
AcquireSurfaceInGLES(const std::shared_ptr<RSRenderSurfaceFrame> & frame)89 sk_sp<SkSurface> DrawingContext::AcquireSurfaceInGLES(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
90 {
91 #if defined(NEW_SKIA)
92 GrDirectContext* grContext = GetDrawingContext();
93 #else
94 GrContext* grContext = GetDrawingContext();
95 #endif
96 GrGLFramebufferInfo framebufferInfo;
97 framebufferInfo.fFBOID = 0;
98 framebufferInfo.fFormat = GL_RGBA8;
99
100 SkColorType colorType = kRGBA_8888_SkColorType;
101
102 std::shared_ptr<FrameConfig> frameConfig = frame->frameConfig;
103 if (frameConfig == nullptr) {
104 LOGE("Failed to acquire surface in gles, frameConfig is nullptr");
105 return nullptr;
106 }
107 GrBackendRenderTarget backendRenderTarget(frameConfig->width, frameConfig->height, 0, STENCIL_BUFFER_SIZE,
108 framebufferInfo);
109 #if defined(NEW_SKIA)
110 SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
111 #else
112 SkSurfaceProps surfaceProps = SkSurfaceProps::kLegacyFontHost_InitType;
113 #endif
114
115 sk_sp<SkColorSpace> skColorSpace = GetSkColorSpace(frame);
116 RSTagTracker tagTracker(grContext, RSTagTracker::TAGTYPE::TAG_ACQUIRE_SURFACE);
117 sk_sp<SkSurface> skSurface = SkSurface::MakeFromBackendRenderTarget(
118 grContext, backendRenderTarget, kBottomLeft_GrSurfaceOrigin, colorType,
119 skColorSpace, &surfaceProps);
120 if (skSurface == nullptr) {
121 LOGE("Failed to acquire surface in gles, skSurface is nullptr");
122 return nullptr;
123 }
124 LOGD("Acquire Surface In GLES Successfully!");
125 return skSurface;
126 }
127
AcquireSurfaceInRaster(const std::shared_ptr<RSRenderSurfaceFrame> & frame)128 sk_sp<SkSurface> DrawingContext::AcquireSurfaceInRaster(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
129 {
130 std::shared_ptr<FrameConfig> frameConfig = frame->frameConfig;
131 if (frameConfig == nullptr) {
132 LOGE("Failed to acquire surface in raster, frameConfig is nullptr");
133 return nullptr;
134 }
135 sptr<SurfaceBuffer> buffer = frameConfig->buffer;
136 if ((buffer == nullptr) || (buffer->GetWidth() <= 0) || (buffer->GetHeight() <= 0)) {
137 LOGE("Failed to acquire surface in raster, buffer is invalide");
138 return nullptr;
139 }
140
141 auto addr = static_cast<uint32_t*>(buffer->GetVirAddr());
142 if (addr == nullptr) {
143 LOGE("Failed to acquire surface in raster, buffer addr is invalid");
144 return nullptr;
145 }
146 SkImageInfo info =
147 SkImageInfo::Make(buffer->GetWidth(), buffer->GetHeight(), kRGBA_8888_SkColorType, kPremul_SkAlphaType);
148 sk_sp<SkSurface> skSurface = SkSurface::MakeRasterDirect(info, addr, buffer->GetStride());
149 LOGD("Acquire Surface In Raster Successfully!");
150 return skSurface;
151 }
152
AcquireSurfaceInVulkan(const std::shared_ptr<RSRenderSurfaceFrame> & frame)153 sk_sp<SkSurface> DrawingContext::AcquireSurfaceInVulkan(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
154 {
155 #ifdef RS_ENABLE_VK
156 if (!RSSystemProperties::IsUseVulkan()) {
157 return nullptr;
158 }
159 VulkanState* vulkanState = frame->vulkanState;
160 if (vulkanState == nullptr) {
161 LOGE("Failed to acquire surface in vulkan, vulkanState is nullptr");
162 return nullptr;
163 }
164 std::shared_ptr<vulkan::VulkanWindow> vulkanWindow = vulkanState->vulkanWindow;
165 if (vulkanWindow == nullptr) {
166 LOGE("Failed to acquire surface in vulkan, vulkanWindow is nullptr");
167 return nullptr;
168 }
169 LOGD("Acquire Surface In Vulkan Successfully!");
170 return vulkanWindow->AcquireSurface();
171 #else
172 return nullptr;
173 #endif
174 }
175
GetSkColorSpace(const std::shared_ptr<RSRenderSurfaceFrame> & frame)176 sk_sp<SkColorSpace> DrawingContext::GetSkColorSpace(const std::shared_ptr<RSRenderSurfaceFrame>& frame)
177 {
178 sk_sp<SkColorSpace> skColorSpace = nullptr;
179 std::shared_ptr<FrameConfig> frameConfig = frame->frameConfig;
180 if (frameConfig == nullptr) {
181 LOGE("Failed to get sk color space, frameConfig is nullptr");
182 return nullptr;
183 }
184
185 GraphicColorGamut colorSpace = frameConfig->colorSpace;
186 switch (colorSpace) {
187 // [planning] in order to stay consistant with the colorspace used before, we disabled
188 // GRAPHIC_COLOR_GAMUT_SRGB to let the branch to default, then skColorSpace is set to nullptr
189 case GRAPHIC_COLOR_GAMUT_DISPLAY_P3:
190 #if defined(NEW_SKIA)
191 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3);
192 #else
193 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
194 #endif
195 break;
196 case GRAPHIC_COLOR_GAMUT_ADOBE_RGB:
197 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB);
198 break;
199 case GRAPHIC_COLOR_GAMUT_BT2020:
200 skColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kRec2020);
201 break;
202 default:
203 break;
204 }
205 return skColorSpace;
206 }
207 }
208 }