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 }