• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@intel.com>
19  */
20 
21 #include "cl_blender.h"
22 #include "cl_device.h"
23 
24 namespace XCam {
25 
CLBlenderScaleKernel(const SmartPtr<CLContext> & context,bool is_uv)26 CLBlenderScaleKernel::CLBlenderScaleKernel (const SmartPtr<CLContext> &context, bool is_uv)
27     : CLImageKernel (context)
28     , _is_uv (is_uv)
29 {
30 }
31 
32 XCamReturn
prepare_arguments(CLArgList & args,CLWorkSize & work_size)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 
CLBlender(const SmartPtr<CLContext> & context,const char * name,bool need_uv,CLBlenderScaleMode scale_mode)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
set_input_merge_area(const Rect & area,uint32_t index)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
prepare_buffer_pool_video_info(const VideoBufferInfo & input,VideoBufferInfo & output)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
prepare_parameters(SmartPtr<VideoBuffer> & input,SmartPtr<VideoBuffer> & output)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>
create_ocl_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