1 /*
2 * cl_image_bo_buffer.cpp - cl image bo buffer
3 *
4 * Copyright (c) 2015 Intel 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 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20
21 #include "cl_image_bo_buffer.h"
22 #include "cl_memory.h"
23 #include "swapped_buffer.h"
24
25
26 namespace XCam {
27
CLImageBoData(SmartPtr<DrmDisplay> & display,SmartPtr<CLImage> & image,drm_intel_bo * bo)28 CLImageBoData::CLImageBoData (SmartPtr<DrmDisplay> &display, SmartPtr<CLImage> &image, drm_intel_bo *bo)
29 : DrmBoData (display, bo)
30 , _image (image)
31 {
32 XCAM_ASSERT (image->get_mem_id ());
33 }
34
35 int
get_fd()36 CLImageBoData::get_fd ()
37 {
38 if (!_image.ptr())
39 return -1;
40 return _image->export_fd ();
41 }
42
CLImageBoBuffer(const VideoBufferInfo & info,const SmartPtr<CLImageBoData> & data)43 CLImageBoBuffer::CLImageBoBuffer (const VideoBufferInfo &info, const SmartPtr<CLImageBoData> &data)
44 : BufferProxy (info, data)
45 , DrmBoBuffer (info, data)
46 {
47 }
48
49 SmartPtr<CLImage>
get_cl_image()50 CLImageBoBuffer::get_cl_image ()
51 {
52 SmartPtr<BufferData> data = get_buffer_data ();
53 SmartPtr<CLImageBoData> image = data.dynamic_cast_ptr<CLImageBoData> ();
54
55 XCAM_FAIL_RETURN(
56 WARNING,
57 image.ptr(),
58 NULL,
59 "CLImageBoBuffer get_buffer_data failed with NULL");
60 return image->get_image ();
61 }
62
63 SmartPtr<SwappedBuffer>
create_new_swap_buffer(const VideoBufferInfo & info,SmartPtr<BufferData> & data)64 CLImageBoBuffer::create_new_swap_buffer (
65 const VideoBufferInfo &info, SmartPtr<BufferData> &data)
66 {
67 XCAM_ASSERT (get_buffer_data ().ptr () == data.ptr ());
68
69 SmartPtr<CLImageBoData> bo = data.dynamic_cast_ptr<CLImageBoData> ();
70
71 XCAM_FAIL_RETURN(
72 WARNING,
73 bo.ptr(),
74 NULL,
75 "CLImageBoBuffer create_new_swap_buffer failed with NULL buffer data");
76
77 return new CLImageBoBuffer (info, bo);
78 }
79
CLBoBufferPool(SmartPtr<DrmDisplay> & display,SmartPtr<CLContext> & context)80 CLBoBufferPool::CLBoBufferPool (SmartPtr<DrmDisplay> &display, SmartPtr<CLContext> &context)
81 : DrmBoBufferPool (display)
82 , _context (context)
83 {
84 XCAM_ASSERT (context.ptr ());
85 XCAM_LOG_DEBUG ("CLBoBufferPool constructed");
86 }
87
~CLBoBufferPool()88 CLBoBufferPool::~CLBoBufferPool ()
89 {
90 XCAM_LOG_DEBUG ("CLBoBufferPool destructed");
91 }
92
93 SmartPtr<CLImageBoData>
create_image_bo(const VideoBufferInfo & info)94 CLBoBufferPool::create_image_bo (const VideoBufferInfo &info)
95 {
96 int32_t mem_fd = -1;
97 SmartPtr<DrmDisplay> display = get_drm_display ();
98 drm_intel_bo *bo = NULL;
99 CLImageDesc desc;
100 SmartPtr<CLImageBoData> data;
101 SmartPtr<CLImage> image;
102 uint32_t swap_flags = get_swap_flags ();
103 uint32_t extra_array_size = 0;
104 if (swap_flags & (uint32_t)(SwappedBuffer::SwapY))
105 ++extra_array_size;
106 if (swap_flags & (uint32_t)(SwappedBuffer::SwapUV))
107 ++extra_array_size;
108
109 if (info.components == 1)
110 image = new CLImage2D (_context, info, CL_MEM_READ_WRITE);
111 else
112 image = new CLImage2DArray (_context, info, CL_MEM_READ_WRITE, extra_array_size);
113 XCAM_FAIL_RETURN (
114 WARNING,
115 image.ptr () && image->get_mem_id (),
116 NULL,
117 "CLBoBufferPool create image failed");
118
119 desc = image->get_image_desc ();
120 mem_fd = image->export_fd ();
121 XCAM_FAIL_RETURN (
122 WARNING,
123 mem_fd >= 0,
124 NULL,
125 "CLBoBufferPool export image fd failed");
126
127 bo = display->create_drm_bo_from_fd (mem_fd, desc.size);
128 XCAM_FAIL_RETURN (
129 WARNING,
130 bo,
131 NULL,
132 "CLBoBufferPool bind fd to bo failed");
133
134 data = new CLImageBoData (display, image, bo);
135 XCAM_FAIL_RETURN (
136 WARNING,
137 data.ptr (),
138 NULL,
139 "CLBoBufferPool bind CLImage to CLImageBoData failed");
140 return data;
141 }
142
143 bool
fixate_video_info(VideoBufferInfo & info)144 CLBoBufferPool::fixate_video_info (VideoBufferInfo &info)
145 {
146 bool need_reset_info = false;
147 uint32_t i = 0;
148 SmartPtr<CLImage> image;
149 uint32_t swap_flags = get_swap_flags ();
150 SmartPtr<CLImageBoData> image_data = create_image_bo (info);
151 XCAM_FAIL_RETURN (
152 WARNING,
153 image_data.ptr (),
154 NULL,
155 "CLBoBufferPool fixate_video_info failed");
156
157 image = image_data->get_image ();
158 XCAM_ASSERT (image.ptr ());
159
160 CLImageDesc desc = image->get_image_desc ();
161 if (desc.row_pitch != info.strides [0] || desc.size != info.size)
162 need_reset_info = true;
163
164 for (i = 1; i < info.components && !need_reset_info; ++i) {
165 XCAM_ASSERT (desc.slice_pitch && desc.array_size >= info.components);
166 if (desc.row_pitch != info.strides [i] ||
167 info.offsets [i] != desc.slice_pitch * i)
168 need_reset_info = true;
169 }
170 if (need_reset_info) {
171 VideoBufferPlanarInfo plane_info;
172 info.get_planar_info (plane_info, 0);
173 uint32_t aligned_width = desc.row_pitch / plane_info.pixel_bytes;
174 uint32_t aligned_height = info.aligned_height;
175 if (info.components > 0)
176 aligned_height = desc.slice_pitch / desc.row_pitch;
177 info.init (info.format, info.width, info.height, aligned_width, aligned_height, desc.size);
178 for (i = 1; i < info.components; ++i) {
179 info.offsets[i] = desc.slice_pitch * i;
180 info.strides[i] = desc.row_pitch;
181 }
182 }
183
184 if (swap_flags && desc.array_size >= 2) {
185 if (swap_flags & (uint32_t)(SwappedBuffer::SwapY)) {
186 _swap_offsets[SwappedBuffer::SwapYOffset0] = info.offsets[0];
187 _swap_offsets[SwappedBuffer::SwapYOffset1] = desc.slice_pitch * 2;
188 }
189 if (swap_flags & (uint32_t)(SwappedBuffer::SwapUV)) {
190 _swap_offsets[SwappedBuffer::SwapUVOffset0] = info.offsets[1];
191 _swap_offsets[SwappedBuffer::SwapUVOffset1] = desc.slice_pitch * (desc.array_size - 1);
192 }
193 }
194
195 if(!init_swap_order (info)) {
196 XCAM_LOG_ERROR ("CLBoBufferPool: fix video info faield to init swap order");
197 return false;
198 }
199
200 add_data_unsafe (image_data);
201
202 return true;
203 }
204
205 SmartPtr<BufferData>
allocate_data(const VideoBufferInfo & buffer_info)206 CLBoBufferPool::allocate_data (const VideoBufferInfo &buffer_info)
207 {
208 SmartPtr<CLImageBoData> image_data = create_image_bo (buffer_info);
209 return image_data;
210 }
211
212 SmartPtr<BufferProxy>
create_buffer_from_data(SmartPtr<BufferData> & data)213 CLBoBufferPool::create_buffer_from_data (SmartPtr<BufferData> &data)
214 {
215 const VideoBufferInfo & info = get_video_info ();
216 SmartPtr<CLImageBoData> image_data = data.dynamic_cast_ptr<CLImageBoData> ();
217 XCAM_ASSERT (image_data.ptr ());
218
219 SmartPtr<CLImageBoBuffer> out_buf = new CLImageBoBuffer (info, image_data);
220 XCAM_ASSERT (out_buf.ptr ());
221 out_buf->set_swap_info (_swap_flags, _swap_offsets);
222 return out_buf;
223 }
224
225 };
226