OSDN Git Service

Remove vasurface.
[android-x86/external-IA-Hardware-Composer.git] / common / compositor / va / varenderer.cpp
1 /*
2 // Copyright (c) 2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include "varenderer.h"
18 #include "platformdefines.h"
19
20 #include <xf86drm.h>
21 #include <drm_fourcc.h>
22
23 #include "hwctrace.h"
24 #include "nativesurface.h"
25 #include "overlaybuffer.h"
26 #include "renderstate.h"
27
28 #ifdef ANDROID
29 #include <va/va_android.h>
30 #endif
31
32 #define ANDROID_DISPLAY_HANDLE 0x18C34078
33 #define UNUSED(x) (void*)(&x)
34
35 namespace hwcomposer {
36
37 VARenderer::~VARenderer() {
38   DestroyContext();
39
40   if (va_display_) {
41     vaTerminate(va_display_);
42   }
43 }
44
45 bool VARenderer::Init(int gpu_fd) {
46 #ifdef ANDROID
47   unsigned int native_display = ANDROID_DISPLAY_HANDLE;
48   va_display_ = vaGetDisplay(&native_display);
49   UNUSED(gpu_fd);
50 #else
51   va_display_ = vaGetDisplayDRM(gpu_fd);
52 #endif
53   if (!va_display_) {
54     ETRACE("vaGetDisplay failed\n");
55     return false;
56   }
57   VAStatus ret = VA_STATUS_SUCCESS;
58   int major, minor;
59   ret = vaInitialize(va_display_, &major, &minor);
60   return ret == VA_STATUS_SUCCESS ? true : false;
61 }
62
63 bool VARenderer::QueryVAProcFilterCaps(VAContextID context,
64                                        VAProcFilterType type, void* caps,
65                                        uint32_t* num) {
66   VAStatus ret =
67       vaQueryVideoProcFilterCaps(va_display_, context, type, caps, num);
68   if (ret != VA_STATUS_SUCCESS)
69     ETRACE("Query Filter Caps failed\n");
70   return ret == VA_STATUS_SUCCESS ? true : false;
71 }
72
73 bool VARenderer::MapVAProcFilterColorModetoHwc(HWCColorControl& vppmode,
74                                                VAProcColorBalanceType vamode) {
75   switch (vamode) {
76     case VAProcColorBalanceHue:
77       vppmode = HWCColorControl::kColorHue;
78       break;
79     case VAProcColorBalanceSaturation:
80       vppmode = HWCColorControl::kColorSaturation;
81       break;
82     case VAProcColorBalanceBrightness:
83       vppmode = HWCColorControl::kColorBrightness;
84       break;
85     case VAProcColorBalanceContrast:
86       vppmode = HWCColorControl::kColorContrast;
87       break;
88     default:
89       return false;
90   }
91   return true;
92 }
93
94 bool VARenderer::SetVAProcFilterColorDefaultValue(
95     VAProcFilterCapColorBalance* caps) {
96   HWCColorControl mode;
97   for (int i = 0; i < VAProcColorBalanceCount; i++) {
98     if (MapVAProcFilterColorModetoHwc(mode, caps[i].type)) {
99       caps_[mode].caps = caps[i];
100       caps_[mode].value = caps[i].range.default_value;
101     }
102   }
103
104   update_caps_ = true;
105   return true;
106 }
107
108 bool VARenderer::SetVAProcFilterColorValue(HWCColorControl mode, float value) {
109   if (value > caps_[mode].caps.range.max_value ||
110       value < caps_[mode].caps.range.min_value) {
111     ETRACE("VAlue Filter value out of range\n");
112     return false;
113   }
114   caps_[mode].value = value;
115   update_caps_ = true;
116   return true;
117 }
118
119 bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
120   CTRACE();
121   OverlayBuffer* buffer_out = surface->GetLayer()->GetBuffer();
122   int rt_format = DrmFormatToRTFormat(buffer_out->GetFormat());
123
124   if (va_context_ == VA_INVALID_ID || render_target_format_ != rt_format) {
125     render_target_format_ = rt_format;
126     if (!CreateContext()) {
127       ETRACE("Create VA context failed\n");
128       return false;
129     }
130   }
131
132   if (!UpdateCaps()) {
133     ETRACE("Failed to update capabailities. \n");
134     return false;
135   }
136
137   // Get Input Surface.
138   OverlayBuffer* buffer_in = state.layer_->GetBuffer();
139   const MediaResourceHandle& resource = buffer_in->GetMediaResource(
140       va_display_, state.layer_->GetSourceCropWidth(),
141       state.layer_->GetSourceCropHeight());
142   VASurfaceID surface_in = resource.surface_;
143   if (surface_in == VA_INVALID_ID) {
144     ETRACE("Failed to create Va Input Surface. \n");
145     return false;
146   }
147
148   // Get Output Surface.
149   const OverlayLayer* layer_out = surface->GetLayer();
150   const MediaResourceHandle& out_resource =
151       layer_out->GetBuffer()->GetMediaResource(
152           va_display_, layer_out->GetSourceCropWidth(),
153           layer_out->GetSourceCropHeight());
154   VASurfaceID surface_out = out_resource.surface_;
155   if (surface_out == VA_INVALID_ID) {
156     ETRACE("Failed to create Va Output Surface. \n");
157     return false;
158   }
159
160   VARectangle surface_region;
161   const OverlayLayer* layer_in = state.layer_;
162   const HwcRect<float>& source_crop = layer_in->GetSourceCrop();
163   surface_region.x = static_cast<int>(source_crop.left);
164   surface_region.y = static_cast<int>(source_crop.top);
165   surface_region.width = layer_in->GetSourceCropWidth();
166   surface_region.height = layer_in->GetSourceCropHeight();
167
168   VARectangle output_region;
169   const HwcRect<float>& source_crop_out = layer_out->GetSourceCrop();
170   output_region.x = static_cast<int>(source_crop_out.left);
171   output_region.y = static_cast<int>(source_crop_out.top);
172   output_region.width = layer_out->GetSourceCropWidth();
173   output_region.height = layer_out->GetSourceCropHeight();
174
175   param_.surface = surface_in;
176   param_.surface_region = &surface_region;
177   param_.output_region = &output_region;
178
179   DUMPTRACE("surface_region: (%d, %d, %d, %d)\n", surface_region.x,
180             surface_region.y, surface_region.width, surface_region.height);
181   DUMPTRACE("Layer DisplayFrame:(%d,%d,%d,%d)\n", output_region.x,
182             output_region.y, output_region.width, output_region.height);
183
184   for (HWCColorMap::const_iterator itr = state.colors_.begin();
185        itr != state.colors_.end(); itr++) {
186     SetVAProcFilterColorValue(itr->first, itr->second);
187   }
188
189   ScopedVABufferID pipeline_buffer(va_display_);
190   if (!pipeline_buffer.CreateBuffer(
191           va_context_, VAProcPipelineParameterBufferType,
192           sizeof(VAProcPipelineParameterBuffer), 1, &param_)) {
193     return false;
194   }
195
196   VAStatus ret = VA_STATUS_SUCCESS;
197   ret = vaBeginPicture(va_display_, va_context_, surface_out);
198   ret |=
199       vaRenderPicture(va_display_, va_context_, &pipeline_buffer.buffer(), 1);
200   ret |= vaEndPicture(va_display_, va_context_);
201
202   return ret == VA_STATUS_SUCCESS ? true : false;
203 }
204
205 bool VARenderer::DestroyMediaResources(
206     std::vector<struct media_import>& resources) {
207   size_t purged_size = resources.size();
208   for (size_t i = 0; i < purged_size; i++) {
209     MediaResourceHandle& handle = resources.at(i);
210     if (handle.surface_ != VA_INVALID_ID) {
211       vaDestroySurfaces(va_display_, &handle.surface_, 1);
212     }
213   }
214
215   return true;
216 }
217
218 bool VARenderer::CreateContext() {
219   DestroyContext();
220
221   VAConfigAttrib config_attrib;
222   config_attrib.type = VAConfigAttribRTFormat;
223   config_attrib.value = render_target_format_;
224   VAStatus ret =
225       vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc,
226                      &config_attrib, 1, &va_config_);
227   if (ret != VA_STATUS_SUCCESS) {
228     ETRACE("Create VA Config failed\n");
229     return false;
230   }
231
232   // These parameters are not used in vaCreateContext so just set them to dummy
233   // values
234   int width = 1;
235   int height = 1;
236   ret = vaCreateContext(va_display_, va_config_, width, height, 0x00, nullptr,
237                         0, &va_context_);
238
239   update_caps_ = true;
240   return ret == VA_STATUS_SUCCESS ? true : false;
241 }
242
243 void VARenderer::DestroyContext() {
244   if (va_context_ != VA_INVALID_ID) {
245     vaDestroyContext(va_display_, va_context_);
246     va_context_ = VA_INVALID_ID;
247   }
248   if (va_config_ != VA_INVALID_ID) {
249     vaDestroyConfig(va_display_, va_config_);
250     va_config_ = VA_INVALID_ID;
251   }
252
253   std::vector<VABufferID>().swap(filters_);
254   std::vector<ScopedVABufferID>().swap(cb_elements_);
255 }
256
257 bool VARenderer::UpdateCaps() {
258   if (!update_caps_) {
259     return true;
260   }
261
262   update_caps_ = true;
263
264   VAProcFilterCapColorBalance vacaps[VAProcColorBalanceCount];
265   uint32_t vacaps_num = VAProcColorBalanceCount;
266
267   if (caps_.empty()) {
268     if (!QueryVAProcFilterCaps(va_context_, VAProcFilterColorBalance, vacaps,
269                                &vacaps_num)) {
270       return false;
271     } else {
272       SetVAProcFilterColorDefaultValue(&vacaps[0]);
273     }
274   } else {
275     std::vector<ScopedVABufferID> cb_elements(VAProcColorBalanceCount,
276                                               va_display_);
277     std::vector<VABufferID>().swap(filters_);
278     std::vector<ScopedVABufferID>().swap(cb_elements_);
279     VAProcFilterParameterBufferColorBalance cbparam;
280     cbparam.type = VAProcFilterColorBalance;
281     cbparam.attrib = VAProcColorBalanceNone;
282
283     for (ColorBalanceCapMapItr itr = caps_.begin(); itr != caps_.end(); itr++) {
284       if (fabs(itr->second.value - itr->second.caps.range.default_value) >=
285           itr->second.caps.range.step) {
286         cbparam.value = itr->second.value;
287         cbparam.attrib = itr->second.caps.type;
288         if (!cb_elements[static_cast<int>(itr->first)].CreateBuffer(
289                 va_context_, VAProcFilterParameterBufferType,
290                 sizeof(VAProcFilterParameterBufferColorBalance), 1, &cbparam)) {
291           return false;
292         }
293         filters_.push_back(cb_elements[static_cast<int>(itr->first)].buffer());
294       }
295     }
296
297     cb_elements_.swap(cb_elements);
298   }
299
300   memset(&param_, 0, sizeof(VAProcPipelineParameterBuffer));
301   param_.surface_color_standard = VAProcColorStandardBT601;
302   param_.output_color_standard = VAProcColorStandardBT601;
303   param_.num_filters = 0;
304   param_.filters = nullptr;
305   param_.filter_flags = VA_FRAME_PICTURE;
306
307   if (filters_.size()) {
308     param_.filters = &filters_[0];
309     param_.num_filters = static_cast<unsigned int>(filters_.size());
310   }
311
312   return true;
313 }
314
315 }  // namespace hwcomposer