/* * cl_blender.cpp - CL blender * * Copyright (c) 2016 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 */ #include "cl_blender.h" #include "cl_device.h" namespace XCam { CLBlenderScaleKernel::CLBlenderScaleKernel (const SmartPtr &context, bool is_uv) : CLImageKernel (context) , _is_uv (is_uv) { } XCamReturn CLBlenderScaleKernel::prepare_arguments (CLArgList &args, CLWorkSize &work_size) { SmartPtr context = get_context (); SmartPtr image_in = get_input_image (); SmartPtr image_out = get_output_image (); XCAM_ASSERT (image_in.ptr () && image_out.ptr ()); int output_offset_x; uint32_t output_width, output_height; get_output_info (output_width, output_height, output_offset_x); args.push_back (new CLMemArgument (image_in)); args.push_back (new CLMemArgument (image_out)); args.push_back (new CLArgumentT (output_offset_x)); args.push_back (new CLArgumentT (output_width)); args.push_back (new CLArgumentT (output_height)); work_size.dim = XCAM_DEFAULT_IMAGE_DIM; work_size.local[0] = 8; work_size.local[1] = 4; work_size.global[0] = XCAM_ALIGN_UP (output_width, work_size.local[0]); work_size.global[1] = XCAM_ALIGN_UP (output_height, work_size.local[1]); return XCAM_RETURN_NO_ERROR; } CLBlender::CLBlender ( const SmartPtr &context, const char *name, bool need_uv, CLBlenderScaleMode scale_mode) : CLImageHandler (context, name) , Blender (XCAM_CL_BLENDER_ALIGNMENT_X, XCAM_CL_BLENDER_ALIGNMENT_Y) , _need_uv (need_uv) , _swap_input_index (false) , _scale_mode (scale_mode) { XCAM_ASSERT (get_alignment_x () == XCAM_CL_BLENDER_ALIGNMENT_X); XCAM_ASSERT (get_alignment_y () == XCAM_CL_BLENDER_ALIGNMENT_Y); } bool CLBlender::set_input_merge_area (const Rect &area, uint32_t index) { Rect tmp_area = area; if (_scale_mode == CLBlenderScaleGlobal) tmp_area.width = get_merge_window ().width; bool ret = Blender::set_input_merge_area (tmp_area, index); if (ret && _scale_mode == CLBlenderScaleGlobal) { XCAM_ASSERT (fabs((int32_t)(area.width - get_merge_window ().width)) < XCAM_CL_BLENDER_ALIGNMENT_X); } return ret; } XCamReturn CLBlender::prepare_buffer_pool_video_info ( const VideoBufferInfo &input, VideoBufferInfo &output) { uint32_t output_width, output_height; get_output_size (output_width, output_height); XCAM_ASSERT (output_height == input.height); // aligned at least XCAM_BLENDER_ALIGNED_WIDTH uint32_t aligned_width = XCAM_MAX (16, XCAM_CL_BLENDER_ALIGNMENT_X); output.init ( input.format, output_width, output_height, XCAM_ALIGN_UP(output_width, aligned_width), XCAM_ALIGN_UP(output_height, 16)); return XCAM_RETURN_NO_ERROR; } XCamReturn CLBlender::prepare_parameters (SmartPtr &input, SmartPtr &output) { XCamReturn ret = XCAM_RETURN_NO_ERROR; XCAM_ASSERT (input.ptr () && output.ptr ()); SmartPtr input0, input1; SmartPtr next = input->find_typed_attach (); XCAM_FAIL_RETURN( WARNING, next.ptr (), XCAM_RETURN_ERROR_PARAM, "CLBlender(%s) does NOT find second buffer in attachment", get_name()); if (_swap_input_index) { input0 = next; input1 = input; } else { input0 = input; input1 = next; } SmartPtr context = get_context (); const VideoBufferInfo &in0_info = input0->get_video_info (); const VideoBufferInfo &in1_info = input1->get_video_info (); const VideoBufferInfo &out_info = output->get_video_info (); if (!get_input_valid_area (0).width) { Rect area; area.width = in0_info.width; area.height = in0_info.height; set_input_valid_area (area, 0); } if (!get_input_valid_area (1).width) { Rect area; area.width = in1_info.width; area.height = in1_info.height; set_input_valid_area (area, 1); } if (!is_merge_window_set ()) { Rect merge_window; XCAM_FAIL_RETURN ( WARNING, auto_calc_merge_window (get_input_valid_area(0).width, get_input_valid_area(1).width, out_info.width, merge_window), XCAM_RETURN_ERROR_PARAM, "CLBlender(%s) auto calculate merge window failed", get_name ()); merge_window.pos_y = 0; merge_window.height = out_info.height; set_merge_window (merge_window); Rect area; area.width = merge_window.width; area.height = merge_window.height; area.pos_x = merge_window.pos_x; set_input_merge_area (area, 0); area.pos_x = 0; set_input_merge_area (area, 1); } ret = allocate_cl_buffers (context, input0, input1, output); return ret; } SmartPtr create_ocl_blender () { SmartPtr context = CLDevice::instance ()->get_context (); XCAM_FAIL_RETURN ( ERROR, context.ptr (), NULL, "create ocl blender failed to get cl context"); SmartPtr blender = create_pyramid_blender (context, 2, true, false).dynamic_cast_ptr (); XCAM_FAIL_RETURN ( ERROR, blender.ptr (), NULL, "create ocl blender failed to get pyramid blender"); return blender; } };