• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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