blob: 50c9e59af89296fdcd82b9d03dc3901d72638df7 [file] [log] [blame]
Pin-chih Linf72774b2019-11-19 18:26:47 +08001/*
2 * Copyright (C) 2019 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 "C2AllocatorBlob"
19
20#include <C2AllocatorBlob.h>
21#include <C2PlatformSupport.h>
22
23#include <android/hardware/graphics/common/1.2/types.h>
24#include <utils/Log.h>
25
26namespace android {
27
28using ::android::hardware::graphics::common::V1_2::PixelFormat;
29
30constexpr uint32_t kLinearBufferHeight = 1u;
31constexpr uint32_t kLinearBufferFormat = static_cast<uint32_t>(PixelFormat::BLOB);
32
33namespace {
34
35c2_status_t GetCapacityFromHandle(const C2Handle* const grallocHandle, size_t* capacity) {
36 uint32_t width, height, format, stride, generation, igbp_slot;
37 uint64_t usage, igbp_id;
38 _UnwrapNativeCodec2GrallocMetadata(grallocHandle, &width, &height, &format, &usage, &stride,
39 &generation, &igbp_id, &igbp_slot);
40
41 if (height != kLinearBufferHeight || format != kLinearBufferFormat) {
42 return C2_BAD_VALUE;
43 }
44 *capacity = width;
45 return C2_OK;
46}
47
48} // namespace
49
50// C2AllocationBlob is a wrapper for C2AllocationGralloc allocated by C2AllocatorGralloc.
51// C2AllocationBlob::handle() delegates to the backed C2AllocationGralloc::handle().
52class C2AllocationBlob : public C2LinearAllocation {
53public:
54 C2AllocationBlob(std::shared_ptr<C2GraphicAllocation> graphicAllocation, size_t capacity,
55 C2Allocator::id_t allocatorId);
56 ~C2AllocationBlob() override;
57 c2_status_t map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence* fence,
58 void** addr /* nonnull */) override;
59 c2_status_t unmap(void* addr, size_t size, C2Fence* fenceFd) override;
60
61 id_t getAllocatorId() const override { return mAllocatorId; }
62 const C2Handle* handle() const override { return mGraphicAllocation->handle(); }
63 bool equals(const std::shared_ptr<C2LinearAllocation>& other) const override {
64 return other && other->handle() == handle();
65 }
66
67private:
68 const std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
69 const C2Allocator::id_t mAllocatorId;
70};
71
72C2AllocationBlob::C2AllocationBlob(
73 std::shared_ptr<C2GraphicAllocation> graphicAllocation, size_t capacity,
74 C2Allocator::id_t allocatorId)
75 : C2LinearAllocation(capacity),
76 mGraphicAllocation(std::move(graphicAllocation)),
77 mAllocatorId(allocatorId) {}
78
79C2AllocationBlob::~C2AllocationBlob() {}
80
81c2_status_t C2AllocationBlob::map(size_t offset, size_t size, C2MemoryUsage usage,
82 C2Fence* fence, void** addr /* nonnull */) {
83 C2PlanarLayout layout;
84 C2Rect rect = C2Rect(size, kLinearBufferHeight).at(offset, 0u);
85 return mGraphicAllocation->map(rect, usage, fence, &layout, reinterpret_cast<uint8_t**>(addr));
86}
87
88c2_status_t C2AllocationBlob::unmap(void* addr, size_t size, C2Fence* fenceFd) {
89 C2Rect rect(size, kLinearBufferHeight);
90 return mGraphicAllocation->unmap(reinterpret_cast<uint8_t**>(&addr), rect, fenceFd);
91}
92
93/* ====================================== BLOB ALLOCATOR ====================================== */
94C2AllocatorBlob::C2AllocatorBlob(id_t id) {
95 C2MemoryUsage minUsage = {0, 0};
96 C2MemoryUsage maxUsage = {C2MemoryUsage::CPU_READ | C2MemoryUsage::READ_PROTECTED,
97 C2MemoryUsage::CPU_WRITE};
98 Traits traits = {"android.allocator.blob", id, LINEAR, minUsage, maxUsage};
99 mTraits = std::make_shared<C2Allocator::Traits>(traits);
100 auto allocatorStore = GetCodec2PlatformAllocatorStore();
101 allocatorStore->fetchAllocator(C2PlatformAllocatorStore::GRALLOC, &mC2AllocatorGralloc);
102 if (!mC2AllocatorGralloc) {
103 ALOGE("Failed to obtain C2AllocatorGralloc as backed allocator");
104 }
105}
106
107C2AllocatorBlob::~C2AllocatorBlob() {}
108
109c2_status_t C2AllocatorBlob::newLinearAllocation(
110 uint32_t capacity, C2MemoryUsage usage, std::shared_ptr<C2LinearAllocation>* allocation) {
111 if (allocation == nullptr) {
112 return C2_BAD_VALUE;
113 }
114
115 allocation->reset();
116
117 if (!mC2AllocatorGralloc) {
118 return C2_CORRUPTED;
119 }
120
121 std::shared_ptr<C2GraphicAllocation> graphicAllocation;
122 c2_status_t status = mC2AllocatorGralloc->newGraphicAllocation(
123 capacity, kLinearBufferHeight, kLinearBufferFormat, usage, &graphicAllocation);
124 if (status != C2_OK) {
125 ALOGE("Failed newGraphicAllocation");
126 return status;
127 }
128
129 allocation->reset(new C2AllocationBlob(std::move(graphicAllocation),
130 static_cast<size_t>(capacity), mTraits->id));
131 return C2_OK;
132}
133
134c2_status_t C2AllocatorBlob::priorLinearAllocation(
135 const C2Handle* handle, std::shared_ptr<C2LinearAllocation>* allocation) {
136 if (allocation == nullptr) {
137 return C2_BAD_VALUE;
138 }
139
140 allocation->reset();
141
142 if (!mC2AllocatorGralloc) {
143 return C2_CORRUPTED;
144 }
145
146 std::shared_ptr<C2GraphicAllocation> graphicAllocation;
147 c2_status_t status = mC2AllocatorGralloc->priorGraphicAllocation(handle, &graphicAllocation);
148 if (status != C2_OK) {
149 ALOGE("Failed priorGraphicAllocation");
150 return status;
151 }
152
153 const C2Handle* const grallocHandle = graphicAllocation->handle();
154 size_t capacity = 0;
155 status = GetCapacityFromHandle(grallocHandle, &capacity);
156 if (status != C2_OK) {
157 ALOGE("Failed to extract capacity from Handle");
158 return status;
159 }
160
161 allocation->reset(new C2AllocationBlob(std::move(graphicAllocation), capacity, mTraits->id));
162 return C2_OK;
163}
164
165id_t C2AllocatorBlob::getId() const {
166 return mTraits->id;
167}
168
169C2String C2AllocatorBlob::getName() const {
170 return mTraits->name;
171}
172
173std::shared_ptr<const C2Allocator::Traits> C2AllocatorBlob::getTraits() const {
174 return mTraits;
175}
176
177// static
178bool C2AllocatorBlob::isValid(const C2Handle* const o) {
179 size_t capacity;
180 // Distinguish C2Handle purely allocated by C2AllocatorGralloc, or one allocated through
181 // C2AllocatorBlob, by checking the handle's height is 1, and its format is
182 // PixelFormat::BLOB by GetCapacityFromHandle().
183 return C2AllocatorGralloc::isValid(o) && GetCapacityFromHandle(o, &capacity) == C2_OK;
184}
185
186} // namespace android