From 0e850596170037e044bede92e5f15ab7b049a30a Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 24 Apr 2023 17:36:56 +0800 Subject: [PATCH] add surfaceBufferOp Signed-off-by: jason Change-Id: I3ae798d8c715cdd45c89af4a0327ebae708bf773 --- rosen/modules/render_service_base/BUILD.gn | 5 + .../include/pipeline/rs_draw_cmd.h | 34 ++++++ .../include/pipeline/rs_recording_canvas.h | 21 +++- .../src/pipeline/rs_draw_cmd.cpp | 104 +++++++++++++++++- .../src/pipeline/rs_draw_cmd_list.cpp | 3 + .../src/pipeline/rs_recording_canvas.cpp | 8 ++ 6 files changed, 173 insertions(+), 2 deletions(-) diff --git a/rosen/modules/render_service_base/BUILD.gn b/rosen/modules/render_service_base/BUILD.gn index 526b25734a..f1e08e4369 100644 --- a/rosen/modules/render_service_base/BUILD.gn +++ b/rosen/modules/render_service_base/BUILD.gn @@ -176,6 +176,10 @@ ohos_source_set("render_service_base_src") { if (rs_enable_gpu) { sources += [ "src/common/rs_shared_context.cpp" ] + defines += [ + "GL_GLEXT_PROTOTYPES", + "EGL_EGLEXT_PROTOTYPES", + ] } if (current_os == "mingw" || current_os == "mac" || current_os == "linux") { @@ -183,6 +187,7 @@ ohos_source_set("render_service_base_src") { } include_dirs = [ + "$graphic_2d_root/frameworks/surface/include", "//foundation/graphic/graphic_2d/rosen/modules/render_service_base/src", "//foundation/graphic/graphic_2d/utils/log", ] diff --git a/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h b/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h index f2f5590da6..f14bd9cec6 100644 --- a/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h +++ b/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h @@ -16,6 +16,12 @@ #ifndef RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_DRAW_CMD_H #define RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_DRAW_CMD_H +#include + +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "GLES2/gl2.h" +#include "GLES2/gl2ext.h" #include "include/core/SkCanvas.h" #include "include/core/SkDrawable.h" #include "include/core/SkImage.h" @@ -32,9 +38,14 @@ #endif #include "pixel_map.h" #include "src/core/SkDrawShadowInfo.h" +#ifdef ROSEN_OHOS +#include "surface_buffer.h" +#include "window.h" +#endif #include "common/rs_common_def.h" #include "pipeline/rs_draw_cmd_list.h" +#include "pipeline/rs_recording_canvas.h" #include "property/rs_properties_def.h" #include "render/rs_image.h" #include "transaction/rs_marshalling_helper.h" @@ -86,6 +97,7 @@ enum RSOpType : uint16_t { MULTIPLY_ALPHA_OPITEM, SAVE_ALPHA_OPITEM, RESTORE_ALPHA_OPITEM, + SURFACEBUFFER_OPITEM, }; class OpItem : public MemObject, public Parcelable { @@ -941,6 +953,28 @@ public: [[nodiscard]] static OpItem* Unmarshalling(Parcel& parcel); }; +#ifdef ROSEN_OHOS +class SurfaceBufferOpItem : public OpItemWithPaint { +public: + SurfaceBufferOpItem(const RSSurfaceBufferInfo& surfaceBufferInfo); + ~SurfaceBufferOpItem() override; + void Draw(RSPaintFilterCanvas& canvas, const SkRect*) const override; + + RSOpType GetType() const override + { + return RSOpType::SURFACEBUFFER_OPITEM; + } + + bool Marshalling(Parcel& parcel) const override; + static OpItem* Unmarshalling(Parcel& parcel); + +private: + RSSurfaceBufferInfo surfaceBufferInfo_; + mutable EGLImageKHR eglImage_ = EGL_NO_IMAGE_KHR; + mutable GLuint texId_ = 0; + mutable OHNativeWindowBuffer* nativeWindowBuffer_ = nullptr; +}; +#endif } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/include/pipeline/rs_recording_canvas.h b/rosen/modules/render_service_base/include/pipeline/rs_recording_canvas.h index f0a0c1708c..b22558535a 100644 --- a/rosen/modules/render_service_base/include/pipeline/rs_recording_canvas.h +++ b/rosen/modules/render_service_base/include/pipeline/rs_recording_canvas.h @@ -31,6 +31,9 @@ #ifdef NEW_SKIA #include "src/core/SkVerticesPriv.h" #endif +#ifdef ROSEN_OHOS +#include "surface_buffer.h" +#endif namespace OHOS { namespace Media { @@ -39,6 +42,20 @@ class PixelMap; namespace Rosen { class DrawCmdList; class OpItem; +#ifdef ROSEN_OHOS +struct RSSurfaceBufferInfo { + RSSurfaceBufferInfo() = default; + RSSurfaceBufferInfo( + const sptr& surfaceBuffer, int offSetX, int offSetY, int width, int height) + : surfaceBuffer_(surfaceBuffer), offSetX_(offSetX), offSetY_(offSetY), width_(width), height_(height) + {} + sptr surfaceBuffer_ = nullptr; + int offSetX_ = 0; + int offSetY_ = 0; + int width_ = 0; + int height_ = 0; +}; +#endif class RSB_EXPORT RSRecordingCanvas : public SkCanvasVirtualEnforcer { public: RSRecordingCanvas(int width, int height); @@ -165,7 +182,9 @@ public: const Rosen::RsImageInfo& rsImageInfo, const SkPaint& paint); void DrawPixelMapWithParm( const std::shared_ptr& pixelmap, const Rosen::RsImageInfo& rsImageInfo, const SkPaint& paint); - +#ifdef ROSEN_OHOS + void DrawSurfaceBuffer(const RSSurfaceBufferInfo& surfaceBufferInfo); +#endif void MultiplyAlpha(float alpha); void SaveAlpha(); void RestoreAlpha(); diff --git a/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd.cpp b/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd.cpp index 5047f3255a..e827ff77a1 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd.cpp @@ -14,7 +14,11 @@ */ #include "pipeline/rs_draw_cmd.h" - +#ifdef ROSEN_OHOS +#include "buffer_utils.h" +#endif +#include "include/gpu/GrContext.h" +#include "message_parcel.h" #include "rs_trace.h" #include "securec.h" @@ -787,6 +791,72 @@ void RestoreAlphaOpItem::Draw(RSPaintFilterCanvas& canvas, const SkRect*) const canvas.RestoreAlpha(); } +#ifdef ROSEN_OHOS +SurfaceBufferOpItem::SurfaceBufferOpItem(const RSSurfaceBufferInfo& surfaceBufferInfo) + : OpItemWithPaint(sizeof(SurfaceBufferOpItem)), surfaceBufferInfo_(surfaceBufferInfo) +{} + +SurfaceBufferOpItem::~SurfaceBufferOpItem() +{ + if (eglImage_ != EGL_NO_IMAGE_KHR) { + auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglDestroyImageKHR(disp, eglImage_); + } + if (nativeWindowBuffer_ != nullptr) { + DestroyNativeWindowBuffer(nativeWindowBuffer_); + } + if (texId_ != 0U) { + glDeleteTextures(1, &texId_); + } +} + +void SurfaceBufferOpItem::Draw(RSPaintFilterCanvas& canvas, const SkRect*) const +{ + if (surfaceBufferInfo_.surfaceBuffer_ == nullptr) { + ROSEN_LOGE("SurfaceBufferOpItem::Draw surfaceBuffer_ is nullptr"); + return; + } + nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(surfaceBufferInfo_.surfaceBuffer_); + if (!nativeWindowBuffer_) { + ROSEN_LOGE("SurfaceBufferOpItem::Draw create native window buffer fail"); + return; + } + EGLint attrs[] = { + EGL_IMAGE_PRESERVED, + EGL_TRUE, + EGL_NONE, + }; + + auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglImage_ = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer_, attrs); + if (eglImage_ == EGL_NO_IMAGE_KHR) { + ROSEN_LOGE("%s create egl image fail %d", __func__, eglGetError()); + return; + } + + // Create texture object + texId_ = 0; + glGenTextures(1, &texId_); + glBindTexture(GL_TEXTURE_2D, texId_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast(eglImage_)); + glBindTexture(GL_TEXTURE_2D, 0); + + GrGLTextureInfo textureInfo = { GL_TEXTURE_2D, texId_, GL_RGBA8_OES }; + + GrBackendTexture backendTexture( + surfaceBufferInfo_.width_, surfaceBufferInfo_.height_, GrMipMapped::kNo, textureInfo); + + auto skImage = SkImage::MakeFromTexture(canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin, + kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()); + + canvas.drawImage(skImage, surfaceBufferInfo_.offSetX_, surfaceBufferInfo_.offSetY_); +} +#endif + // RectOpItem bool RectOpItem::Marshalling(Parcel& parcel) const { @@ -1795,5 +1865,37 @@ OpItem* RestoreAlphaOpItem::Unmarshalling(Parcel& parcel) { return new RestoreAlphaOpItem(); } + +// SurfaceBufferOpItem +#ifdef ROSEN_OHOS +bool SurfaceBufferOpItem::Marshalling(Parcel& parcel) const +{ + MessageParcel* parcelSurfaceBuffer = static_cast(&parcel); + WriteSurfaceBufferImpl( + *parcelSurfaceBuffer, surfaceBufferInfo_.surfaceBuffer_->GetSeqNum(), surfaceBufferInfo_.surfaceBuffer_); + bool success = RSMarshallingHelper::Marshalling(parcel, surfaceBufferInfo_.offSetX_) && + RSMarshallingHelper::Marshalling(parcel, surfaceBufferInfo_.offSetY_) && + RSMarshallingHelper::Marshalling(parcel, surfaceBufferInfo_.width_) && + RSMarshallingHelper::Marshalling(parcel, surfaceBufferInfo_.height_); + return success; +} + +OpItem* SurfaceBufferOpItem::Unmarshalling(Parcel& parcel) +{ + RSSurfaceBufferInfo surfaceBufferInfo; + MessageParcel *parcelSurfaceBuffer = static_cast(&parcel); + uint32_t sequence = 1U; + ReadSurfaceBufferImpl(*parcelSurfaceBuffer, sequence, surfaceBufferInfo.surfaceBuffer_); + bool success = RSMarshallingHelper::Unmarshalling(parcel, surfaceBufferInfo.offSetX_) && + RSMarshallingHelper::Unmarshalling(parcel, surfaceBufferInfo.offSetY_) && + RSMarshallingHelper::Unmarshalling(parcel, surfaceBufferInfo.width_) && + RSMarshallingHelper::Unmarshalling(parcel, surfaceBufferInfo.height_); + if (!success) { + ROSEN_LOGE("SurfaceBufferOptItem::Unmarshalling failed"); + return nullptr; + } + return new SurfaceBufferOpItem(surfaceBufferInfo); +} +#endif } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd_list.cpp b/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd_list.cpp index 83cb8bbd73..af89dc4164 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd_list.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_draw_cmd_list.cpp @@ -68,6 +68,9 @@ static std::unordered_map opUnmarshallingFuncLUT { MULTIPLY_ALPHA_OPITEM, MultiplyAlphaOpItem::Unmarshalling }, { SAVE_ALPHA_OPITEM, SaveAlphaOpItem::Unmarshalling }, { RESTORE_ALPHA_OPITEM, RestoreAlphaOpItem::Unmarshalling }, +#ifdef ROSEN_OHOS + { SURFACEBUFFER_OPITEM, SurfaceBufferOpItem::Unmarshalling }, +#endif }; #ifdef ROSEN_OHOS diff --git a/rosen/modules/render_service_base/src/pipeline/rs_recording_canvas.cpp b/rosen/modules/render_service_base/src/pipeline/rs_recording_canvas.cpp index a49cf32b25..8f6cb97585 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_recording_canvas.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_recording_canvas.cpp @@ -400,6 +400,14 @@ void RSRecordingCanvas::DrawPixelMapWithParm( AddOp(std::move(op)); } +#ifdef ROSEN_OHOS +void RSRecordingCanvas::DrawSurfaceBuffer(const RSSurfaceBufferInfo& surfaceBufferInfo) +{ + std::unique_ptr op = std::make_unique(surfaceBufferInfo); + AddOp(std::move(op)); +} +#endif + void RSRecordingCanvas::onDrawBehind(const SkPaint& paint) { // [PLANNING]: To be implemented -- Gitee