blob: fee67b44a472d657f671e5f5e87e811d2eed129d [file] [log] [blame]
Naseer Ahmedb92e73f2016-03-12 02:03:48 -05001/*
Saurabh Shah7d476ed2016-06-27 16:40:58 -07002 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
Naseer Ahmedb92e73f2016-03-12 02:03:48 -05003 * Not a Contribution.
4 *
5 * Copyright 2015 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -080020#include <stdint.h>
Gurunath Ramaswamyf081afe2017-07-04 22:08:36 -070021#include <utility>
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -080022#include <qdMetaData.h>
23
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050024#include "hwc_layers.h"
Naseer Ahmed42752212017-01-27 17:32:21 -050025#ifndef USE_GRALLOC1
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050026#include <gr.h>
Naseer Ahmed42752212017-01-27 17:32:21 -050027#endif
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050028#include <utils/debug.h>
29#include <cmath>
30
31#define __CLASS__ "HWCLayer"
32
33namespace sdm {
34
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050035std::atomic<hwc2_layer_t> HWCLayer::next_id_(1);
36
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -080037DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_metadata) {
38 if (getMetaData(const_cast<private_handle_t *>(pvt_handle), GET_COLOR_METADATA,
39 color_metadata) != 0) {
40 ColorSpace_t csc = ITU_R_601;
41 if (getMetaData(const_cast<private_handle_t *>(pvt_handle), GET_COLOR_SPACE,
42 &csc) == 0) {
43 if (csc == ITU_R_601_FR || csc == ITU_R_2020_FR) {
44 color_metadata->range = Range_Full;
45 }
Arun Kumar K.Rbc0addf2016-10-03 22:38:16 -070046
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -080047 switch (csc) {
48 case ITU_R_601:
49 case ITU_R_601_FR:
50 // video and display driver uses 601_525
51 color_metadata->colorPrimaries = ColorPrimaries_BT601_6_525;
52 break;
53 case ITU_R_709:
54 color_metadata->colorPrimaries = ColorPrimaries_BT709_5;
55 break;
56 case ITU_R_2020:
57 case ITU_R_2020_FR:
Arun Kumar K.Rbc0addf2016-10-03 22:38:16 -070058 color_metadata->colorPrimaries = ColorPrimaries_BT2020;
59 break;
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -080060 default:
61 DLOGE("Unsupported CSC: %d", csc);
62 return kErrorNotSupported;
63 }
64 } else {
Arun Kumar K.Rbc0addf2016-10-03 22:38:16 -070065 return kErrorNotSupported;
66 }
67 }
68
69 return kErrorNone;
70}
71
Arun Kumar K.R80e58eb2017-07-13 10:37:00 +053072// Returns true when color primary is supported
73bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary) {
74 auto standard = dataspace & HAL_DATASPACE_STANDARD_MASK;
75 bool supported_csc = true;
76 switch (standard) {
77 case HAL_DATASPACE_STANDARD_BT709:
78 *color_primary = ColorPrimaries_BT709_5;
79 break;
80 case HAL_DATASPACE_STANDARD_BT601_525:
81 case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
82 *color_primary = ColorPrimaries_BT601_6_525;
83 break;
84 case HAL_DATASPACE_STANDARD_BT601_625:
85 case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
86 *color_primary = ColorPrimaries_BT601_6_625;
87 break;
88 case HAL_DATASPACE_STANDARD_DCI_P3:
89 *color_primary = ColorPrimaries_DCIP3;
90 break;
91 case HAL_DATASPACE_STANDARD_BT2020:
92 *color_primary = ColorPrimaries_BT2020;
93 break;
94 default:
95 DLOGV_IF(kTagStrategy, "Unsupported Standard Request = %d", standard);
96 supported_csc = false;
97 }
98 return supported_csc;
99}
100
101bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer) {
102 auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK;
103 bool supported_transfer = true;
104 switch (transfer) {
105 case HAL_DATASPACE_TRANSFER_SRGB:
106 *gamma_transfer = Transfer_sRGB;
107 break;
108 case HAL_DATASPACE_TRANSFER_SMPTE_170M:
109 *gamma_transfer = Transfer_SMPTE_170M;
110 break;
111 case HAL_DATASPACE_TRANSFER_ST2084:
112 *gamma_transfer = Transfer_SMPTE_ST2084;
113 break;
114 case HAL_DATASPACE_TRANSFER_HLG:
115 *gamma_transfer = Transfer_HLG;
116 break;
117 case HAL_DATASPACE_TRANSFER_LINEAR:
118 *gamma_transfer = Transfer_Linear;
119 break;
120 case HAL_DATASPACE_TRANSFER_GAMMA2_2:
121 *gamma_transfer = Transfer_Gamma2_2;
122 break;
123 default:
124 DLOGV_IF(kTagStrategy, "Unsupported Transfer Request = %d", transfer);
125 supported_transfer = false;
126 }
127 return supported_transfer;
128}
129
130void GetRange(const int32_t &dataspace, ColorRange *color_range) {
131 auto range = dataspace & HAL_DATASPACE_RANGE_MASK;
132 switch (range) {
133 case HAL_DATASPACE_RANGE_FULL:
134 *color_range = Range_Full;
135 break;
136 case HAL_DATASPACE_RANGE_LIMITED:
137 *color_range = Range_Limited;
138 break;
139 default:
140 DLOGV_IF(kTagStrategy, "Unsupported Range Request = %d", range);
141 break;
142 }
143}
144
145bool IsBT2020(const ColorPrimaries &color_primary) {
146 switch (color_primary) {
147 case ColorPrimaries_BT2020:
148 return true;
149 break;
150 default:
151 return false;
152 }
153}
154
155// Retrieve ColorMetaData from android_data_space_t (STANDARD|TRANSFER|RANGE)
156bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata) {
157 bool valid = false;
158 valid = GetColorPrimary(dataspace, &(color_metadata->colorPrimaries));
159 if (!valid) {
160 return valid;
161 }
162 valid = GetTransfer(dataspace, &(color_metadata->transfer));
163 if (!valid) {
164 return valid;
165 }
166 GetRange(dataspace, &(color_metadata->range));
167
168 return true;
169}
170
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500171// Layer operations
Naseer Ahmed42752212017-01-27 17:32:21 -0500172HWCLayer::HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator)
173 : id_(next_id_++), display_id_(display_id), buffer_allocator_(buf_allocator) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500174 layer_ = new Layer();
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500175 // Fences are deferred, so the first time this layer is presented, return -1
176 // TODO(user): Verify that fences are properly obtained on suspend/resume
177 release_fences_.push(-1);
178}
179
180HWCLayer::~HWCLayer() {
181 // Close any fences left for this layer
182 while (!release_fences_.empty()) {
183 close(release_fences_.front());
184 release_fences_.pop();
185 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500186 if (layer_) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500187 delete layer_;
188 }
189}
190
191HWC2::Error HWCLayer::SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence) {
192 if (!buffer) {
Naseer Ahmed2f71fd02017-06-01 19:55:39 -0400193 if (client_requested_ == HWC2::Composition::Device ||
194 client_requested_ == HWC2::Composition::Cursor) {
195 DLOGE("Invalid buffer handle: %p on layer: %d", buffer, id_);
196 return HWC2::Error::BadParameter;
197 } else {
198 return HWC2::Error::None;
199 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500200 }
201
Naseer Ahmede3f007a2016-06-07 18:13:28 -0400202 if (acquire_fence == 0) {
203 DLOGE("acquire_fence is zero");
204 return HWC2::Error::BadParameter;
205 }
206
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500207 const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
Naseer Ahmed6fe11ed2016-08-26 21:15:44 -0400208
Naseer Ahmed6fe11ed2016-08-26 21:15:44 -0400209 if (handle->fd < 0) {
210 return HWC2::Error::BadParameter;
Naseer Ahmed6fe11ed2016-08-26 21:15:44 -0400211 }
212
Arun Kumar K.R9c19cdd2016-11-21 16:48:43 -0800213 LayerBuffer *layer_buffer = &layer_->input_buffer;
Ramkumar Radhakrishnanb27735f2016-08-26 22:37:23 -0700214 int aligned_width, aligned_height;
Naseer Ahmed42752212017-01-27 17:32:21 -0500215#ifdef USE_GRALLOC1
216 buffer_allocator_->GetCustomWidthAndHeight(handle, &aligned_width, &aligned_height);
217#else
Ramkumar Radhakrishnanb27735f2016-08-26 22:37:23 -0700218 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(handle, aligned_width, aligned_height);
Naseer Ahmed42752212017-01-27 17:32:21 -0500219#endif
Ramkumar Radhakrishnanb27735f2016-08-26 22:37:23 -0700220
Sushil Chauhan409e8442017-06-12 17:43:25 -0700221 LayerBufferFormat format = GetSDMFormat(handle->format, handle->flags);
222 if ((format != layer_buffer->format) || (UINT32(aligned_width) != layer_buffer->width) ||
223 (UINT32(aligned_height) != layer_buffer->height)) {
224 // Layer buffer geometry has changed.
225 geometry_changes_ |= kBufferGeometry;
226 }
227
228 layer_buffer->format = format;
Ramkumar Radhakrishnanb27735f2016-08-26 22:37:23 -0700229 layer_buffer->width = UINT32(aligned_width);
230 layer_buffer->height = UINT32(aligned_height);
Naseer Ahmed42752212017-01-27 17:32:21 -0500231 layer_buffer->unaligned_width = UINT32(handle->unaligned_width);
232 layer_buffer->unaligned_height = UINT32(handle->unaligned_height);
Ramkumar Radhakrishnanb27735f2016-08-26 22:37:23 -0700233
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800234 if (SetMetaData(const_cast<private_handle_t *>(handle), layer_) != kErrorNone) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500235 return HWC2::Error::BadLayer;
236 }
237
Sushil Chauhan409e8442017-06-12 17:43:25 -0700238 layer_buffer->flags.video = (handle->buffer_type == BUFFER_TYPE_VIDEO) ? true : false;
239
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500240 // TZ Protected Buffer - L1
Sushil Chauhan409e8442017-06-12 17:43:25 -0700241 bool secure = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER);
242 bool secure_camera = secure && (handle->flags & private_handle_t::PRIV_FLAGS_CAMERA_WRITE);
243 bool secure_display = (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY);
244 if (secure != layer_buffer->flags.secure || secure_camera != layer_buffer->flags.secure_camera ||
245 secure_display != layer_buffer->flags.secure_display) {
246 // Secure attribute of layer buffer has changed.
247 needs_validate_ = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500248 }
Sushil Chauhan409e8442017-06-12 17:43:25 -0700249
250 layer_buffer->flags.secure = secure;
251 layer_buffer->flags.secure_camera = secure_camera;
252 layer_buffer->flags.secure_display = secure_display;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500253
Pullakavi Srinivas756b1fc2017-08-08 14:32:06 +0530254 layer_buffer->planes[0].fd = handle->fd;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500255 layer_buffer->planes[0].offset = handle->offset;
256 layer_buffer->planes[0].stride = UINT32(handle->width);
257 layer_buffer->acquire_fence_fd = acquire_fence;
Naseer Ahmed18630d32016-10-26 16:14:19 -0400258 layer_buffer->size = handle->size;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500259 layer_buffer->buffer_id = reinterpret_cast<uint64_t>(handle);
260
261 return HWC2::Error::None;
262}
263
264HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
Sushil Chauhan409e8442017-06-12 17:43:25 -0700265 // Check if there is an update in SurfaceDamage rects
266 if (layer_->dirty_regions.size() != damage.numRects) {
267 needs_validate_ = true;
268 } else {
269 for (uint32_t j = 0; j < damage.numRects; j++) {
270 LayerRect damage_rect;
271 SetRect(damage.rects[j], &damage_rect);
272 if (damage_rect != layer_->dirty_regions.at(j)) {
273 needs_validate_ = true;
274 break;
275 }
276 }
277 }
278
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700279 layer_->dirty_regions.clear();
Naseer Ahmed6786e5d2016-06-24 16:38:52 -0400280 for (uint32_t i = 0; i < damage.numRects; i++) {
281 LayerRect rect;
282 SetRect(damage.rects[i], &rect);
283 layer_->dirty_regions.push_back(rect);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500284 }
285 return HWC2::Error::None;
286}
287
288HWC2::Error HWCLayer::SetLayerBlendMode(HWC2::BlendMode mode) {
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700289 LayerBlending blending = kBlendingPremultiplied;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500290 switch (mode) {
291 case HWC2::BlendMode::Coverage:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700292 blending = kBlendingCoverage;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500293 break;
294 case HWC2::BlendMode::Premultiplied:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700295 blending = kBlendingPremultiplied;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500296 break;
297 case HWC2::BlendMode::None:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700298 blending = kBlendingOpaque;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500299 break;
300 default:
301 return HWC2::Error::BadParameter;
302 }
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700303
304 if (layer_->blending != blending) {
305 geometry_changes_ |= kBlendMode;
306 layer_->blending = blending;
307 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500308 return HWC2::Error::None;
309}
310
311HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
Arun Kumar K.R1018d5b2017-06-08 13:51:05 +0530312 if (client_requested_ != HWC2::Composition::SolidColor) {
313 return HWC2::Error::None;
314 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500315 layer_->solid_fill_color = GetUint32Color(color);
Arun Kumar K.R9c19cdd2016-11-21 16:48:43 -0800316 layer_->input_buffer.format = kFormatARGB8888;
Naseer Ahmed16c72b92016-07-22 20:02:31 -0400317 DLOGV_IF(kTagCompManager, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
318 layer_->solid_fill_color);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500319 return HWC2::Error::None;
320}
321
322HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700323 client_requested_ = type;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500324 switch (type) {
325 case HWC2::Composition::Client:
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500326 break;
327 case HWC2::Composition::Device:
328 // We try and default to this in SDM
329 break;
330 case HWC2::Composition::SolidColor:
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500331 break;
332 case HWC2::Composition::Cursor:
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500333 break;
334 case HWC2::Composition::Invalid:
335 return HWC2::Error::BadParameter;
336 default:
337 return HWC2::Error::Unsupported;
338 }
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700339
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500340 return HWC2::Error::None;
341}
342
343HWC2::Error HWCLayer::SetLayerDataspace(int32_t dataspace) {
Naseer Ahmed43f22bb2017-05-05 17:40:46 -0400344 // Map deprecated dataspace values to appropriate
345 // new enums
346 if (dataspace & 0xffff) {
347 switch (dataspace & 0xffff) {
348 case HAL_DATASPACE_SRGB:
349 dataspace = HAL_DATASPACE_V0_SRGB;
350 break;
351 case HAL_DATASPACE_JFIF:
352 dataspace = HAL_DATASPACE_V0_JFIF;
353 break;
354 case HAL_DATASPACE_SRGB_LINEAR:
355 dataspace = HAL_DATASPACE_V0_SRGB_LINEAR;
356 break;
357 case HAL_DATASPACE_BT601_625:
358 dataspace = HAL_DATASPACE_V0_BT601_625;
359 break;
360 case HAL_DATASPACE_BT601_525:
361 dataspace = HAL_DATASPACE_V0_BT601_525;
362 break;
363 case HAL_DATASPACE_BT709:
364 dataspace = HAL_DATASPACE_V0_BT709;
365 break;
366 default:
367 // unknown legacy dataspace
368 DLOGW_IF(kTagQDCM, "Unsupported dataspace type %d", dataspace);
369 }
370 }
371
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530372 // cache the dataspace, to be used later to update SDM ColorMetaData
Naseer Ahmedade4ee62016-10-07 17:07:38 -0400373 if (dataspace_ != dataspace) {
374 geometry_changes_ |= kDataspace;
375 dataspace_ = dataspace;
376 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500377 return HWC2::Error::None;
378}
379
380HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700381 LayerRect dst_rect = {};
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700382
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700383 SetRect(frame, &dst_rect);
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700384 if (dst_rect_ != dst_rect) {
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700385 geometry_changes_ |= kDisplayFrame;
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700386 dst_rect_ = dst_rect;
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700387 }
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700388
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500389 return HWC2::Error::None;
390}
391
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700392void HWCLayer::ResetPerFrameData() {
393 layer_->dst_rect = dst_rect_;
394 layer_->transform = layer_transform_;
395}
396
Pullakavi Srinivas68a166c2017-05-24 12:17:07 +0530397HWC2::Error HWCLayer::SetCursorPosition(int32_t x, int32_t y) {
398 hwc_rect_t frame = {};
399 frame.left = x;
400 frame.top = y;
401 frame.right = x + INT(layer_->dst_rect.right - layer_->dst_rect.left);
402 frame.bottom = y + INT(layer_->dst_rect.bottom - layer_->dst_rect.top);
403 SetLayerDisplayFrame(frame);
404
405 return HWC2::Error::None;
406}
407
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500408HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
409 // Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700410 uint8_t plane_alpha = static_cast<uint8_t>(std::round(255.0f * alpha));
411 if (layer_->plane_alpha != plane_alpha) {
412 geometry_changes_ |= kPlaneAlpha;
413 layer_->plane_alpha = plane_alpha;
414 }
415
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500416 return HWC2::Error::None;
417}
418
419HWC2::Error HWCLayer::SetLayerSourceCrop(hwc_frect_t crop) {
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700420 LayerRect src_rect = {};
421 SetRect(crop, &src_rect);
422 if (layer_->src_rect != src_rect) {
423 geometry_changes_ |= kSourceCrop;
424 layer_->src_rect = src_rect;
425 }
426
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500427 return HWC2::Error::None;
428}
429
430HWC2::Error HWCLayer::SetLayerTransform(HWC2::Transform transform) {
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700431 LayerTransform layer_transform = {};
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500432 switch (transform) {
433 case HWC2::Transform::FlipH:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700434 layer_transform.flip_horizontal = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500435 break;
436 case HWC2::Transform::FlipV:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700437 layer_transform.flip_vertical = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500438 break;
439 case HWC2::Transform::Rotate90:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700440 layer_transform.rotation = 90.0f;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500441 break;
442 case HWC2::Transform::Rotate180:
Arun Kumar K.Rf641dff2016-06-16 13:20:02 -0700443 layer_transform.flip_horizontal = true;
444 layer_transform.flip_vertical = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500445 break;
446 case HWC2::Transform::Rotate270:
Arun Kumar K.Rf641dff2016-06-16 13:20:02 -0700447 layer_transform.rotation = 90.0f;
448 layer_transform.flip_horizontal = true;
449 layer_transform.flip_vertical = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500450 break;
451 case HWC2::Transform::FlipHRotate90:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700452 layer_transform.rotation = 90.0f;
453 layer_transform.flip_horizontal = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500454 break;
455 case HWC2::Transform::FlipVRotate90:
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700456 layer_transform.rotation = 90.0f;
457 layer_transform.flip_vertical = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500458 break;
Arun Kumar K.R5f20a7a2016-06-17 16:03:54 -0700459 case HWC2::Transform::None:
460 // do nothing
461 break;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500462 }
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700463
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700464 if (layer_transform_ != layer_transform) {
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700465 geometry_changes_ |= kTransform;
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700466 layer_transform_ = layer_transform;
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700467 }
Prabhanjan Kandula5265b052017-05-30 17:13:40 -0700468
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500469 return HWC2::Error::None;
470}
471
472HWC2::Error HWCLayer::SetLayerVisibleRegion(hwc_region_t visible) {
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700473 layer_->visible_regions.clear();
Naseer Ahmed6786e5d2016-06-24 16:38:52 -0400474 for (uint32_t i = 0; i < visible.numRects; i++) {
475 LayerRect rect;
476 SetRect(visible.rects[i], &rect);
477 layer_->visible_regions.push_back(rect);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500478 }
479
480 return HWC2::Error::None;
481}
482
483HWC2::Error HWCLayer::SetLayerZOrder(uint32_t z) {
Arun Kumar K.R3e89f792016-06-01 17:14:15 -0700484 if (z_ != z) {
485 geometry_changes_ |= kZOrder;
486 z_ = z;
487 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500488 return HWC2::Error::None;
489}
490
491void HWCLayer::SetRect(const hwc_rect_t &source, LayerRect *target) {
492 target->left = FLOAT(source.left);
493 target->top = FLOAT(source.top);
494 target->right = FLOAT(source.right);
495 target->bottom = FLOAT(source.bottom);
496}
497
498void HWCLayer::SetRect(const hwc_frect_t &source, LayerRect *target) {
499 // Recommended way of rounding as in hwcomposer2.h - SetLayerSourceCrop
500 target->left = std::ceil(source.left);
501 target->top = std::ceil(source.top);
502 target->right = std::floor(source.right);
503 target->bottom = std::floor(source.bottom);
504}
505
506uint32_t HWCLayer::GetUint32Color(const hwc_color_t &source) {
507 // Returns 32 bit ARGB
508 uint32_t a = UINT32(source.a) << 24;
509 uint32_t r = UINT32(source.r) << 16;
510 uint32_t g = UINT32(source.g) << 8;
511 uint32_t b = UINT32(source.b);
Naseer Ahmed16c72b92016-07-22 20:02:31 -0400512 uint32_t color = a | r | g | b;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500513 return color;
514}
515
516LayerBufferFormat HWCLayer::GetSDMFormat(const int32_t &source, const int flags) {
517 LayerBufferFormat format = kFormatInvalid;
518 if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
519 switch (source) {
520 case HAL_PIXEL_FORMAT_RGBA_8888:
521 format = kFormatRGBA8888Ubwc;
522 break;
523 case HAL_PIXEL_FORMAT_RGBX_8888:
524 format = kFormatRGBX8888Ubwc;
525 break;
526 case HAL_PIXEL_FORMAT_BGR_565:
527 format = kFormatBGR565Ubwc;
528 break;
529 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
530 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
531 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
532 format = kFormatYCbCr420SPVenusUbwc;
533 break;
Arun Kumar K.R54885f02017-03-23 11:56:59 -0700534 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
535 format = kFormatYCbCr420TP10Ubwc;
536 break;
Rohit Kulkarni7943ec92016-12-20 18:18:46 -0800537 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
538 format = kFormatYCbCr420P010Ubwc;
539 break;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500540 default:
541 DLOGE("Unsupported format type for UBWC %d", source);
542 return kFormatInvalid;
543 }
544 return format;
545 }
546
547 switch (source) {
548 case HAL_PIXEL_FORMAT_RGBA_8888:
549 format = kFormatRGBA8888;
550 break;
551 case HAL_PIXEL_FORMAT_RGBA_5551:
552 format = kFormatRGBA5551;
553 break;
554 case HAL_PIXEL_FORMAT_RGBA_4444:
555 format = kFormatRGBA4444;
556 break;
557 case HAL_PIXEL_FORMAT_BGRA_8888:
558 format = kFormatBGRA8888;
559 break;
560 case HAL_PIXEL_FORMAT_RGBX_8888:
561 format = kFormatRGBX8888;
562 break;
563 case HAL_PIXEL_FORMAT_BGRX_8888:
564 format = kFormatBGRX8888;
565 break;
566 case HAL_PIXEL_FORMAT_RGB_888:
567 format = kFormatRGB888;
568 break;
Camus Wongc106d082017-03-31 16:07:29 -0400569 case HAL_PIXEL_FORMAT_BGR_888:
570 format = kFormatBGR888;
571 break;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500572 case HAL_PIXEL_FORMAT_RGB_565:
573 format = kFormatRGB565;
574 break;
575 case HAL_PIXEL_FORMAT_BGR_565:
576 format = kFormatBGR565;
577 break;
578 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
579 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
580 format = kFormatYCbCr420SemiPlanarVenus;
581 break;
582 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
583 format = kFormatYCrCb420SemiPlanarVenus;
584 break;
585 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
586 format = kFormatYCbCr420SPVenusUbwc;
587 break;
588 case HAL_PIXEL_FORMAT_YV12:
589 format = kFormatYCrCb420PlanarStride16;
590 break;
591 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
592 format = kFormatYCrCb420SemiPlanar;
593 break;
594 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
595 format = kFormatYCbCr420SemiPlanar;
596 break;
597 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
598 format = kFormatYCbCr422H2V1SemiPlanar;
599 break;
600 case HAL_PIXEL_FORMAT_YCbCr_422_I:
601 format = kFormatYCbCr422H2V1Packed;
602 break;
Camus Wongc106d082017-03-31 16:07:29 -0400603 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
604 format = kFormatCbYCrY422H2V1Packed;
605 break;
Naseer Ahmed72dea242016-05-03 19:13:07 -0400606 case HAL_PIXEL_FORMAT_RGBA_1010102:
607 format = kFormatRGBA1010102;
608 break;
609 case HAL_PIXEL_FORMAT_ARGB_2101010:
610 format = kFormatARGB2101010;
611 break;
612 case HAL_PIXEL_FORMAT_RGBX_1010102:
613 format = kFormatRGBX1010102;
614 break;
615 case HAL_PIXEL_FORMAT_XRGB_2101010:
616 format = kFormatXRGB2101010;
617 break;
618 case HAL_PIXEL_FORMAT_BGRA_1010102:
619 format = kFormatBGRA1010102;
620 break;
621 case HAL_PIXEL_FORMAT_ABGR_2101010:
622 format = kFormatABGR2101010;
623 break;
624 case HAL_PIXEL_FORMAT_BGRX_1010102:
625 format = kFormatBGRX1010102;
626 break;
627 case HAL_PIXEL_FORMAT_XBGR_2101010:
628 format = kFormatXBGR2101010;
629 break;
630 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
631 format = kFormatYCbCr420P010;
632 break;
633 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
634 format = kFormatYCbCr420TP10Ubwc;
635 break;
Rohit Kulkarni7943ec92016-12-20 18:18:46 -0800636 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
637 format = kFormatYCbCr420P010Ubwc;
638 break;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500639 default:
640 DLOGW("Unsupported format type = %d", source);
641 return kFormatInvalid;
642 }
643
644 return format;
645}
646
647LayerBufferS3DFormat HWCLayer::GetS3DFormat(uint32_t s3d_format) {
648 LayerBufferS3DFormat sdm_s3d_format = kS3dFormatNone;
649 switch (s3d_format) {
650 case HAL_NO_3D:
651 sdm_s3d_format = kS3dFormatNone;
652 break;
653 case HAL_3D_SIDE_BY_SIDE_L_R:
654 sdm_s3d_format = kS3dFormatLeftRight;
655 break;
656 case HAL_3D_SIDE_BY_SIDE_R_L:
657 sdm_s3d_format = kS3dFormatRightLeft;
658 break;
659 case HAL_3D_TOP_BOTTOM:
660 sdm_s3d_format = kS3dFormatTopBottom;
661 break;
662 default:
663 DLOGW("Invalid S3D format %d", s3d_format);
664 }
665 return sdm_s3d_format;
666}
667
Gurunath Ramaswamyf081afe2017-07-04 22:08:36 -0700668void HWCLayer::GetUBWCStatsFromMetaData(UBWCStats *cr_stats, UbwcCrStatsVector *cr_vec) {
669 // TODO(user): Check if we can use UBWCStats directly
670 // in layer_buffer or copy directly to Vector
671 if (cr_stats->bDataValid) {
672 switch (cr_stats->version) {
673 case UBWC_2_0:
674 cr_vec->push_back(std::make_pair(32, cr_stats->ubwc_stats.nCRStatsTile32));
675 cr_vec->push_back(std::make_pair(64, cr_stats->ubwc_stats.nCRStatsTile64));
676 cr_vec->push_back(std::make_pair(96, cr_stats->ubwc_stats.nCRStatsTile96));
677 cr_vec->push_back(std::make_pair(128, cr_stats->ubwc_stats.nCRStatsTile128));
678 cr_vec->push_back(std::make_pair(160, cr_stats->ubwc_stats.nCRStatsTile160));
679 cr_vec->push_back(std::make_pair(192, cr_stats->ubwc_stats.nCRStatsTile192));
680 cr_vec->push_back(std::make_pair(256, cr_stats->ubwc_stats.nCRStatsTile256));
681 break;
682 default:
683 DLOGW("Invalid UBWC Version %d", cr_stats->version);
684 break;
685 } // switch(cr_stats->version)
686 } // if (cr_stats->bDatvalid)
687}
688
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500689DisplayError HWCLayer::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
Arun Kumar K.R9c19cdd2016-11-21 16:48:43 -0800690 LayerBuffer *layer_buffer = &layer->input_buffer;
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800691 private_handle_t *handle = const_cast<private_handle_t *>(pvt_handle);
692 IGC_t igc = {};
Sushil Chauhan409e8442017-06-12 17:43:25 -0700693 LayerIGC layer_igc = layer_buffer->igc;
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800694 if (getMetaData(handle, GET_IGC, &igc) == 0) {
Sushil Chauhan409e8442017-06-12 17:43:25 -0700695 if (SetIGC(igc, &layer_igc) != kErrorNone) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500696 return kErrorNotSupported;
697 }
698 }
699
Anjaneya Prasad Musunurid47d15b2017-08-03 10:57:51 +0530700 float fps = 0;
Sushil Chauhan409e8442017-06-12 17:43:25 -0700701 uint32_t frame_rate = layer->frame_rate;
702 if (getMetaData(handle, GET_REFRESH_RATE, &fps) == 0) {
703 frame_rate = RoundToStandardFPS(fps);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500704 }
705
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800706 int32_t interlaced = 0;
Sushil Chauhan409e8442017-06-12 17:43:25 -0700707 bool interlace = layer_buffer->flags.interlace;
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800708 if (getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
Sushil Chauhan409e8442017-06-12 17:43:25 -0700709 interlace = interlaced ? true : false;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500710 }
711
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800712 uint32_t linear_format = 0;
713 if (getMetaData(handle, GET_LINEAR_FORMAT, &linear_format) == 0) {
714 layer_buffer->format = GetSDMFormat(INT32(linear_format), 0);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500715 }
716
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800717 uint32_t s3d = 0;
Sushil Chauhan409e8442017-06-12 17:43:25 -0700718 LayerBufferS3DFormat s3d_format = layer_buffer->s3d_format;
Arun Kumar K.R3e45ac42017-03-08 19:00:02 -0800719 if (getMetaData(handle, GET_S3D_FORMAT, &s3d) == 0) {
Sushil Chauhan409e8442017-06-12 17:43:25 -0700720 s3d_format = GetS3DFormat(s3d);
721 }
722
723 if ((layer_igc != layer_buffer->igc) || (interlace != layer_buffer->flags.interlace) ||
724 (frame_rate != layer->frame_rate) || (s3d_format != layer_buffer->s3d_format)) {
725 // Layer buffer metadata has changed.
726 needs_validate_ = true;
727 layer_buffer->igc = layer_igc;
728 layer->frame_rate = frame_rate;
729 layer_buffer->s3d_format = s3d_format;
730 layer_buffer->flags.interlace = interlace;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500731 }
732
Gurunath Ramaswamyf081afe2017-07-04 22:08:36 -0700733 // Check if metadata is set
734 struct UBWCStats cr_stats[NUM_UBWC_CR_STATS_LAYERS] = {};
735
736 for (int i = 0; i < NUM_UBWC_CR_STATS_LAYERS; i++) {
737 layer_buffer->ubwc_crstats[i].clear();
738 }
739
740 if (getMetaData(handle, GET_UBWC_CR_STATS_INFO, cr_stats) == 0) {
741 // Only copy top layer for now as only top field for interlaced is used
742 GetUBWCStatsFromMetaData(&cr_stats[0], &(layer_buffer->ubwc_crstats[0]));
743 } // if (getMetaData)
744
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500745 return kErrorNone;
746}
747
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500748DisplayError HWCLayer::SetIGC(IGC_t source, LayerIGC *target) {
749 switch (source) {
750 case IGC_NotSpecified:
751 *target = kIGCNotSpecified;
752 break;
753 case IGC_sRGB:
754 *target = kIGCsRGB;
755 break;
756 default:
757 DLOGE("Unsupported IGC: %d", source);
758 return kErrorNotSupported;
759 }
760
761 return kErrorNone;
762}
763
Naseer Ahmedade4ee62016-10-07 17:07:38 -0400764
765
766bool HWCLayer::SupportLocalConversion(ColorPrimaries working_primaries) {
767 if (layer_->input_buffer.color_metadata.colorPrimaries <= ColorPrimaries_BT601_6_525 &&
768 working_primaries <= ColorPrimaries_BT601_6_525) {
769 return true;
770 }
771 return false;
772}
773
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530774bool HWCLayer::ValidateAndSetCSC() {
775 if (client_requested_ != HWC2::Composition::Device &&
776 client_requested_ != HWC2::Composition::Cursor) {
777 // Check the layers which are configured to Device
Naseer Ahmedade4ee62016-10-07 17:07:38 -0400778 return true;
779 }
780
Naseer Ahmedade4ee62016-10-07 17:07:38 -0400781 LayerBuffer *layer_buffer = &layer_->input_buffer;
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530782 bool use_color_metadata = true;
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530783#ifdef FEATURE_WIDE_COLOR
Arun Kumar K.R80e58eb2017-07-13 10:37:00 +0530784 ColorMetaData csc = {};
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530785 if (dataspace_ != HAL_DATASPACE_UNKNOWN) {
Arun Kumar K.R80e58eb2017-07-13 10:37:00 +0530786 use_color_metadata = false;
787 bool valid_csc = GetSDMColorSpace(dataspace_, &csc);
788 if (!valid_csc) {
789 return false;
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530790 }
Arun Kumar K.R80e58eb2017-07-13 10:37:00 +0530791 // if we are here here, update the sdm layer csc.
792 layer_buffer->color_metadata.transfer = csc.transfer;
793 layer_buffer->color_metadata.colorPrimaries = csc.colorPrimaries;
794 layer_buffer->color_metadata.range = csc.range;
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530795 }
796#endif
797
Arun Kumar K.R80e58eb2017-07-13 10:37:00 +0530798 if (IsBT2020(layer_buffer->color_metadata.colorPrimaries)) {
799 // android_dataspace_t doesnt support mastering display and light levels
800 // so retrieve it from metadata for BT2020(HDR)
801 use_color_metadata = true;
802 }
803
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530804 if (use_color_metadata) {
805 const private_handle_t *handle =
806 reinterpret_cast<const private_handle_t *>(layer_buffer->buffer_id);
807 if (sdm::SetCSC(handle, &layer_buffer->color_metadata) != kErrorNone) {
Naseer Ahmedade4ee62016-10-07 17:07:38 -0400808 return false;
Arun Kumar K.R961a28f2017-07-07 15:26:30 +0530809 }
Naseer Ahmedade4ee62016-10-07 17:07:38 -0400810 }
811
Naseer Ahmedade4ee62016-10-07 17:07:38 -0400812 return true;
813}
814
815
Naseer Ahmed89ff4522016-05-17 11:36:27 -0400816uint32_t HWCLayer::RoundToStandardFPS(float fps) {
817 static const uint32_t standard_fps[4] = {24, 30, 48, 60};
818 uint32_t frame_rate = (uint32_t)(fps);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500819
820 int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0]));
821 for (int i = 0; i < count; i++) {
Naseer Ahmed89ff4522016-05-17 11:36:27 -0400822 if ((standard_fps[i] - frame_rate) < 2) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500823 // Most likely used for video, the fps can fluctuate
824 // Ex: b/w 29 and 30 for 30 fps clip
825 return standard_fps[i];
826 }
827 }
828
Naseer Ahmed89ff4522016-05-17 11:36:27 -0400829 return frame_rate;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500830}
831
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700832void HWCLayer::SetComposition(const LayerComposition &sdm_composition) {
833 auto hwc_composition = HWC2::Composition::Invalid;
834 switch (sdm_composition) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500835 case kCompositionGPU:
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700836 hwc_composition = HWC2::Composition::Client;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500837 break;
Saurabh Shaha4af3de2017-04-19 17:15:24 -0700838 case kCompositionCursor:
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700839 hwc_composition = HWC2::Composition::Cursor;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500840 break;
841 default:
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700842 hwc_composition = HWC2::Composition::Device;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500843 break;
844 }
845 // Update solid fill composition
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700846 if (sdm_composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
847 hwc_composition = HWC2::Composition::SolidColor;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500848 }
Arun Kumar K.R2c0ff8d2016-06-01 16:56:52 -0700849 device_selected_ = hwc_composition;
850
851 return;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500852}
853void HWCLayer::PushReleaseFence(int32_t fence) {
854 release_fences_.push(fence);
855}
856int32_t HWCLayer::PopReleaseFence(void) {
857 if (release_fences_.empty())
858 return -1;
859 auto fence = release_fences_.front();
860 release_fences_.pop();
861 return fence;
862}
863
864} // namespace sdm