1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "Codec2-BufferTypes"
19 #include <android-base/logging.h>
20
21 #include <codec2/common/BufferTypes.h>
22
23 #include <C2AllocatorIon.h>
24 #include <C2AllocatorGralloc.h>
25 #include <C2BlockInternal.h>
26 #include <C2Buffer.h>
27 #include <C2Component.h>
28 #include <C2FenceFactory.h>
29 #include <C2PlatformSupport.h>
30 #include <C2Work.h>
31
32 namespace android {
33
34 // C2LinearBlock, vector<C2Param*>, C2Fence -> C2Buffer
CreateLinearBuffer(std::shared_ptr<C2Buffer> * buffer,const std::shared_ptr<C2LinearBlock> & block,const std::vector<C2Param * > & meta,const C2Fence & fence)35 bool CreateLinearBuffer(
36 std::shared_ptr<C2Buffer>* buffer,
37 const std::shared_ptr<C2LinearBlock>& block,
38 const std::vector<C2Param*>& meta,
39 const C2Fence& fence) {
40 // Check the block meta. It should have exactly 1 C2Info:
41 // C2Hal_RangeInfo.
42 if ((meta.size() != 1) || !meta[0]) {
43 LOG(ERROR) << "Invalid C2LinearBlock::meta.";
44 return false;
45 }
46 if (meta[0]->size() != sizeof(C2Hal_RangeInfo)) {
47 LOG(ERROR) << "Invalid range info in C2LinearBlock.";
48 return false;
49 }
50 C2Hal_RangeInfo *rangeInfo =
51 reinterpret_cast<C2Hal_RangeInfo*>(meta[0]);
52
53 // Create C2Buffer from C2LinearBlock.
54 *buffer = C2Buffer::CreateLinearBuffer(block->share(
55 rangeInfo->offset, rangeInfo->length,
56 fence));
57 if (!(*buffer)) {
58 LOG(ERROR) << "CreateLinearBuffer failed.";
59 return false;
60 }
61 return true;
62 }
63
64 // C2GraphicBlock, vector<C2Param*>, C2Fence -> C2Buffer
CreateGraphicBuffer(std::shared_ptr<C2Buffer> * buffer,const std::shared_ptr<C2GraphicBlock> & block,const std::vector<C2Param * > & meta,const C2Fence & fence)65 bool CreateGraphicBuffer(
66 std::shared_ptr<C2Buffer>* buffer,
67 const std::shared_ptr<C2GraphicBlock>& block,
68 const std::vector<C2Param*>& meta,
69 const C2Fence& fence) {
70 // Check the block meta. It should have exactly 1 C2Info:
71 // C2Hal_RectInfo.
72 if ((meta.size() != 1) || !meta[0]) {
73 LOG(ERROR) << "Invalid C2GraphicBlock::meta.";
74 return false;
75 }
76 if (meta[0]->size() != sizeof(C2Hal_RectInfo)) {
77 LOG(ERROR) << "Invalid rect info in C2GraphicBlock.";
78 return false;
79 }
80 C2Hal_RectInfo *rectInfo =
81 reinterpret_cast<C2Hal_RectInfo*>(meta[0]);
82
83 // Create C2Buffer from C2GraphicBlock.
84 *buffer = C2Buffer::CreateGraphicBuffer(block->share(
85 C2Rect(rectInfo->width, rectInfo->height).
86 at(rectInfo->left, rectInfo->top),
87 fence));
88 if (!(*buffer)) {
89 LOG(ERROR) << "CreateGraphicBuffer failed.";
90 return false;
91 }
92 return true;
93 }
94
95 namespace /* unnamed */ {
96
97 template <typename BlockProcessor>
forEachBlock(C2FrameData & frameData,BlockProcessor process)98 void forEachBlock(C2FrameData& frameData,
99 BlockProcessor process) {
100 for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) {
101 if (buffer) {
102 for (const C2ConstGraphicBlock& block :
103 buffer->data().graphicBlocks()) {
104 process(block);
105 }
106 }
107 }
108 }
109
110 template <typename BlockProcessor>
forEachBlock(const std::list<std::unique_ptr<C2Work>> & workList,BlockProcessor process,bool processInput,bool processOutput)111 void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList,
112 BlockProcessor process,
113 bool processInput, bool processOutput) {
114 for (const std::unique_ptr<C2Work>& work : workList) {
115 if (!work) {
116 continue;
117 }
118 if (processInput) {
119 forEachBlock(work->input, process);
120 }
121 if (processOutput) {
122 for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
123 if (worklet) {
124 forEachBlock(worklet->output,
125 process);
126 }
127 }
128 }
129 }
130 }
131
132 } // unnamed namespace
133
BeginTransferBufferQueueBlock(const C2ConstGraphicBlock & block)134 bool BeginTransferBufferQueueBlock(const C2ConstGraphicBlock& block) {
135 std::shared_ptr<_C2BlockPoolData> data =
136 _C2BlockFactory::GetGraphicBlockPoolData(block);
137 if (data && _C2BlockFactory::GetBufferQueueData(data)) {
138 _C2BlockFactory::BeginTransferBlockToClient(data);
139 return true;
140 }
141 return false;
142 }
143
BeginTransferBufferQueueBlocks(const std::list<std::unique_ptr<C2Work>> & workList,bool processInput,bool processOutput)144 void BeginTransferBufferQueueBlocks(
145 const std::list<std::unique_ptr<C2Work>>& workList,
146 bool processInput, bool processOutput) {
147 forEachBlock(workList, BeginTransferBufferQueueBlock,
148 processInput, processOutput);
149 }
150
EndTransferBufferQueueBlock(const C2ConstGraphicBlock & block,bool transfer)151 bool EndTransferBufferQueueBlock(
152 const C2ConstGraphicBlock& block,
153 bool transfer) {
154 std::shared_ptr<_C2BlockPoolData> data =
155 _C2BlockFactory::GetGraphicBlockPoolData(block);
156 if (data && _C2BlockFactory::GetBufferQueueData(data)) {
157 _C2BlockFactory::EndTransferBlockToClient(data, transfer);
158 return true;
159 }
160 return false;
161 }
162
EndTransferBufferQueueBlocks(const std::list<std::unique_ptr<C2Work>> & workList,bool transfer,bool processInput,bool processOutput)163 void EndTransferBufferQueueBlocks(
164 const std::list<std::unique_ptr<C2Work>>& workList,
165 bool transfer,
166 bool processInput, bool processOutput) {
167 forEachBlock(workList,
168 std::bind(EndTransferBufferQueueBlock,
169 std::placeholders::_1, transfer),
170 processInput, processOutput);
171 }
172
DisplayBufferQueueBlock(const C2ConstGraphicBlock & block)173 bool DisplayBufferQueueBlock(const C2ConstGraphicBlock& block) {
174 std::shared_ptr<_C2BlockPoolData> data =
175 _C2BlockFactory::GetGraphicBlockPoolData(block);
176 if (data && _C2BlockFactory::GetBufferQueueData(data)) {
177 _C2BlockFactory::DisplayBlockToBufferQueue(data);
178 return true;
179 }
180 return false;
181 }
182
183 } // namespace android
184
185