• 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 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