Home | History | Annotate | Download | only in ocl
      1 /*
      2  * cl_blender.cpp - CL blender
      3  *
      4  *  Copyright (c) 2016 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_blender.h"
     22 #include "cl_device.h"
     23 
     24 namespace XCam {
     25 
     26 CLBlenderScaleKernel::CLBlenderScaleKernel (const SmartPtr<CLContext> &context, bool is_uv)
     27     : CLImageKernel (context)
     28     , _is_uv (is_uv)
     29 {
     30 }
     31 
     32 XCamReturn
     33 CLBlenderScaleKernel::prepare_arguments (CLArgList &args, CLWorkSize &work_size)
     34 {
     35     SmartPtr<CLContext> context = get_context ();
     36 
     37     SmartPtr<CLImage> image_in = get_input_image ();
     38     SmartPtr<CLImage> image_out = get_output_image ();
     39     XCAM_ASSERT (image_in.ptr () && image_out.ptr ());
     40     int output_offset_x;
     41     uint32_t output_width, output_height;
     42     get_output_info (output_width, output_height, output_offset_x);
     43 
     44     args.push_back (new CLMemArgument (image_in));
     45     args.push_back (new CLMemArgument (image_out));
     46     args.push_back (new CLArgumentT<int> (output_offset_x));
     47     args.push_back (new CLArgumentT<uint32_t> (output_width));
     48     args.push_back (new CLArgumentT<uint32_t> (output_height));
     49 
     50     work_size.dim = XCAM_DEFAULT_IMAGE_DIM;
     51     work_size.local[0] = 8;
     52     work_size.local[1] = 4;
     53     work_size.global[0] = XCAM_ALIGN_UP (output_width, work_size.local[0]);
     54     work_size.global[1] = XCAM_ALIGN_UP (output_height, work_size.local[1]);
     55 
     56     return XCAM_RETURN_NO_ERROR;
     57 }
     58 
     59 CLBlender::CLBlender (
     60     const SmartPtr<CLContext> &context, const char *name,
     61     bool need_uv, CLBlenderScaleMode scale_mode)
     62     : CLImageHandler (context, name)
     63     , Blender (XCAM_CL_BLENDER_ALIGNMENT_X, XCAM_CL_BLENDER_ALIGNMENT_Y)
     64     , _need_uv (need_uv)
     65     , _swap_input_index (false)
     66     , _scale_mode (scale_mode)
     67 {
     68     XCAM_ASSERT (get_alignment_x () == XCAM_CL_BLENDER_ALIGNMENT_X);
     69     XCAM_ASSERT (get_alignment_y () == XCAM_CL_BLENDER_ALIGNMENT_Y);
     70 }
     71 
     72 bool
     73 CLBlender::set_input_merge_area (const Rect &area, uint32_t index)
     74 {
     75     Rect tmp_area = area;
     76     if (_scale_mode == CLBlenderScaleGlobal)
     77         tmp_area.width = get_merge_window ().width;
     78 
     79     bool ret = Blender::set_input_merge_area (tmp_area, index);
     80 
     81     if (ret && _scale_mode == CLBlenderScaleGlobal) {
     82         XCAM_ASSERT (fabs((int32_t)(area.width - get_merge_window ().width)) < XCAM_CL_BLENDER_ALIGNMENT_X);
     83     }
     84 
     85     return ret;
     86 }
     87 
     88 XCamReturn
     89 CLBlender::prepare_buffer_pool_video_info (
     90     const VideoBufferInfo &input,
     91     VideoBufferInfo &output)
     92 {
     93     uint32_t output_width, output_height;
     94     get_output_size (output_width, output_height);
     95     XCAM_ASSERT (output_height == input.height);
     96 
     97     // aligned at least XCAM_BLENDER_ALIGNED_WIDTH
     98     uint32_t aligned_width = XCAM_MAX (16, XCAM_CL_BLENDER_ALIGNMENT_X);
     99     output.init (
    100         input.format, output_width, output_height,
    101         XCAM_ALIGN_UP(output_width, aligned_width), XCAM_ALIGN_UP(output_height, 16));
    102     return XCAM_RETURN_NO_ERROR;
    103 }
    104 
    105 XCamReturn
    106 CLBlender::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
    107 {
    108     XCamReturn ret = XCAM_RETURN_NO_ERROR;
    109     XCAM_ASSERT (input.ptr () && output.ptr ());
    110     SmartPtr<VideoBuffer> input0, input1;
    111 
    112     SmartPtr<VideoBuffer> next = input->find_typed_attach<VideoBuffer> ();
    113     XCAM_FAIL_RETURN(
    114         WARNING,
    115         next.ptr (),
    116         XCAM_RETURN_ERROR_PARAM,
    117         "CLBlender(%s) does NOT find second buffer in attachment", get_name());
    118 
    119     if (_swap_input_index) {
    120         input0 = next;
    121         input1 = input;
    122     } else {
    123         input0 = input;
    124         input1 = next;
    125     }
    126 
    127     SmartPtr<CLContext> context = get_context ();
    128     const VideoBufferInfo &in0_info = input0->get_video_info ();
    129     const VideoBufferInfo &in1_info = input1->get_video_info ();
    130     const VideoBufferInfo &out_info = output->get_video_info ();
    131 
    132     if (!get_input_valid_area (0).width) {
    133         Rect area;
    134         area.width = in0_info.width;
    135         area.height = in0_info.height;
    136         set_input_valid_area (area, 0);
    137     }
    138     if (!get_input_valid_area (1).width) {
    139         Rect area;
    140         area.width = in1_info.width;
    141         area.height = in1_info.height;
    142         set_input_valid_area (area, 1);
    143     }
    144 
    145     if (!is_merge_window_set ()) {
    146         Rect merge_window;
    147         XCAM_FAIL_RETURN (
    148             WARNING,
    149             auto_calc_merge_window (get_input_valid_area(0).width, get_input_valid_area(1).width, out_info.width, merge_window),
    150             XCAM_RETURN_ERROR_PARAM,
    151             "CLBlender(%s) auto calculate merge window failed", get_name ());
    152 
    153         merge_window.pos_y = 0;
    154         merge_window.height = out_info.height;
    155         set_merge_window (merge_window);
    156 
    157         Rect area;
    158         area.width = merge_window.width;
    159         area.height = merge_window.height;
    160         area.pos_x = merge_window.pos_x;
    161         set_input_merge_area (area, 0);
    162         area.pos_x = 0;
    163         set_input_merge_area (area, 1);
    164     }
    165 
    166     ret = allocate_cl_buffers (context, input0, input1, output);
    167     return ret;
    168 }
    169 
    170 SmartPtr<Blender>
    171 create_ocl_blender ()
    172 {
    173     SmartPtr<CLContext> context = CLDevice::instance ()->get_context ();
    174     XCAM_FAIL_RETURN (
    175         ERROR, context.ptr (), NULL,
    176         "create ocl blender failed to get cl context");
    177     SmartPtr<CLBlender> blender = create_pyramid_blender (context, 2, true, false).dynamic_cast_ptr<CLBlender> ();
    178     XCAM_FAIL_RETURN (
    179         ERROR, blender.ptr (), NULL,
    180         "create ocl blender failed to get pyramid blender");
    181     return blender;
    182 }
    183 
    184 };
    185 
    186