2 // Copyright (c) 2017 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "varenderer.h"
18 #include "platformdefines.h"
21 #include <drm_fourcc.h>
24 #include "nativesurface.h"
25 #include "overlaybuffer.h"
26 #include "renderstate.h"
29 #include <va/va_android.h>
32 #define ANDROID_DISPLAY_HANDLE 0x18C34078
33 #define UNUSED(x) (void*)(&x)
35 namespace hwcomposer {
37 VARenderer::~VARenderer() {
41 vaTerminate(va_display_);
45 bool VARenderer::Init(int gpu_fd) {
47 unsigned int native_display = ANDROID_DISPLAY_HANDLE;
48 va_display_ = vaGetDisplay(&native_display);
51 va_display_ = vaGetDisplayDRM(gpu_fd);
54 ETRACE("vaGetDisplay failed\n");
57 VAStatus ret = VA_STATUS_SUCCESS;
59 ret = vaInitialize(va_display_, &major, &minor);
60 return ret == VA_STATUS_SUCCESS ? true : false;
63 bool VARenderer::QueryVAProcFilterCaps(VAContextID context,
64 VAProcFilterType type, void* caps,
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;
73 bool VARenderer::MapVAProcFilterColorModetoHwc(HWCColorControl& vppmode,
74 VAProcColorBalanceType vamode) {
76 case VAProcColorBalanceHue:
77 vppmode = HWCColorControl::kColorHue;
79 case VAProcColorBalanceSaturation:
80 vppmode = HWCColorControl::kColorSaturation;
82 case VAProcColorBalanceBrightness:
83 vppmode = HWCColorControl::kColorBrightness;
85 case VAProcColorBalanceContrast:
86 vppmode = HWCColorControl::kColorContrast;
94 bool VARenderer::SetVAProcFilterColorDefaultValue(
95 VAProcFilterCapColorBalance* caps) {
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;
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");
114 caps_[mode].value = value;
119 bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
121 OverlayBuffer* buffer_out = surface->GetLayer()->GetBuffer();
122 int rt_format = DrmFormatToRTFormat(buffer_out->GetFormat());
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");
133 ETRACE("Failed to update capabailities. \n");
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");
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");
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();
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();
175 param_.surface = surface_in;
176 param_.surface_region = &surface_region;
177 param_.output_region = &output_region;
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);
184 for (HWCColorMap::const_iterator itr = state.colors_.begin();
185 itr != state.colors_.end(); itr++) {
186 SetVAProcFilterColorValue(itr->first, itr->second);
189 ScopedVABufferID pipeline_buffer(va_display_);
190 if (!pipeline_buffer.CreateBuffer(
191 va_context_, VAProcPipelineParameterBufferType,
192 sizeof(VAProcPipelineParameterBuffer), 1, ¶m_)) {
196 VAStatus ret = VA_STATUS_SUCCESS;
197 ret = vaBeginPicture(va_display_, va_context_, surface_out);
199 vaRenderPicture(va_display_, va_context_, &pipeline_buffer.buffer(), 1);
200 ret |= vaEndPicture(va_display_, va_context_);
202 return ret == VA_STATUS_SUCCESS ? true : false;
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);
218 bool VARenderer::CreateContext() {
221 VAConfigAttrib config_attrib;
222 config_attrib.type = VAConfigAttribRTFormat;
223 config_attrib.value = render_target_format_;
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");
232 // These parameters are not used in vaCreateContext so just set them to dummy
236 ret = vaCreateContext(va_display_, va_config_, width, height, 0x00, nullptr,
240 return ret == VA_STATUS_SUCCESS ? true : false;
243 void VARenderer::DestroyContext() {
244 if (va_context_ != VA_INVALID_ID) {
245 vaDestroyContext(va_display_, va_context_);
246 va_context_ = VA_INVALID_ID;
248 if (va_config_ != VA_INVALID_ID) {
249 vaDestroyConfig(va_display_, va_config_);
250 va_config_ = VA_INVALID_ID;
253 std::vector<VABufferID>().swap(filters_);
254 std::vector<ScopedVABufferID>().swap(cb_elements_);
257 bool VARenderer::UpdateCaps() {
264 VAProcFilterCapColorBalance vacaps[VAProcColorBalanceCount];
265 uint32_t vacaps_num = VAProcColorBalanceCount;
268 if (!QueryVAProcFilterCaps(va_context_, VAProcFilterColorBalance, vacaps,
272 SetVAProcFilterColorDefaultValue(&vacaps[0]);
275 std::vector<ScopedVABufferID> cb_elements(VAProcColorBalanceCount,
277 std::vector<VABufferID>().swap(filters_);
278 std::vector<ScopedVABufferID>().swap(cb_elements_);
279 VAProcFilterParameterBufferColorBalance cbparam;
280 cbparam.type = VAProcFilterColorBalance;
281 cbparam.attrib = VAProcColorBalanceNone;
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)) {
293 filters_.push_back(cb_elements[static_cast<int>(itr->first)].buffer());
297 cb_elements_.swap(cb_elements);
300 memset(¶m_, 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;
307 if (filters_.size()) {
308 param_.filters = &filters_[0];
309 param_.num_filters = static_cast<unsigned int>(filters_.size());
315 } // namespace hwcomposer