enable GPU rendering for separated buffers under uni_render condition

Signed-off-by: Klaus_q <wangqi175@huawei.com>
Change-Id: I1c417d150d93416e7613545c240e60fae3d73b16
This commit is contained in:
Klaus_q 2022-06-08 16:41:33 +08:00
parent 8138c800c9
commit 883e0c2d6f
13 changed files with 111 additions and 56 deletions

View File

@ -24,6 +24,7 @@
"features": [
"graphic_standard_feature_bootanimation_enable",
"graphic_standard_feature_ace_enable_gpu",
"graphic_standard_feature_rs_enable_eglimage",
"graphic_standard_feature_color_gamut_enable"
],
"rom": "10000KB",

View File

@ -15,6 +15,7 @@ declare_args() {
graphic_standard_feature_bootanimation_enable = true
graphic_standard_feature_ace_enable_gpu = true
graphic_standard_feature_color_gamut_enable = false
graphic_standard_feature_rs_enable_eglimage = false
}
if (graphic_standard_feature_ace_enable_gpu) {
@ -38,6 +39,14 @@ if (graphic_standard_feature_ace_enable_gpu) {
libgl = []
}
if (graphic_standard_feature_rs_enable_eglimage) {
gpu_defines += [ "RS_ENABLE_EGLIMAGE" ]
rs_enable_eglimage = true
} else {
gpu_defines += [ "RS_DISABLE_EGLIMAGE" ]
rs_enable_eglimage = false
}
if (graphic_standard_feature_color_gamut_enable) {
color_gamut_enable = true
} else {

View File

@ -45,7 +45,7 @@ ohos_shared_library("librender_service") {
"core/transaction/rs_render_service_stub.cpp",
]
if (rs_enable_gpu) {
if (rs_enable_eglimage) {
sources += [ "core/pipeline/rs_egl_image_manager.cpp" ]
}

View File

@ -95,7 +95,9 @@ void RSCompatibleProcessor::ProcessSurface(RSSurfaceRenderNode& node)
SkMatrix matrix;
matrix.reset();
auto params = RsRenderServiceUtil::CreateBufferDrawParam(node);
SkPaint paint;
paint.setAlphaf(node.GetGlobalAlpha());
auto params = RsRenderServiceUtil::CreateBufferDrawParam(node, SkMatrix(), ScreenRotation::ROTATION_0, paint);
RsRenderServiceUtil::DrawBuffer(*canvas_, params);
}

View File

@ -78,7 +78,9 @@ void RSHardwareProcessor::Init(ScreenId id, int32_t offsetX, int32_t offsetY)
auto mainThread = RSMainThread::Instance();
if (mainThread != nullptr) {
renderContext_ = mainThread->GetRenderContext();
#ifdef RS_ENABLE_EGLIMAGE
eglImageManager_ = mainThread->GetRSEglImageManager();
#endif // RS_ENABLE_EGLIMAGE
}
#endif // RS_ENABLE_GL
}
@ -455,13 +457,16 @@ void RSHardwareProcessor::Redraw(
layerInfo->GetCompositionType(), layerInfo->GetLayerSize().x, layerInfo->GetLayerSize().y,
layerInfo->GetLayerSize().w, layerInfo->GetLayerSize().h);
int saveCount = canvas->getSaveCount();
auto params = RsRenderServiceUtil::CreateBufferDrawParam(node, currScreenInfo_.rotationMatrix, rotation_);
SkPaint paint;
paint.setAlphaf(node.GetGlobalAlpha());
auto params = RsRenderServiceUtil::CreateBufferDrawParam(node, currScreenInfo_.rotationMatrix,
rotation_, paint);
params.targetColorGamut = static_cast<ColorGamut>(currScreenInfo_.colorGamut);
const auto& clipRect = layerInfo->GetLayerSize();
params.clipRect = SkRect::MakeXYWH(clipRect.x, clipRect.y, clipRect.w, clipRect.h);
Vector2f center(node.GetDstRect().left_ + node.GetDstRect().width_ * 0.5f,
node.GetDstRect().top_ + node.GetDstRect().height_ * 0.5f);
#ifdef RS_ENABLE_GL
#ifdef RS_ENABLE_EGLIMAGE
if (ifUseGPU) {
RsRenderServiceUtil::DrawImage(eglImageManager_, renderContext_->GetGrContext(), *canvas, params,
[this, &node, &center](RSPaintFilterCanvas& canvas, BufferDrawParam& params) -> void {
@ -487,12 +492,9 @@ void RSHardwareProcessor::Redraw(
DrawBufferPostProcess(canvas, node, params, center);
});
canvas->restoreToCount(saveCount);
#endif // RS_ENABLE_GL
#endif // RS_ENABLE_EGLIMAGE
}
rsSurface_->FlushFrame(currFrame_);
#ifdef RS_ENABLE_GL
eglImageManager_->ShrinkCachesIfNeeded();
#endif // RS_ENABLE_GL
}
void RSHardwareProcessor::OnRotate()

View File

@ -71,8 +71,11 @@ void RSMainThread::Init()
#ifdef RS_ENABLE_GL
renderContext_ = std::make_shared<RenderContext>();
renderContext_->InitializeEglContext();
eglImageManager_ = std::make_shared<RSEglImageManager>(renderContext_->GetEGLDisplay());
#endif // RS_ENABLE_GL
#ifdef RS_ENABLE_EGLIMAGE
eglImageManager_ = std::make_shared<RSEglImageManager>(renderContext_->GetEGLDisplay());
#endif // RS_ENABLE_EGLIMAGE
}
void RSMainThread::Start()
@ -179,6 +182,9 @@ void RSMainThread::Render()
}
rootNode->Prepare(visitor);
rootNode->Process(visitor);
#ifdef RS_ENABLE_EGLIMAGE
eglImageManager_->ShrinkCachesIfNeeded();
#endif // RS_ENABLE_EGLIMAGE
}
void RSMainThread::RequestNextVSync()

View File

@ -83,17 +83,19 @@ public:
PostTask([t(std::move(scheduledTask))]() { t->Run(); });
return std::move(taskFuture);
}
#ifdef RS_ENABLE_GL
std::shared_ptr<RenderContext> GetRenderContext() const
{
return renderContext_;
}
#endif // RS_ENABLE_GL
#ifdef RS_ENABLE_EGLIMAGE
std::shared_ptr<RSEglImageManager> GetRSEglImageManager() const
{
return eglImageManager_;
}
#endif // RS_ENABLE_GL
#endif // RS_ENABLE_EGLIMAGE
RSContext& GetContext()
{
@ -144,11 +146,14 @@ private:
mutable std::mutex uniRenderMutex_;
bool uniRenderFinished_ = false;
std::condition_variable uniRenderCond_;
#ifdef RS_ENABLE_GL
std::shared_ptr<RenderContext> renderContext_;
std::shared_ptr<RSEglImageManager> eglImageManager_;
#endif // RS_ENABLE_GL
#ifdef RS_ENABLE_EGLIMAGE
std::shared_ptr<RSEglImageManager> eglImageManager_;
#endif // RS_ENABLE_EGLIMAGE
};
} // namespace Rosen
} // namespace OHOS

View File

@ -60,10 +60,14 @@ protected:
#ifdef RS_ENABLE_GL
std::shared_ptr<RenderContext> renderContext_;
std::shared_ptr<RSEglImageManager> eglImageManager_;
#endif // RS_ENABLE_GL
std::unique_ptr<RSSurfaceFrame> currFrame_;
std::shared_ptr<RSSurfaceOhos> rsSurface_;
#ifdef RS_ENABLE_EGLIMAGE
std::shared_ptr<RSEglImageManager> eglImageManager_;
#endif // RS_ENABLE_EGLIMAGE
private:
int32_t releaseFence_ = -1;
bool isMirror_ = false;

View File

@ -849,26 +849,20 @@ SkMatrix RsRenderServiceUtil::GetCanvasTransform(const RSSurfaceRenderNode& node
}
BufferDrawParam RsRenderServiceUtil::CreateBufferDrawParam(RSSurfaceRenderNode& node, SkMatrix canvasMatrix,
ScreenRotation rotation)
ScreenRotation rotation, SkPaint paint)
{
const RSProperties& property = node.GetRenderProperties();
SkRect dstRect = SkRect::MakeXYWH(node.GetDstRect().left_, node.GetDstRect().top_,
node.GetDstRect().width_, node.GetDstRect().height_);
auto alpha = node.GetGlobalAlpha();
BufferDrawParam params;
auto buffer = node.GetBuffer();
sptr<Surface> surface = node.GetConsumer();
if (!buffer || !surface) {
return params;
}
SkPaint paint;
paint.setAlphaf(alpha);
params.buffer = buffer;
params.matrix = GetCanvasTransform(node, canvasMatrix, rotation, dstRect);
params.acquireFence = node.GetAcquireFence();
params.srcRect = SkRect::MakeXYWH(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
const auto surfaceTransform = surface->GetTransform();
if (surfaceTransform == TransformType::ROTATE_90 || surfaceTransform == TransformType::ROTATE_270) {
@ -953,7 +947,7 @@ void RsRenderServiceUtil::DrawBuffer(RSPaintFilterCanvas& canvas, BufferDrawPara
canvas.restore();
}
#ifdef RS_ENABLE_GL
#ifdef RS_ENABLE_EGLIMAGE
void RsRenderServiceUtil::DrawImage(std::shared_ptr<RSEglImageManager> eglImageManager, GrContext* grContext,
RSPaintFilterCanvas& canvas, BufferDrawParam& bufferDrawParam, CanvasPostProcess process)
{
@ -969,16 +963,18 @@ void RsRenderServiceUtil::DrawImage(std::shared_ptr<RSEglImageManager> eglImageM
RS_LOGE("RsRenderServiceUtil::MapEglImageFromSurfaceBuffer return invalid EGL texture ID");
return;
}
SkColorType colorType = (buffer->GetFormat() == PIXEL_FMT_BGRA_8888) ?
kBGRA_8888_SkColorType : kRGBA_8888_SkColorType;
GrGLTextureInfo grExternalTextureInfo = {GL_TEXTURE_EXTERNAL_OES, eglTextureId, GL_RGBA8};
GrBackendTexture backendTexture(bufferDrawParam.srcRect.width(), bufferDrawParam.srcRect.height(),
GrMipMapped::kNo, grExternalTextureInfo);
image = SkImage::MakeFromTexture(grContext, backendTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, nullptr);
SetPropertiesForCanvas(canvas, bufferDrawParam, process);
canvas.drawImageRect(image, bufferDrawParam.srcRect, bufferDrawParam.dstRect, &(bufferDrawParam.paint));
canvas.restore();
}
#endif // RS_ENABLE_GL
#endif // RS_ENABLE_EGLIMAGE
void RsRenderServiceUtil::InitEnableClient()
{

View File

@ -71,13 +71,13 @@ public:
static void DrawBuffer(RSPaintFilterCanvas& canvas, BufferDrawParam& bufferDrawParam,
CanvasPostProcess process = nullptr);
#ifdef RS_ENABLE_GL
#ifdef RS_ENABLE_EGLIMAGE
static void DrawImage(std::shared_ptr<RSEglImageManager> eglImageManager, GrContext* grContext,
RSPaintFilterCanvas& canvas, BufferDrawParam& bufferDrawParam, CanvasPostProcess process);
#endif // RS_ENABLE_GL
RSPaintFilterCanvas& canvas, BufferDrawParam& bufferDrawParam, CanvasPostProcess process = nullptr);
#endif // RS_ENABLE_EGLIMAGE
static BufferDrawParam CreateBufferDrawParam(RSSurfaceRenderNode& node, SkMatrix canvasMatrix = SkMatrix(),
ScreenRotation rotation = ScreenRotation::ROTATION_0);
ScreenRotation rotation = ScreenRotation::ROTATION_0, SkPaint paint = SkPaint());
static void DealAnimation(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node, BufferDrawParam& params,
const Vector2f& center);
static void InitEnableClient();

View File

@ -112,12 +112,15 @@ bool RSSoftwareProcessor::GenerateParamAndDrawBuffer(RSSurfaceRenderNode& node)
node.SetDstRect({geoPtr->GetAbsRect().left_ - offsetX_, geoPtr->GetAbsRect().top_ - offsetY_,
geoPtr->GetAbsRect().width_, geoPtr->GetAbsRect().height_});
BufferDrawParam params;
SkPaint paint;
paint.setAlphaf(node.GetGlobalAlpha());
if (GetMirror()) {
RS_LOGI("RSSoftwareProcessor::ProcessSurface mirrorScreen is not support rotation");
params = RsRenderServiceUtil::CreateBufferDrawParam(node);
params = RsRenderServiceUtil::CreateBufferDrawParam(node, SkMatrix(), ScreenRotation::ROTATION_0, paint);
} else {
params = RsRenderServiceUtil::CreateBufferDrawParam(node, currScreenInfo_.rotationMatrix, rotation_);
params = RsRenderServiceUtil::CreateBufferDrawParam(node, currScreenInfo_.rotationMatrix, rotation_, paint);
}
RsRenderServiceUtil::DrawBuffer(*canvas_, params);
return true;
}

View File

@ -250,8 +250,13 @@ void RSUniRenderVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
RS_LOGI("RSUniRenderVisitor::ProcessSurfaceRenderNode buffer is not available, set black");
canvas_->clear(SK_ColorBLACK);
} else {
#ifdef RS_ENABLE_EGLIMAGE
RS_LOGI("RSUniRenderVisitor::ProcessSurfaceRenderNode draw image on canvas");
DrawImageOnCanvas(node);
#else
RS_LOGI("RSUniRenderVisitor::ProcessSurfaceRenderNode draw buffer on canvas");
DrawBufferOnCanvas(node);
#endif // RS_ENABLE_EGLIMAGE
}
canvas_->restore();
RS_TRACE_END();
@ -333,32 +338,13 @@ void RSUniRenderVisitor::DrawBufferOnCanvas(RSSurfaceRenderNode& node)
if (!canvas_) {
RS_LOGE("RSUniRenderVisitor::DrawBufferOnCanvas canvas is nullptr");
}
bool bitmapCreated = false;
SkBitmap bitmap;
std::vector<uint8_t> newTmpBuffer;
auto buffer = node.GetBuffer();
if (buffer->GetFormat() == PIXEL_FMT_YCRCB_420_SP || buffer->GetFormat() == PIXEL_FMT_YCBCR_420_SP) {
bitmapCreated = RsRenderServiceUtil::CreateYuvToRGBABitMap(buffer, newTmpBuffer, bitmap);
} else {
SkColorType colorType = (buffer->GetFormat() == PIXEL_FMT_BGRA_8888) ?
kBGRA_8888_SkColorType : kRGBA_8888_SkColorType;
SkImageInfo imageInfo = SkImageInfo::Make(buffer->GetWidth(), buffer->GetHeight(),
colorType, kPremul_SkAlphaType);
auto pixmap = SkPixmap(imageInfo, buffer->GetVirAddr(), buffer->GetStride());
bitmapCreated = bitmap.installPixels(pixmap);
}
if (!bitmapCreated) {
RS_LOGE("RSUniRenderVisitor::DrawBufferOnCanvas installPixels failed");
return;
}
SkPaint paint;
paint.setAntiAlias(true);
paint.setAlphaf(node.GetContextAlpha() * node.GetRenderProperties().GetAlpha());
canvas_->save();
const RSProperties& property = node.GetRenderProperties();
auto params = RsRenderServiceUtil::CreateBufferDrawParam(node, SkMatrix(), ScreenRotation::ROTATION_0, paint);
auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetBackgroundFilter());
if (filter != nullptr) {
auto skRectPtr = std::make_unique<SkRect>();
@ -367,12 +353,50 @@ void RSUniRenderVisitor::DrawBufferOnCanvas(RSSurfaceRenderNode& node)
node.GetRenderProperties().GetBoundsWidth(), node.GetRenderProperties().GetBoundsHeight());
RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr);
}
canvas_->drawBitmapRect(bitmap,
SkRect::MakeXYWH(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight()),
SkRect::MakeXYWH(node.GetRenderProperties().GetBoundsPositionX(),
node.GetRenderProperties().GetBoundsPositionY(),
node.GetRenderProperties().GetBoundsWidth(), node.GetRenderProperties().GetBoundsHeight()), &paint);
canvas_->restore();
RsRenderServiceUtil::DrawBuffer(*canvas_, params);
}
#ifdef RS_ENABLE_EGLIMAGE
void RSUniRenderVisitor::DrawImageOnCanvas(RSSurfaceRenderNode& node)
{
if (!canvas_) {
RS_LOGE("RSUniRenderVisitor::DrawImageOnCanvas canvas is nullptr");
}
auto buffer = node.GetBuffer();
SkPaint paint;
paint.setAntiAlias(true);
paint.setAlphaf(node.GetContextAlpha() * node.GetRenderProperties().GetAlpha());
canvas_->save();
const RSProperties& property = node.GetRenderProperties();
auto params = RsRenderServiceUtil::CreateBufferDrawParam(node, SkMatrix(), ScreenRotation::ROTATION_0, paint);
auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetBackgroundFilter());
if (filter != nullptr) {
auto skRectPtr = std::make_unique<SkRect>();
skRectPtr->setXYWH(node.GetRenderProperties().GetBoundsPositionX(),
node.GetRenderProperties().GetBoundsPositionY(),
node.GetRenderProperties().GetBoundsWidth(), node.GetRenderProperties().GetBoundsHeight());
RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr);
}
if (buffer->GetFormat() == PIXEL_FMT_YCRCB_420_SP || buffer->GetFormat() == PIXEL_FMT_YCBCR_420_SP) {
RsRenderServiceUtil::DrawBuffer(*canvas_, params);
} else {
auto mainThread = RSMainThread::Instance();
std::shared_ptr<RenderContext> renderContext;
std::shared_ptr<RSEglImageManager> eglImageManager;
if (mainThread != nullptr) {
renderContext = mainThread->GetRenderContext();
eglImageManager = mainThread->GetRSEglImageManager();
}
RsRenderServiceUtil::DrawImage(eglImageManager, renderContext->GetGrContext(), *canvas_, params, nullptr);
auto consumerSurface = node.GetConsumer();
GSError error = consumerSurface->RegisterDeleteBufferListener([eglImageManager_ = eglImageManager]
(int32_t bufferId) {eglImageManager_->UnMapEglImageFromSurfaceBuffer(bufferId);
});
if (error != GSERROR_OK) {
RS_LOGE("RSUniRenderVisitor::DrawImageOnCanvas: fail to register UnMapEglImage callback.");
}
}
}
#endif // RS_ENABLE_EGLIMAGE
} // namespace Rosen
} // namespace OHOS

View File

@ -45,6 +45,9 @@ public:
private:
void DrawBufferOnCanvas(RSSurfaceRenderNode& node);
#ifdef RS_ENABLE_EGLIMAGE
void DrawImageOnCanvas(RSSurfaceRenderNode& node);
#endif // RS_ENABLE_EGLIMAGE
static bool IsChildOfDisplayNode(RSBaseRenderNode& node);
static bool IsChildOfSurfaceNode(RSBaseRenderNode& node);
static bool IsChildOfLeashNode(RSBaseRenderNode& node);