xref: /aosp_15_r20/external/libgav1/src/utils/block_parameters_holder.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1*09537850SAkhilesh Sanikop // Copyright 2019 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop //      http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop 
15*09537850SAkhilesh Sanikop #include "src/utils/block_parameters_holder.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <algorithm>
18*09537850SAkhilesh Sanikop 
19*09537850SAkhilesh Sanikop #include "src/utils/common.h"
20*09537850SAkhilesh Sanikop #include "src/utils/constants.h"
21*09537850SAkhilesh Sanikop #include "src/utils/logging.h"
22*09537850SAkhilesh Sanikop #include "src/utils/types.h"
23*09537850SAkhilesh Sanikop 
24*09537850SAkhilesh Sanikop namespace libgav1 {
25*09537850SAkhilesh Sanikop 
Reset(int rows4x4,int columns4x4)26*09537850SAkhilesh Sanikop bool BlockParametersHolder::Reset(int rows4x4, int columns4x4) {
27*09537850SAkhilesh Sanikop   rows4x4_ = rows4x4;
28*09537850SAkhilesh Sanikop   columns4x4_ = columns4x4;
29*09537850SAkhilesh Sanikop   index_ = 0;
30*09537850SAkhilesh Sanikop   return block_parameters_cache_.Reset(rows4x4_, columns4x4_) &&
31*09537850SAkhilesh Sanikop          block_parameters_.Resize(rows4x4_ * columns4x4_);
32*09537850SAkhilesh Sanikop }
33*09537850SAkhilesh Sanikop 
Get(int row4x4,int column4x4,BlockSize block_size)34*09537850SAkhilesh Sanikop BlockParameters* BlockParametersHolder::Get(int row4x4, int column4x4,
35*09537850SAkhilesh Sanikop                                             BlockSize block_size) {
36*09537850SAkhilesh Sanikop   const size_t index = index_.fetch_add(1, std::memory_order_relaxed);
37*09537850SAkhilesh Sanikop   if (index >= block_parameters_.size()) return nullptr;
38*09537850SAkhilesh Sanikop   auto& bp = block_parameters_.get()[index];
39*09537850SAkhilesh Sanikop   if (bp == nullptr) {
40*09537850SAkhilesh Sanikop     bp.reset(new (std::nothrow) BlockParameters);
41*09537850SAkhilesh Sanikop     if (bp == nullptr) return nullptr;
42*09537850SAkhilesh Sanikop   }
43*09537850SAkhilesh Sanikop   FillCache(row4x4, column4x4, block_size, bp.get());
44*09537850SAkhilesh Sanikop   return bp.get();
45*09537850SAkhilesh Sanikop }
46*09537850SAkhilesh Sanikop 
FillCache(int row4x4,int column4x4,BlockSize block_size,BlockParameters * const bp)47*09537850SAkhilesh Sanikop void BlockParametersHolder::FillCache(int row4x4, int column4x4,
48*09537850SAkhilesh Sanikop                                       BlockSize block_size,
49*09537850SAkhilesh Sanikop                                       BlockParameters* const bp) {
50*09537850SAkhilesh Sanikop   int rows = std::min(static_cast<int>(kNum4x4BlocksHigh[block_size]),
51*09537850SAkhilesh Sanikop                       rows4x4_ - row4x4);
52*09537850SAkhilesh Sanikop   const int columns = std::min(static_cast<int>(kNum4x4BlocksWide[block_size]),
53*09537850SAkhilesh Sanikop                                columns4x4_ - column4x4);
54*09537850SAkhilesh Sanikop   auto* bp_dst = &block_parameters_cache_[row4x4][column4x4];
55*09537850SAkhilesh Sanikop   // Specialize columns cases (values in kNum4x4BlocksWide[]) for better
56*09537850SAkhilesh Sanikop   // performance.
57*09537850SAkhilesh Sanikop   if (columns == 1) {
58*09537850SAkhilesh Sanikop     SetBlock<BlockParameters*>(rows, 1, bp, bp_dst, columns4x4_);
59*09537850SAkhilesh Sanikop   } else if (columns == 2) {
60*09537850SAkhilesh Sanikop     SetBlock<BlockParameters*>(rows, 2, bp, bp_dst, columns4x4_);
61*09537850SAkhilesh Sanikop   } else if (columns == 4) {
62*09537850SAkhilesh Sanikop     SetBlock<BlockParameters*>(rows, 4, bp, bp_dst, columns4x4_);
63*09537850SAkhilesh Sanikop   } else if (columns == 8) {
64*09537850SAkhilesh Sanikop     SetBlock<BlockParameters*>(rows, 8, bp, bp_dst, columns4x4_);
65*09537850SAkhilesh Sanikop   } else if (columns == 16) {
66*09537850SAkhilesh Sanikop     SetBlock<BlockParameters*>(rows, 16, bp, bp_dst, columns4x4_);
67*09537850SAkhilesh Sanikop   } else if (columns == 32) {
68*09537850SAkhilesh Sanikop     SetBlock<BlockParameters*>(rows, 32, bp, bp_dst, columns4x4_);
69*09537850SAkhilesh Sanikop   } else {
70*09537850SAkhilesh Sanikop     do {
71*09537850SAkhilesh Sanikop       // The following loop has better performance than using std::fill().
72*09537850SAkhilesh Sanikop       // std::fill() has some overhead in checking zero loop count.
73*09537850SAkhilesh Sanikop       int x = columns;
74*09537850SAkhilesh Sanikop       auto* d = bp_dst;
75*09537850SAkhilesh Sanikop       do {
76*09537850SAkhilesh Sanikop         *d++ = bp;
77*09537850SAkhilesh Sanikop       } while (--x != 0);
78*09537850SAkhilesh Sanikop       bp_dst += columns4x4_;
79*09537850SAkhilesh Sanikop     } while (--rows != 0);
80*09537850SAkhilesh Sanikop   }
81*09537850SAkhilesh Sanikop }
82*09537850SAkhilesh Sanikop 
83*09537850SAkhilesh Sanikop }  // namespace libgav1
84