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