• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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