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 (at) 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 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 36 CLImageBoData::get_fd () 37 { 38 if (!_image.ptr()) 39 return -1; 40 return _image->export_fd (); 41 } 42 43 CLImageBoBuffer::CLImageBoBuffer (const VideoBufferInfo &info, const SmartPtr<CLImageBoData> &data) 44 : BufferProxy (info, data) 45 , DrmBoBuffer (info, data) 46 { 47 } 48 49 SmartPtr<CLImage> 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> 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 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 88 CLBoBufferPool::~CLBoBufferPool () 89 { 90 XCAM_LOG_DEBUG ("CLBoBufferPool destructed"); 91 } 92 93 SmartPtr<CLImageBoData> 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 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> 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> 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