blob: 342857b425c04e524018f094d0b189a4699e4533 [file] [log] [blame]
Naseer Ahmedb92e73f2016-03-12 02:03:48 -05001/*
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +05302* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
Naseer Ahmedb92e73f2016-03-12 02:03:48 -05003*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above
10* copyright notice, this list of conditions and the following
11* disclaimer in the documentation and/or other materials provided
12* with the distribution.
13* * Neither the name of The Linux Foundation nor the names of its
14* contributors may be used to endorse or promote products derived
15* from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <cutils/properties.h>
31#include <sync/sync.h>
32#include <utils/constants.h>
33#include <utils/debug.h>
Sushil Chauhan06521582018-03-19 14:00:23 -070034#include <utils/utils.h>
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050035#include <stdarg.h>
36#include <sys/mman.h>
37
Arun Kumar K.R29cd6582016-05-10 19:12:45 -070038#include <map>
39#include <string>
40#include <vector>
41
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053042#include "hwc_display_builtin.h"
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050043#include "hwc_debugger.h"
Pullakavi Srinivas9189e602018-12-19 16:58:07 +053044#include "hwc_session.h"
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050045
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053046#define __CLASS__ "HWCDisplayBuiltIn"
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050047
48namespace sdm {
49
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +053050static void SetRect(LayerRect &src_rect, GLRect *target) {
51 target->left = src_rect.left;
52 target->top = src_rect.top;
53 target->right = src_rect.right;
54 target->bottom = src_rect.bottom;
55}
56
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053057int HWCDisplayBuiltIn::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
Varun Arora7c8ee542018-05-01 20:58:16 -070058 HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053059 qService::QService *qservice, hwc2_display_t id, int32_t sdm_id,
60 HWCDisplay **hwc_display) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050061 int status = 0;
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053062 uint32_t builtin_width = 0;
63 uint32_t builtin_height = 0;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050064
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053065 HWCDisplay *hwc_display_builtin =
66 new HWCDisplayBuiltIn(core_intf, buffer_allocator, callbacks, event_handler, qservice, id,
67 sdm_id);
68 status = hwc_display_builtin->Init();
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050069 if (status) {
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053070 delete hwc_display_builtin;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050071 return status;
72 }
73
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053074 hwc_display_builtin->GetMixerResolution(&builtin_width, &builtin_height);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050075 int width = 0, height = 0;
Uday Kiran Pichika5e656b22018-05-15 18:48:24 +053076 HWCDebugHandler::Get()->GetProperty(FB_WIDTH_PROP, &width);
77 HWCDebugHandler::Get()->GetProperty(FB_HEIGHT_PROP, &height);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050078 if (width > 0 && height > 0) {
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053079 builtin_width = UINT32(width);
80 builtin_height = UINT32(height);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050081 }
82
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053083 status = hwc_display_builtin->SetFrameBufferResolution(builtin_width, builtin_height);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050084 if (status) {
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053085 Destroy(hwc_display_builtin);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050086 return status;
87 }
88
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053089 *hwc_display = hwc_display_builtin;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050090
91 return status;
92}
93
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053094void HWCDisplayBuiltIn::Destroy(HWCDisplay *hwc_display) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -050095 hwc_display->Deinit();
96 delete hwc_display;
97}
98
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +053099HWCDisplayBuiltIn::HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
Varun Arora7c8ee542018-05-01 20:58:16 -0700100 HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530101 qService::QService *qservice, hwc2_display_t id,
102 int32_t sdm_id)
103 : HWCDisplay(core_intf, buffer_allocator, callbacks, event_handler, qservice, kBuiltIn, id,
Gousemoodhin Nadaf087c3102019-01-07 19:34:56 +0530104 sdm_id, DISPLAY_CLASS_BUILTIN),
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530105 buffer_allocator_(buffer_allocator),
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530106 cpu_hint_(NULL), layer_stitch_task_(*this) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500107}
108
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530109int HWCDisplayBuiltIn::Init() {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500110 cpu_hint_ = new CPUHint();
111 if (cpu_hint_->Init(static_cast<HWCDebugHandler *>(HWCDebugHandler::Get())) != kErrorNone) {
112 delete cpu_hint_;
113 cpu_hint_ = NULL;
114 }
115
116 use_metadata_refresh_rate_ = true;
117 int disable_metadata_dynfps = 0;
Uday Kiran Pichika5e656b22018-05-15 18:48:24 +0530118 HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500119 if (disable_metadata_dynfps) {
120 use_metadata_refresh_rate_ = false;
121 }
122
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700123 int status = HWCDisplay::Init();
124 if (status) {
125 return status;
126 }
127 color_mode_ = new HWCColorMode(display_intf_);
Naseer Ahmed61f60952017-05-24 16:48:35 -0400128 color_mode_->Init();
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700129
Padmanabhan Komanduru866bf6a2019-03-19 14:30:48 +0530130 int optimize_refresh = 0;
131 HWCDebugHandler::Get()->GetProperty(ENABLE_OPTIMIZE_REFRESH, &optimize_refresh);
132 enable_optimize_refresh_ = (optimize_refresh == 1);
133 if (enable_optimize_refresh_) {
Padmanabhan Komandurue74cf4f2019-04-25 17:38:43 -0700134 DLOGI("Drop redundant drawcycles %d", id_);
135 }
136
Sushil Chauhandbd8db42020-02-28 13:07:48 -0800137 int vsyncs = 0;
138 HWCDebugHandler::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &vsyncs);
139 if (vsyncs > 0) {
140 SetVsyncsApplyRateChange(UINT32(vsyncs));
141 }
142
Mathew Joseph Karimpanalb1c15862019-07-04 11:14:24 +0530143 is_primary_ = display_intf_->IsPrimaryDisplay();
144
Rajavenu Kyathamf87a7a72019-12-05 16:43:07 +0530145 if (is_primary_) {
146 Debug::GetWindowRect(&window_rect_.left, &window_rect_.top,
147 &window_rect_.right, &window_rect_.bottom);
148 DLOGI("Window rect : [%f %f %f %f]", window_rect_.left, window_rect_.top,
149 window_rect_.right, window_rect_.bottom);
150 }
Naseer Ahmed61f60952017-05-24 16:48:35 -0400151 return status;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500152}
153
Dileep Marchya58928122020-01-28 12:16:51 +0530154void HWCDisplayBuiltIn::Dump(std::ostringstream *os) {
155 HWCDisplay::Dump(os);
156 *os << histogram.Dump();
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -0800157}
158
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530159HWC2::Error HWCDisplayBuiltIn::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500160 auto status = HWC2::Error::None;
161 DisplayError error = kErrorNone;
162
Gurpreet Singh Dhamia4276882019-04-12 10:30:58 -0700163 DTRACE_SCOPED();
164
Mathew Joseph Karimpanalb1c15862019-07-04 11:14:24 +0530165 if (display_paused_ || (!is_primary_ && active_secure_sessions_[kSecureDisplay])) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500166 MarkLayersForGPUBypass();
167 return status;
168 }
169
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700170 if (color_tranform_failed_) {
171 // Must fall back to client composition
172 MarkLayersForClientComposition();
173 }
174
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500175 // Fill in the remaining blanks in the layers and add them to the SDM layerstack
176 BuildLayerStack();
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530177
178 // Add stitch layer to layer stack.
179 AppendStitchLayer();
180
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700181 // Checks and replaces layer stack for solid fill
182 SolidFillPrepare();
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500183
Sushil Chauhan8008d602018-09-04 14:43:27 -0700184 // Apply current Color Mode and Render Intent.
Xu Yang84e61412018-12-06 14:52:16 +0800185 if (color_mode_->ApplyCurrentColorModeWithRenderIntent(
186 static_cast<bool>(layer_stack_.flags.hdr_present)) != HWC2::Error::None) {
Sushil Chauhan8008d602018-09-04 14:43:27 -0700187 // Fallback to GPU Composition, if Color Mode can't be applied.
188 MarkLayersForClientComposition();
189 }
190
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500191 bool pending_output_dump = dump_frame_count_ && dump_output_to_file_;
192
Sushil Chauhan06521582018-03-19 14:00:23 -0700193 if (readback_buffer_queued_ || pending_output_dump) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500194 // RHS values were set in FrameCaptureAsync() called from a binder thread. They are picked up
Sushil Chauhan06521582018-03-19 14:00:23 -0700195 // here in a subsequent draw round. Readback is not allowed for any secure use case.
196 readback_configured_ = !layer_stack_.flags.secure_present;
197 if (readback_configured_) {
Sushil Chauhanf42d8622018-09-30 23:20:37 -0700198 DisablePartialUpdateOneFrame();
Sushil Chauhan06521582018-03-19 14:00:23 -0700199 layer_stack_.output_buffer = &output_buffer_;
200 layer_stack_.flags.post_processed_output = post_processed_output_;
201 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500202 }
203
Ramakant Singh5db0dfb2017-08-23 12:34:57 +0530204 uint32_t num_updating_layers = GetUpdatingLayersCount();
205 bool one_updating_layer = (num_updating_layers == 1);
206 if (num_updating_layers != 0) {
207 ToggleCPUHint(one_updating_layer);
208 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500209
210 uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
Pullakavi Srinivas4619db92019-04-20 15:07:59 +0530211 error = display_intf_->SetRefreshRate(refresh_rate, force_refresh_rate_);
212
213 // Get the refresh rate set.
214 display_intf_->GetRefreshRate(&refresh_rate);
215 bool vsync_source = (callbacks_->GetVsyncSource() == id_);
216
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500217 if (error == kErrorNone) {
Pullakavi Srinivas4619db92019-04-20 15:07:59 +0530218 if (vsync_source && (current_refresh_rate_ < refresh_rate)) {
219 DTRACE_BEGIN("HWC2::Vsync::Enable");
220 // Display is ramping up from idle.
221 // Client realizes need for resync upon change in config.
222 // Since we know config has changed, triggering vsync proactively
223 // can help in reducing pipeline delays to enable events.
224 SetVsyncEnabled(HWC2::Vsync::Enable);
225 DTRACE_END();
226 }
227 // On success, set current refresh rate to new refresh rate.
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500228 current_refresh_rate_ = refresh_rate;
229 }
230
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500231 if (layer_set_.empty()) {
Uday Kiran Pichika8d827732018-01-09 18:08:38 +0530232 // Avoid flush for Command mode panel.
Pullakavi Srinivas2d55f3a2019-07-16 14:49:06 +0530233 flush_ = !client_connected_;
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700234 validated_ = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500235 return status;
236 }
237
238 status = PrepareLayerStack(out_num_types, out_num_requests);
Namit Solanki5b428dc2018-02-27 11:39:05 +0530239 pending_commit_ = true;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500240 return status;
241}
242
Padmanabhan Komandurue74cf4f2019-04-25 17:38:43 -0700243HWC2::Error HWCDisplayBuiltIn::CommitLayerStack() {
244 skip_commit_ = CanSkipCommit();
245 return HWCDisplay::CommitLayerStack();
246}
247
248bool HWCDisplayBuiltIn::CanSkipCommit() {
249 if (layer_stack_invalid_) {
250 return false;
251 }
252
253 // Reject repeated drawcycle requests if it satisfies all conditions.
254 // 1. None of the layerstack attributes changed.
255 // 2. No new buffer latched.
256 // 3. No refresh request triggered by HWC.
257 // 4. This display is not source of vsync.
258 bool buffers_latched = false;
259 for (auto &hwc_layer : layer_set_) {
260 buffers_latched |= hwc_layer->BufferLatched();
261 hwc_layer->ResetBufferFlip();
262 }
263
Padmanabhan Komanduruf5e6c5d2019-04-04 13:56:31 +0530264 bool vsync_source = (callbacks_->GetVsyncSource() == id_);
Padmanabhan Komanduru866bf6a2019-03-19 14:30:48 +0530265 bool skip_commit = enable_optimize_refresh_ && !pending_commit_ && !buffers_latched &&
Padmanabhan Komanduruf5e6c5d2019-04-04 13:56:31 +0530266 !pending_refresh_ && !vsync_source;
Padmanabhan Komandurue74cf4f2019-04-25 17:38:43 -0700267 pending_refresh_ = false;
268
269 return skip_commit;
270}
271
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530272HWC2::Error HWCDisplayBuiltIn::CommitStitchLayers() {
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +0530273 if (disable_layer_stitch_) {
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530274 return HWC2::Error::None;
275 }
276
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +0530277 if (!validated_ || skip_commit_) {
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530278 return HWC2::Error::None;
279 }
280
281 for (auto &layer : layer_stack_.layers) {
282 LayerComposition &composition = layer->composition;
283 if (composition != kCompositionStitch) {
284 continue;
285 }
286
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +0530287 LayerStitchContext ctx = {};
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530288 // Stitch target doesn't have an input fence.
289 // Render all layers at specified destination.
290 LayerBuffer &input_buffer = layer->input_buffer;
291 ctx.src_hnd = reinterpret_cast<const private_handle_t *>(input_buffer.buffer_id);
292 Layer *stitch_layer = stitch_target_->GetSDMLayer();
293 LayerBuffer &output_buffer = stitch_layer->input_buffer;
294 ctx.dst_hnd = reinterpret_cast<const private_handle_t *>(output_buffer.buffer_id);
295 SetRect(layer->stitch_dst_rect, &ctx.dst_rect);
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530296 ctx.src_acquire_fence = input_buffer.acquire_fence;
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530297
298 layer_stitch_task_.PerformTask(LayerStitchTaskCode::kCodeStitch, &ctx);
299
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530300 // Merge with current fence.
301 output_buffer.acquire_fence = Fence::Merge(output_buffer.acquire_fence, ctx.release_fence);
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530302 }
303
304 return HWC2::Error::None;
305}
306
Padmanabhan Komanduru6693fcb2019-11-22 21:06:52 +0530307void HWCDisplayBuiltIn::CacheAvrStatus() {
308 QSyncMode qsync_mode = kQSyncModeNone;
309
310 DisplayError error = display_intf_->GetQSyncMode(&qsync_mode);
311 if (error != kErrorNone) {
312 return;
313 }
314
315 bool qsync_enabled = (qsync_mode != kQSyncModeNone);
316 if (qsync_enabled_ != qsync_enabled) {
317 qsync_reconfigured_ = true;
318 qsync_enabled_ = qsync_enabled;
319 } else {
320 qsync_reconfigured_ = false;
321 }
322}
323
324bool HWCDisplayBuiltIn::IsQsyncCallbackNeeded(bool *qsync_enabled, int32_t *refresh_rate,
325 int32_t *qsync_refresh_rate) {
326 if (!qsync_reconfigured_) {
327 return false;
328 }
329
330 bool vsync_source = (callbacks_->GetVsyncSource() == id_);
331 // Qsync callback not needed if this display is not the source of vsync
332 if (!vsync_source) {
333 return false;
334 }
335
336 *qsync_enabled = qsync_enabled_;
337 uint32_t current_rate = 0;
338 display_intf_->GetRefreshRate(&current_rate);
339 *refresh_rate = INT32(current_rate);
340 *qsync_refresh_rate = min_refresh_rate_;
341
342 return true;
343}
344
Dileep Marchyaad668432019-12-02 10:44:52 +0530345HWC2::Error HWCDisplayBuiltIn::Present(shared_ptr<Fence> *out_retire_fence) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500346 auto status = HWC2::Error::None;
Gurpreet Singh Dhamia4276882019-04-12 10:30:58 -0700347
348 DTRACE_SCOPED();
Mathew Joseph Karimpanalb1c15862019-07-04 11:14:24 +0530349
350 if (!is_primary_ && active_secure_sessions_[kSecureDisplay]) {
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530351 return status;
Mathew Joseph Karimpanalb1c15862019-07-04 11:14:24 +0530352 } else if (display_paused_) {
Pullakavi Srinivas0a1dba62018-07-02 15:49:11 +0530353 DisplayError error = display_intf_->Flush(&layer_stack_);
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700354 validated_ = false;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500355 if (error != kErrorNone) {
356 DLOGE("Flush failed. Error = %d", error);
357 }
358 } else {
Padmanabhan Komanduru6693fcb2019-11-22 21:06:52 +0530359 CacheAvrStatus();
360
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +0530361 status = CommitStitchLayers();
362 if (status != HWC2::Error::None) {
363 DLOGE("Stitch failed: %d", status);
364 return status;
365 }
366
Padmanabhan Komandurue74cf4f2019-04-25 17:38:43 -0700367 status = CommitLayerStack();
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500368 if (status == HWC2::Error::None) {
369 HandleFrameOutput();
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +0530370 PostCommitStitchLayers();
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500371 status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
372 }
373 }
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700374
Namit Solanki5b428dc2018-02-27 11:39:05 +0530375 pending_commit_ = false;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500376 return status;
377}
378
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +0530379void HWCDisplayBuiltIn::PostCommitStitchLayers() {
380 if (disable_layer_stitch_) {
381 return;
382 }
383
384 // Close Stitch buffer acquire fence.
385 Layer *stitch_layer = stitch_target_->GetSDMLayer();
386 LayerBuffer &output_buffer = stitch_layer->input_buffer;
387 for (auto &layer : layer_stack_.layers) {
388 LayerComposition &composition = layer->composition;
389 if (composition != kCompositionStitch) {
390 continue;
391 }
392 LayerBuffer &input_buffer = layer->input_buffer;
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530393 input_buffer.release_fence = output_buffer.acquire_fence;
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +0530394 }
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +0530395}
396
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530397HWC2::Error HWCDisplayBuiltIn::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700398 if (out_modes == nullptr) {
399 *out_num_modes = color_mode_->GetColorModeCount();
400 } else {
401 color_mode_->GetColorModes(out_num_modes, out_modes);
402 }
403
404 return HWC2::Error::None;
405}
406
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530407HWC2::Error HWCDisplayBuiltIn::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
Naseer Ahmede7a77982018-06-04 10:56:04 -0400408 RenderIntent *out_intents) {
409 if (out_intents == nullptr) {
410 *out_num_intents = color_mode_->GetRenderIntentCount(mode);
411 } else {
412 color_mode_->GetRenderIntents(mode, out_num_intents, out_intents);
413 }
414 return HWC2::Error::None;
415}
416
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530417HWC2::Error HWCDisplayBuiltIn::SetColorMode(ColorMode mode) {
Naseer Ahmede7a77982018-06-04 10:56:04 -0400418 return SetColorModeWithRenderIntent(mode, RenderIntent::COLORIMETRIC);
419}
420
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530421HWC2::Error HWCDisplayBuiltIn::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
Sushil Chauhan8008d602018-09-04 14:43:27 -0700422 auto status = color_mode_->CacheColorModeWithRenderIntent(mode, intent);
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700423 if (status != HWC2::Error::None) {
Naseer Ahmede7a77982018-06-04 10:56:04 -0400424 DLOGE("failed for mode = %d intent = %d", mode, intent);
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700425 return status;
426 }
Ramkumar Radhakrishnan44c64362018-12-12 13:03:59 -0800427 callbacks_->Refresh(id_);
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700428 validated_ = false;
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700429 return status;
430}
431
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530432HWC2::Error HWCDisplayBuiltIn::SetColorModeById(int32_t color_mode_id) {
Naseer Ahmed6776dae2017-05-09 11:49:41 -0400433 auto status = color_mode_->SetColorModeById(color_mode_id);
434 if (status != HWC2::Error::None) {
435 DLOGE("failed for mode = %d", color_mode_id);
436 return status;
437 }
438
Ramkumar Radhakrishnan44c64362018-12-12 13:03:59 -0800439 callbacks_->Refresh(id_);
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700440 validated_ = false;
Naseer Ahmed6776dae2017-05-09 11:49:41 -0400441
442 return status;
443}
444
Xu Yang84e61412018-12-06 14:52:16 +0800445HWC2::Error HWCDisplayBuiltIn::SetColorModeFromClientApi(int32_t color_mode_id) {
446 DisplayError error = kErrorNone;
447 std::string mode_string;
448
449 error = display_intf_->GetColorModeName(color_mode_id, &mode_string);
450 if (error) {
451 DLOGE("Failed to get mode name for mode %d", color_mode_id);
452 return HWC2::Error::BadParameter;
453 }
454
455 auto status = color_mode_->SetColorModeFromClientApi(mode_string);
456 if (status != HWC2::Error::None) {
457 DLOGE("Failed to set mode = %d", color_mode_id);
458 return status;
459 }
460
461 return status;
462}
463
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530464HWC2::Error HWCDisplayBuiltIn::RestoreColorTransform() {
Ch Ganesh Kumar5d43ff62017-10-13 19:01:47 +0530465 auto status = color_mode_->RestoreColorTransform();
466 if (status != HWC2::Error::None) {
467 DLOGE("failed to RestoreColorTransform");
468 return status;
469 }
470
Ramkumar Radhakrishnan44c64362018-12-12 13:03:59 -0800471 callbacks_->Refresh(id_);
Ch Ganesh Kumar5d43ff62017-10-13 19:01:47 +0530472
473 return status;
474}
475
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530476HWC2::Error HWCDisplayBuiltIn::SetColorTransform(const float *matrix,
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700477 android_color_transform_t hint) {
478 if (!matrix) {
479 return HWC2::Error::BadParameter;
480 }
481
482 auto status = color_mode_->SetColorTransform(matrix, hint);
483 if (status != HWC2::Error::None) {
484 DLOGE("failed for hint = %d", hint);
485 color_tranform_failed_ = true;
486 return status;
487 }
488
Ramkumar Radhakrishnan44c64362018-12-12 13:03:59 -0800489 callbacks_->Refresh(id_);
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700490 color_tranform_failed_ = false;
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700491 validated_ = false;
Arun Kumar K.R29cd6582016-05-10 19:12:45 -0700492
493 return status;
494}
495
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530496HWC2::Error HWCDisplayBuiltIn::SetReadbackBuffer(const native_handle_t *buffer,
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530497 shared_ptr<Fence> acquire_fence,
498 bool post_processed_output, CWBClient client) {
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530499 if (cwb_client_ != client && cwb_client_ != kCWBClientNone) {
500 DLOGE("CWB is in use with client = %d", cwb_client_);
501 return HWC2::Error::NoResources;
502 }
503
Sushil Chauhan06521582018-03-19 14:00:23 -0700504 const private_handle_t *handle = reinterpret_cast<const private_handle_t *>(buffer);
505 if (!handle || (handle->fd < 0)) {
506 return HWC2::Error::BadParameter;
507 }
508
509 // Configure the output buffer as Readback buffer
510 output_buffer_.width = UINT32(handle->width);
511 output_buffer_.height = UINT32(handle->height);
512 output_buffer_.unaligned_width = UINT32(handle->unaligned_width);
513 output_buffer_.unaligned_height = UINT32(handle->unaligned_height);
514 output_buffer_.format = HWCLayer::GetSDMFormat(handle->format, handle->flags);
515 output_buffer_.planes[0].fd = handle->fd;
516 output_buffer_.planes[0].stride = UINT32(handle->width);
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530517 output_buffer_.acquire_fence = acquire_fence;
Sushil Chauhand0dc03d2018-09-19 07:08:40 -0700518 output_buffer_.handle_id = handle->id;
Sushil Chauhan06521582018-03-19 14:00:23 -0700519
520 post_processed_output_ = post_processed_output;
521 readback_buffer_queued_ = true;
522 readback_configured_ = false;
523 validated_ = false;
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530524 cwb_client_ = client;
Sushil Chauhan06521582018-03-19 14:00:23 -0700525
Sushil Chauhan06521582018-03-19 14:00:23 -0700526 return HWC2::Error::None;
527}
528
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530529HWC2::Error HWCDisplayBuiltIn::GetReadbackBufferFence(shared_ptr<Fence> *release_fence) {
Sushil Chauhan06521582018-03-19 14:00:23 -0700530 auto status = HWC2::Error::None;
531
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530532 if (readback_configured_ && output_buffer_.release_fence) {
533 *release_fence = output_buffer_.release_fence;
Sushil Chauhan06521582018-03-19 14:00:23 -0700534 } else {
535 status = HWC2::Error::Unsupported;
Sushil Chauhan06521582018-03-19 14:00:23 -0700536 }
537
538 post_processed_output_ = false;
539 readback_buffer_queued_ = false;
540 readback_configured_ = false;
541 output_buffer_ = {};
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530542 cwb_client_ = kCWBClientNone;
Sushil Chauhan06521582018-03-19 14:00:23 -0700543
544 return status;
545}
546
Gurpreet Singh Dhami1207e462018-12-27 20:02:02 -0500547DisplayError HWCDisplayBuiltIn::TeardownConcurrentWriteback(void) {
548 DisplayError error = kErrorNotSupported;
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530549 if (Fence::Wait(output_buffer_.release_fence) != kErrorNone) {
550 DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
551 return kErrorResources;
Gurpreet Singh Dhami1207e462018-12-27 20:02:02 -0500552 }
553
554 if (display_intf_) {
555 error = display_intf_->TeardownConcurrentWriteback();
556 }
557
558 return error;
559}
560
Yuchao Ma577f0f72018-07-09 11:20:00 +0800561HWC2::Error HWCDisplayBuiltIn::SetDisplayDppsAdROI(uint32_t h_start, uint32_t h_end,
562 uint32_t v_start, uint32_t v_end,
563 uint32_t factor_in, uint32_t factor_out) {
564 DisplayError error = kErrorNone;
565 DisplayDppsAd4RoiCfg dpps_ad4_roi_cfg = {};
566 uint32_t panel_width = 0, panel_height = 0;
567 constexpr uint16_t kMaxFactorVal = 0xffff;
568
569 if (h_start >= h_end || v_start >= v_end || factor_in > kMaxFactorVal ||
570 factor_out > kMaxFactorVal) {
571 DLOGE("Invalid roi region = [%u, %u, %u, %u, %u, %u]",
572 h_start, h_end, v_start, v_end, factor_in, factor_out);
573 return HWC2::Error::BadParameter;
574 }
575
576 GetPanelResolution(&panel_width, &panel_height);
577
578 if (h_start >= panel_width || h_end > panel_width ||
579 v_start >= panel_height || v_end > panel_height) {
580 DLOGE("Invalid roi region = [%u, %u, %u, %u], panel resolution = [%u, %u]",
581 h_start, h_end, v_start, v_end, panel_width, panel_height);
582 return HWC2::Error::BadParameter;
583 }
584
585 dpps_ad4_roi_cfg.h_start = h_start;
586 dpps_ad4_roi_cfg.h_end = h_end;
587 dpps_ad4_roi_cfg.v_start = v_start;
588 dpps_ad4_roi_cfg.v_end = v_end;
589 dpps_ad4_roi_cfg.factor_in = factor_in;
590 dpps_ad4_roi_cfg.factor_out = factor_out;
591
592 error = display_intf_->SetDisplayDppsAdROI(&dpps_ad4_roi_cfg);
593 if (error)
594 return HWC2::Error::BadConfig;
595
Ramkumar Radhakrishnan44c64362018-12-12 13:03:59 -0800596 callbacks_->Refresh(id_);
Yuchao Ma577f0f72018-07-09 11:20:00 +0800597
598 return HWC2::Error::None;
599}
600
Xu Yang9dacc872018-12-25 11:04:28 +0800601HWC2::Error HWCDisplayBuiltIn::SetFrameTriggerMode(uint32_t mode) {
602 DisplayError error = kErrorNone;
603 FrameTriggerMode trigger_mode = kFrameTriggerDefault;
604
605 if (mode >= kFrameTriggerMax) {
606 DLOGE("Invalid input mode %d", mode);
607 return HWC2::Error::BadParameter;
608 }
609
610 trigger_mode = static_cast<FrameTriggerMode>(mode);
611 error = display_intf_->SetFrameTriggerMode(trigger_mode);
612 if (error)
613 return HWC2::Error::BadConfig;
614
615 callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
616 validated_ = false;
617
618 return HWC2::Error::None;
619}
620
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530621int HWCDisplayBuiltIn::Perform(uint32_t operation, ...) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500622 va_list args;
623 va_start(args, operation);
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700624 int val = 0;
Gopikrishnaiah Anandancc123062017-07-31 17:21:03 -0700625 LayerSolidFill *solid_fill_color;
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700626 LayerRect *rect = NULL;
627
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500628 switch (operation) {
629 case SET_METADATA_DYN_REFRESH_RATE:
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700630 val = va_arg(args, int32_t);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500631 SetMetaDataRefreshRateFlag(val);
632 break;
633 case SET_BINDER_DYN_REFRESH_RATE:
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700634 val = va_arg(args, int32_t);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500635 ForceRefreshRate(UINT32(val));
636 break;
637 case SET_DISPLAY_MODE:
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700638 val = va_arg(args, int32_t);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500639 SetDisplayMode(UINT32(val));
640 break;
641 case SET_QDCM_SOLID_FILL_INFO:
Gopikrishnaiah Anandancc123062017-07-31 17:21:03 -0700642 solid_fill_color = va_arg(args, LayerSolidFill*);
643 SetQDCMSolidFillInfo(true, *solid_fill_color);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500644 break;
645 case UNSET_QDCM_SOLID_FILL_INFO:
Gopikrishnaiah Anandancc123062017-07-31 17:21:03 -0700646 solid_fill_color = va_arg(args, LayerSolidFill*);
647 SetQDCMSolidFillInfo(false, *solid_fill_color);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500648 break;
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700649 case SET_QDCM_SOLID_FILL_RECT:
650 rect = va_arg(args, LayerRect*);
651 solid_fill_rect_ = *rect;
652 break;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500653 default:
654 DLOGW("Invalid operation %d", operation);
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700655 va_end(args);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500656 return -EINVAL;
657 }
Arun Kumar K.R536c7d62016-06-14 18:47:39 -0700658 va_end(args);
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700659 validated_ = false;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500660
661 return 0;
662}
663
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530664DisplayError HWCDisplayBuiltIn::SetDisplayMode(uint32_t mode) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500665 DisplayError error = kErrorNone;
666
667 if (display_intf_) {
668 error = display_intf_->SetDisplayMode(mode);
Tharaga Balachandran04192a62018-08-29 16:23:25 -0400669 if (error == kErrorNone) {
670 DisplayConfigFixedInfo fixed_info = {};
671 display_intf_->GetConfig(&fixed_info);
672 is_cmd_mode_ = fixed_info.is_cmdmode;
673 partial_update_enabled_ = fixed_info.partial_update;
674 for (auto hwc_layer : layer_set_) {
675 hwc_layer->SetPartialUpdate(partial_update_enabled_);
676 }
677 client_target_->SetPartialUpdate(partial_update_enabled_);
678 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500679 }
680
681 return error;
682}
683
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530684void HWCDisplayBuiltIn::SetMetaDataRefreshRateFlag(bool enable) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500685 int disable_metadata_dynfps = 0;
686
Uday Kiran Pichika5e656b22018-05-15 18:48:24 +0530687 HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500688 if (disable_metadata_dynfps) {
689 return;
690 }
691 use_metadata_refresh_rate_ = enable;
692}
693
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530694void HWCDisplayBuiltIn::SetQDCMSolidFillInfo(bool enable, const LayerSolidFill &color) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500695 solid_fill_enable_ = enable;
696 solid_fill_color_ = color;
697}
698
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530699void HWCDisplayBuiltIn::ToggleCPUHint(bool set) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500700 if (!cpu_hint_) {
701 return;
702 }
703
704 if (set) {
705 cpu_hint_->Set();
706 } else {
707 cpu_hint_->Reset();
708 }
709}
710
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530711int HWCDisplayBuiltIn::HandleSecureSession(const std::bitset<kSecureMax> &secure_sessions,
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700712 bool *power_on_pending) {
713 if (!power_on_pending) {
714 return -EINVAL;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500715 }
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700716
Mathew Joseph Karimpanalb1c15862019-07-04 11:14:24 +0530717 if (!is_primary_) {
718 return HWCDisplay::HandleSecureSession(secure_sessions, power_on_pending);
719 }
720
Ramkumar Radhakrishnan44c64362018-12-12 13:03:59 -0800721 if (current_power_mode_ != HWC2::PowerMode::On) {
722 return 0;
723 }
724
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700725 if (active_secure_sessions_[kSecureDisplay] != secure_sessions[kSecureDisplay]) {
726 SecureEvent secure_event =
727 secure_sessions.test(kSecureDisplay) ? kSecureDisplayStart : kSecureDisplayEnd;
Pullakavi Srinivas0a1dba62018-07-02 15:49:11 +0530728 DisplayError err = display_intf_->HandleSecureEvent(secure_event, &layer_stack_);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700729 if (err != kErrorNone) {
730 DLOGE("Set secure event failed");
731 return err;
732 }
733
Mathew Joseph Karimpanalb1c15862019-07-04 11:14:24 +0530734 DLOGI("SecureDisplay state changed from %d to %d for display %d-%d",
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700735 active_secure_sessions_.test(kSecureDisplay), secure_sessions.test(kSecureDisplay),
Mathew Joseph Karimpanalb1c15862019-07-04 11:14:24 +0530736 id_, type_);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700737 }
738 active_secure_sessions_ = secure_sessions;
739 *power_on_pending = false;
740 return 0;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500741}
742
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530743void HWCDisplayBuiltIn::ForceRefreshRate(uint32_t refresh_rate) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500744 if ((refresh_rate && (refresh_rate < min_refresh_rate_ || refresh_rate > max_refresh_rate_)) ||
745 force_refresh_rate_ == refresh_rate) {
746 // Cannot honor force refresh rate, as its beyond the range or new request is same
747 return;
748 }
749
750 force_refresh_rate_ = refresh_rate;
751
Ramkumar Radhakrishnan44c64362018-12-12 13:03:59 -0800752 callbacks_->Refresh(id_);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500753
754 return;
755}
756
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530757uint32_t HWCDisplayBuiltIn::GetOptimalRefreshRate(bool one_updating_layer) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500758 if (force_refresh_rate_) {
759 return force_refresh_rate_;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500760 } else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
761 return metadata_refresh_rate_;
762 }
763
764 return max_refresh_rate_;
765}
766
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530767void HWCDisplayBuiltIn::SetIdleTimeoutMs(uint32_t timeout_ms) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500768 display_intf_->SetIdleTimeoutMs(timeout_ms);
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700769 validated_ = false;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500770}
771
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530772void HWCDisplayBuiltIn::HandleFrameOutput() {
Sushil Chauhan06521582018-03-19 14:00:23 -0700773 if (readback_buffer_queued_) {
774 validated_ = false;
775 }
776
Sushil Chauhan1d3b90c2018-12-11 16:52:35 -0800777 if (frame_capture_buffer_queued_) {
778 HandleFrameCapture();
779 } else if (dump_output_to_file_) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500780 HandleFrameDump();
781 }
782}
783
Sushil Chauhan1d3b90c2018-12-11 16:52:35 -0800784void HWCDisplayBuiltIn::HandleFrameCapture() {
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530785 if (readback_configured_ && output_buffer_.release_fence) {
786 frame_capture_status_ = Fence::Wait(output_buffer_.release_fence);
Sushil Chauhan1d3b90c2018-12-11 16:52:35 -0800787 }
788
789 frame_capture_buffer_queued_ = false;
790 readback_buffer_queued_ = false;
791 post_processed_output_ = false;
792 readback_configured_ = false;
793 output_buffer_ = {};
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530794 cwb_client_ = kCWBClientNone;
Sushil Chauhan1d3b90c2018-12-11 16:52:35 -0800795}
796
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530797void HWCDisplayBuiltIn::HandleFrameDump() {
Ramkumar Radhakrishnan68331fc2019-06-19 11:24:12 -0700798 if (dump_frame_count_) {
799 int ret = 0;
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530800 ret = Fence::Wait(output_buffer_.release_fence);
801 if (ret != kErrorNone) {
802 DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
Ramkumar Radhakrishnan68331fc2019-06-19 11:24:12 -0700803 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500804
Ramkumar Radhakrishnan68331fc2019-06-19 11:24:12 -0700805 if (!ret) {
Dileep Marchyaad668432019-12-02 10:44:52 +0530806 DumpOutputBuffer(output_buffer_info_, output_buffer_base_, layer_stack_.retire_fence);
807 validated_ = false;
808 }
Ramkumar Radhakrishnan68331fc2019-06-19 11:24:12 -0700809
810 if (0 == (dump_frame_count_ - 1)) {
811 dump_output_to_file_ = false;
812 // Unmap and Free buffer
813 if (munmap(output_buffer_base_, output_buffer_info_.alloc_buffer_info.size) != 0) {
814 DLOGE("unmap failed with err %d", errno);
815 }
816 if (buffer_allocator_->FreeBuffer(&output_buffer_info_) != 0) {
817 DLOGE("FreeBuffer failed");
818 }
819
Sushil Chauhan06521582018-03-19 14:00:23 -0700820 readback_buffer_queued_ = false;
Ramkumar Radhakrishnan68331fc2019-06-19 11:24:12 -0700821 post_processed_output_ = false;
822 readback_configured_ = false;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500823
Ramkumar Radhakrishnan68331fc2019-06-19 11:24:12 -0700824 output_buffer_ = {};
825 output_buffer_info_ = {};
826 output_buffer_base_ = nullptr;
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530827 cwb_client_ = kCWBClientNone;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500828 }
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500829 }
830}
831
Sushil Chauhan267a6192018-06-06 18:41:47 -0700832HWC2::Error HWCDisplayBuiltIn::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type,
833 int32_t format, bool post_processed) {
834 HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type, format, post_processed);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500835 dump_output_to_file_ = bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP);
836 DLOGI("output_layer_dump_enable %d", dump_output_to_file_);
837
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530838 if (dump_output_to_file_) {
839 if (cwb_client_ != kCWBClientNone) {
Ramakant Singh2d617ae2020-05-12 23:41:37 +0530840 DLOGW("CWB is in use with client = %d", cwb_client_);
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530841 return HWC2::Error::NoResources;
842 }
843 }
844
Sushil Chauhand0dc03d2018-09-19 07:08:40 -0700845 if (!count || !dump_output_to_file_ || (output_buffer_info_.alloc_buffer_info.fd >= 0)) {
Mathew Joseph Karimpanaldbd64f82017-10-06 10:13:38 +0530846 return HWC2::Error::None;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500847 }
848
849 // Allocate and map output buffer
Sushil Chauhan267a6192018-06-06 18:41:47 -0700850 if (post_processed) {
851 // To dump post-processed (DSPP) output, use Panel resolution.
852 GetPanelResolution(&output_buffer_info_.buffer_config.width,
853 &output_buffer_info_.buffer_config.height);
854 } else {
855 // To dump Layer Mixer output, use FrameBuffer resolution.
856 GetFrameBufferResolution(&output_buffer_info_.buffer_config.width,
857 &output_buffer_info_.buffer_config.height);
858 }
859
860 output_buffer_info_.buffer_config.format = HWCLayer::GetSDMFormat(format, 0);
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500861 output_buffer_info_.buffer_config.buffer_count = 1;
862 if (buffer_allocator_->AllocateBuffer(&output_buffer_info_) != 0) {
863 DLOGE("Buffer allocation failed");
864 output_buffer_info_ = {};
Mathew Joseph Karimpanaldbd64f82017-10-06 10:13:38 +0530865 return HWC2::Error::NoResources;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500866 }
867
868 void *buffer = mmap(NULL, output_buffer_info_.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
869 MAP_SHARED, output_buffer_info_.alloc_buffer_info.fd, 0);
870
871 if (buffer == MAP_FAILED) {
872 DLOGE("mmap failed with err %d", errno);
873 buffer_allocator_->FreeBuffer(&output_buffer_info_);
874 output_buffer_info_ = {};
Mathew Joseph Karimpanaldbd64f82017-10-06 10:13:38 +0530875 return HWC2::Error::NoResources;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500876 }
877
878 output_buffer_base_ = buffer;
Sushil Chauhan06521582018-03-19 14:00:23 -0700879 const native_handle_t *handle = static_cast<native_handle_t *>(output_buffer_info_.private_data);
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530880 SetReadbackBuffer(handle, nullptr, post_processed, kCWBClientFrameDump);
Sushil Chauhan06521582018-03-19 14:00:23 -0700881
Mathew Joseph Karimpanaldbd64f82017-10-06 10:13:38 +0530882 return HWC2::Error::None;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500883}
884
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530885int HWCDisplayBuiltIn::FrameCaptureAsync(const BufferInfo &output_buffer_info,
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500886 bool post_processed_output) {
Dileep Marchyacb2a3a92019-06-21 17:30:50 +0530887 if (cwb_client_ != kCWBClientNone) {
888 DLOGE("CWB is in use with client = %d", cwb_client_);
889 return -1;
890 }
891
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500892 // Note: This function is called in context of a binder thread and a lock is already held
893 if (output_buffer_info.alloc_buffer_info.fd < 0) {
894 DLOGE("Invalid fd %d", output_buffer_info.alloc_buffer_info.fd);
895 return -1;
896 }
897
898 auto panel_width = 0u;
899 auto panel_height = 0u;
900 auto fb_width = 0u;
901 auto fb_height = 0u;
902
903 GetPanelResolution(&panel_width, &panel_height);
904 GetFrameBufferResolution(&fb_width, &fb_height);
905
Ch Ganesh Kumar5c4988b2017-06-07 15:21:02 +0530906 if (post_processed_output && (output_buffer_info.buffer_config.width < panel_width ||
907 output_buffer_info.buffer_config.height < panel_height)) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500908 DLOGE("Buffer dimensions should not be less than panel resolution");
909 return -1;
Ch Ganesh Kumar5c4988b2017-06-07 15:21:02 +0530910 } else if (!post_processed_output && (output_buffer_info.buffer_config.width < fb_width ||
911 output_buffer_info.buffer_config.height < fb_height)) {
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500912 DLOGE("Buffer dimensions should not be less than FB resolution");
913 return -1;
914 }
915
Sushil Chauhan06521582018-03-19 14:00:23 -0700916 const native_handle_t *buffer = static_cast<native_handle_t *>(output_buffer_info.private_data);
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530917 SetReadbackBuffer(buffer, nullptr, post_processed_output, kCWBClientColor);
Sushil Chauhan1d3b90c2018-12-11 16:52:35 -0800918 frame_capture_buffer_queued_ = true;
919 frame_capture_status_ = -EAGAIN;
Naseer Ahmedb92e73f2016-03-12 02:03:48 -0500920
921 return 0;
922}
923
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530924DisplayError HWCDisplayBuiltIn::SetDetailEnhancerConfig
Alan Kwong2e136332016-08-16 07:50:16 -0400925 (const DisplayDetailEnhancerData &de_data) {
926 DisplayError error = kErrorNotSupported;
927
928 if (display_intf_) {
929 error = display_intf_->SetDetailEnhancerData(de_data);
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700930 validated_ = false;
Alan Kwong2e136332016-08-16 07:50:16 -0400931 }
932 return error;
933}
934
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530935DisplayError HWCDisplayBuiltIn::ControlPartialUpdate(bool enable, uint32_t *pending) {
Arun Kumar K.R17bbd042016-06-07 17:38:02 -0700936 DisplayError error = kErrorNone;
937
938 if (display_intf_) {
939 error = display_intf_->ControlPartialUpdate(enable, pending);
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700940 validated_ = false;
Arun Kumar K.R17bbd042016-06-07 17:38:02 -0700941 }
942
943 return error;
944}
945
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +0530946DisplayError HWCDisplayBuiltIn::DisablePartialUpdateOneFrame() {
Arun Kumar K.R17bbd042016-06-07 17:38:02 -0700947 DisplayError error = kErrorNone;
948
949 if (display_intf_) {
950 error = display_intf_->DisablePartialUpdateOneFrame();
Saurabh Shaha307e8c2017-09-28 18:05:40 -0700951 validated_ = false;
Arun Kumar K.R17bbd042016-06-07 17:38:02 -0700952 }
953
954 return error;
955}
956
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -0800957HWC2::Error HWCDisplayBuiltIn::SetDisplayedContentSamplingEnabledVndService(bool enabled) {
958 std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex);
959 vndservice_sampling_vote = enabled;
960 if (api_sampling_vote || vndservice_sampling_vote) {
961 histogram.start();
Lakshmi Narayana Kalavalaf30c2292019-09-26 15:26:24 -0700962 display_intf_->colorSamplingOn();
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -0800963 } else {
Lakshmi Narayana Kalavalaf30c2292019-09-26 15:26:24 -0700964 display_intf_->colorSamplingOff();
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -0800965 histogram.stop();
966 }
967 return HWC2::Error::None;
968}
969
970HWC2::Error HWCDisplayBuiltIn::SetDisplayedContentSamplingEnabled(int32_t enabled,
971 uint8_t component_mask,
972 uint64_t max_frames) {
973 if ((enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) &&
974 (enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_DISABLE))
975 return HWC2::Error::BadParameter;
976
977 std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex);
978 if (enabled == HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) {
979 api_sampling_vote = true;
980 } else {
981 api_sampling_vote = false;
982 }
983
984 auto start = api_sampling_vote || vndservice_sampling_vote;
985 if (start && max_frames == 0) {
986 histogram.start();
Lakshmi Narayana Kalavalaf30c2292019-09-26 15:26:24 -0700987 display_intf_->colorSamplingOn();
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -0800988 } else if (start) {
989 histogram.start(max_frames);
Lakshmi Narayana Kalavalaf30c2292019-09-26 15:26:24 -0700990 display_intf_->colorSamplingOn();
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -0800991 } else {
Lakshmi Narayana Kalavalaf30c2292019-09-26 15:26:24 -0700992 display_intf_->colorSamplingOff();
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -0800993 histogram.stop();
994 }
995 return HWC2::Error::None;
996}
997
998HWC2::Error HWCDisplayBuiltIn::GetDisplayedContentSamplingAttributes(
999 int32_t *format, int32_t *dataspace, uint8_t *supported_components) {
1000 return histogram.getAttributes(format, dataspace, supported_components);
1001}
1002
1003HWC2::Error HWCDisplayBuiltIn::GetDisplayedContentSample(
1004 uint64_t max_frames, uint64_t timestamp, uint64_t *numFrames,
1005 int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
1006 uint64_t *samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
1007 histogram.collect(max_frames, timestamp, samples_size, samples, numFrames);
1008 return HWC2::Error::None;
1009}
Arun Kumar K.R17bbd042016-06-07 17:38:02 -07001010
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +05301011DisplayError HWCDisplayBuiltIn::SetMixerResolution(uint32_t width, uint32_t height) {
Sushil Chauhan409e8442017-06-12 17:43:25 -07001012 DisplayError error = display_intf_->SetMixerResolution(width, height);
Ramkumar Radhakrishnanf7f52162019-06-06 19:40:04 -07001013 callbacks_->Refresh(id_);
Saurabh Shaha307e8c2017-09-28 18:05:40 -07001014 validated_ = false;
Sushil Chauhan409e8442017-06-12 17:43:25 -07001015 return error;
Arun Kumar K.R8da7f502016-06-07 17:45:50 -07001016}
1017
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +05301018DisplayError HWCDisplayBuiltIn::GetMixerResolution(uint32_t *width, uint32_t *height) {
Arun Kumar K.R8da7f502016-06-07 17:45:50 -07001019 return display_intf_->GetMixerResolution(width, height);
1020}
1021
Dileep Marchyaf3ce11f2018-04-30 23:35:46 +05301022HWC2::Error HWCDisplayBuiltIn::SetQSyncMode(QSyncMode qsync_mode) {
Pullakavi Srinivas24574142019-08-14 12:18:12 +05301023 // Client needs to ensure that config change and qsync mode change
1024 // are not triggered in the same drawcycle.
1025 if (pending_config_) {
1026 DLOGE("Failed to set qsync mode. Pending active config transition");
1027 return HWC2::Error::Unsupported;
1028 }
1029
Sushil Chauhan380a59d2018-03-19 15:47:50 -07001030 auto err = display_intf_->SetQSyncMode(qsync_mode);
1031 if (err != kErrorNone) {
1032 return HWC2::Error::Unsupported;
1033 }
1034
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001035 validated_ = false;
Sushil Chauhan380a59d2018-03-19 15:47:50 -07001036 return HWC2::Error::None;
1037}
1038
Ramkumar Radhakrishnan4faf8a62018-11-15 17:15:37 -08001039DisplayError HWCDisplayBuiltIn::ControlIdlePowerCollapse(bool enable, bool synchronous) {
Ramkumar Radhakrishnanf985d482018-07-23 18:10:41 -07001040 DisplayError error = kErrorNone;
1041
1042 if (display_intf_) {
1043 error = display_intf_->ControlIdlePowerCollapse(enable, synchronous);
1044 validated_ = false;
1045 }
Ramkumar Radhakrishnan4faf8a62018-11-15 17:15:37 -08001046 return error;
Ramkumar Radhakrishnanf985d482018-07-23 18:10:41 -07001047}
1048
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301049DisplayError HWCDisplayBuiltIn::SetDynamicDSIClock(uint64_t bitclk) {
Dileep Marchyaafa45bc2019-06-21 17:05:31 +05301050 DisablePartialUpdateOneFrame();
1051 DisplayError error = display_intf_->SetDynamicDSIClock(bitclk);
1052 if (error != kErrorNone) {
1053 DLOGE(" failed: Clk: %llu Error: %d", bitclk, error);
1054 return error;
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301055 }
1056
1057 callbacks_->Refresh(id_);
1058 validated_ = false;
1059
1060 return kErrorNone;
1061}
1062
1063DisplayError HWCDisplayBuiltIn::GetDynamicDSIClock(uint64_t *bitclk) {
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301064 if (display_intf_) {
1065 return display_intf_->GetDynamicDSIClock(bitclk);
1066 }
1067
1068 return kErrorNotSupported;
1069}
1070
1071DisplayError HWCDisplayBuiltIn::GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates) {
1072 if (display_intf_) {
1073 return display_intf_->GetSupportedDSIClock(bitclk_rates);
1074 }
1075
1076 return kErrorNotSupported;
1077}
1078
Padmanabhan Komandurue74cf4f2019-04-25 17:38:43 -07001079HWC2::Error HWCDisplayBuiltIn::UpdateDisplayId(hwc2_display_t id) {
1080 id_ = id;
1081 return HWC2::Error::None;
1082}
1083
1084HWC2::Error HWCDisplayBuiltIn::SetPendingRefresh() {
1085 pending_refresh_ = true;
1086 return HWC2::Error::None;
1087}
1088
Varun Arora75c05f02019-05-14 14:53:37 -07001089HWC2::Error HWCDisplayBuiltIn::SetPanelBrightness(float brightness) {
1090 DisplayError ret = display_intf_->SetPanelBrightness(brightness);
1091 if (ret != kErrorNone) {
1092 return HWC2::Error::NoResources;
1093 }
1094
1095 return HWC2::Error::None;
1096}
1097
1098HWC2::Error HWCDisplayBuiltIn::GetPanelBrightness(float *brightness) {
1099 DisplayError ret = display_intf_->GetPanelBrightness(brightness);
1100 if (ret != kErrorNone) {
1101 return HWC2::Error::NoResources;
1102 }
1103
1104 return HWC2::Error::None;
1105}
Xu Yang45d0abf2019-07-05 11:34:06 +08001106
Yuchao Maada1c402019-11-12 14:47:11 +08001107HWC2::Error HWCDisplayBuiltIn::GetPanelMaxBrightness(uint32_t *max_brightness_level) {
1108 DisplayError ret = display_intf_->GetPanelMaxBrightness(max_brightness_level);
1109 if (ret != kErrorNone) {
1110 return HWC2::Error::NoResources;
1111 }
1112
1113 return HWC2::Error::None;
1114}
1115
Xu Yang45d0abf2019-07-05 11:34:06 +08001116HWC2::Error HWCDisplayBuiltIn::SetBLScale(uint32_t level) {
1117 DisplayError ret = display_intf_->SetBLScale(level);
1118 if (ret != kErrorNone) {
1119 return HWC2::Error::NoResources;
1120 }
Srinivas Pullakavi3c4337f2019-07-03 11:24:31 +05301121 return HWC2::Error::None;
1122}
Xu Yang45d0abf2019-07-05 11:34:06 +08001123
Srinivas Pullakavi3c4337f2019-07-03 11:24:31 +05301124HWC2::Error HWCDisplayBuiltIn::UpdatePowerMode(HWC2::PowerMode mode) {
1125 current_power_mode_ = mode;
1126 validated_ = false;
Xu Yang45d0abf2019-07-05 11:34:06 +08001127 return HWC2::Error::None;
1128}
1129
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +05301130HWC2::Error HWCDisplayBuiltIn::SetClientTarget(buffer_handle_t target,
1131 shared_ptr<Fence> acquire_fence,
Padmanabhan Komanduru9a91e9f2019-09-12 12:33:19 +05301132 int32_t dataspace, hwc_region_t damage) {
1133 HWC2::Error error = HWCDisplay::SetClientTarget(target, acquire_fence, dataspace, damage);
1134 if (error != HWC2::Error::None) {
1135 return error;
1136 }
1137
1138 Layer *sdm_layer = client_target_->GetSDMLayer();
Padmanabhan Komandurua4bf6062019-10-13 09:04:49 +05301139 uint32_t fb_width = 0, fb_height = 0;
1140
1141 GetFrameBufferResolution(&fb_width, &fb_height);
1142
1143 if (fb_width != sdm_layer->input_buffer.unaligned_width ||
1144 fb_height != sdm_layer->input_buffer.unaligned_height) {
1145 if (SetFrameBufferConfig(sdm_layer->input_buffer.unaligned_width,
1146 sdm_layer->input_buffer.unaligned_height)) {
1147 return HWC2::Error::BadParameter;
1148 }
1149 }
Padmanabhan Komanduru9a91e9f2019-09-12 12:33:19 +05301150
1151 return HWC2::Error::None;
1152}
Sushil Chauhan1566a132019-10-02 11:59:28 -07001153
1154bool HWCDisplayBuiltIn::IsSmartPanelConfig(uint32_t config_id) {
1155 if (config_id < hwc_config_map_.size()) {
1156 uint32_t index = hwc_config_map_.at(config_id);
1157 return variable_config_map_.at(index).smart_panel;
1158 }
1159
1160 return false;
1161}
1162
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +05301163int HWCDisplayBuiltIn::Deinit() {
1164 // Destory color convert instance. This destroys thread and underlying GL resources.
1165 if (gl_layer_stitch_) {
1166 layer_stitch_task_.PerformTask(LayerStitchTaskCode::kCodeDestroyInstance, nullptr);
1167 }
1168
Lakshmi Narayana Kalavala25fe12c2019-12-11 20:44:55 -08001169 histogram.stop();
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +05301170 return HWCDisplay::Deinit();
1171}
1172
1173void HWCDisplayBuiltIn::OnTask(const LayerStitchTaskCode &task_code,
1174 SyncTask<LayerStitchTaskCode>::TaskContext *task_context) {
1175 switch (task_code) {
1176 case LayerStitchTaskCode::kCodeGetInstance: {
1177 gl_layer_stitch_ = GLLayerStitch::GetInstance(false /* Non-secure */);
1178 }
1179 break;
1180 case LayerStitchTaskCode::kCodeStitch: {
1181 DTRACE_SCOPED();
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +05301182 LayerStitchContext* ctx = reinterpret_cast<LayerStitchContext*>(task_context);
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +05301183 gl_layer_stitch_->Blit(ctx->src_hnd, ctx->dst_hnd, ctx->src_rect, ctx->dst_rect,
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +05301184 ctx->src_acquire_fence, ctx->dst_acquire_fence,
1185 &(ctx->release_fence));
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +05301186 }
1187 break;
1188 case LayerStitchTaskCode::kCodeDestroyInstance: {
1189 if (gl_layer_stitch_) {
1190 GLLayerStitch::Destroy(gl_layer_stitch_);
1191 }
1192 }
1193 break;
1194 }
1195}
1196
1197bool HWCDisplayBuiltIn::InitLayerStitch() {
1198 if (!is_primary_) {
1199 // Disable on all non-primary builtins.
1200 DLOGI("Non-primary builtin.");
Pullakavi Srinivas94793b42019-11-27 20:03:50 +05301201 disable_layer_stitch_ = true;
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +05301202 return true;
1203 }
1204
1205 // Disable by default.
1206 int value = 1;
1207 Debug::Get()->GetProperty(DISABLE_LAYER_STITCH, &value);
1208 disable_layer_stitch_ = (value == 1);
1209
1210 if (disable_layer_stitch_) {
1211 DLOGI("Layer Stitch Disabled !!!");
1212 return true;
1213 }
1214
1215 // Initialize stitch context. This will be non-secure.
1216 layer_stitch_task_.PerformTask(LayerStitchTaskCode::kCodeGetInstance, nullptr);
1217 if (gl_layer_stitch_ == nullptr) {
1218 DLOGE("Failed to get LayerStitch Instance");
1219 return false;
1220 }
1221
1222 if (!AllocateStitchBuffer()) {
1223 return true;
1224 }
1225
1226 stitch_target_ = new HWCLayer(id_, static_cast<HWCBufferAllocator *>(buffer_allocator_));
1227
1228 // Populate buffer params and pvt handle.
1229 InitStitchTarget();
1230
1231 DLOGI("Created LayerStitch instance: %p", gl_layer_stitch_);
1232
1233 return true;
1234}
1235
1236bool HWCDisplayBuiltIn::AllocateStitchBuffer() {
1237 // Buffer dimensions: FB width * (1.5 * height)
1238
1239 DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config_);
1240 if (error != kErrorNone) {
1241 DLOGE("Get frame buffer config failed. Error = %d", error);
1242 return false;
1243 }
1244
1245 BufferConfig &config = buffer_info_.buffer_config;
1246 config.width = fb_config_.x_pixels;
1247 config.height = fb_config_.y_pixels * kBufferHeightFactor;
1248
1249 // By default UBWC is enabled and below property is global enable/disable for all
1250 // buffers allocated through gralloc , including framebuffer targets.
1251 int ubwc_disabled = 0;
1252 HWCDebugHandler::Get()->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
1253 config.format = ubwc_disabled ? kFormatRGBA8888 : kFormatRGBA8888Ubwc;
1254
1255 config.gfx_client = true;
1256
1257 // Populate default params.
1258 config.secure = false;
1259 config.cache = false;
1260 config.secure_camera = false;
1261
1262 error = buffer_allocator_->AllocateBuffer(&buffer_info_);
1263
1264 if (error != kErrorNone) {
1265 DLOGE("Failed to allocate buffer. Error: %d", error);
1266 return false;
1267 }
1268
1269 return true;
1270}
1271
1272void HWCDisplayBuiltIn::InitStitchTarget() {
1273 LayerBuffer buffer = {};
1274 buffer.planes[0].fd = buffer_info_.alloc_buffer_info.fd;
1275 buffer.planes[0].offset = 0;
1276 buffer.planes[0].stride = buffer_info_.alloc_buffer_info.stride;
1277 buffer.size = buffer_info_.alloc_buffer_info.size;
1278 buffer.handle_id = buffer_info_.alloc_buffer_info.id;
1279 buffer.width = buffer_info_.alloc_buffer_info.aligned_width;
1280 buffer.height = buffer_info_.alloc_buffer_info.aligned_height;
1281 buffer.unaligned_width = fb_config_.x_pixels;
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +05301282 buffer.unaligned_height = fb_config_.y_pixels * kBufferHeightFactor;
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +05301283 buffer.format = buffer_info_.alloc_buffer_info.format;
1284
1285 Layer *sdm_stitch_target = stitch_target_->GetSDMLayer();
1286 sdm_stitch_target->composition = kCompositionStitchTarget;
1287 sdm_stitch_target->input_buffer = buffer;
1288 sdm_stitch_target->input_buffer.buffer_id = reinterpret_cast<uint64_t>(buffer_info_.private_data);
1289}
1290
1291void HWCDisplayBuiltIn::AppendStitchLayer() {
1292 if (disable_layer_stitch_) {
1293 return;
1294 }
1295
1296 // Append stitch target buffer to layer stack.
1297 Layer *sdm_stitch_target = stitch_target_->GetSDMLayer();
1298 sdm_stitch_target->composition = kCompositionStitchTarget;
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +05301299 sdm_stitch_target->dst_rect = {0, 0, FLOAT(fb_config_.x_pixels), FLOAT(fb_config_.y_pixels)};
Pullakavi Srinivas1ae4acb2019-11-18 19:33:45 +05301300 layer_stack_.layers.push_back(sdm_stitch_target);
1301}
1302
Lakshmi Narayana Kalavalae0127eb2019-12-03 11:07:26 -08001303DisplayError HWCDisplayBuiltIn::HistogramEvent(int fd, uint32_t blob_id) {
1304 histogram.notify_histogram_event(fd, blob_id);
1305 return kErrorNone;
1306}
Pullakavi Srinivasdb2b84a2019-11-21 14:47:35 +05301307
1308int HWCDisplayBuiltIn::PostInit() {
1309 auto status = InitLayerStitch();
1310 if (!status) {
1311 DLOGW("Failed to initialize Layer Stitch context");
1312 // Disable layer stitch.
1313 disable_layer_stitch_ = true;
1314 }
1315
1316 return 0;
1317}
1318
Venkat Thogaru8e9b1242020-03-30 19:25:24 +05301319bool HWCDisplayBuiltIn::HasReadBackBufferSupport() {
1320 DisplayConfigFixedInfo fixed_info = {};
1321 display_intf_->GetConfig(&fixed_info);
1322
1323 return fixed_info.readback_supported;
1324}
1325
Naseer Ahmedb92e73f2016-03-12 02:03:48 -05001326} // namespace sdm