• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * cl_va_memory.cpp - CL va memory
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@intel.com>
19  */
20 
21 #include "cl_va_memory.h"
22 #include "cl_image_bo_buffer.h"
23 
24 namespace XCam {
25 
CLVaBuffer(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo)26 CLVaBuffer::CLVaBuffer (
27     const SmartPtr<CLIntelContext> &context,
28     SmartPtr<DrmBoBuffer> &bo)
29     : CLBuffer (context)
30     , _bo (bo)
31 {
32     init_va_buffer (context, bo);
33 }
34 
35 bool
init_va_buffer(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo)36 CLVaBuffer::init_va_buffer (const SmartPtr<CLIntelContext> &context, SmartPtr<DrmBoBuffer> &bo)
37 {
38     cl_mem mem_id = NULL;
39     uint32_t bo_name = 0;
40     cl_import_buffer_info_intel import_buffer_info;
41 
42     xcam_mem_clear (import_buffer_info);
43     import_buffer_info.fd = bo->get_fd ();
44     import_buffer_info.size = bo->get_size ();
45     if (import_buffer_info.fd != -1) {
46         mem_id = context->import_dma_buffer (import_buffer_info);
47     }
48 
49     if (mem_id == NULL) {
50         drm_intel_bo_flink (bo->get_bo (), &bo_name);
51         mem_id = context->create_va_buffer (bo_name);
52         if (mem_id == NULL) {
53             XCAM_LOG_WARNING ("CLVaBuffer create va buffer failed");
54             return false;
55         }
56     }
57 
58     set_mem_id (mem_id);
59     return true;
60 }
61 
CLVaImage(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo,uint32_t offset,bool single_plane)62 CLVaImage::CLVaImage (
63     const SmartPtr<CLIntelContext> &context,
64     SmartPtr<DrmBoBuffer> &bo,
65     uint32_t offset,
66     bool single_plane)
67     : CLImage (context)
68     , _bo (bo)
69 {
70     CLImageDesc cl_desc;
71 
72     const VideoBufferInfo & video_info = bo->get_video_info ();
73     if (!video_info_2_cl_image_desc (video_info, cl_desc)) {
74         XCAM_LOG_WARNING ("CLVaImage create va image failed on default videoinfo");
75         return;
76     }
77     if (single_plane) {
78         cl_desc.array_size = 0;
79         cl_desc.slice_pitch = 0;
80     } else if (!merge_multi_plane (video_info, cl_desc)) {
81         XCAM_LOG_WARNING ("CLVaImage create va image failed on merging planes");
82         return;
83     }
84 
85     init_va_image (context, bo, cl_desc, offset);
86 }
87 
CLVaImage(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo,const CLImageDesc & image_info,uint32_t offset)88 CLVaImage::CLVaImage (
89     const SmartPtr<CLIntelContext> &context,
90     SmartPtr<DrmBoBuffer> &bo,
91     const CLImageDesc &image_info,
92     uint32_t offset)
93     : CLImage (context)
94     , _bo (bo)
95 {
96     init_va_image (context, bo, image_info, offset);
97 }
98 
99 bool
merge_multi_plane(const VideoBufferInfo & video_info,CLImageDesc & cl_desc)100 CLVaImage::merge_multi_plane (
101     const VideoBufferInfo &video_info,
102     CLImageDesc &cl_desc)
103 {
104     if (cl_desc.array_size <= 1)
105         return true;
106 
107     switch (video_info.format) {
108     case V4L2_PIX_FMT_NV12:
109         cl_desc.height = video_info.aligned_height + video_info.height / 2;
110         break;
111 
112     case XCAM_PIX_FMT_RGB48_planar:
113     case XCAM_PIX_FMT_RGB24_planar:
114         cl_desc.height = video_info.aligned_height * 3;
115         break;
116 
117     case XCAM_PIX_FMT_SGRBG16_planar:
118     case XCAM_PIX_FMT_SGRBG8_planar:
119         cl_desc.height = video_info.aligned_height * 4;
120         break;
121 
122     default:
123         XCAM_LOG_WARNING ("CLVaImage unknown format(%s) plane change", xcam_fourcc_to_string(video_info.format));
124         return false;
125     }
126     cl_desc.array_size = 0;
127     cl_desc.slice_pitch = 0;
128     return true;
129 }
130 
131 bool
init_va_image(const SmartPtr<CLIntelContext> & context,SmartPtr<DrmBoBuffer> & bo,const CLImageDesc & cl_desc,uint32_t offset)132 CLVaImage::init_va_image (
133     const SmartPtr<CLIntelContext> &context, SmartPtr<DrmBoBuffer> &bo,
134     const CLImageDesc &cl_desc, uint32_t offset)
135 {
136 
137     uint32_t bo_name = 0;
138     cl_mem mem_id = 0;
139     bool need_create = true;
140     cl_libva_image va_image_info;
141     cl_import_image_info_intel import_image_info;
142 
143     xcam_mem_clear (va_image_info);
144     xcam_mem_clear (import_image_info);
145     import_image_info.offset = va_image_info.offset = offset;
146     import_image_info.width = va_image_info.width = cl_desc.width;
147     import_image_info.height = va_image_info.height = cl_desc.height;
148     import_image_info.fmt = va_image_info.fmt = cl_desc.format;
149     import_image_info.row_pitch = va_image_info.row_pitch = cl_desc.row_pitch;
150     import_image_info.size = cl_desc.size;
151     import_image_info.type = CL_MEM_OBJECT_IMAGE2D;
152 
153     XCAM_ASSERT (bo.ptr ());
154 
155     SmartPtr<CLImageBoBuffer> cl_image_buffer = bo.dynamic_cast_ptr<CLImageBoBuffer> ();
156     if (cl_image_buffer.ptr ()) {
157         SmartPtr<CLImage> cl_image_data = cl_image_buffer->get_cl_image ();
158         XCAM_ASSERT (cl_image_data.ptr ());
159         CLImageDesc old_desc = cl_image_data->get_image_desc ();
160         if (cl_desc == old_desc) {
161             need_create = false;
162             mem_id = cl_image_data->get_mem_id ();
163         }
164     }
165 
166     if (need_create) {
167         import_image_info.fd = bo->get_fd();
168         if (import_image_info.fd != -1)
169             mem_id = context->import_dma_image (import_image_info);
170 
171         if (mem_id == NULL) {
172             if (drm_intel_bo_flink (bo->get_bo (), &bo_name) == 0) {
173                 va_image_info.bo_name = bo_name;
174                 mem_id = context->create_va_image (va_image_info);
175             }
176             if (mem_id == NULL) {
177                 XCAM_LOG_WARNING ("create va image failed");
178                 return false;
179             }
180         }
181     } else {
182         va_image_info.bo_name = uint32_t(-1);
183     }
184 
185     set_mem_id (mem_id, need_create);
186     init_desc_by_image ();
187     _va_image_info = va_image_info;
188     return true;
189 }
190 
191 };
192