Home | History | Annotate | Download | only in ocl
      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