Updating beta-recording files 2

Signed-off-by: denispavlov <pavlov.denis@huawei.com>
This commit is contained in:
denispavlov 2024-05-16 16:50:04 +03:00
parent 710aac04e8
commit 126acab37e
6 changed files with 184 additions and 104 deletions

View File

@ -212,8 +212,8 @@ ohos_shared_library("librender_service") {
include_dirs += [ "$graphic_2d_ext_root/chipset_vsync/include" ] include_dirs += [ "$graphic_2d_ext_root/chipset_vsync/include" ]
} }
if (rs_enable_recording_dcl && defined(use_rosen_drawing) && if (defined(rs_enable_recording_dcl) && rs_enable_recording_dcl &&
use_rosen_drawing) { defined(use_rosen_drawing) && use_rosen_drawing) {
deps += [ deps += [
"$graphic_2d_root/rosen/samples/2d_graphics:drawing_engine_sample", "$graphic_2d_root/rosen/samples/2d_graphics:drawing_engine_sample",
"$graphic_2d_root/rosen/samples/2d_graphics:drawing_sample_replayer", "$graphic_2d_root/rosen/samples/2d_graphics:drawing_sample_replayer",

View File

@ -126,7 +126,7 @@ void RSRenderServiceConnection::MoveRenderNodeMap(
void RSRenderServiceConnection::RemoveRenderNodeMap( void RSRenderServiceConnection::RemoveRenderNodeMap(
std::shared_ptr<std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap) noexcept std::shared_ptr<std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap) noexcept
{ {
// temp solution for DongHu to resolve with dma leak // temp solution to address the dma leak
for (auto& [_, node] : *subRenderNodeMap) { for (auto& [_, node] : *subRenderNodeMap) {
auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node); auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
if (surfaceNode && surfaceNode->GetName().find("ShellAssistantAnco") != std::string::npos) { if (surfaceNode && surfaceNode->GetName().find("ShellAssistantAnco") != std::string::npos) {

View File

@ -183,7 +183,7 @@ void RSRenderNodeMap::EraseAbilityComponentNumsInProcess(NodeId id)
void RSRenderNodeMap::UnregisterRenderNode(NodeId id) void RSRenderNodeMap::UnregisterRenderNode(NodeId id)
{ {
EraseAbilityComponentNumsInProcess(id); EraseAbilityComponentNumsInProcess(id);
// temp solution for DongHu to resolve with dma leak // temp solution to address the dma leak
auto surfaceNode = surfaceNodeMap_[id]; auto surfaceNode = surfaceNodeMap_[id];
if (surfaceNode) { if (surfaceNode) {
if (surfaceNode->GetName().find("ShellAssistantAnco") == std::string::npos) { if (surfaceNode->GetName().find("ShellAssistantAnco") == std::string::npos) {

View File

@ -23,26 +23,21 @@ namespace OHOS::Rosen {
std::mutex ImageCache::mutex_; std::mutex ImageCache::mutex_;
std::map<uint64_t, Image> ImageCache::cache_; std::map<uint64_t, Image> ImageCache::cache_;
// Image
Image::Image(const uint8_t* data, size_t size, size_t skipBytes) : skipBytes(skipBytes)
{
if (data && (size > 0)) {
this->data.insert(this->data.end(), data, data + size);
}
}
Image::Image(std::vector<uint8_t>&& data, size_t skipBytes) : data(std::move(data)), skipBytes(skipBytes) {}
bool Image::IsValid() const bool Image::IsValid() const
{ {
return !data.empty() && (data.size() < maxSize); return (!data.empty()) && (data.size() < maxSize);
} }
void Image::Serialize(Archive& archive) void Image::Serialize(Archive& archive)
{ {
// cast due to backward compatibility
archive.Serialize(reinterpret_cast<uint32_t&>(skipBytes));
archive.Serialize(data); archive.Serialize(data);
archive.Serialize(parcelSkipBytes);
archive.Serialize(dmaSize);
archive.Serialize(dmaWidth);
archive.Serialize(dmaHeight);
archive.Serialize(dmaStride);
archive.Serialize(dmaFormat);
archive.Serialize(dmaUsage);
} }
// ImageCache // ImageCache

View File

@ -36,15 +36,19 @@ public:
public: public:
explicit Image() = default; explicit Image() = default;
explicit Image(const uint8_t* data, size_t size, size_t skipBytes);
explicit Image(std::vector<uint8_t> && data, size_t skipBytes);
void Serialize(Archive& archive); void Serialize(Archive& archive);
bool IsValid() const; bool IsValid() const;
public: public:
std::vector<uint8_t> data; std::vector<uint8_t> data;
size_t skipBytes = 0u; uint64_t parcelSkipBytes = 0u;
int32_t dmaWidth = 0;
int32_t dmaHeight = 0;
int32_t dmaStride = 0;
int32_t dmaFormat = 0;
uint64_t dmaUsage = 0u;
size_t dmaSize = 0u;
}; };
class RSB_EXPORT ImageCache final { class RSB_EXPORT ImageCache final {

View File

@ -28,6 +28,108 @@
namespace OHOS::Media { namespace OHOS::Media {
SurfaceBuffer* IncrementSurfaceBufferReference(sptr<SurfaceBuffer>& buffer)
{
if (auto object = buffer.GetRefPtr()) {
object->IncStrongRef(object);
return object;
}
return nullptr;
}
static bool IsDataValid(const void* data, size_t size)
{
return data && (size > 0);
}
static std::vector<uint8_t> GenerateRawCopy(const uint8_t* data, size_t size)
{
std::vector<uint8_t> out;
if (IsDataValid(data, size)) {
out.insert(out.end(), data, data + size);
}
return out;
}
static std::vector<uint8_t> GenerateMiniatureAstc(const uint8_t* data, size_t size)
{
constexpr uint32_t astcBytesPerPixel = 16u;
return GenerateRawCopy(data, astcBytesPerPixel);
}
static std::vector<uint8_t> GenerateMiniature(const uint8_t* data, size_t size, uint32_t pixelBytes)
{
if (!IsDataValid(data, size)) {
return {};
}
constexpr uint32_t rgbaBytesPerPixel = 4u;
constexpr uint32_t pixelBytesThreshold = 256u; // in case the pixelBytes field in the map has invalid value
const uint32_t bytesPerPixel =
((pixelBytes > 0) && (pixelBytes < pixelBytesThreshold)) ? pixelBytes : rgbaBytesPerPixel;
const auto pixelCount = size / bytesPerPixel;
std::vector<uint64_t> averageValue(bytesPerPixel, 0);
constexpr uint32_t sampleCount = 100u;
for (uint32_t sample = 0; sample < sampleCount; sample++) {
for (uint32_t channel = 0; channel < bytesPerPixel; channel++) {
averageValue[channel] += data[(sample * pixelCount / sampleCount) * bytesPerPixel + channel];
}
}
std::vector<uint8_t> out(bytesPerPixel, 0);
for (uint32_t i = 0; i < bytesPerPixel; i++) {
out[i] = static_cast<uint8_t>(averageValue[i] / sampleCount);
}
return out;
}
static std::vector<uint8_t> GenerateImageData(const uint8_t* data, size_t size, bool isAstc, uint32_t pixelBytes)
{
if (!Rosen::RSProfiler::IsBetaRecordEnabled()) {
return GenerateRawCopy(data, size);
}
return isAstc ? GenerateMiniatureAstc(data, size) : GenerateMiniature(data, size, pixelBytes);
}
static std::vector<uint8_t> GenerateImageData(const uint8_t* data, size_t size, PixelMap& map)
{
return GenerateImageData(data, size, map.IsAstc(), map.GetPixelBytes());
}
static bool CopyImageData(const uint8_t* srcImage, size_t srcSize, uint8_t* dstImage, size_t dstSize)
{
if (!srcImage || !dstImage || (srcSize == 0) || (dstSize == 0) || (srcSize > dstSize)) {
return false;
}
if (dstSize == srcSize) {
return Rosen::Utils::Move(dstImage, dstSize, srcImage, srcSize);
}
for (size_t offset = 0; offset < dstSize;) {
const size_t size = std::min(dstSize - offset, srcSize);
if (!Rosen::Utils::Move(dstImage + offset, size, srcImage, size)) {
return false;
}
offset += size;
}
return true;
}
static bool CopyImageData(const std::vector<uint8_t>& data, uint8_t* dstImage, size_t dstSize)
{
return CopyImageData(data.data(), data.size(), dstImage, dstSize);
}
static bool CopyImageData(const Rosen::Image* image, uint8_t* dstImage, size_t dstSize)
{
return image ? CopyImageData(image->data, dstImage, dstSize) : false;
}
struct UnmarshallingContext { struct UnmarshallingContext {
public: public:
static constexpr int headerLength = 24; // NOLINT static constexpr int headerLength = 24; // NOLINT
@ -46,7 +148,7 @@ public:
return false; return false;
} }
if (!Rosen::Utils::Move(base, size, image->data.data(), size)) { if (!CopyImageData(image, base, size)) {
delete base; delete base;
base = nullptr; base = nullptr;
return false; return false;
@ -62,31 +164,24 @@ public:
return false; return false;
} }
auto* buffer = reinterpret_cast<const BufferHandle*>(image->data.data()); sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
if (!buffer || (buffer->width == 0) || (buffer->height == 0)) { if (!surfaceBuffer) {
base = nullptr;
context = nullptr;
return false; return false;
} }
BufferRequestConfig config = {}; const BufferRequestConfig config = { .width = image->dmaWidth,
config.width = buffer->width; .height = image->dmaHeight,
config.strideAlignment = buffer->stride; .strideAlignment = image->dmaStride,
config.height = buffer->height; .format = image->dmaFormat,
config.format = buffer->format; .usage = image->dmaUsage };
config.usage = buffer->usage;
sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
surfaceBuffer->Alloc(config); surfaceBuffer->Alloc(config);
base = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr()); base = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
Rosen::Utils::Move(base, buffer->size, image->data.data() + sizeof(BufferHandle), buffer->size); if (base && CopyImageData(image, base, image->dmaSize)) {
context = IncrementSurfaceBufferReference(surfaceBuffer);
void* nativeBuffer = surfaceBuffer.GetRefPtr(); return true;
auto* ref = reinterpret_cast<OHOS::RefBase*>(nativeBuffer); }
ref->IncStrongRef(ref); return false;
context = nativeBuffer;
return true;
} }
public: public:
@ -104,23 +199,18 @@ public:
// It works ONLY thanks to the 'friend class ImageSource' in PixelMap. // It works ONLY thanks to the 'friend class ImageSource' in PixelMap.
class ImageSource { class ImageSource {
public: public:
// See PixelMap::Unmarshalling
// foundation/multimedia/image_framework/frameworks/innerkitsimpl/common/src/pixel_map.cpp
static PixelMap* Unmarshal(Parcel& parcel); static PixelMap* Unmarshal(Parcel& parcel);
static bool Marshal(Parcel& parcel, PixelMap& map); static bool Marshal(Parcel& parcel, PixelMap& map);
private: private:
static uint64_t NewImageId(); static void CacheImage(
static bool CacheImage(uint64_t id, const void* data, size_t size, size_t skipBytes); uint64_t id, const std::vector<uint8_t>& data, size_t skipBytes, BufferHandle* bufferHandle = nullptr);
static bool CacheImage(uint64_t id, std::vector<uint8_t> && data, size_t skipBytes);
static Rosen::Image* GetCachedImage(uint64_t id); static Rosen::Image* GetCachedImage(uint64_t id);
static uint8_t* MapImage(int32_t file, size_t size, int32_t flags); static uint8_t* MapImage(int32_t file, size_t size, int32_t flags);
static void UnmapImage(void* image, size_t size); static void UnmapImage(void* image, size_t size);
// See foundation/multimedia/image_framework/frameworks/innerkitsimpl/utils/include/image_utils.h
static bool IsValidFormat(const PixelFormat& format); static bool IsValidFormat(const PixelFormat& format);
static void SurfaceBufferReference(void* buffer);
static void OnClientMarshalling(PixelMap& map, uint64_t id); static void OnClientMarshalling(PixelMap& map, uint64_t id);
@ -131,21 +221,31 @@ private:
static PixelMap* FinalizeUnmarshalling(UnmarshallingContext& context); static PixelMap* FinalizeUnmarshalling(UnmarshallingContext& context);
}; };
uint64_t ImageSource::NewImageId() void ImageSource::CacheImage(
uint64_t id, const std::vector<uint8_t>& data, size_t skipBytes, BufferHandle* bufferHandle)
{ {
return Rosen::ImageCache::New(); if (data.empty()) {
} return;
}
bool ImageSource::CacheImage(uint64_t id, const void* data, size_t size, size_t skipBytes) if (bufferHandle && ((bufferHandle->width == 0) || (bufferHandle->height == 0))) {
{ return;
Rosen::Image image(reinterpret_cast<const uint8_t*>(data), size, skipBytes); }
return Rosen::ImageCache::Add(id, std::move(image));
}
bool ImageSource::CacheImage(uint64_t id, std::vector<uint8_t>&& data, size_t skipBytes) Rosen::Image image;
{ image.data = data;
Rosen::Image image(std::move(data), skipBytes);
return Rosen::ImageCache::Add(id, std::move(image)); if (bufferHandle) {
image.dmaSize = bufferHandle->size;
image.dmaWidth = bufferHandle->width;
image.dmaHeight = bufferHandle->height;
image.dmaStride = bufferHandle->stride;
image.dmaFormat = bufferHandle->format;
image.dmaUsage = bufferHandle->usage;
}
image.parcelSkipBytes = skipBytes;
Rosen::ImageCache::Add(id, std::move(image));
} }
Rosen::Image* ImageSource::GetCachedImage(uint64_t id) Rosen::Image* ImageSource::GetCachedImage(uint64_t id)
@ -161,7 +261,7 @@ uint8_t* ImageSource::MapImage(int32_t file, size_t size, int32_t flags)
void ImageSource::UnmapImage(void* image, size_t size) void ImageSource::UnmapImage(void* image, size_t size)
{ {
if (image && size > 0) { if (IsDataValid(image, size)) {
::munmap(image, size); ::munmap(image, size);
} }
} }
@ -175,14 +275,6 @@ bool ImageSource::IsValidFormat(const PixelFormat& format)
(format == PixelFormat::ASTC_6x6) || (format == PixelFormat::ASTC_8x8); (format == PixelFormat::ASTC_6x6) || (format == PixelFormat::ASTC_8x8);
} }
void ImageSource::SurfaceBufferReference(void* buffer)
{
if (buffer) {
auto object = reinterpret_cast<OHOS::RefBase*>(buffer);
object->IncStrongRef(object);
}
}
bool ImageSource::InitUnmarshalling(UnmarshallingContext& context) bool ImageSource::InitUnmarshalling(UnmarshallingContext& context)
{ {
if (!context.map) { if (!context.map) {
@ -213,8 +305,7 @@ bool ImageSource::UnmarshalFromSharedMemory(UnmarshallingContext& context, uint6
const int32_t file = const int32_t file =
Rosen::RSProfiler::IsParcelMock(context.parcel) ? invalidFile : context.map->ReadFileDescriptor(context.parcel); Rosen::RSProfiler::IsParcelMock(context.parcel) ? invalidFile : context.map->ReadFileDescriptor(context.parcel);
if (file < 0) { if (file < 0) {
auto image = GetCachedImage(id); if (auto image = GetCachedImage(id)) {
if (image && (static_cast<uint32_t>(context.size) == image->data.size())) {
if (context.GatherImageFromFile(image)) { if (context.GatherImageFromFile(image)) {
context.parcel.SkipBytes(UnmarshallingContext::headerLength); context.parcel.SkipBytes(UnmarshallingContext::headerLength);
return true; return true;
@ -232,7 +323,8 @@ bool ImageSource::UnmarshalFromSharedMemory(UnmarshallingContext& context, uint6
} }
} }
CacheImage(id, image, context.size, UnmarshallingContext::headerLength); const auto imageData = GenerateImageData(image, context.size, *context.map);
CacheImage(id, imageData, UnmarshallingContext::headerLength);
context.context = new int32_t(); context.context = new int32_t();
if (!context.context) { if (!context.context) {
@ -249,7 +341,7 @@ bool ImageSource::UnmarshalFromDMA(UnmarshallingContext& context, uint64_t id)
{ {
auto image = Rosen::RSProfiler::IsParcelMock(context.parcel) ? GetCachedImage(id) : nullptr; auto image = Rosen::RSProfiler::IsParcelMock(context.parcel) ? GetCachedImage(id) : nullptr;
if (image) { if (image) {
context.parcel.SkipBytes(image->skipBytes); context.parcel.SkipBytes(image->parcelSkipBytes);
return context.GatherDmaImageFromFile(image); return context.GatherDmaImageFromFile(image);
} }
@ -257,18 +349,12 @@ bool ImageSource::UnmarshalFromDMA(UnmarshallingContext& context, uint64_t id)
sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create(); sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
surfaceBuffer->ReadFromMessageParcel(static_cast<MessageParcel&>(context.parcel)); surfaceBuffer->ReadFromMessageParcel(static_cast<MessageParcel&>(context.parcel));
auto* virAddr = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr()); context.base = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
void* nativeBuffer = surfaceBuffer.GetRefPtr(); context.context = IncrementSurfaceBufferReference(surfaceBuffer);
SurfaceBufferReference(nativeBuffer);
context.base = virAddr;
context.context = nativeBuffer;
if (auto buffer = surfaceBuffer->GetBufferHandle()) { if (auto bufferHandle = surfaceBuffer->GetBufferHandle()) {
std::vector<uint8_t> data; const auto imageData = GenerateImageData(context.base, bufferHandle->size, *context.map);
data.resize(sizeof(BufferHandle) + buffer->size); CacheImage(id, imageData, context.parcel.GetReadPosition() - readPosition, bufferHandle);
Rosen::Utils::Move(data.data(), sizeof(BufferHandle), buffer, sizeof(BufferHandle));
Rosen::Utils::Move(data.data() + sizeof(BufferHandle), buffer->size, virAddr, buffer->size);
CacheImage(id, std::move(data), context.parcel.GetReadPosition() - readPosition);
} }
return true; return true;
@ -338,31 +424,27 @@ PixelMap* ImageSource::Unmarshal(Parcel& parcel)
void ImageSource::OnClientMarshalling(Media::PixelMap& map, uint64_t id) void ImageSource::OnClientMarshalling(Media::PixelMap& map, uint64_t id)
{ {
if (Rosen::RSMarshallingHelper::GetUseSharedMem(std::this_thread::get_id())) { if (Rosen::RSProfiler::IsSharedMemoryEnabled()) {
return;
}
const auto descriptor = map.GetFd();
if (!descriptor) {
return; return;
} }
if (map.GetAllocatorType() == AllocatorType::DMA_ALLOC) { if (map.GetAllocatorType() == AllocatorType::DMA_ALLOC) {
// DMA TEXTURE auto surfaceBuffer = reinterpret_cast<SurfaceBuffer*>(descriptor);
auto sbBuffer = static_cast<SurfaceBuffer*>(map.GetFd()); if (auto bufferHandle = surfaceBuffer->GetBufferHandle()) {
const auto imageData = GenerateImageData(
auto bufferHandle = sbBuffer->GetBufferHandle(); reinterpret_cast<const uint8_t*>(surfaceBuffer->GetVirAddr()), bufferHandle->size, map);
uint32_t imageSize = bufferHandle->size; CacheImage(id, imageData, UnmarshallingContext::headerLength, bufferHandle);
const size_t totalSize = sizeof(BufferHandle) + imageSize;
void* imagePtr = sbBuffer->GetVirAddr();
if (!imagePtr) {
return;
} }
} else {
std::vector<uint8_t> data;
data.resize(totalSize);
Rosen::Utils::Move(data.data(), sizeof(BufferHandle), bufferHandle, sizeof(BufferHandle));
Rosen::Utils::Move(data.data() + sizeof(BufferHandle), imageSize, imagePtr, imageSize);
CacheImage(id, data.data(), totalSize, UnmarshallingContext::headerLength);
} else if (auto file = static_cast<const int32_t*>(map.GetFd())) {
const size_t size = map.isAstc_ ? map.pixelsSize_ : map.rowDataSize_ * map.imageInfo_.size.height; const size_t size = map.isAstc_ ? map.pixelsSize_ : map.rowDataSize_ * map.imageInfo_.size.height;
if (auto image = MapImage(*file, size, PROT_READ)) { if (auto image = MapImage(*reinterpret_cast<const int32_t*>(map.GetFd()), size, PROT_READ)) {
CacheImage(id, image, size, UnmarshallingContext::headerLength); const auto imageData = GenerateImageData(image, size, map);
CacheImage(id, imageData, UnmarshallingContext::headerLength);
UnmapImage(image, size); UnmapImage(image, size);
} }
} }
@ -370,11 +452,10 @@ void ImageSource::OnClientMarshalling(Media::PixelMap& map, uint64_t id)
bool ImageSource::Marshal(Parcel& parcel, Media::PixelMap& map) bool ImageSource::Marshal(Parcel& parcel, Media::PixelMap& map)
{ {
const uint64_t id = NewImageId(); const uint64_t id = Rosen::ImageCache::New();
if (!parcel.WriteUint64(id) || !map.Marshalling(parcel)) { if (!parcel.WriteUint64(id) || !map.Marshalling(parcel)) {
return false; return false;
} }
OnClientMarshalling(map, id); OnClientMarshalling(map, id);
return true; return true;
} }