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 "rs_base_render_engine.h"
17 #include <memory>
18 #include "rs_divided_render_util.h"
19 #include "common/rs_optional_trace.h"
20 #include "pipeline/rs_uni_render_judgement.h"
21 #include "platform/common/rs_log.h"
22 #include "platform/common/rs_system_properties.h"
23 #if defined(NEW_RENDER_CONTEXT)
24 #include "render_context_factory.h"
25 #include "rs_surface_factory.h"
26 #include "ohos/rs_render_surface_ohos.h"
27 #else
28 #include "platform/ohos/backend/rs_surface_ohos_gl.h"
29 #include "platform/ohos/backend/rs_surface_ohos_raster.h"
30 #ifdef RS_ENABLE_VK
31 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
32 #endif
33 #endif
34 #include "render/rs_skia_filter.h"
35
36 namespace OHOS {
37 namespace Rosen {
RSBaseRenderEngine()38 RSBaseRenderEngine::RSBaseRenderEngine()
39 {
40 }
41
~RSBaseRenderEngine()42 RSBaseRenderEngine::~RSBaseRenderEngine() noexcept
43 {
44 }
45
Init()46 void RSBaseRenderEngine::Init()
47 {
48 #if defined(NEW_RENDER_CONTEXT)
49 RenderType renderType = RenderType::GLES;
50 #if defined(RS_ENABLE_GL)
51 renderType = RenderType::GLES;
52 #elif defined(RS_ENABLE_VK)
53 renderType = RenderType::VULKAN;
54 #else
55 renderType = RenderType::RASTER;
56 #endif
57 renderContext_ = RenderContextBaseFactory::CreateRenderContext(renderType);
58 renderContext_->Init();
59 drawingContext_ = std::make_shared<Rosen::DrawingContext>(renderContext_->GetRenderType());
60 drawingContext_->SetUpDrawingContext();
61 #else
62 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
63 renderContext_ = std::make_shared<RenderContext>();
64 renderContext_->InitializeEglContext();
65 if (RSUniRenderJudgement::IsUniRender()) {
66 RS_LOGI("RSRenderEngine::RSRenderEngine set new cacheDir");
67 renderContext_->SetUniRenderMode(true);
68 }
69 #ifndef USE_ROSEN_DRAWING
70 renderContext_->SetUpGrContext();
71 #else
72 renderContext_->SetUpGpuContext();
73 #endif // USE_ROSEN_DRAWING
74 #endif // RS_ENABLE_GL || RS_ENABLE_VK
75 #endif
76 #if defined(RS_ENABLE_EGLIMAGE)
77 #if defined(NEW_RENDER_CONTEXT)
78 std::shared_ptr<RSRenderSurfaceFrame> frame = renderContext_->GetRSRenderSurfaceFrame();
79 eglImageManager_ = std::make_shared<RSEglImageManager>(frame->eglState->eglDisplay);
80 #else
81 eglImageManager_ = std::make_shared<RSEglImageManager>(renderContext_->GetEGLDisplay());
82 #endif
83 #endif // RS_ENABLE_EGLIMAGE
84 }
85
NeedForceCPU(const std::vector<LayerInfoPtr> & layers)86 bool RSBaseRenderEngine::NeedForceCPU(const std::vector<LayerInfoPtr>& layers)
87 {
88 bool forceCPU = false;
89 for (const auto& layer: layers) {
90 if (layer == nullptr) {
91 continue;
92 }
93
94 auto buffer = layer->GetBuffer();
95 if (buffer == nullptr) {
96 continue;
97 }
98
99 #ifndef RS_ENABLE_EGLIMAGE
100 const auto bufferFormat = buffer->GetFormat();
101 if (bufferFormat == GRAPHIC_PIXEL_FMT_YCRCB_420_SP || bufferFormat == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
102 forceCPU = true;
103 break;
104 }
105 #endif
106
107 GraphicColorGamut srcGamut = static_cast<GraphicColorGamut>(buffer->GetSurfaceBufferColorGamut());
108 GraphicColorGamut dstGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
109 if (srcGamut != dstGamut) {
110 forceCPU = true;
111 break;
112 }
113 }
114
115 return forceCPU;
116 }
117
118 #ifndef USE_ROSEN_DRAWING
CreateEglImageFromBuffer(RSPaintFilterCanvas & canvas,const sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & acquireFence,const uint32_t threadIndex)119 sk_sp<SkImage> RSBaseRenderEngine::CreateEglImageFromBuffer(RSPaintFilterCanvas& canvas,
120 const sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& acquireFence, const uint32_t threadIndex)
121 #else
122 std::shared_ptr<Drawing::Image> RSBaseRenderEngine::CreateEglImageFromBuffer(RSPaintFilterCanvas& canvas,
123 const sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& acquireFence, const uint32_t threadIndex)
124 #endif
125 {
126 #ifdef RS_ENABLE_EGLIMAGE
127 if (!RSBaseRenderUtil::IsBufferValid(buffer)) {
128 RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer invalid param!");
129 return nullptr;
130 }
131 #ifndef USE_ROSEN_DRAWING
132 #ifdef NEW_SKIA
133 if (canvas.recordingContext() == nullptr) {
134 #else
135 if (canvas.getGrContext() == nullptr) {
136 #endif
137 #else
138 if (canvas.GetGPUContext() == nullptr) {
139 #endif
140 RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer GrContext is null!");
141 return nullptr;
142 }
143 auto eglTextureId = eglImageManager_->MapEglImageFromSurfaceBuffer(buffer, acquireFence, threadIndex);
144 if (eglTextureId == 0) {
145 RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer MapEglImageFromSurfaceBuffer return invalid texture ID");
146 return nullptr;
147 }
148 #ifndef USE_ROSEN_DRAWING
149 SkColorType colorType = (buffer->GetFormat() == GRAPHIC_PIXEL_FMT_BGRA_8888) ?
150 kBGRA_8888_SkColorType : kRGBA_8888_SkColorType;
151 GrGLTextureInfo grExternalTextureInfo = { GL_TEXTURE_EXTERNAL_OES, eglTextureId, GL_RGBA8 };
152 GrBackendTexture backendTexture(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(),
153 GrMipMapped::kNo, grExternalTextureInfo);
154 #ifdef NEW_SKIA
155 return SkImage::MakeFromTexture(canvas.recordingContext(), backendTexture,
156 kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, nullptr);
157 #else
158 return SkImage::MakeFromTexture(canvas.getGrContext(), backendTexture,
159 kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, nullptr);
160 #endif
161 #else
162 Drawing::ColorType colorType = (buffer->GetFormat() == GRAPHIC_PIXEL_FMT_BGRA_8888) ?
163 Drawing::ColorType::COLORTYPE_BGRA_8888 : Drawing::ColorType::COLORTYPE_RGBA_8888;
164 Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
165
166 Drawing::TextureInfo externalTextureInfo;
167 externalTextureInfo.SetWidth(buffer->GetSurfaceBufferWidth());
168 externalTextureInfo.SetHeight(buffer->GetSurfaceBufferHeight());
169 externalTextureInfo.SetIsMipMapped(false);
170 externalTextureInfo.SetTarget(GL_TEXTURE_EXTERNAL_OES);
171 externalTextureInfo.SetID(eglTextureId);
172 externalTextureInfo.SetFormat(GL_RGBA8);
173
174 auto image = std::make_shared<Drawing::Image>();
175 if (!image->BuildFromTexture(*canvas.GetGPUContext(), externalTextureInfo,
176 Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, nullptr)) {
177 RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer image BuildFromTexture failed");
178 return nullptr;
179 }
180 return image;
181 #endif
182 #else
183 return nullptr;
184 #endif // RS_ENABLE_EGLIMAGE
185 }
186
187 #ifdef NEW_RENDER_CONTEXT
188 std::unique_ptr<RSRenderFrame> RSBaseRenderEngine::RequestFrame(
189 const std::shared_ptr<RSRenderSurfaceOhos>& rsSurface,
190 const BufferRequestConfig& config, bool forceCPU, bool useAFBC)
191 #else
192 std::unique_ptr<RSRenderFrame> RSBaseRenderEngine::RequestFrame(const std::shared_ptr<RSSurfaceOhos>& rsSurface,
193 const BufferRequestConfig& config, bool forceCPU, bool useAFBC)
194 #endif
195 {
196 if (rsSurface == nullptr) {
197 RS_LOGE("RSBaseRenderEngine::RequestFrame: surface is null!");
198 return nullptr;
199 }
200 RS_OPTIONAL_TRACE_BEGIN("RSBaseRenderEngine::RequestFrame(RSSurface)");
201 rsSurface->SetSurfacePixelFormat(config.format);
202
203 auto bufferUsage = config.usage;
204 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
205 if (forceCPU) {
206 bufferUsage |= BUFFER_USAGE_CPU_WRITE;
207 }
208 #else // (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
209 bufferUsage |= BUFFER_USAGE_CPU_WRITE;
210 #endif // (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
211 rsSurface->SetSurfaceBufferUsage(bufferUsage);
212
213 // check if we can use GPU context
214 #if defined(NEW_RENDER_CONTEXT)
215 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
216 if (forceCPU) {
217 std::shared_ptr<RenderContextBase> renderContextRaster = RenderContextBaseFactory::CreateRenderContext(
218 RenderType::RASTER);
219 renderContextRaster->Init();
220 std::shared_ptr<DrawingContext> drawingContextRaster = std::make_shared<DrawingContext>(RenderType::RASTER);
221 rsSurface->SetRenderContext(renderContextRaster);
222 rsSurface->SetDrawingContext(drawingContextRaster);
223 RS_LOGD("RSBaseRenderEngine::RequestFrame force CPU");
224 } else {
225 if (renderContext_ != nullptr) {
226 rsSurface->SetRenderContext(renderContext_);
227 }
228 if (drawingContext_ != nullptr) {
229 rsSurface->SetDrawingContext(drawingContext_);
230 }
231 }
232 #endif
233 #else
234 #ifdef RS_ENABLE_GL
235 if (renderContext_ != nullptr) {
236 rsSurface->SetRenderContext(renderContext_.get());
237 }
238 #endif
239 #endif
240 auto surfaceFrame = rsSurface->RequestFrame(config.width, config.height, 0, useAFBC);
241 RS_OPTIONAL_TRACE_END();
242 if (surfaceFrame == nullptr) {
243 RS_LOGE("RSBaseRenderEngine::RequestFrame: request SurfaceFrame failed!");
244 return nullptr;
245 }
246 #ifdef NEW_RENDER_CONTEXT
247 return std::make_unique<RSRenderFrame>(rsSurface);
248 #else
249 return std::make_unique<RSRenderFrame>(rsSurface, std::move(surfaceFrame));
250 #endif
251 }
252
253 std::unique_ptr<RSRenderFrame> RSBaseRenderEngine::RequestFrame(const sptr<Surface>& targetSurface,
254 const BufferRequestConfig& config, bool forceCPU, bool useAFBC)
255 {
256 RS_OPTIONAL_TRACE_BEGIN("RSBaseRenderEngine::RequestFrame(targetSurface)");
257 if (targetSurface == nullptr) {
258 RS_LOGE("RSBaseRenderEngine::RequestFrame: surface is null!");
259 RS_OPTIONAL_TRACE_END();
260 return nullptr;
261 }
262
263 auto surfaceId = targetSurface->GetUniqueId();
264 if (rsSurfaces_.count(surfaceId) == 0) {
265 #if defined(NEW_RENDER_CONTEXT)
266 std::shared_ptr<RSRenderSurface> renderSurface = RSSurfaceFactory::CreateRSSurface(PlatformName::OHOS,
267 targetSurface);
268 rsSurfaces_[surfaceId] = std::static_pointer_cast<RSRenderSurfaceOhos>(renderSurface);
269 #else
270 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
271 if (forceCPU) {
272 rsSurfaces_[surfaceId] = std::make_shared<RSSurfaceOhosRaster>(targetSurface);
273 } else {
274 rsSurfaces_[surfaceId] = std::make_shared<RSSurfaceOhosGl>(targetSurface);
275 }
276 #elif defined(RS_ENABLE_VK)
277 rsSurfaces_[surfaceId] = std::make_shared<RSSurfaceOhosVulkan>(targetSurface);
278 #else
279 rsSurfaces_[surfaceId] = std::make_shared<RSSurfaceOhosRaster>(targetSurface);
280 #endif // (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
281 #endif
282 }
283
284 RS_OPTIONAL_TRACE_END();
285 return RequestFrame(rsSurfaces_.at(surfaceId), config, forceCPU, useAFBC);
286 }
287
288 void RSBaseRenderEngine::SetUiTimeStamp(const std::unique_ptr<RSRenderFrame>& renderFrame, const uint64_t surfaceId)
289 {
290 #ifdef NEW_RENDER_CONTEXT
291 std::shared_ptr<RSRenderSurfaceOhos> surfaceOhos = nullptr;
292 #else
293 std::shared_ptr<RSSurfaceOhos> surfaceOhos = nullptr;
294 #endif
295 for (auto it = rsSurfaces_.begin(); it != rsSurfaces_.end(); ++it) {
296 if (it->first == surfaceId) {
297 surfaceOhos = it->second;
298 break;
299 }
300 }
301
302 if (surfaceOhos == nullptr) {
303 RS_LOGE("RSBaseRenderEngine::SetUiTimeStamp: surfaceOhos is null!");
304 return;
305 }
306
307 if (renderFrame == nullptr) {
308 RS_LOGE("RSBaseRenderEngine::SetUiTimeStamp: renderFrame is null!.");
309 return;
310 }
311
312 #ifdef NEW_RENDER_CONTEXT
313 surfaceOhos->SetUiTimeStamp();
314 #else
315 auto& frame = renderFrame->GetFrame();
316 surfaceOhos->SetUiTimeStamp(frame);
317 #endif
318 }
319
320 void RSBaseRenderEngine::DrawDisplayNodeWithParams(RSPaintFilterCanvas& canvas, RSDisplayRenderNode& node,
321 BufferDrawParam& params)
322 {
323 if (params.useCPU) {
324 DrawBuffer(canvas, params);
325 } else {
326 RegisterDeleteBufferListener(node.GetConsumer());
327 DrawImage(canvas, params);
328 }
329 }
330
331 void RSBaseRenderEngine::SetColorFilterMode(ColorFilterMode mode)
332 {
333 uint32_t uMode = static_cast<uint32_t>(mode);
334 uint32_t uInvertMode = static_cast<uint32_t>(ColorFilterMode::INVERT_COLOR_ENABLE_MODE);
335 uint32_t ucolorFilterMode = static_cast<uint32_t>(colorFilterMode_);
336 bool isInvertModeEnabled = ((ucolorFilterMode & uInvertMode) == uInvertMode);
337
338 switch (mode) {
339 case ColorFilterMode::INVERT_COLOR_DISABLE_MODE: {
340 if (colorFilterMode_ != ColorFilterMode::COLOR_FILTER_END) {
341 colorFilterMode_ = static_cast<ColorFilterMode>(ucolorFilterMode & ~uInvertMode);
342 }
343 break;
344 }
345 case ColorFilterMode::INVERT_COLOR_ENABLE_MODE: {
346 if (colorFilterMode_ != ColorFilterMode::COLOR_FILTER_END) {
347 colorFilterMode_ = static_cast<ColorFilterMode>(ucolorFilterMode | uInvertMode);
348 } else {
349 colorFilterMode_ = mode;
350 }
351 break;
352 }
353 case ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE:
354 case ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE:
355 case ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE: {
356 if (isInvertModeEnabled) {
357 colorFilterMode_ = static_cast<ColorFilterMode>(uMode | uInvertMode);
358 } else {
359 colorFilterMode_ = mode;
360 }
361 break;
362 }
363 case ColorFilterMode::DALTONIZATION_NORMAL_MODE: {
364 if (isInvertModeEnabled) {
365 colorFilterMode_ = ColorFilterMode::INVERT_COLOR_ENABLE_MODE;
366 } else {
367 colorFilterMode_ = ColorFilterMode::COLOR_FILTER_END;
368 }
369 break;
370 }
371
372 // INVERT_DALTONIZATION_PROTANOMALY_MODE, INVERT_DALTONIZATION_DEUTERANOMALY_MODE
373 // INVERT_DALTONIZATION_TRITANOMALY_MODE and COLOR_FILTER_END can not be set directly
374 case ColorFilterMode::INVERT_DALTONIZATION_PROTANOMALY_MODE: // fall-through
375 case ColorFilterMode::INVERT_DALTONIZATION_DEUTERANOMALY_MODE: // fall-through
376 case ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE: // fall-through
377 case ColorFilterMode::COLOR_FILTER_END: // fall-through
378 default: {
379 colorFilterMode_ = ColorFilterMode::COLOR_FILTER_END;
380 break;
381 }
382 }
383 }
384
385 void RSBaseRenderEngine::DrawBuffer(RSPaintFilterCanvas& canvas, BufferDrawParam& params)
386 {
387 RS_OPTIONAL_TRACE_BEGIN("RSBaseRenderEngine::DrawBuffer(CPU)");
388 #ifndef USE_ROSEN_DRAWING
389 SkBitmap bitmap;
390 #else
391 Drawing::Bitmap bitmap;
392 #endif
393 std::vector<uint8_t> newBuffer;
394 if (!RSBaseRenderUtil::ConvertBufferToBitmap(params.buffer, newBuffer, params.targetColorGamut, bitmap,
395 params.metaDatas)) {
396 RS_LOGE("RSDividedRenderUtil::DrawBuffer: create bitmap failed.");
397 RS_OPTIONAL_TRACE_END();
398 return;
399 }
400 #ifndef USE_ROSEN_DRAWING
401 #ifdef NEW_SKIA
402 canvas.drawImageRect(bitmap.asImage(), params.srcRect, params.dstRect,
403 SkSamplingOptions(), &(params.paint), SkCanvas::kStrict_SrcRectConstraint);
404 #else
405 canvas.drawBitmapRect(bitmap, params.srcRect, params.dstRect, &(params.paint));
406 #endif
407 #else
408 Drawing::Image drImage;
409 drImage.BuildFromBitmap(bitmap);
410 canvas.DrawImageRect(drImage, params.srcRect, params.dstRect, Drawing::SamplingOptions(),
411 Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
412 #endif
413 RS_OPTIONAL_TRACE_END();
414 }
415
416 void RSBaseRenderEngine::DrawImage(RSPaintFilterCanvas& canvas, BufferDrawParam& params)
417 {
418 RS_OPTIONAL_TRACE_BEGIN("RSBaseRenderEngine::DrawImage(GPU)");
419 auto image = CreateEglImageFromBuffer(canvas, params.buffer, params.acquireFence, params.threadIndex);
420 if (image == nullptr) {
421 RS_LOGE("RSBaseRenderEngine::DrawImage: image is nullptr!");
422 RS_OPTIONAL_TRACE_END();
423 return;
424 }
425 #ifndef USE_ROSEN_DRAWING
426 #ifdef NEW_SKIA
427 canvas.drawImageRect(image, params.srcRect, params.dstRect,
428 SkSamplingOptions(), &(params.paint), SkCanvas::kStrict_SrcRectConstraint);
429 #else
430 canvas.drawImageRect(image, params.srcRect, params.dstRect, &(params.paint));
431 #endif
432 #else
433 canvas.AttachBrush(params.paint);
434 canvas.DrawImageRect(*image.get(), params.srcRect, params.dstRect,
435 Drawing::SamplingOptions(), Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
436 canvas.DetachBrush();
437 #endif
438 RS_OPTIONAL_TRACE_END();
439 }
440
441 void RSBaseRenderEngine::RegisterDeleteBufferListener(const sptr<IConsumerSurface>& consumer, bool isForUniRedraw)
442 {
443 #ifdef RS_ENABLE_EGLIMAGE
444 auto regUnMapEglImageFunc = [this, isForUniRedraw](int32_t bufferId) {
445 if (isForUniRedraw) {
446 eglImageManager_->UnMapEglImageFromSurfaceBufferForUniRedraw(bufferId);
447 } else {
448 eglImageManager_->UnMapEglImageFromSurfaceBuffer(bufferId);
449 }
450 };
451 if (consumer == nullptr ||
452 (consumer->RegisterDeleteBufferListener(regUnMapEglImageFunc, isForUniRedraw) != GSERROR_OK)) {
453 RS_LOGE("RSBaseRenderEngine::RegisterDeleteBufferListener: failed to register UnMapEglImage callback.");
454 }
455 #endif // #ifdef RS_ENABLE_EGLIMAGE
456 }
457
458 void RSBaseRenderEngine::RegisterDeleteBufferListener(RSSurfaceHandler& handler)
459 {
460 #ifdef RS_ENABLE_EGLIMAGE
461 auto regUnMapEglImageFunc = [this](int32_t bufferId) {
462 eglImageManager_->UnMapEglImageFromSurfaceBuffer(bufferId);
463 };
464 handler.RegisterDeleteBufferListener(regUnMapEglImageFunc);
465 #endif // #ifdef RS_ENABLE_EGLIMAGE
466 }
467
468 void RSBaseRenderEngine::ShrinkCachesIfNeeded(bool isForUniRedraw)
469 {
470 #ifdef RS_ENABLE_EGLIMAGE
471 if (eglImageManager_ != nullptr) {
472 eglImageManager_->ShrinkCachesIfNeeded(isForUniRedraw);
473 }
474 #endif // RS_ENABLE_EGLIMAGE
475
476 while (rsSurfaces_.size() > MAX_RS_SURFACE_SIZE) {
477 auto it = rsSurfaces_.begin();
478 (void)rsSurfaces_.erase(it);
479 }
480 }
481
482 void RSBaseRenderEngine::UnMapRsSurface(uint64_t id)
483 {
484 rsSurfaces_.erase(id);
485 }
486 } // namespace Rosen
487 } // namespace OHOS
488