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