xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/xcore/drm_buffer.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * drm_buffer.cpp - DRM Buffer Implementation
3  *
4  *  Copyright (c) 2021 Rockchip Corporation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 #include "drm_buffer.h"
20 
21 #include <drm/drm.h>
22 #include <sys/mman.h>
23 #include <xf86drm.h>
24 
25 #include <memory>
26 #include <string>
27 
28 #include "dma_buffer.h"
29 #include "drm_device.h"
30 #include "xcam_defs.h"
31 #include "xcam_log.h"
32 
33 namespace XCam {
34 
~DrmBuffer()35 DrmBuffer::~DrmBuffer() {
36     for (auto it = dma_bufs_.begin(); it != dma_bufs_.end();) {
37         dma_bufs_.erase(it);
38     }
39     auto dev = drm_device_.lock();
40     if (dev != nullptr) {
41         dev->DestroyDumbObject(dumb_object_);
42     }
43 }
44 
DrmBuffer(const std::shared_ptr<DrmDevice> & dev,std::unique_ptr<DrmDumbObject> dumb_object)45 DrmBuffer::DrmBuffer(const std::shared_ptr<DrmDevice>& dev,
46                      std::unique_ptr<DrmDumbObject> dumb_object)
47     : drm_device_(std::weak_ptr<DrmDevice>(dev)) {
48     dumb_object_ = std::move(dumb_object);
49     for (int i = 0; i < dumb_object_->num_planes; i++) {
50         dma_bufs_.push_back(std::unique_ptr<DmaBuffer>(
51             new DmaBuffer(dumb_object_->fds[i], dumb_object_->sizes[i])));
52     }
53 }
54 
numPlanes()55 int DrmBuffer::numPlanes() { return dma_bufs_.size(); }
56 
map(unsigned int plane)57 uint8_t* DrmBuffer::map(unsigned int plane) {
58     if (plane >= dma_bufs_.size()) {
59         return nullptr;
60     }
61     auto&& buf = dma_bufs_.at(plane);
62     if (!buf->mapped()) {
63         auto dev = drm_device_.lock();
64         dev->RequestMapDumbObject(dumb_object_, plane);
65     }
66     auto ptr = reinterpret_cast<uint8_t*>(buf->map());
67     buf->beginCpuAccess(DmaBufferDirection::kBidirectional);
68     return ptr;
69 }
70 
map()71 uint8_t* DrmBuffer::map() { return map(0); }
72 
unmap(unsigned int plane)73 bool DrmBuffer::unmap(unsigned int plane) {
74     if (plane >= dma_bufs_.size()) {
75         return false;
76     }
77     auto&& buf = dma_bufs_.at(plane);
78     buf->endCpuAccess(DmaBufferDirection::kBidirectional);
79     buf->unmap();
80     return true;
81 }
82 
unmap()83 bool DrmBuffer::unmap() { return unmap(0); }
84 
getFd(unsigned int plane)85 int DrmBuffer::getFd(unsigned int plane) {
86     if (plane >= dma_bufs_.size()) {
87         return -1;
88     }
89     return dma_bufs_.at(plane)->getFd();
90 }
91 
getSize()92 size_t DrmBuffer::getSize() { return getSize(0); }
93 
getSize(unsigned int plane)94 size_t DrmBuffer::getSize(unsigned int plane) { return dma_bufs_.at(plane)->getSize(); }
95 
get_fd()96 int DrmBuffer::get_fd() { return getFd(0); }
97 
get_bo()98 DrmDumbObject* DrmBuffer::get_bo() { return dumb_object_.get(); }
99 
DrmBufferProxy(const VideoBufferInfo & info,const SmartPtr<DrmBuffer> & data)100 DrmBufferProxy::DrmBufferProxy(const VideoBufferInfo& info, const SmartPtr<DrmBuffer>& data)
101     : BufferProxy(info, data) {
102     XCAM_ASSERT(data.ptr());
103 }
104 
get_bo()105 DrmDumbObject* DrmBufferProxy::get_bo() {
106     auto data   = get_buffer_data();
107     auto buffer = data.dynamic_cast_ptr<DrmBuffer>();
108 
109     XCAM_FAIL_RETURN(WARNING, buffer.ptr(), NULL, "DrmBuffer get_buffer_data failed with NULL");
110 
111     return buffer->get_bo();
112 }
113 
GetFd()114 int DrmBufferProxy::GetFd() {
115     auto data   = get_buffer_data();
116     auto buffer = data.dynamic_cast_ptr<DrmBuffer>();
117 
118     return buffer->get_fd();
119 }
120 
DrmBufferPool(std::shared_ptr<DrmDevice> device)121 DrmBufferPool::DrmBufferPool(std::shared_ptr<DrmDevice> device) : drm_device_(device) {}
122 
fixate_video_info(VideoBufferInfo & info)123 bool DrmBufferPool::fixate_video_info(VideoBufferInfo& info) {
124     VideoBufferInfo out_info;
125 
126     out_info.init(info.format, info.width, info.height, info.aligned_width, info.aligned_height);
127 
128     info = out_info;
129 
130     return true;
131 }
132 
allocate_data(const VideoBufferInfo & buffer_info)133 SmartPtr<BufferData> DrmBufferPool::allocate_data(const VideoBufferInfo& buffer_info) {
134     SmartPtr<DrmBuffer> buffer_data;
135     auto bo = drm_device_->CreateDumbObject(buffer_info.aligned_width, buffer_info.aligned_height,
136                                             buffer_info.color_bits, 1);
137     if (bo != nullptr) {
138         buffer_data = new DrmBuffer(drm_device_, std::move(bo));
139     }
140     return buffer_data;
141 }
142 
create_buffer_from_data(SmartPtr<BufferData> & data)143 SmartPtr<BufferProxy> DrmBufferPool::create_buffer_from_data(SmartPtr<BufferData>& data) {
144     const VideoBufferInfo& info     = get_video_info();
145     SmartPtr<DrmBuffer> buffer_data = data.dynamic_cast_ptr<DrmBuffer>();
146     XCAM_ASSERT(buffer_data.ptr());
147 
148     SmartPtr<DrmBufferProxy> out_buf = new DrmBufferProxy(info, buffer_data);
149     XCAM_ASSERT(out_buf.ptr());
150     return out_buf;
151 }
152 
153 }  // namespace XCam
154