Home | History | Annotate | Download | only in ocl
      1 /*
      2  * cl_context.cpp - CL context
      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 
     22 #include "cl_context.h"
     23 #include "cl_kernel.h"
     24 #include "cl_device.h"
     25 #include <utility>
     26 
     27 #undef XCAM_CL_MAX_EVENT_SIZE
     28 #define XCAM_CL_MAX_EVENT_SIZE 256
     29 
     30 #define OCL_EXT_NAME_CREATE_BUFFER_FROM_LIBVA_INTEL "clCreateBufferFromLibvaIntel"
     31 #define OCL_EXT_NAME_CREATE_BUFFER_FROM_FD_INTEL    "clCreateBufferFromFdINTEL"
     32 #define OCL_EXT_NAME_CREATE_IMAGE_FROM_LIBVA_INTEL  "clCreateImageFromLibvaIntel"
     33 #define OCL_EXT_NAME_CREATE_IMAGE_FROM_FD_INTEL     "clCreateImageFromFdINTEL"
     34 #define OCL_EXT_NAME_GET_MEM_OBJECT_FD_INTEL        "clGetMemObjectFdIntel"
     35 
     36 namespace XCam {
     37 
     38 class CLKernel;
     39 
     40 void
     41 CLContext::context_pfn_notify (
     42     const char* erro_info,
     43     const void *private_info,
     44     size_t cb,
     45     void *user_data
     46 )
     47 {
     48     CLContext *context = (CLContext*) user_data;
     49     XCAM_UNUSED (context);
     50     XCAM_UNUSED (erro_info);
     51     XCAM_UNUSED (private_info);
     52     XCAM_UNUSED (cb);
     53     XCAM_LOG_DEBUG ("cl context pfn error:%s", XCAM_STR (erro_info));
     54 }
     55 
     56 void CLContext::program_pfn_notify (
     57     cl_program program, void *user_data)
     58 {
     59     CLContext *context = (CLContext*) user_data;
     60     char kernel_names [XCAM_CL_MAX_STR_SIZE];
     61 
     62     XCAM_UNUSED (context);
     63     XCAM_UNUSED (program);
     64     xcam_mem_clear (kernel_names);
     65     //clGetProgramInfo (program, CL_PROGRAM_KERNEL_NAMES, sizeof (kernel_names) - 1, kernel_names, NULL);
     66     //XCAM_LOG_DEBUG ("cl program report error on kernels: %s", kernel_names);
     67 }
     68 
     69 uint32_t
     70 CLContext::event_list_2_id_array (
     71     CLEventList &events_wait,
     72     cl_event *cl_events, uint32_t max_count)
     73 {
     74     uint32_t num_of_events_wait = 0;
     75 
     76     for (CLEventList::iterator iter = events_wait.begin ();
     77             iter != events_wait.end (); ++iter) {
     78         SmartPtr<CLEvent> &event = *iter;
     79 
     80         if (num_of_events_wait >= max_count) {
     81             XCAM_LOG_WARNING ("CLEventList(%d) larger than id_array(max_count:%d)", (uint32_t)events_wait.size(), max_count);
     82             break;
     83         }
     84         XCAM_ASSERT (event->get_event_id ());
     85         cl_events[num_of_events_wait++] = event->get_event_id ();
     86     }
     87 
     88     return num_of_events_wait;
     89 }
     90 
     91 
     92 CLContext::CLContext (SmartPtr<CLDevice> &device)
     93     : _context_id (NULL)
     94     , _device (device)
     95 {
     96     if (!init_context ()) {
     97         XCAM_LOG_ERROR ("CL init context failed");
     98     }
     99 
    100     XCAM_LOG_DEBUG ("CLContext constructed");
    101 }
    102 
    103 CLContext::~CLContext ()
    104 {
    105     destroy_context ();
    106     XCAM_LOG_DEBUG ("CLContext destructed");
    107 }
    108 
    109 void
    110 CLContext::terminate ()
    111 {
    112     //_kernel_map.clear ();
    113     _cmd_queue_list.clear ();
    114 }
    115 
    116 XCamReturn
    117 CLContext::flush ()
    118 {
    119     cl_int error_code = CL_SUCCESS;
    120     cl_command_queue cmd_queue_id = NULL;
    121     SmartPtr<CLCommandQueue> cmd_queue = get_default_cmd_queue ();
    122 
    123     XCAM_ASSERT (cmd_queue.ptr ());
    124     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    125     error_code = clFlush (cmd_queue_id);
    126 
    127     XCAM_FAIL_RETURN (
    128         WARNING,
    129         error_code == CL_SUCCESS,
    130         XCAM_RETURN_ERROR_CL,
    131         "CL flush cmdqueue failed with error_code:%d", error_code);
    132 
    133     return XCAM_RETURN_NO_ERROR;
    134 }
    135 
    136 
    137 XCamReturn
    138 CLContext::finish ()
    139 {
    140     cl_int error_code = CL_SUCCESS;
    141     cl_command_queue cmd_queue_id = NULL;
    142     SmartPtr<CLCommandQueue> cmd_queue = get_default_cmd_queue ();
    143 
    144     XCAM_ASSERT (cmd_queue.ptr ());
    145     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    146     error_code = clFinish (cmd_queue_id);
    147 
    148     XCAM_FAIL_RETURN (
    149         WARNING,
    150         error_code == CL_SUCCESS,
    151         XCAM_RETURN_ERROR_CL,
    152         "CL finish cmdqueue failed with error_code:%d", error_code);
    153 
    154     return XCAM_RETURN_NO_ERROR;
    155 }
    156 
    157 bool
    158 CLContext::init_context ()
    159 {
    160     cl_context context_id = NULL;
    161     cl_int err_code = 0;
    162     cl_device_id device_id = _device->get_device_id ();
    163 
    164     XCAM_ASSERT (_context_id == NULL);
    165 
    166     if (!_device->is_inited()) {
    167         XCAM_LOG_ERROR ("create cl context failed since device is not initialized");
    168         return false;
    169     }
    170 
    171     context_id =
    172         clCreateContext (NULL, 1, &device_id,
    173                          CLContext::context_pfn_notify, this,
    174                          &err_code);
    175     if (err_code != CL_SUCCESS)
    176     {
    177         XCAM_LOG_WARNING ("create cl context failed, error:%d", err_code);
    178         return false;
    179     }
    180     _context_id = context_id;
    181     return true;
    182 }
    183 
    184 bool
    185 CLContext::init_cmd_queue (SmartPtr<CLContext> &self)
    186 {
    187     XCAM_ASSERT (_cmd_queue_list.empty ());
    188     XCAM_ASSERT (self.ptr() == this);
    189     SmartPtr<CLCommandQueue> cmd_queue = create_cmd_queue (self);
    190     if (!cmd_queue.ptr ())
    191         return false;
    192 
    193     _cmd_queue_list.push_back (cmd_queue);
    194     return true;
    195 }
    196 
    197 SmartPtr<CLCommandQueue>
    198 CLContext::get_default_cmd_queue ()
    199 {
    200     CLCmdQueueList::iterator iter;
    201 
    202     XCAM_ASSERT (!_cmd_queue_list.empty ());
    203     if (_cmd_queue_list.empty ())
    204         return NULL;
    205     iter = _cmd_queue_list.begin ();
    206     return *iter;
    207 }
    208 
    209 void
    210 CLContext::destroy_context ()
    211 {
    212     if (!is_valid ())
    213         return;
    214     clReleaseContext (_context_id);
    215     _context_id = NULL;
    216 }
    217 
    218 XCamReturn
    219 CLContext::execute_kernel (
    220     const SmartPtr<CLKernel> kernel,
    221     const SmartPtr<CLCommandQueue> queue,
    222     CLEventList &events_wait,
    223     SmartPtr<CLEvent> &event_out)
    224 {
    225     XCAM_ASSERT (kernel.ptr ());
    226 
    227     cl_int error_code = CL_SUCCESS;
    228     cl_command_queue cmd_queue_id = NULL;
    229     cl_event *event_out_id = NULL;
    230     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
    231     uint32_t num_of_events_wait = 0;
    232     uint32_t work_group_size = 1;
    233     const size_t *local_sizes = NULL;
    234     cl_kernel kernel_id = kernel->get_kernel_id ();
    235     CLWorkSize work_size = kernel->get_work_size ();
    236     SmartPtr<CLCommandQueue> cmd_queue = queue;
    237 
    238     if (!cmd_queue.ptr ()) {
    239         cmd_queue = get_default_cmd_queue ();
    240     }
    241     XCAM_ASSERT (cmd_queue.ptr ());
    242 
    243     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    244     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
    245     if (event_out.ptr ())
    246         event_out_id = &event_out->get_event_id ();
    247 
    248     for (uint32_t i = 0; i < work_size.dim; ++i) {
    249         work_group_size *= work_size.local[i];
    250     }
    251     if (work_group_size)
    252         local_sizes = work_size.local;
    253     else
    254         local_sizes = NULL;
    255 
    256     error_code =
    257         clEnqueueNDRangeKernel (
    258             cmd_queue_id, kernel_id,
    259             work_size.dim, NULL, work_size.global, local_sizes,
    260             num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
    261             event_out_id);
    262 
    263     XCAM_FAIL_RETURN(
    264         WARNING,
    265         error_code == CL_SUCCESS,
    266         XCAM_RETURN_ERROR_CL,
    267         "execute kernel(%s) failed with error_code:%d",
    268         kernel->get_kernel_name (), error_code);
    269 
    270     return XCAM_RETURN_NO_ERROR;
    271 }
    272 
    273 XCamReturn
    274 CLContext::set_event_callback (
    275     SmartPtr<CLEvent> &event, cl_int status,
    276     void (*callback) (cl_event, cl_int, void*),
    277     void *user_data)
    278 {
    279     XCAM_ASSERT (event.ptr () && event->get_event_id ());
    280     cl_int error_code = clSetEventCallback (event->get_event_id (), status, callback, user_data);
    281     return (error_code == CL_SUCCESS ? XCAM_RETURN_NO_ERROR : XCAM_RETURN_ERROR_CL);
    282 }
    283 
    284 SmartPtr<CLCommandQueue>
    285 CLContext::create_cmd_queue (SmartPtr<CLContext> &self)
    286 {
    287     cl_device_id device_id = _device->get_device_id ();
    288     cl_command_queue cmd_queue_id = NULL;
    289     cl_int err_code = 0;
    290     SmartPtr<CLCommandQueue> result;
    291 
    292     XCAM_ASSERT (self.ptr() == this);
    293 
    294 #if defined (CL_VERSION_2_0) && (CL_VERSION_2_0 == 1)
    295     cmd_queue_id = clCreateCommandQueueWithProperties (_context_id, device_id, 0, &err_code);
    296 #else
    297     cmd_queue_id = clCreateCommandQueue (_context_id, device_id, 0, &err_code);
    298 #endif
    299     if (err_code != CL_SUCCESS) {
    300         XCAM_LOG_WARNING ("create CL command queue failed, errcode:%d", err_code);
    301         return NULL;
    302     }
    303 
    304     result = new CLCommandQueue (self, cmd_queue_id);
    305     return result;
    306 }
    307 
    308 cl_kernel
    309 CLContext::generate_kernel_id (
    310     CLKernel *kernel,
    311     const uint8_t *source, size_t length,
    312     CLContext::KernelBuildType type,
    313     uint8_t **gen_binary, size_t *binary_size,
    314     const char *build_option)
    315 {
    316     struct CLProgram {
    317         cl_program id;
    318 
    319         CLProgram ()
    320             : id (NULL)
    321         {}
    322         ~CLProgram () {
    323             if (id)
    324                 clReleaseProgram (id);
    325         }
    326     };
    327 
    328     CLProgram program;
    329     cl_kernel kernel_id = NULL;
    330     cl_int error_code = CL_SUCCESS;
    331     cl_device_id device_id = _device->get_device_id ();
    332     const char * name = kernel->get_kernel_name ();
    333 
    334     XCAM_ASSERT (source && length);
    335     XCAM_ASSERT (name);
    336 
    337     switch (type) {
    338     case KERNEL_BUILD_SOURCE:
    339         program.id =
    340             clCreateProgramWithSource (
    341                 _context_id, 1,
    342                 (const char**)(&source), (const size_t *)&length,
    343                 &error_code);
    344         break;
    345     case KERNEL_BUILD_BINARY:
    346         program.id =
    347             clCreateProgramWithBinary (
    348                 _context_id, 1, &device_id,
    349                 (const size_t *)&length, (const uint8_t**)(&source),
    350                 NULL, &error_code);
    351         break;
    352     }
    353 
    354     XCAM_FAIL_RETURN (
    355         WARNING,
    356         error_code == CL_SUCCESS,
    357         NULL,
    358         "cl create program failed with error_cod:%d", error_code);
    359     XCAM_ASSERT (program.id);
    360 
    361     error_code = clBuildProgram (program.id, 1, &device_id, build_option, CLContext::program_pfn_notify, this);
    362     if (error_code != CL_SUCCESS) {
    363         //char error_log [XCAM_CL_MAX_STR_SIZE];
    364         char error_log [1024 * 1024 + 32];
    365         xcam_mem_clear (error_log);
    366         clGetProgramBuildInfo (program.id, device_id, CL_PROGRAM_BUILD_LOG, sizeof (error_log) - 1, error_log, NULL);
    367         XCAM_LOG_WARNING ("CL build program failed on %s, build log:%s", name, error_log);
    368         return NULL;
    369     }
    370 
    371     if (gen_binary != NULL && binary_size != NULL) {
    372         error_code = clGetProgramInfo (program.id, CL_PROGRAM_BINARY_SIZES, sizeof (size_t) * 1, binary_size, NULL);
    373         if (error_code != CL_SUCCESS) {
    374             XCAM_LOG_WARNING ("CL query binary sizes failed on %s, errcode:%d", name, error_code);
    375         }
    376 
    377         *gen_binary = (uint8_t *) xcam_malloc0 (sizeof (uint8_t) * (*binary_size));
    378 
    379         error_code = clGetProgramInfo (program.id, CL_PROGRAM_BINARIES, sizeof (uint8_t *) * 1, gen_binary, NULL);
    380         if (error_code != CL_SUCCESS) {
    381             XCAM_LOG_WARNING ("CL query program binaries failed on %s, errcode:%d", name, error_code);
    382         }
    383     }
    384 
    385     kernel_id = clCreateKernel (program.id, name, &error_code);
    386     XCAM_FAIL_RETURN (
    387         WARNING,
    388         error_code == CL_SUCCESS,
    389         NULL,
    390         "cl create kernel(%s) failed with error_cod:%d", name, error_code);
    391 
    392     return kernel_id;
    393 }
    394 
    395 void
    396 CLContext::destroy_kernel_id (cl_kernel &kernel_id)
    397 {
    398     if (kernel_id) {
    399         clReleaseKernel (kernel_id);
    400         kernel_id = NULL;
    401     }
    402 }
    403 
    404 #if 0
    405 bool
    406 CLContext::insert_kernel (SmartPtr<CLKernel> &kernel)
    407 {
    408     std::string kernel_name = kernel->get_kernel_name ();
    409     CLKernelMap::iterator i_pos = _kernel_map.lower_bound (kernel_name);
    410 
    411     XCAM_ASSERT (!kernel_name.empty());
    412     if (i_pos != _kernel_map.end () && !_kernel_map.key_comp ()(kernel_name, i_pos->first)) {
    413         // need update
    414         i_pos->second = kernel;
    415         XCAM_LOG_DEBUG ("kernel:%s already exist in context, now update to new one", kernel_name.c_str());
    416         return true;
    417     }
    418 
    419     _kernel_map.insert (i_pos, std::make_pair (kernel_name, kernel));
    420     return true;
    421 }
    422 #endif
    423 
    424 cl_mem
    425 CLContext::create_image (
    426     cl_mem_flags flags, const cl_image_format& format,
    427     const cl_image_desc &image_info, void *host_ptr)
    428 {
    429     cl_mem mem_id = NULL;
    430     cl_int errcode = CL_SUCCESS;
    431 
    432     mem_id = clCreateImage (
    433                  _context_id, flags,
    434                  &format, &image_info,
    435                  host_ptr, &errcode);
    436 
    437     XCAM_FAIL_RETURN (
    438         WARNING,
    439         errcode == CL_SUCCESS,
    440         NULL,
    441         "create cl image failed, errcode:%d", errcode);
    442     return mem_id;
    443 }
    444 
    445 void
    446 CLContext::destroy_mem (cl_mem mem_id)
    447 {
    448     if (mem_id)
    449         clReleaseMemObject (mem_id);
    450 }
    451 
    452 cl_mem
    453 CLContext::create_buffer (uint32_t size, cl_mem_flags flags, void *host_ptr)
    454 {
    455     cl_mem mem_id = NULL;
    456     cl_int errcode = CL_SUCCESS;
    457 
    458     XCAM_ASSERT (_context_id);
    459 
    460     mem_id = clCreateBuffer (
    461                  _context_id, flags,
    462                  size, host_ptr,
    463                  &errcode);
    464 
    465     XCAM_FAIL_RETURN (
    466         WARNING,
    467         errcode == CL_SUCCESS,
    468         NULL,
    469         "create cl buffer failed, errcode:%d", errcode);
    470     return mem_id;
    471 }
    472 
    473 cl_mem
    474 CLContext::create_sub_buffer (
    475     cl_mem main_mem,
    476     cl_buffer_region region,
    477     cl_mem_flags flags)
    478 {
    479     cl_mem sub_mem = NULL;
    480     cl_int errcode = CL_SUCCESS;
    481 
    482     sub_mem = clCreateSubBuffer (main_mem, flags, CL_BUFFER_CREATE_TYPE_REGION, &region, &errcode);
    483     XCAM_FAIL_RETURN (
    484         WARNING,
    485         errcode == CL_SUCCESS,
    486         NULL,
    487         "create sub buffer failed, errcode:%d", errcode);
    488 
    489     return sub_mem;
    490 }
    491 
    492 XCamReturn
    493 CLContext::enqueue_read_buffer (
    494     cl_mem buf_id, void *ptr,
    495     uint32_t offset, uint32_t size,
    496     bool block,
    497     CLEventList &events_wait,
    498     SmartPtr<CLEvent> &event_out)
    499 {
    500     SmartPtr<CLCommandQueue> cmd_queue;
    501     cl_command_queue cmd_queue_id = NULL;
    502     cl_event *event_out_id = NULL;
    503     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
    504     uint32_t num_of_events_wait = 0;
    505     cl_int errcode = CL_SUCCESS;
    506 
    507     cmd_queue = get_default_cmd_queue ();
    508     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    509     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
    510     if (event_out.ptr ())
    511         event_out_id = &event_out->get_event_id ();
    512 
    513     XCAM_ASSERT (_context_id);
    514     XCAM_ASSERT (cmd_queue_id);
    515     errcode = clEnqueueReadBuffer (
    516                   cmd_queue_id, buf_id,
    517                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
    518                   offset, size, ptr,
    519                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
    520                   event_out_id);
    521 
    522     XCAM_FAIL_RETURN (
    523         WARNING,
    524         errcode == CL_SUCCESS,
    525         XCAM_RETURN_ERROR_CL,
    526         "cl enqueue read buffer failed with error_code:%d", errcode);
    527 
    528     return XCAM_RETURN_NO_ERROR;
    529 }
    530 
    531 XCamReturn
    532 CLContext::enqueue_write_buffer (
    533     cl_mem buf_id, void *ptr,
    534     uint32_t offset, uint32_t size,
    535     bool block,
    536     CLEventList &events_wait,
    537     SmartPtr<CLEvent> &event_out)
    538 {
    539     SmartPtr<CLCommandQueue> cmd_queue;
    540     cl_command_queue cmd_queue_id = NULL;
    541     cl_event *event_out_id = NULL;
    542     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
    543     uint32_t num_of_events_wait = 0;
    544     cl_int errcode = CL_SUCCESS;
    545 
    546     cmd_queue = get_default_cmd_queue ();
    547     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    548     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
    549     if (event_out.ptr ())
    550         event_out_id = &event_out->get_event_id ();
    551 
    552     XCAM_ASSERT (_context_id);
    553     XCAM_ASSERT (cmd_queue_id);
    554     errcode = clEnqueueWriteBuffer (
    555                   cmd_queue_id, buf_id,
    556                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
    557                   offset, size, ptr,
    558                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
    559                   event_out_id);
    560 
    561     XCAM_FAIL_RETURN (
    562         WARNING,
    563         errcode == CL_SUCCESS,
    564         XCAM_RETURN_ERROR_CL,
    565         "cl enqueue write buffer failed with error_code:%d", errcode);
    566 
    567     return XCAM_RETURN_NO_ERROR;
    568 }
    569 
    570 XCamReturn
    571 CLContext::enqueue_map_buffer (
    572     cl_mem buf_id, void *&ptr,
    573     uint32_t offset, uint32_t size,
    574     bool block,
    575     cl_map_flags map_flags,
    576     CLEventList &events_wait,
    577     SmartPtr<CLEvent> &event_out)
    578 {
    579     SmartPtr<CLCommandQueue> cmd_queue;
    580     cl_command_queue cmd_queue_id = NULL;
    581     cl_event *event_out_id = NULL;
    582     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
    583     uint32_t num_of_events_wait = 0;
    584     cl_int errcode = CL_SUCCESS;
    585     void *out_ptr = NULL;
    586 
    587     cmd_queue = get_default_cmd_queue ();
    588     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    589     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
    590     if (event_out.ptr ())
    591         event_out_id = &event_out->get_event_id ();
    592 
    593     XCAM_ASSERT (_context_id);
    594     XCAM_ASSERT (cmd_queue_id);
    595     out_ptr = clEnqueueMapBuffer (
    596                   cmd_queue_id, buf_id,
    597                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
    598                   map_flags,
    599                   offset, size,
    600                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
    601                   event_out_id,
    602                   &errcode);
    603 
    604     XCAM_FAIL_RETURN (
    605         WARNING,
    606         out_ptr && errcode == CL_SUCCESS,
    607         XCAM_RETURN_ERROR_CL,
    608         "cl enqueue map buffer failed with error_code:%d", errcode);
    609 
    610     ptr = out_ptr;
    611     return XCAM_RETURN_NO_ERROR;
    612 }
    613 
    614 
    615 XCamReturn
    616 CLContext::enqueue_map_image (
    617     cl_mem buf_id, void *&ptr,
    618     const size_t *origin,
    619     const size_t *region,
    620     size_t *image_row_pitch,
    621     size_t *image_slice_pitch,
    622     bool block,
    623     cl_map_flags map_flags,
    624     CLEventList &events_wait,
    625     SmartPtr<CLEvent> &event_out)
    626 {
    627     SmartPtr<CLCommandQueue> cmd_queue;
    628     cl_command_queue cmd_queue_id = NULL;
    629     cl_event *event_out_id = NULL;
    630     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
    631     uint32_t num_of_events_wait = 0;
    632     cl_int errcode = CL_SUCCESS;
    633     void *out_ptr = NULL;
    634 
    635     cmd_queue = get_default_cmd_queue ();
    636     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    637     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
    638     if (event_out.ptr ())
    639         event_out_id = &event_out->get_event_id ();
    640 
    641     XCAM_ASSERT (_context_id);
    642     XCAM_ASSERT (cmd_queue_id);
    643 
    644     out_ptr = clEnqueueMapImage (
    645                   cmd_queue_id, buf_id,
    646                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
    647                   map_flags,
    648                   origin,
    649                   region,
    650                   image_row_pitch,
    651                   image_slice_pitch,
    652                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
    653                   event_out_id,
    654                   &errcode);
    655 
    656     XCAM_FAIL_RETURN (
    657         WARNING,
    658         out_ptr && errcode == CL_SUCCESS,
    659         XCAM_RETURN_ERROR_CL,
    660         "cl enqueue map buffer failed with error_code:%d", errcode);
    661 
    662     ptr = out_ptr;
    663     return XCAM_RETURN_NO_ERROR;
    664 }
    665 
    666 XCamReturn
    667 CLContext::enqueue_unmap (
    668     cl_mem mem_id,
    669     void *ptr,
    670     CLEventList &events_wait,
    671     SmartPtr<CLEvent> &event_out)
    672 {
    673     SmartPtr<CLCommandQueue> cmd_queue;
    674     cl_command_queue cmd_queue_id = NULL;
    675     cl_event *event_out_id = NULL;
    676     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
    677     uint32_t num_of_events_wait = 0;
    678     cl_int errcode = CL_SUCCESS;
    679 
    680     cmd_queue = get_default_cmd_queue ();
    681     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
    682     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
    683     if (event_out.ptr ())
    684         event_out_id = &event_out->get_event_id ();
    685 
    686     XCAM_ASSERT (_context_id);
    687     XCAM_ASSERT (cmd_queue_id);
    688     errcode = clEnqueueUnmapMemObject (
    689                   cmd_queue_id, mem_id, ptr,
    690                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
    691                   event_out_id);
    692 
    693     XCAM_FAIL_RETURN (
    694         WARNING,
    695         errcode == CL_SUCCESS,
    696         XCAM_RETURN_ERROR_CL,
    697         "cl enqueue unmap buffer failed with error_code:%d", errcode);
    698 
    699     return XCAM_RETURN_NO_ERROR;
    700 }
    701 
    702 CLCommandQueue::CLCommandQueue (SmartPtr<CLContext> &context, cl_command_queue id)
    703     : _context (context)
    704     , _cmd_queue_id (id)
    705 {
    706     XCAM_ASSERT (context.ptr ());
    707     XCAM_ASSERT (id);
    708     XCAM_LOG_DEBUG ("CLCommandQueue constructed");
    709 }
    710 
    711 CLCommandQueue::~CLCommandQueue ()
    712 {
    713     destroy ();
    714     XCAM_LOG_DEBUG ("CLCommandQueue desstructed");
    715 }
    716 
    717 void
    718 CLCommandQueue::destroy ()
    719 {
    720     if (_cmd_queue_id == NULL)
    721         return;
    722 
    723     clReleaseCommandQueue (_cmd_queue_id);
    724     _cmd_queue_id = NULL;
    725 }
    726 
    727 };
    728