1 /*
2 * Copyright (c) 2021-2022 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 "pipeline/rs_dirty_region_manager.h"
17
18 #include <string>
19
20 #include "common/rs_occlusion_region.h"
21 #include "rs_trace.h"
22
23 #include "platform/common/rs_log.h"
24 namespace OHOS {
25 namespace Rosen {
RSDirtyRegionManager()26 RSDirtyRegionManager::RSDirtyRegionManager()
27 {
28 dirtyHistory_.resize(HISTORY_QUEUE_MAX_SIZE);
29 advancedDirtyHistory_.resize(HISTORY_QUEUE_MAX_SIZE);
30 debugRegionEnabled_.resize(DebugRegionType::TYPE_MAX);
31 dirtyCanvasNodeInfo_.resize(DirtyRegionType::TYPE_AMOUNT);
32 dirtySurfaceNodeInfo_.resize(DirtyRegionType::TYPE_AMOUNT);
33 }
34
RSDirtyRegionManager(bool isDisplayDirtyManager)35 RSDirtyRegionManager::RSDirtyRegionManager(bool isDisplayDirtyManager)
36 {
37 dirtyHistory_.resize(HISTORY_QUEUE_MAX_SIZE);
38 advancedDirtyHistory_.resize(HISTORY_QUEUE_MAX_SIZE);
39 debugRegionEnabled_.resize(DebugRegionType::TYPE_MAX);
40 dirtyCanvasNodeInfo_.resize(DirtyRegionType::TYPE_AMOUNT);
41 dirtySurfaceNodeInfo_.resize(DirtyRegionType::TYPE_AMOUNT);
42 isDisplayDirtyManager_ = isDisplayDirtyManager;
43 }
44
MergeDirtyRect(const RectI & rect,bool isDebugRect)45 void RSDirtyRegionManager::MergeDirtyRect(const RectI& rect, bool isDebugRect)
46 {
47 if (rect.IsEmpty()) {
48 return;
49 }
50 if (currentFrameDirtyRegion_.IsEmpty()) {
51 currentFrameDirtyRegion_ = rect;
52 } else {
53 currentFrameDirtyRegion_ = currentFrameDirtyRegion_.JoinRect(rect);
54 }
55 UpdateCurrentFrameAdvancedDirtyRegion(rect);
56 if (isDisplayDirtyManager_) {
57 mergedDirtyRegions_.emplace_back(rect);
58 }
59 if (isDebugRect) {
60 debugRect_ = rect;
61 }
62 }
63
UpdateCurrentFrameAdvancedDirtyRegion(RectI rect)64 void RSDirtyRegionManager::UpdateCurrentFrameAdvancedDirtyRegion(RectI rect)
65 {
66 currentFrameAdvancedDirtyRegion_.emplace_back(rect);
67 if (static_cast<int>(currentFrameAdvancedDirtyRegion_.size()) > maxNumOfDirtyRects_) {
68 currentFrameAdvancedDirtyRegion_.clear();
69 currentFrameAdvancedDirtyRegion_.emplace_back(currentFrameDirtyRegion_);
70 }
71 }
72
MergeHwcDirtyRect(const RectI & rect)73 void RSDirtyRegionManager::MergeHwcDirtyRect(const RectI& rect)
74 {
75 if (rect.IsEmpty()) {
76 return;
77 }
78 if (hwcDirtyRegion_.IsEmpty()) {
79 hwcDirtyRegion_ = rect;
80 } else {
81 hwcDirtyRegion_ = hwcDirtyRegion_.JoinRect(rect);
82 }
83 Occlusion::Region tempRegion = Occlusion::Region(Occlusion::Rect(rect));
84 for (auto& r : advancedDirtyRegion_) {
85 Occlusion::Region region = Occlusion::Region(Occlusion::Rect(r));
86 tempRegion.OrSelf(region);
87 }
88 advancedDirtyRegion_ = tempRegion.GetRegionRectIs();
89 }
90
MergeDirtyRectIfIntersect(const RectI & rect)91 bool RSDirtyRegionManager::MergeDirtyRectIfIntersect(const RectI& rect)
92 {
93 if (!currentFrameDirtyRegion_.Intersect(rect)) {
94 return false;
95 }
96 currentFrameDirtyRegion_ = currentFrameDirtyRegion_.JoinRect(rect);
97 if (isDisplayDirtyManager_) {
98 mergedDirtyRegions_.emplace_back(rect);
99 }
100 return true;
101 }
102
MergeDirtyRectAfterMergeHistory(const RectI & rect)103 void RSDirtyRegionManager::MergeDirtyRectAfterMergeHistory(const RectI& rect)
104 {
105 if (rect.IsEmpty()) {
106 return;
107 }
108 if (dirtyRegion_.IsEmpty()) {
109 dirtyRegion_ = rect;
110 } else {
111 dirtyRegion_ = dirtyRegion_.JoinRect(rect);
112 }
113 }
114
UpdateVisitedDirtyRects(const std::vector<RectI> & rects)115 void RSDirtyRegionManager::UpdateVisitedDirtyRects(const std::vector<RectI>& rects)
116 {
117 if (rects.empty()) {
118 visitedDirtyRegions_.clear();
119 return;
120 }
121 visitedDirtyRegions_ = rects;
122 }
123
GetIntersectedVisitedDirtyRect(const RectI & absRect) const124 RectI RSDirtyRegionManager::GetIntersectedVisitedDirtyRect(const RectI& absRect) const
125 {
126 RectI belowDirty = currentFrameDirtyRegion_;
127 for (const auto& subDirty : visitedDirtyRegions_) {
128 if (absRect.IsInsideOf(belowDirty)) {
129 return belowDirty;
130 }
131 belowDirty = belowDirty.JoinRect(subDirty.IntersectRect(absRect));
132 }
133 return belowDirty;
134 }
135
UpdateCacheableFilterRect(const RectI & rect)136 void RSDirtyRegionManager::UpdateCacheableFilterRect(const RectI& rect)
137 {
138 if (rect.IsEmpty()) {
139 return;
140 }
141 cacheableFilterRects_.emplace_back(rect);
142 }
143
IfCacheableFilterRectFullyCover(const RectI & targetRect)144 bool RSDirtyRegionManager::IfCacheableFilterRectFullyCover(const RectI& targetRect)
145 {
146 for (auto rect : cacheableFilterRects_) {
147 if (targetRect.IsInsideOf(rect)) {
148 return true;
149 }
150 }
151 return false;
152 }
153
IntersectDirtyRect(const RectI & rect)154 void RSDirtyRegionManager::IntersectDirtyRect(const RectI& rect)
155 {
156 currentFrameDirtyRegion_ = currentFrameDirtyRegion_.IntersectRect(rect);
157 for (auto& frameRect : currentFrameAdvancedDirtyRegion_) {
158 frameRect = frameRect.IntersectRect(rect);
159 }
160 }
161
ClipDirtyRectWithinSurface()162 void RSDirtyRegionManager::ClipDirtyRectWithinSurface()
163 {
164 auto clipRect = activeSurfaceRect_.IsEmpty() ? surfaceRect_ : activeSurfaceRect_;
165 int left = std::max(std::max(currentFrameDirtyRegion_.left_, 0), clipRect.left_);
166 int top = std::max(std::max(currentFrameDirtyRegion_.top_, 0), clipRect.top_);
167 int width = std::min(currentFrameDirtyRegion_.GetRight(), clipRect.GetRight()) - left;
168 int height = std::min(currentFrameDirtyRegion_.GetBottom(), clipRect.GetBottom()) - top;
169 // If new region is invalid, currentFrameDirtyRegion_ would be reset as [0, 0, 0, 0]
170 currentFrameDirtyRegion_ = ((width <= 0) || (height <= 0)) ? RectI() : RectI(left, top, width, height);
171
172 for (auto& frameRect : currentFrameAdvancedDirtyRegion_) {
173 int left = std::max(std::max(frameRect.left_, 0), surfaceRect_.left_);
174 int top = std::max(std::max(frameRect.top_, 0), surfaceRect_.top_);
175 int width = std::min(frameRect.GetRight(), surfaceRect_.GetRight()) - left;
176 int height = std::min(frameRect.GetBottom(), surfaceRect_.GetBottom()) - top;
177 // If new region is invalid, frameRect would be reset as [0, 0, 0, 0]
178 frameRect = ((width <= 0) || (height <= 0)) ? RectI() : RectI(left, top, width, height);
179 }
180 }
181
GetCurrentFrameDirtyRegion()182 const RectI& RSDirtyRegionManager::GetCurrentFrameDirtyRegion()
183 {
184 return currentFrameDirtyRegion_;
185 }
186
GetDirtyRegion() const187 const RectI& RSDirtyRegionManager::GetDirtyRegion() const
188 {
189 return dirtyRegion_;
190 }
191
SetCurrentFrameDirtyRect(const RectI & dirtyRect)192 void RSDirtyRegionManager::SetCurrentFrameDirtyRect(const RectI& dirtyRect)
193 {
194 currentFrameDirtyRegion_ = dirtyRect;
195 }
196
GetUifirstFrameDirtyRegion()197 const RectI& RSDirtyRegionManager::GetUifirstFrameDirtyRegion()
198 {
199 return uifirstFrameDirtyRegion_;
200 }
201
SetUifirstFrameDirtyRect(const RectI & dirtyRect)202 void RSDirtyRegionManager::SetUifirstFrameDirtyRect(const RectI& dirtyRect)
203 {
204 uifirstFrameDirtyRegion_ = dirtyRect;
205 }
206
OnSync(std::shared_ptr<RSDirtyRegionManager> targetManager)207 void RSDirtyRegionManager::OnSync(std::shared_ptr<RSDirtyRegionManager> targetManager)
208 {
209 if (!targetManager) {
210 return;
211 }
212 RSDirtyRegionManager *ptr = targetManager.get();
213 ptr->lastActiveSurfaceRect_ = lastActiveSurfaceRect_;
214 ptr->activeSurfaceRect_ = activeSurfaceRect_;
215 ptr->surfaceRect_ = surfaceRect_;
216 ptr->dirtyRegion_ = dirtyRegion_;
217 ptr->advancedDirtyRegion_ = advancedDirtyRegion_;
218 ptr->hwcDirtyRegion_ = hwcDirtyRegion_;
219 ptr->currentFrameDirtyRegion_ = currentFrameDirtyRegion_;
220 ptr->uifirstFrameDirtyRegion_ = uifirstFrameDirtyRegion_;
221 ptr->currentFrameAdvancedDirtyRegion_ = currentFrameAdvancedDirtyRegion_;
222 ptr->maxNumOfDirtyRects_ = maxNumOfDirtyRects_;
223 ptr->dirtyRegionForQuickReject_ = {};
224 ptr->debugRect_ = debugRect_;
225 if (RSSystemProperties::GetDirtyRegionDebugType() != DirtyRegionDebugType::DISABLED) {
226 ptr->dirtySurfaceNodeInfo_ = dirtySurfaceNodeInfo_;
227 ptr->dirtyCanvasNodeInfo_ = dirtyCanvasNodeInfo_;
228 ptr->mergedDirtyRegions_ = mergedDirtyRegions_;
229 }
230 // To avoid the impact of the remaining surface dirty on global dirty when nodes are skipped the next frame.
231 Clear();
232 uifirstFrameDirtyRegion_.Clear();
233 // check if the switch is opened
234 UpdateMaxNumOfDirtyRectByState();
235 }
236
GetDirtyRegionFlipWithinSurface() const237 RectI RSDirtyRegionManager::GetDirtyRegionFlipWithinSurface() const
238 {
239 RectI glRect;
240 if (isDirtyRegionAlignedEnable_) {
241 glRect = GetPixelAlignedRect(dirtyRegion_);
242 } else {
243 glRect = dirtyRegion_;
244 }
245
246 if (!RSSystemProperties::IsUseVulkan()) {
247 // left-top to left-bottom corner(in current surface)
248 glRect.top_ = surfaceRect_.height_ - glRect.top_ - glRect.height_;
249 }
250 return glRect;
251 }
252
GetRectFlipWithinSurface(const RectI & rect) const253 RectI RSDirtyRegionManager::GetRectFlipWithinSurface(const RectI& rect) const
254 {
255 RectI glRect = rect;
256
257 if (!RSSystemProperties::IsUseVulkan()) {
258 // left-top to left-bottom corner(in current surface)
259 glRect.top_ = surfaceRect_.height_ - rect.top_ - rect.height_;
260 }
261 return glRect;
262 }
263
GetLatestDirtyRegion() const264 const RectI& RSDirtyRegionManager::GetLatestDirtyRegion() const
265 {
266 if (historyHead_ < 0) {
267 return dirtyRegion_;
268 }
269 return dirtyHistory_[historyHead_];
270 }
271
GetPixelAlignedRect(const RectI & rect,int32_t alignedBits)272 RectI RSDirtyRegionManager::GetPixelAlignedRect(const RectI& rect, int32_t alignedBits)
273 {
274 RectI newRect = rect;
275 if (alignedBits > 1) {
276 int32_t left = (rect.left_ / alignedBits) * alignedBits;
277 int32_t top = (rect.top_ / alignedBits) * alignedBits;
278 int32_t width = ((rect.GetRight() + alignedBits - 1) / alignedBits) * alignedBits - left;
279 int32_t height = ((rect.GetBottom() + alignedBits - 1) / alignedBits) * alignedBits - top;
280 newRect = RectI(left, top, width, height);
281 }
282 return newRect;
283 }
284
Clear()285 void RSDirtyRegionManager::Clear()
286 {
287 dirtyRegion_.Clear();
288 advancedDirtyRegion_.clear();
289 currentFrameDirtyRegion_.Clear();
290 currentFrameAdvancedDirtyRegion_.clear();
291 hwcDirtyRegion_.Clear();
292 visitedDirtyRegions_.clear();
293 mergedDirtyRegions_.clear();
294 cacheableFilterRects_.clear();
295 dirtyCanvasNodeInfo_.clear();
296 dirtyCanvasNodeInfo_.resize(DirtyRegionType::TYPE_AMOUNT);
297 dirtySurfaceNodeInfo_.clear();
298 dirtySurfaceNodeInfo_.resize(DirtyRegionType::TYPE_AMOUNT);
299 isDfxTarget_ = false;
300 isFilterCacheRectValid_ = true;
301 }
302
IsCurrentFrameDirty() const303 bool RSDirtyRegionManager::IsCurrentFrameDirty() const
304 {
305 return !currentFrameDirtyRegion_.IsEmpty() && currentFrameDirtyRegion_ != debugRect_;
306 }
307
IsDirty() const308 bool RSDirtyRegionManager::IsDirty() const
309 {
310 return !dirtyRegion_.IsEmpty();
311 }
312
UpdateDirty(bool enableAligned)313 void RSDirtyRegionManager::UpdateDirty(bool enableAligned)
314 {
315 if (enableAligned) {
316 UpdateDirtyByAligned();
317 }
318 // if last frame doesn't align and current frame need align, we should align history ditry regions.
319 if (!isDirtyRegionAlignedEnable_ && enableAligned) {
320 AlignHistory();
321 }
322 isDirtyRegionAlignedEnable_ = enableAligned;
323 PushHistory(currentFrameDirtyRegion_);
324 dirtyRegion_ = MergeHistory(bufferAge_, currentFrameDirtyRegion_);
325 MergeAdvancedDirtyHistory(bufferAge_);
326 }
327
UpdateDirtyByAligned(int32_t alignedBits)328 void RSDirtyRegionManager::UpdateDirtyByAligned(int32_t alignedBits)
329 {
330 currentFrameDirtyRegion_ = GetPixelAlignedRect(currentFrameDirtyRegion_, alignedBits);
331 for (auto& rect : currentFrameAdvancedDirtyRegion_) {
332 rect = GetPixelAlignedRect(rect, alignedBits);
333 }
334 }
335
UpdateDirtyRegionInfoForDfx(NodeId id,RSRenderNodeType nodeType,DirtyRegionType dirtyType,const RectI & rect)336 void RSDirtyRegionManager::UpdateDirtyRegionInfoForDfx(NodeId id, RSRenderNodeType nodeType,
337 DirtyRegionType dirtyType, const RectI& rect)
338 {
339 if ((dirtyType >= dirtyCanvasNodeInfo_.size()) || (dirtyType >= DirtyRegionType::TYPE_AMOUNT) ||
340 (dirtyType < 0) || (rect.IsEmpty())) {
341 return;
342 }
343 if (nodeType == RSRenderNodeType::CANVAS_NODE) {
344 dirtyCanvasNodeInfo_[dirtyType].emplace(std::make_pair(id, rect));
345 } else if (nodeType == RSRenderNodeType::SURFACE_NODE) {
346 dirtySurfaceNodeInfo_[dirtyType].emplace(std::make_pair(id, rect));
347 }
348 }
349
GetDirtyRegionInfo(std::map<NodeId,RectI> & target,RSRenderNodeType nodeType,DirtyRegionType dirtyType) const350 void RSDirtyRegionManager::GetDirtyRegionInfo(std::map<NodeId, RectI>& target,
351 RSRenderNodeType nodeType, DirtyRegionType dirtyType) const
352 {
353 target.clear();
354 if ((dirtyType >= dirtyCanvasNodeInfo_.size()) || (dirtyType >= DirtyRegionType::TYPE_AMOUNT) ||
355 (dirtyType < 0)) {
356 return;
357 }
358 if (nodeType == RSRenderNodeType::CANVAS_NODE) {
359 target = dirtyCanvasNodeInfo_[dirtyType];
360 } else if (nodeType == RSRenderNodeType::SURFACE_NODE) {
361 target = dirtySurfaceNodeInfo_[dirtyType];
362 }
363 }
364
HasOffset()365 bool RSDirtyRegionManager::HasOffset()
366 {
367 return hasOffset_;
368 }
SetOffset(int offsetX,int offsetY)369 void RSDirtyRegionManager::SetOffset(int offsetX, int offsetY)
370 {
371 offsetX_ = offsetX;
372 offsetY_ = offsetY;
373 }
GetOffsetedDirtyRegion() const374 RectI RSDirtyRegionManager::GetOffsetedDirtyRegion() const
375 {
376 return GetDirtyRegion().Offset(offsetX_, offsetY_);
377 }
378
SetBufferAge(const int age)379 bool RSDirtyRegionManager::SetBufferAge(const int age)
380 {
381 if (age < 0) {
382 bufferAge_ = 0; // reset invalid age
383 return false;
384 }
385 bufferAge_ = static_cast<unsigned int>(age);
386 return true;
387 }
388
MergeSurfaceRect()389 void RSDirtyRegionManager::MergeSurfaceRect()
390 {
391 return MergeDirtyRect(activeSurfaceRect_.IsEmpty() ? surfaceRect_ : activeSurfaceRect_);
392 }
393
ResetDirtyAsSurfaceSize()394 void RSDirtyRegionManager::ResetDirtyAsSurfaceSize()
395 {
396 const auto& rect = activeSurfaceRect_.IsEmpty() ? surfaceRect_ : activeSurfaceRect_;
397 dirtyRegion_ = rect;
398 currentFrameDirtyRegion_ = rect;
399 advancedDirtyRegion_ = {rect};
400 currentFrameAdvancedDirtyRegion_ = {rect};
401 dirtyRegionForQuickReject_ = {rect};
402 }
403
UpdateMaxNumOfDirtyRectByState()404 void RSDirtyRegionManager::UpdateMaxNumOfDirtyRectByState()
405 {
406 if (isDisplayDirtyManager_) {
407 SetMaxNumOfDirtyRects((advancedDirtyRegionType_ == AdvancedDirtyRegionType::DISABLED) ?
408 RSAdvancedDirtyConfig::DISABLED_RECT_NUM_EACH_NODE : RSAdvancedDirtyConfig::MAX_RECT_NUM_EACH_NODE);
409 } else {
410 SetMaxNumOfDirtyRects((advancedDirtyRegionType_ == AdvancedDirtyRegionType::SET_ADVANCED_SURFACE_AND_DISPLAY) ?
411 RSAdvancedDirtyConfig::MAX_RECT_NUM_EACH_NODE : RSAdvancedDirtyConfig::DISABLED_RECT_NUM_EACH_NODE);
412 }
413 }
414
UpdateDebugRegionTypeEnable(DirtyRegionDebugType dirtyDebugType)415 void RSDirtyRegionManager::UpdateDebugRegionTypeEnable(DirtyRegionDebugType dirtyDebugType)
416 {
417 debugRegionEnabled_.assign(DebugRegionType::TYPE_MAX, false);
418 switch (dirtyDebugType) {
419 case DirtyRegionDebugType::CURRENT_SUB:
420 debugRegionEnabled_[DebugRegionType::CURRENT_SUB] = true;
421 break;
422 case DirtyRegionDebugType::CURRENT_WHOLE:
423 debugRegionEnabled_[DebugRegionType::CURRENT_WHOLE] = true;
424 break;
425 case DirtyRegionDebugType::MULTI_HISTORY:
426 debugRegionEnabled_[DebugRegionType::MULTI_HISTORY] = true;
427 break;
428 case DirtyRegionDebugType::CURRENT_SUB_AND_WHOLE:
429 debugRegionEnabled_[DebugRegionType::CURRENT_SUB] = true;
430 debugRegionEnabled_[DebugRegionType::CURRENT_WHOLE] = true;
431 break;
432 case DirtyRegionDebugType::CURRENT_WHOLE_AND_MULTI_HISTORY:
433 debugRegionEnabled_[DebugRegionType::CURRENT_WHOLE] = true;
434 debugRegionEnabled_[DebugRegionType::MULTI_HISTORY] = true;
435 break;
436 case DirtyRegionDebugType::EGL_DAMAGE:
437 debugRegionEnabled_[DebugRegionType::EGL_DAMAGE] = true;
438 break;
439 case DirtyRegionDebugType::DISABLED:
440 default:
441 break;
442 }
443 }
444
MergeHistory(unsigned int age,RectI rect) const445 RectI RSDirtyRegionManager::MergeHistory(unsigned int age, RectI rect) const
446 {
447 if (age == 0 || age > historySize_) {
448 rect = rect.JoinRect(surfaceRect_);
449 age = historySize_;
450 }
451 // GetHistory(historySize_) is equal to dirtyHistory_[historyHead_] (latest his rect)
452 // therefore, this loop merges rect with age frames' dirtyRect
453 // Attention: should not set i >= 0 for unsigned int!!!!!
454 for (unsigned int i = historySize_; i > historySize_ - age; --i) {
455 auto subRect = GetHistory((i - 1));
456 if (subRect.IsEmpty()) {
457 continue;
458 }
459 if (rect.IsEmpty()) {
460 rect = subRect;
461 continue;
462 }
463 // only join valid his dirty region
464 rect = rect.JoinRect(subRect);
465 }
466 return rect;
467 }
468
MergeAdvancedDirtyHistory(unsigned int age)469 void RSDirtyRegionManager::MergeAdvancedDirtyHistory(unsigned int age)
470 {
471 if (age == 0 || age > historySize_) {
472 RS_LOGW("RSDirtyRegionManager::MergeAdvancedDirtyHistory unvalid age : %{public}d"
473 "historySize : %{public}d", age, historySize_);
474 advancedDirtyRegion_ = {surfaceRect_};
475 return;
476 }
477 advancedDirtyRegion_ = {};
478 Occlusion::Region tempRegion = Occlusion::Region();
479 for (auto& rect : currentFrameAdvancedDirtyRegion_) {
480 if (rect.IsEmpty()) {
481 continue;
482 }
483 Occlusion::Region region = Occlusion::Region(Occlusion::Rect(rect));
484 tempRegion.OrSelf(region);
485 }
486
487 for (unsigned int i = historySize_; i > historySize_ - age; --i) {
488 auto rects = GetAdvancedDirtyHistory((i - 1));
489 if (rects.empty()) {
490 continue;
491 }
492 for (auto& rect : rects) {
493 if (rect.IsEmpty()) {
494 continue;
495 }
496 Occlusion::Region region = Occlusion::Region(Occlusion::Rect(rect));
497 tempRegion.OrSelf(region);
498 }
499 }
500 advancedDirtyRegion_ = tempRegion.GetRegionRectIs();
501 }
502
PushHistory(RectI rect)503 void RSDirtyRegionManager::PushHistory(RectI rect)
504 {
505 int next = (historyHead_ + 1) % HISTORY_QUEUE_MAX_SIZE;
506 dirtyHistory_[next] = rect;
507 advancedDirtyHistory_[next] = currentFrameAdvancedDirtyRegion_;
508 if (historySize_ < HISTORY_QUEUE_MAX_SIZE) {
509 ++historySize_;
510 }
511 historyHead_ = next;
512 }
513
GetHistory(unsigned int i) const514 RectI RSDirtyRegionManager::GetHistory(unsigned int i) const
515 {
516 if (i >= HISTORY_QUEUE_MAX_SIZE) {
517 i %= HISTORY_QUEUE_MAX_SIZE;
518 }
519 if (historySize_ > 0) {
520 i = (i + historyHead_) % historySize_;
521 }
522 return dirtyHistory_[i];
523 }
524
GetAdvancedDirtyHistory(unsigned int i) const525 std::vector<RectI> RSDirtyRegionManager::GetAdvancedDirtyHistory(unsigned int i) const
526 {
527 if (i >= HISTORY_QUEUE_MAX_SIZE) {
528 i %= HISTORY_QUEUE_MAX_SIZE;
529 }
530 if (historySize_ > 0) {
531 i = (i + historyHead_) % historySize_;
532 }
533 return advancedDirtyHistory_[i];
534 }
535
AlignHistory()536 void RSDirtyRegionManager::AlignHistory()
537 {
538 for (uint8_t i = 0; i < dirtyHistory_.size(); i++) {
539 dirtyHistory_[i] = GetPixelAlignedRect(dirtyHistory_[i]);
540 }
541
542 for (auto& rects : advancedDirtyHistory_) {
543 for (auto& rect : rects) {
544 rect = GetPixelAlignedRect(rect);
545 }
546 }
547 }
548
549 } // namespace Rosen
550 } // namespace OHOS
551