1 /*
2 * Copyright (c) 2025 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 "dirty_region/rs_gpu_dirty_collector.h"
17
18 #include "common/rs_optional_trace.h"
19 #include "common/rs_rect.h"
20 #include "platform/common/rs_system_properties.h"
21
22 namespace OHOS {
23 namespace Rosen {
GetInstance()24 RSGpuDirtyCollector& RSGpuDirtyCollector::GetInstance()
25 {
26 static RSGpuDirtyCollector instance;
27 return instance;
28 }
29
SetSelfDrawingGpuDirtyPidList(const std::vector<int32_t> & pidList)30 void RSGpuDirtyCollector::SetSelfDrawingGpuDirtyPidList(const std::vector<int32_t>& pidList)
31 {
32 std::lock_guard<std::mutex> lock(pidListMutex_);
33 selfDrawingGpuDirtyPidList_.clear();
34 selfDrawingGpuDirtyPidList_.insert(pidList.begin(), pidList.end());
35 }
36
IsGpuDirtyEnable(NodeId nodeId)37 bool RSGpuDirtyCollector::IsGpuDirtyEnable(NodeId nodeId)
38 {
39 std::lock_guard<std::mutex> lock(pidListMutex_);
40 int32_t pid = ExtractPid(nodeId);
41 return selfDrawingGpuDirtyPidList_.find(pid) != selfDrawingGpuDirtyPidList_.end();
42 }
43
44 #ifndef ROSEN_CROSS_PLATFORM
GetBufferSelfDrawingData(const sptr<SurfaceBuffer> & buffer)45 BufferSelfDrawingData* RSGpuDirtyCollector::GetBufferSelfDrawingData(const sptr<SurfaceBuffer> &buffer)
46 {
47 if (buffer == nullptr) {
48 return nullptr;
49 }
50 BlobDataType* data = nullptr;
51 BufferSelfDrawingData* src = nullptr;
52 std::vector<uint8_t> rec;
53 int32_t ret = buffer->GetMetadata(RSGpuDirtyCollectorConst::ATTRKEY_GPU_DIRTY_REGION, rec);
54 if (ret == GSERROR_OK && rec.size() == sizeof(BlobDataType)) {
55 data = reinterpret_cast<BlobDataType*>(rec.data());
56 src = reinterpret_cast<BufferSelfDrawingData*>(data->vaddr + data->offset);
57 }
58 return src;
59 }
60
DirtyRegionCompute(const sptr<SurfaceBuffer> & buffer,Rect & rect)61 bool RSGpuDirtyCollector::DirtyRegionCompute(const sptr<SurfaceBuffer> &buffer, Rect &rect)
62 {
63 if (!RSSystemProperties::GetSelfDrawingDirtyRegionEnabled()) {
64 return false;
65 }
66
67 if (buffer == nullptr) {
68 return false;
69 }
70 auto src = RSGpuDirtyCollector::GetBufferSelfDrawingData(buffer);
71 if (src == nullptr) {
72 return false;
73 }
74 // Determine whether current frame dirty region is valid and application enable self drawning dirty region
75 bool isSelfDrawingDirtyRegionEnable = src->curFrameDirtyEnable && src->gpuDirtyEnable;
76 if (!isSelfDrawingDirtyRegionEnable) {
77 RS_OPTIONAL_TRACE_NAME_FMT("RSGpuDirtyCollector::DirtyRegionCompute curFrameDirtyEnable:%d, gpuDirtyEnable:%d",
78 src->curFrameDirtyEnable, src->gpuDirtyEnable);
79 return false;
80 }
81 // when layer don't have dirty region, the right and bottom of Gpu Dirty Region are initialized to minimum values
82 // the left and top are initialized to maximum values, Gpu Dirty Region can't set to (0, 0, 0, 0)
83 bool isNotDirty = src->left == static_cast<uint32_t>(buffer->GetWidth()) &&
84 src->top == static_cast<uint32_t>(buffer->GetHeight()) && src->right == 0 && src->bottom == 0;
85 if (isNotDirty) {
86 rect = { 0, 0, 0, 0 };
87 return true;
88 }
89 bool isDirtyRegionInvalid = src->left < 0 || src->left > static_cast<uint32_t>(buffer->GetWidth()) ||
90 src->right < 0 || src->right > static_cast<uint32_t>(buffer->GetWidth()) || src->top < 0 ||
91 src->top > static_cast<uint32_t>(buffer->GetHeight()) || src->bottom < 0 || src->bottom >
92 static_cast<uint32_t>(buffer->GetHeight()) || src->left >= src->right || src->top >= src->bottom;
93 if (isDirtyRegionInvalid) {
94 RS_OPTIONAL_TRACE_NAME_FMT("invalidBufferSelfDrawingData:[%d, %d, %d, %d]",
95 src->left, src->top, src->right, src->bottom);
96 return false;
97 }
98 rect = { src->left, src->top, src->right - src->left, src->bottom - src->top };
99 return true;
100 }
101
SetGpuDirtyEnabled(const sptr<SurfaceBuffer> & buffer,bool gpuDirtyEnable)102 void RSGpuDirtyCollector::SetGpuDirtyEnabled(const sptr<SurfaceBuffer> &buffer, bool gpuDirtyEnable)
103 {
104 if (buffer == nullptr) {
105 return;
106 }
107 auto src = RSGpuDirtyCollector::GetBufferSelfDrawingData(buffer);
108 if (src != nullptr) {
109 src->gpuDirtyEnable = RSSystemProperties::GetGpuDirtyApsEnabled() && gpuDirtyEnable;
110 }
111 }
112 #endif
113 } // namespace Rosen
114 } // namespace OHOS
115