| /* |
| * cl_image_bo_buffer.cpp - cl image bo buffer |
| * |
| * Copyright (c) 2015 Intel Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * Author: Wind Yuan <feng.yuan@intel.com> |
| */ |
| |
| #include "cl_image_bo_buffer.h" |
| #include "cl_memory.h" |
| #include "swapped_buffer.h" |
| |
| |
| namespace XCam { |
| |
| CLImageBoData::CLImageBoData (SmartPtr<DrmDisplay> &display, SmartPtr<CLImage> &image, drm_intel_bo *bo) |
| : DrmBoData (display, bo) |
| , _image (image) |
| { |
| XCAM_ASSERT (image->get_mem_id ()); |
| } |
| |
| int |
| CLImageBoData::get_fd () |
| { |
| if (!_image.ptr()) |
| return -1; |
| return _image->export_fd (); |
| } |
| |
| CLImageBoBuffer::CLImageBoBuffer (const VideoBufferInfo &info, const SmartPtr<CLImageBoData> &data) |
| : BufferProxy (info, data) |
| , DrmBoBuffer (info, data) |
| { |
| } |
| |
| SmartPtr<CLImage> |
| CLImageBoBuffer::get_cl_image () |
| { |
| SmartPtr<BufferData> data = get_buffer_data (); |
| SmartPtr<CLImageBoData> image = data.dynamic_cast_ptr<CLImageBoData> (); |
| |
| XCAM_FAIL_RETURN( |
| WARNING, |
| image.ptr(), |
| NULL, |
| "CLImageBoBuffer get_buffer_data failed with NULL"); |
| return image->get_image (); |
| } |
| |
| SmartPtr<SwappedBuffer> |
| CLImageBoBuffer::create_new_swap_buffer ( |
| const VideoBufferInfo &info, SmartPtr<BufferData> &data) |
| { |
| XCAM_ASSERT (get_buffer_data ().ptr () == data.ptr ()); |
| |
| SmartPtr<CLImageBoData> bo = data.dynamic_cast_ptr<CLImageBoData> (); |
| |
| XCAM_FAIL_RETURN( |
| WARNING, |
| bo.ptr(), |
| NULL, |
| "CLImageBoBuffer create_new_swap_buffer failed with NULL buffer data"); |
| |
| return new CLImageBoBuffer (info, bo); |
| } |
| |
| CLBoBufferPool::CLBoBufferPool (SmartPtr<DrmDisplay> &display, SmartPtr<CLContext> &context) |
| : DrmBoBufferPool (display) |
| , _context (context) |
| { |
| XCAM_ASSERT (context.ptr ()); |
| XCAM_LOG_DEBUG ("CLBoBufferPool constructed"); |
| } |
| |
| CLBoBufferPool::~CLBoBufferPool () |
| { |
| XCAM_LOG_DEBUG ("CLBoBufferPool destructed"); |
| } |
| |
| SmartPtr<CLImageBoData> |
| CLBoBufferPool::create_image_bo (const VideoBufferInfo &info) |
| { |
| int32_t mem_fd = -1; |
| SmartPtr<DrmDisplay> display = get_drm_display (); |
| drm_intel_bo *bo = NULL; |
| CLImageDesc desc; |
| SmartPtr<CLImageBoData> data; |
| SmartPtr<CLImage> image; |
| uint32_t swap_flags = get_swap_flags (); |
| uint32_t extra_array_size = 0; |
| if (swap_flags & (uint32_t)(SwappedBuffer::SwapY)) |
| ++extra_array_size; |
| if (swap_flags & (uint32_t)(SwappedBuffer::SwapUV)) |
| ++extra_array_size; |
| |
| if (info.components == 1) |
| image = new CLImage2D (_context, info, CL_MEM_READ_WRITE); |
| else |
| image = new CLImage2DArray (_context, info, CL_MEM_READ_WRITE, extra_array_size); |
| XCAM_FAIL_RETURN ( |
| WARNING, |
| image.ptr () && image->get_mem_id (), |
| NULL, |
| "CLBoBufferPool create image failed"); |
| |
| desc = image->get_image_desc (); |
| mem_fd = image->export_fd (); |
| XCAM_FAIL_RETURN ( |
| WARNING, |
| mem_fd >= 0, |
| NULL, |
| "CLBoBufferPool export image fd failed"); |
| |
| bo = display->create_drm_bo_from_fd (mem_fd, desc.size); |
| XCAM_FAIL_RETURN ( |
| WARNING, |
| bo, |
| NULL, |
| "CLBoBufferPool bind fd to bo failed"); |
| |
| data = new CLImageBoData (display, image, bo); |
| XCAM_FAIL_RETURN ( |
| WARNING, |
| data.ptr (), |
| NULL, |
| "CLBoBufferPool bind CLImage to CLImageBoData failed"); |
| return data; |
| } |
| |
| bool |
| CLBoBufferPool::fixate_video_info (VideoBufferInfo &info) |
| { |
| bool need_reset_info = false; |
| uint32_t i = 0; |
| SmartPtr<CLImage> image; |
| uint32_t swap_flags = get_swap_flags (); |
| SmartPtr<CLImageBoData> image_data = create_image_bo (info); |
| XCAM_FAIL_RETURN ( |
| WARNING, |
| image_data.ptr (), |
| NULL, |
| "CLBoBufferPool fixate_video_info failed"); |
| |
| image = image_data->get_image (); |
| XCAM_ASSERT (image.ptr ()); |
| |
| CLImageDesc desc = image->get_image_desc (); |
| if (desc.row_pitch != info.strides [0] || desc.size != info.size) |
| need_reset_info = true; |
| |
| for (i = 1; i < info.components && !need_reset_info; ++i) { |
| XCAM_ASSERT (desc.slice_pitch && desc.array_size >= info.components); |
| if (desc.row_pitch != info.strides [i] || |
| info.offsets [i] != desc.slice_pitch * i) |
| need_reset_info = true; |
| } |
| if (need_reset_info) { |
| VideoBufferPlanarInfo plane_info; |
| info.get_planar_info (plane_info, 0); |
| uint32_t aligned_width = desc.row_pitch / plane_info.pixel_bytes; |
| uint32_t aligned_height = info.aligned_height; |
| if (info.components > 0) |
| aligned_height = desc.slice_pitch / desc.row_pitch; |
| info.init (info.format, info.width, info.height, aligned_width, aligned_height, desc.size); |
| for (i = 1; i < info.components; ++i) { |
| info.offsets[i] = desc.slice_pitch * i; |
| info.strides[i] = desc.row_pitch; |
| } |
| } |
| |
| if (swap_flags && desc.array_size >= 2) { |
| if (swap_flags & (uint32_t)(SwappedBuffer::SwapY)) { |
| _swap_offsets[SwappedBuffer::SwapYOffset0] = info.offsets[0]; |
| _swap_offsets[SwappedBuffer::SwapYOffset1] = desc.slice_pitch * 2; |
| } |
| if (swap_flags & (uint32_t)(SwappedBuffer::SwapUV)) { |
| _swap_offsets[SwappedBuffer::SwapUVOffset0] = info.offsets[1]; |
| _swap_offsets[SwappedBuffer::SwapUVOffset1] = desc.slice_pitch * (desc.array_size - 1); |
| } |
| } |
| |
| if(!init_swap_order (info)) { |
| XCAM_LOG_ERROR ("CLBoBufferPool: fix video info faield to init swap order"); |
| return false; |
| } |
| |
| add_data_unsafe (image_data); |
| |
| return true; |
| } |
| |
| SmartPtr<BufferData> |
| CLBoBufferPool::allocate_data (const VideoBufferInfo &buffer_info) |
| { |
| SmartPtr<CLImageBoData> image_data = create_image_bo (buffer_info); |
| return image_data; |
| } |
| |
| SmartPtr<BufferProxy> |
| CLBoBufferPool::create_buffer_from_data (SmartPtr<BufferData> &data) |
| { |
| const VideoBufferInfo & info = get_video_info (); |
| SmartPtr<CLImageBoData> image_data = data.dynamic_cast_ptr<CLImageBoData> (); |
| XCAM_ASSERT (image_data.ptr ()); |
| |
| SmartPtr<CLImageBoBuffer> out_buf = new CLImageBoBuffer (info, image_data); |
| XCAM_ASSERT (out_buf.ptr ()); |
| out_buf->set_swap_info (_swap_flags, _swap_offsets); |
| return out_buf; |
| } |
| |
| }; |