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 "ohos/rs_render_surface_ohos.h"
17
18 #include "include/core/SkSurface.h"
19
20 #include "utils/log.h"
21 #include "rs_trace.h"
22 #include "window.h"
23
24 #if !defined(NEW_SKIA)
25 #include "memory/rs_tag_tracker.h"
26 #endif
27
28 #include "render_backend_utils.h"
29
30 namespace OHOS {
31 namespace Rosen {
RSRenderSurfaceOhos(const sptr<Surface> & surface,const std::shared_ptr<DrawingContext> & drawingContext)32 RSRenderSurfaceOhos::RSRenderSurfaceOhos(const sptr<Surface>& surface,
33 const std::shared_ptr<DrawingContext>& drawingContext)
34 {
35 drawingContext_ = drawingContext;
36 frame_ = std::make_shared<RSRenderSurfaceFrame>();
37 std::shared_ptr<FrameConfig> frameConfig = std::make_shared<FrameConfig>();
38 std::shared_ptr<SurfaceConfig> surfaceConfig = std::make_shared<SurfaceConfig>();
39 std::shared_ptr<EGLState> eglState = std::make_shared<EGLState>();
40 surfaceConfig->producer = surface;
41 frame_->frameConfig = frameConfig;
42 frame_->surfaceConfig = surfaceConfig;
43 frame_->eglState = eglState;
44 }
45
~RSRenderSurfaceOhos()46 RSRenderSurfaceOhos::~RSRenderSurfaceOhos()
47 {
48 if (!RenderBackendUtils::IsValidFrame(frame_)) {
49 LOGE("Failed to ~RSRenderSurfaceOhos, frame_ is invalid");
50 return;
51 }
52 std::shared_ptr<SurfaceConfig> surfaceConfig = frame_->surfaceConfig;
53 if (surfaceConfig->nativeWindow != nullptr) {
54 DestoryNativeWindow(surfaceConfig->nativeWindow);
55 surfaceConfig->nativeWindow = nullptr;
56 }
57 if (renderContext_ != nullptr) {
58 renderContext_->DestroySurface(frame_);
59 }
60 frame_ = nullptr;
61 drawingContext_ = nullptr;
62 renderContext_ = nullptr;
63 }
64
IsValid() const65 bool RSRenderSurfaceOhos::IsValid() const
66 {
67 if (!RenderBackendUtils::IsValidFrame(frame_)) {
68 LOGE("Failed to check surface is valid, frame_ is invalid");
69 return false;
70 }
71 return frame_->surfaceConfig->producer != nullptr;
72 }
73
GetSurfaceOhos() const74 sptr<Surface> RSRenderSurfaceOhos::GetSurfaceOhos() const
75 {
76 if (!IsValid()) {
77 LOGE("Failed to get ohos render surface, render surface is invalid");
78 return nullptr;
79 }
80 return frame_->surfaceConfig->producer;
81 }
82
GetQueueSize() const83 uint32_t RSRenderSurfaceOhos::GetQueueSize() const
84 {
85 sptr<Surface> producer = GetSurfaceOhos();
86 if (producer == nullptr) {
87 LOGE("Failed to get queue size, render surface is invalid");
88 return 0;
89 }
90 return producer->GetQueueSize();
91 }
92
RequestFrame(int32_t width,int32_t height,uint64_t uiTimestamp,bool useAFBC)93 std::shared_ptr<RSRenderSurfaceFrame> RSRenderSurfaceOhos::RequestFrame(
94 int32_t width, int32_t height, uint64_t uiTimestamp, bool useAFBC)
95 {
96 if (renderContext_ == nullptr) {
97 LOGE("Failed to request frame, renderContext_ is nullptr");
98 return nullptr;
99 }
100 if (!RenderBackendUtils::IsValidFrame(frame_)) {
101 LOGE("Failed to request frame, frame_ is invalid");
102 return nullptr;
103 }
104 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
105 frameConfig->width = width;
106 frameConfig->height = height;
107 frameConfig->uiTimestamp = uiTimestamp;
108 frameConfig->useAFBC = useAFBC;
109 frameConfig->skSurface = nullptr;
110
111 std::shared_ptr<SurfaceConfig> surfaceConfig = frame_->surfaceConfig;
112 if (surfaceConfig->producer == nullptr) {
113 LOGE("Failed to request frame, surfaceConfig->producer is invalid");
114 return nullptr;
115 }
116 bool isSuccess = renderContext_->CreateSurface(frame_);
117 if (!isSuccess) {
118 LOGE("Failed to request frame, create surface by renderContext_ failed");
119 return nullptr;
120 }
121 LOGD("Request frame successfully, width is %{public}d, height is %{public}d", width, height);
122 return frame_;
123 }
124
FlushFrame(uint64_t uiTimestamp)125 bool RSRenderSurfaceOhos::FlushFrame(uint64_t uiTimestamp)
126 {
127 if (renderContext_ == nullptr) {
128 LOGE("Failed to flush frame, renderContext_ is nullptr");
129 return false;
130 }
131 // gles render flush
132 RenderType renderType = renderContext_->GetRenderType();
133 if (renderType == RenderType::GLES) {
134 RenderFrame();
135 }
136 renderContext_->SwapBuffers(frame_);
137 LOGD("FlushFrame successfully");
138 return true;
139 }
140
SetUiTimeStamp(uint64_t uiTimestamp)141 void RSRenderSurfaceOhos::SetUiTimeStamp(uint64_t uiTimestamp)
142 {
143 if (renderContext_ == nullptr) {
144 LOGE("Failed to set ui timestamp, renderContext_ is nullptr");
145 return;
146 }
147
148 if (!RenderBackendUtils::IsValidFrame(frame_)) {
149 LOGE("Failed to set ui timestamp, frame_ is invalid");
150 return;
151 }
152 RenderType renderType = renderContext_->GetRenderType();
153 struct timespec curTime = {0, 0};
154 clock_gettime(CLOCK_MONOTONIC, &curTime);
155 // 1000000000 is used for transfer second to nsec
156 uint64_t duration = static_cast<uint64_t>(curTime.tv_sec) * 1000000000 + static_cast<uint64_t>(curTime.tv_nsec);
157 std::shared_ptr<SurfaceConfig> surfaceConfig = frame_->surfaceConfig;
158 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
159 if (renderType == RenderType::GLES || renderType == RenderType::VULKAN) {
160 NativeWindowHandleOpt(surfaceConfig->nativeWindow, SET_UI_TIMESTAMP, duration);
161 } else {
162 if (frameConfig->buffer == nullptr) {
163 LOGE("Failed to set ui timestamp, frameConfig buffer is nullptr");
164 return;
165 }
166 if (frameConfig->buffer->GetExtraData() == nullptr) {
167 LOGE("Failed to set ui timestamp, frame_->buffer_->GetExtraData is nullptr");
168 return;
169 }
170 GSError ret = frameConfig->buffer->GetExtraData()->ExtraSet("timeStamp", static_cast<int64_t>(duration));
171 if (ret != GSERROR_OK) {
172 LOGE("Failed to set ui timestamp, frame buffer get ExtraSet failed");
173 }
174 }
175 }
176
SetDamageRegion(const std::vector<RectI> & rects)177 void RSRenderSurfaceOhos::SetDamageRegion(const std::vector<RectI>& rects)
178 {
179 if (renderContext_ == nullptr) {
180 LOGE("Failed to set damage region, renderContext_ is nullptr");
181 return;
182 }
183 if (!RenderBackendUtils::IsValidFrame(frame_)) {
184 LOGE("Failed to set damage region, frame_ is invalid");
185 return;
186 }
187 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
188 frameConfig->damageRects = rects;
189 renderContext_->DamageFrame(frame_);
190 }
191
GetBufferAge()192 int32_t RSRenderSurfaceOhos::GetBufferAge()
193 {
194 if (renderContext_ == nullptr) {
195 LOGE("Failed to set damage region, renderContext_ is nullptr");
196 return 0;
197 }
198 return renderContext_->GetBufferAge();
199 }
200
ClearBuffer()201 void RSRenderSurfaceOhos::ClearBuffer()
202 {
203 if (renderContext_ == nullptr) {
204 LOGE("Failed to clear buffer, renderContext_ is nullptr");
205 return;
206 }
207 if (!RenderBackendUtils::IsValidFrame(frame_)) {
208 LOGE("Failed to clear buffer, frame_ is invalid");
209 return;
210 }
211 std::shared_ptr<SurfaceConfig> surfaceConfig = frame_->surfaceConfig;
212 DestoryNativeWindow(surfaceConfig->nativeWindow);
213 surfaceConfig->nativeWindow = nullptr;
214 renderContext_->MakeCurrent();
215 renderContext_->DestroySurface(frame_);
216 if (!IsValid()) {
217 LOGE("Failed to clear buffer, render surface is invalid");
218 return;
219 }
220 surfaceConfig->producer->GoBackground();
221 LOGD("Clear buffer successfully");
222 }
223
GetCanvas()224 SkCanvas* RSRenderSurfaceOhos::GetCanvas()
225 {
226 sk_sp<SkSurface> skSurface = GetSurface();
227 if (skSurface == nullptr) {
228 LOGE("Failed to get canvas, skSurface is nullptr");
229 return nullptr;
230 }
231 return skSurface->getCanvas();
232 }
233
GetSurface()234 sk_sp<SkSurface> RSRenderSurfaceOhos::GetSurface()
235 {
236 if (!RenderBackendUtils::IsValidFrame(frame_)) {
237 LOGE("Failed to get surface, frame_ is invalid");
238 return nullptr;
239 }
240 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
241 if (frameConfig->skSurface == nullptr) {
242 if (drawingContext_ == nullptr) {
243 LOGE("Failed to get surface, drawingContext_ is nullptr");
244 return nullptr;
245 }
246 drawingContext_->SetUpDrawingContext();
247 frameConfig->skSurface = drawingContext_->AcquireSurface(frame_);
248 }
249 return frameConfig->skSurface;
250 }
251
GetColorSpace()252 GraphicColorGamut RSRenderSurfaceOhos::GetColorSpace()
253 {
254 if (!RenderBackendUtils::IsValidFrame(frame_)) {
255 LOGE("Failed to get color space, frame_ is invalid");
256 return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
257 }
258 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
259 return frameConfig->colorSpace;
260 }
261
SetColorSpace(GraphicColorGamut colorSpace)262 void RSRenderSurfaceOhos::SetColorSpace(GraphicColorGamut colorSpace)
263 {
264 if (!RenderBackendUtils::IsValidFrame(frame_)) {
265 LOGE("Failed to set color space, frame_ is invalid");
266 return;
267 }
268 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
269 frameConfig->colorSpace = colorSpace;
270 }
271
SetSurfaceBufferUsage(uint64_t usage)272 void RSRenderSurfaceOhos::SetSurfaceBufferUsage(uint64_t usage)
273 {
274 if (!RenderBackendUtils::IsValidFrame(frame_)) {
275 LOGE("Failed to set surface buffer usage, frame_ is invalid");
276 return;
277 }
278 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
279 frameConfig->bufferUsage = usage;
280 }
281
SetSurfacePixelFormat(uint64_t pixelFormat)282 void RSRenderSurfaceOhos::SetSurfacePixelFormat(uint64_t pixelFormat)
283 {
284 if (!RenderBackendUtils::IsValidFrame(frame_)) {
285 LOGE("Failed to set suface pixel format, frame_ is invalid");
286 return;
287 }
288 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
289 frameConfig->pixelFormat = pixelFormat;
290 }
291
SetReleaseFence(const int32_t & fence)292 void RSRenderSurfaceOhos::SetReleaseFence(const int32_t& fence)
293 {
294 if (!RenderBackendUtils::IsValidFrame(frame_)) {
295 LOGE("Failed to set release fence, frame_ is invalid");
296 return;
297 }
298 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
299 frameConfig->releaseFence = fence;
300 }
301
GetReleaseFence() const302 int32_t RSRenderSurfaceOhos::GetReleaseFence() const
303 {
304 if (!RenderBackendUtils::IsValidFrame(frame_)) {
305 LOGE("Failed to get release fence, frame_ is invalid");
306 return -1;
307 }
308 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
309 return frameConfig->releaseFence;
310 }
311
RenderFrame()312 void RSRenderSurfaceOhos::RenderFrame()
313 {
314 if (!RenderBackendUtils::IsValidFrame(frame_)) {
315 LOGE("Failed to render frame, frame_ is invalid");
316 return;
317 }
318 std::shared_ptr<FrameConfig> frameConfig = frame_->frameConfig;
319 if (frameConfig->skSurface == nullptr) {
320 LOGE("Failed to render frame, frameConfig skSurface is nullptr");
321 return;
322 }
323 RS_TRACE_FUNC();
324 if (frameConfig->skSurface->getCanvas() != nullptr) {
325 LOGD("Render frame successfully");
326 frameConfig->skSurface->getCanvas()->flush();
327 } else {
328 LOGE("Failed to render frame, canvas is nullptr");
329 }
330 }
331 }
332 }