• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The libgav1 Authors
2 //
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 #include "src/utils/block_parameters_holder.h"
16 
17 #include <algorithm>
18 #include <atomic>
19 #include <new>
20 
21 #include "src/utils/common.h"
22 #include "src/utils/constants.h"
23 #include "src/utils/logging.h"
24 #include "src/utils/types.h"
25 
26 namespace libgav1 {
27 
Reset(int rows4x4,int columns4x4)28 bool BlockParametersHolder::Reset(int rows4x4, int columns4x4) {
29   rows4x4_ = rows4x4;
30   columns4x4_ = columns4x4;
31   index_ = 0;
32   return block_parameters_cache_.Reset(rows4x4_, columns4x4_) &&
33          block_parameters_.Resize(rows4x4_ * columns4x4_);
34 }
35 
Get(int row4x4,int column4x4,BlockSize block_size)36 BlockParameters* BlockParametersHolder::Get(int row4x4, int column4x4,
37                                             BlockSize block_size) {
38   const size_t index = index_.fetch_add(1, std::memory_order_relaxed);
39   if (index >= block_parameters_.size()) return nullptr;
40   auto& bp = block_parameters_.get()[index];
41   if (bp == nullptr) {
42     bp.reset(new (std::nothrow) BlockParameters);
43     if (bp == nullptr) return nullptr;
44   }
45   FillCache(row4x4, column4x4, block_size, bp.get());
46   return bp.get();
47 }
48 
FillCache(int row4x4,int column4x4,BlockSize block_size,BlockParameters * const bp)49 void BlockParametersHolder::FillCache(int row4x4, int column4x4,
50                                       BlockSize block_size,
51                                       BlockParameters* const bp) {
52   int rows = std::min(static_cast<int>(kNum4x4BlocksHigh[block_size]),
53                       rows4x4_ - row4x4);
54   const int columns = std::min(static_cast<int>(kNum4x4BlocksWide[block_size]),
55                                columns4x4_ - column4x4);
56   auto* bp_dst = &block_parameters_cache_[row4x4][column4x4];
57   // Specialize columns cases (values in kNum4x4BlocksWide[]) for better
58   // performance.
59   if (columns == 1) {
60     SetBlock<BlockParameters*>(rows, 1, bp, bp_dst, columns4x4_);
61   } else if (columns == 2) {
62     SetBlock<BlockParameters*>(rows, 2, bp, bp_dst, columns4x4_);
63   } else if (columns == 4) {
64     SetBlock<BlockParameters*>(rows, 4, bp, bp_dst, columns4x4_);
65   } else if (columns == 8) {
66     SetBlock<BlockParameters*>(rows, 8, bp, bp_dst, columns4x4_);
67   } else if (columns == 16) {
68     SetBlock<BlockParameters*>(rows, 16, bp, bp_dst, columns4x4_);
69   } else if (columns == 32) {
70     SetBlock<BlockParameters*>(rows, 32, bp, bp_dst, columns4x4_);
71   } else {
72     do {
73       // The following loop has better performance than using std::fill().
74       // std::fill() has some overhead in checking zero loop count.
75       int x = columns;
76       auto* d = bp_dst;
77       do {
78         *d++ = bp;
79       } while (--x != 0);
80       bp_dst += columns4x4_;
81     } while (--rows != 0);
82   }
83 }
84 
85 }  // namespace libgav1
86