mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2024-11-24 07:30:38 +00:00
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:
parent
8138c800c9
commit
883e0c2d6f
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -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" ]
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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, ¢er](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()
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user