OSDN Git Service

fix build error
[android-x86/external-IA-Hardware-Composer.git] / wsi / physicaldisplay.cpp
1 /*
2 // Copyright (c) 2016 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include "physicaldisplay.h"
18
19 #include <cmath>
20
21 #include <hwcdefs.h>
22 #include <hwclayer.h>
23 #include <hwctrace.h>
24
25 #include <algorithm>
26 #include <sstream>
27 #include <string>
28
29 #include "displayplanemanager.h"
30 #include "displayqueue.h"
31 #include "hwcutils.h"
32 #include "wsi_utils.h"
33
34 namespace hwcomposer {
35
36 PhysicalDisplay::PhysicalDisplay(uint32_t gpu_fd, uint32_t pipe_id)
37     : pipe_(pipe_id),
38       width_(0),
39       height_(0),
40       custom_resolution_(false),
41       gpu_fd_(gpu_fd),
42       power_mode_(kOn) {
43 }
44
45 PhysicalDisplay::~PhysicalDisplay() {
46 }
47
48 bool PhysicalDisplay::Initialize(NativeBufferHandler *buffer_handler) {
49   display_queue_.reset(new DisplayQueue(gpu_fd_, false, buffer_handler, this));
50   InitializeDisplay();
51   return true;
52 }
53
54 const NativeBufferHandler *PhysicalDisplay::GetNativeBufferHandler() const {
55   if (display_queue_) {
56     return display_queue_->GetNativeBufferHandler();
57   }
58
59   return NULL;
60 }
61
62 void PhysicalDisplay::MarkForDisconnect() {
63   SPIN_LOCK(modeset_lock_);
64
65   IHOTPLUGEVENTTRACE("PhysicalDisplay::MarkForDisconnect recieved.");
66   connection_state_ |= kDisconnectionInProgress;
67   display_state_ |= kRefreshClonedDisplays;
68   SPIN_UNLOCK(modeset_lock_);
69 }
70
71 void PhysicalDisplay::NotifyClientOfConnectedState() {
72   SPIN_LOCK(modeset_lock_);
73   bool refresh_needed = false;
74   if (hotplug_callback_ && (connection_state_ & kConnected) &&
75       (display_state_ & kNotifyClient)) {
76     IHOTPLUGEVENTTRACE(
77         "PhysicalDisplay Sent Hotplug even call back with connected value set "
78         "to true. %p hotplugdisplayid: %d \n",
79         this, hot_plug_display_id_);
80     hotplug_callback_->Callback(hot_plug_display_id_, true);
81     display_state_ &= ~kNotifyClient;
82 #ifdef ENABLE_ANDROID_WA
83     if (ordered_display_id_ == 0) {
84       refresh_needed = true;
85     }
86 #endif
87   }
88   SPIN_UNLOCK(modeset_lock_);
89
90   if (refresh_needed) {
91     if (!display_queue_->IsIgnoreUpdates()) {
92       display_queue_->ForceRefresh();
93     }
94   }
95 }
96
97 void PhysicalDisplay::NotifyClientOfDisConnectedState() {
98   SPIN_LOCK(modeset_lock_);
99   if (hotplug_callback_ && !(connection_state_ & kConnected) &&
100       (display_state_ & kNotifyClient)) {
101     IHOTPLUGEVENTTRACE(
102         "PhysicalDisplay Sent Hotplug even call back with connected value set "
103         "to false. %p hotplugdisplayid: %d \n",
104         this, hot_plug_display_id_);
105     hotplug_callback_->Callback(hot_plug_display_id_, false);
106     display_state_ &= ~kNotifyClient;
107   }
108   SPIN_UNLOCK(modeset_lock_);
109 }
110
111 void PhysicalDisplay::DisConnect() {
112   SPIN_LOCK(modeset_lock_);
113
114   connection_state_ &= ~kDisconnectionInProgress;
115
116   if (!(connection_state_ & kConnected)) {
117     SPIN_UNLOCK(modeset_lock_);
118
119     return;
120   }
121   IHOTPLUGEVENTTRACE(
122       "PhysicalDisplay DisConnect called for Display: %p hotplugdisplayid: %d "
123       "\n",
124       this, hot_plug_display_id_);
125   display_state_ |= kNotifyClient;
126
127   if (power_mode_ != kOff) {
128     display_queue_->SetPowerMode(kOff);
129   }
130
131   connection_state_ &= ~kConnected;
132   display_state_ &= ~kUpdateDisplay;
133   SPIN_UNLOCK(modeset_lock_);
134 }
135
136 void PhysicalDisplay::Connect() {
137   SPIN_LOCK(modeset_lock_);
138
139   connection_state_ &= ~kDisconnectionInProgress;
140
141   SPIN_UNLOCK(modeset_lock_);
142
143   if (source_display_) {
144     // Current display is a cloned display, set the source_display_'s
145     // k_RefreshClonedDisplays flag. This makes clone parent have a
146     // chance to update it's cloned display list
147     PhysicalDisplay *p_clone_parent = (PhysicalDisplay *)source_display_;
148     SPIN_LOCK(p_clone_parent->modeset_lock_);
149     p_clone_parent->display_state_ |= kRefreshClonedDisplays;
150     SPIN_UNLOCK(p_clone_parent->modeset_lock_);
151   }
152
153   SPIN_LOCK(modeset_lock_);
154   if (connection_state_ & kConnected) {
155     SPIN_UNLOCK(modeset_lock_);
156     return;
157   }
158
159   connection_state_ |= kConnected;
160   display_state_ &= ~kInitialized;
161   display_state_ |= kNotifyClient;
162   IHOTPLUGEVENTTRACE("PhysicalDisplay::Connect recieved. %p \n", this);
163
164   if (!display_queue_->Initialize(pipe_, width_, height_, this)) {
165     ETRACE("Failed to initialize Display Queue.");
166   } else {
167     display_state_ |= kInitialized;
168   }
169
170   if (display_state_ & kUpdateConfig) {
171     display_state_ &= ~kUpdateConfig;
172     display_queue_->DisplayConfigurationChanged();
173     UpdateDisplayConfig();
174   }
175
176   UpdatePowerMode();
177
178   SPIN_UNLOCK(modeset_lock_);
179 }
180
181 bool PhysicalDisplay::IsConnected() const {
182   if (connection_state_ & kDisconnectionInProgress)
183     return false;
184
185   return connection_state_ & kConnected;
186 }
187
188 uint32_t PhysicalDisplay::PowerMode() const {
189   return power_mode_;
190 }
191
192 int PhysicalDisplay::GetDisplayPipe() {
193   return pipe_;
194 }
195
196 bool PhysicalDisplay::EnableDRMCommit(bool enable) {
197   display_queue_->ForceIgnoreUpdates(!enable);
198   if (enable)
199     return !display_queue_->IsIgnoreUpdates();
200   else
201     return display_queue_->IsIgnoreUpdates();
202 }
203
204 bool PhysicalDisplay::SetActiveConfig(uint32_t config) {
205   // update the activeConfig
206   IHOTPLUGEVENTTRACE(
207       "SetActiveConfig: New config to be used %d pipe: %p display: %p", config,
208       pipe_, this);
209   config_ = config;
210   display_state_ |= kNeedsModeset;
211   if (connection_state_ & kConnected) {
212     display_queue_->DisplayConfigurationChanged();
213     UpdateDisplayConfig();
214   } else {
215     display_state_ |= kUpdateConfig;
216   }
217
218   return true;
219 }
220
221 bool PhysicalDisplay::GetActiveConfig(uint32_t *config) {
222   if (!config)
223     return false;
224   IHOTPLUGEVENTTRACE(
225       "GetActiveConfig: Current config being used Config: %d pipe: %d display: "
226       "%p",
227       config_, pipe_, this);
228   *config = config_;
229   return true;
230 }
231
232 bool PhysicalDisplay::SetPowerMode(uint32_t power_mode) {
233 #ifndef DISABLE_HOTPLUG_NOTIFICATION
234   ScopedSpinLock lock(modeset_lock_);
235 #endif
236
237   if (power_mode_ == power_mode) {
238     return true;
239   }
240
241   power_mode_ = power_mode;
242   if (!(connection_state_ & kConnected)) {
243     IHOTPLUGEVENTTRACE(
244         "PhysicalDisplay is not connected, postponing power mode update.");
245     display_state_ |= kPendingPowerMode;
246     return true;
247   } else if (connection_state_ & kDisconnectionInProgress) {
248     IHOTPLUGEVENTTRACE(
249         "PhysicalDisplay diconnection in progress, postponing power mode "
250         "update.");
251     // Don't update power mode in case disconnect is in
252     // progress.
253     display_state_ |= kPendingPowerMode;
254     return true;
255   }
256
257   return UpdatePowerMode();
258 }
259
260 bool PhysicalDisplay::UpdatePowerMode() {
261   display_state_ &= ~kPendingPowerMode;
262
263   if (power_mode_ == kOn) {
264     display_state_ |= kNeedsModeset;
265     display_state_ |= kUpdateDisplay;
266     IHOTPLUGEVENTTRACE(
267         "UpdatePowerMode: Powering on Display: pipe: %d display: "
268         "%p",
269         pipe_, this);
270     PowerOn();
271   } else {
272     IHOTPLUGEVENTTRACE(
273         "UpdatePowerMode: Power mode is not kOn: pipe: %d display: "
274         "%p",
275         pipe_, this);
276     display_state_ &= ~kUpdateDisplay;
277   }
278
279   if (!(display_state_ & kInitialized))
280     return true;
281
282   return display_queue_->SetPowerMode(power_mode_);
283 }
284
285 bool PhysicalDisplay::Present(std::vector<HwcLayer *> &source_layers,
286                               int32_t *retire_fence,
287                               PixelUploaderCallback *call_back,
288                               bool handle_constraints) {
289   CTRACE();
290   SPIN_LOCK(modeset_lock_);
291
292   bool handle_hotplug_notifications = false;
293   if (display_state_ & kHandlePendingHotPlugNotifications) {
294     display_state_ &= ~kHandlePendingHotPlugNotifications;
295     handle_hotplug_notifications = true;
296   }
297
298   if (!(display_state_ & kUpdateDisplay)) {
299     bool success = true;
300     if (power_mode_ != kDozeSuspend) {
301       ETRACE("Trying to update an Disconnected Display.%p \n", this);
302     }
303
304     SPIN_UNLOCK(modeset_lock_);
305
306     if (handle_hotplug_notifications) {
307       NotifyClientsOfDisplayChangeStatus();
308     }
309
310     return success;
311   }
312
313   if (source_display_) {
314     ETRACE("Trying to update display independently when in cloned mode.%p \n",
315            this);
316   }
317
318   if (display_state_ & kRefreshClonedDisplays) {
319     RefreshClones();
320   }
321
322   SPIN_UNLOCK(modeset_lock_);
323
324   if (handle_hotplug_notifications) {
325     NotifyClientsOfDisplayChangeStatus();
326     IHOTPLUGEVENTTRACE("Handle_hoplug_notifications done. %p \n", this);
327   }
328
329   bool ignore_clone_update = false;
330   bool success = display_queue_->QueueUpdate(source_layers, retire_fence,
331                                              &ignore_clone_update, call_back,
332                                              handle_constraints);
333   if (success && !clones_.empty() && !ignore_clone_update) {
334     HandleClonedDisplays(this);
335   }
336
337   size_t size = source_layers.size();
338   for (size_t layer_index = 0; layer_index < size; layer_index++) {
339     HwcLayer *layer = source_layers.at(layer_index);
340     if (!layer->IsVisible())
341       continue;
342
343     layer->Validate();
344   }
345
346   return success;
347 }
348
349 bool PhysicalDisplay::PresentClone(NativeDisplay *display) {
350   CTRACE();
351   SPIN_LOCK(modeset_lock_);
352
353   if (display_state_ & kRefreshClonedDisplays) {
354     RefreshClones();
355   }
356   SPIN_UNLOCK(modeset_lock_);
357
358   display_queue_->PresentClonedCommit(
359       static_cast<PhysicalDisplay *>(display)->display_queue_.get());
360   HandleClonedDisplays(display);
361   return true;
362 }
363
364 void PhysicalDisplay::HandleClonedDisplays(NativeDisplay *display) {
365   if (clones_.empty())
366     return;
367
368   for (auto clone_display : clones_) {
369     clone_display->PresentClone(display);
370   }
371 }
372
373 int PhysicalDisplay::RegisterVsyncCallback(
374     std::shared_ptr<VsyncCallback> callback, uint32_t display_id) {
375   return display_queue_->RegisterVsyncCallback(callback, display_id);
376 }
377
378 void PhysicalDisplay::RegisterRefreshCallback(
379     std::shared_ptr<RefreshCallback> callback, uint32_t display_id) {
380   return display_queue_->RegisterRefreshCallback(callback, display_id);
381 }
382
383 void PhysicalDisplay::RegisterHotPlugCallback(
384     std::shared_ptr<HotPlugCallback> callback, uint32_t display_id) {
385   SPIN_LOCK(modeset_lock_);
386   hot_plug_display_id_ = display_id;
387   hotplug_callback_ = callback;
388 #ifndef ENABLE_ANDROID_WA
389   bool connected = connection_state_ & kConnected;
390 #endif
391   SPIN_UNLOCK(modeset_lock_);
392 #ifdef ENABLE_ANDROID_WA
393   if (hotplug_callback_ && ordered_display_id_ == 0) {
394     display_state_ &= ~kNotifyClient;
395     display_state_ |= kHandlePendingHotPlugNotifications;
396     IHOTPLUGEVENTTRACE("RegisterHotPlugCallback: pipe: %d display: %p", pipe_,
397                        this);
398     hotplug_callback_->Callback(hot_plug_display_id_, true);
399   }
400 #else
401   if (hotplug_callback_) {
402     if (connected) {
403       hotplug_callback_->Callback(hot_plug_display_id_, true);
404     } else {
405       hotplug_callback_->Callback(hot_plug_display_id_, false);
406     }
407   }
408 #endif
409 }
410
411 void PhysicalDisplay::VSyncControl(bool enabled) {
412   display_queue_->VSyncControl(enabled);
413 }
414
415 bool PhysicalDisplay::CheckPlaneFormat(uint32_t format) {
416   return display_queue_->CheckPlaneFormat(format);
417 }
418
419 void PhysicalDisplay::SetGamma(float red, float green, float blue) {
420   display_queue_->SetGamma(red, green, blue);
421 }
422
423 void PhysicalDisplay::SetColorTransform(const float *matrix,
424                                         HWCColorTransform hint) {
425   display_queue_->SetColorTransform(matrix, hint);
426 }
427
428 void PhysicalDisplay::SetContrast(uint32_t red, uint32_t green, uint32_t blue) {
429   display_queue_->SetContrast(red, green, blue);
430 }
431
432 void PhysicalDisplay::SetBrightness(uint32_t red, uint32_t green,
433                                     uint32_t blue) {
434   display_queue_->SetBrightness(red, green, blue);
435 }
436
437 void PhysicalDisplay::SetDisableExplicitSync(bool disable_explicit_sync) {
438   display_queue_->SetDisableExplicitSync(disable_explicit_sync);
439 }
440
441 void PhysicalDisplay::SetVideoScalingMode(uint32_t mode) {
442   display_queue_->SetVideoScalingMode(mode);
443 }
444
445 void PhysicalDisplay::SetVideoColor(HWCColorControl color, float value) {
446   display_queue_->SetVideoColor(color, value);
447 }
448
449 void PhysicalDisplay::GetVideoColor(HWCColorControl color, float *value,
450                                     float *start, float *end) {
451   display_queue_->GetVideoColor(color, value, start, end);
452 }
453
454 void PhysicalDisplay::RestoreVideoDefaultColor(HWCColorControl color) {
455   display_queue_->RestoreVideoDefaultColor(color);
456 }
457
458 void PhysicalDisplay::SetVideoDeinterlace(HWCDeinterlaceFlag flag,
459                                           HWCDeinterlaceControl mode) {
460   display_queue_->SetVideoDeinterlace(flag, mode);
461 }
462
463 void PhysicalDisplay::RestoreVideoDefaultDeinterlace() {
464   display_queue_->RestoreVideoDefaultDeinterlace();
465 }
466
467 void PhysicalDisplay::SetCanvasColor(uint16_t bpc, uint16_t red, uint16_t green,
468                                      uint16_t blue, uint16_t alpha) {
469   display_queue_->SetCanvasColor(bpc, red, green, blue, alpha);
470 }
471
472 void PhysicalDisplay::SetPAVPSessionStatus(bool enabled,
473                                            uint32_t pavp_session_id,
474                                            uint32_t pavp_instance_id) {
475   display_queue_->SetPAVPSessionStatus(enabled, pavp_session_id,
476                                        pavp_instance_id);
477 }
478
479 bool PhysicalDisplay::PopulatePlanes(
480     std::vector<std::unique_ptr<DisplayPlane>> & /*overlay_planes*/) {
481   ETRACE("PopulatePlanes unimplemented in PhysicalDisplay.");
482   return false;
483 }
484
485 bool PhysicalDisplay::TestCommit(
486     const std::vector<OverlayPlane> & /*commit_planes*/) const {
487   ETRACE("TestCommit unimplemented in PhysicalDisplay.");
488   return false;
489 }
490
491 void PhysicalDisplay::UpdateScalingRatio(uint32_t primary_width,
492                                          uint32_t primary_height,
493                                          uint32_t display_width,
494                                          uint32_t display_height) {
495   display_queue_->UpdateScalingRatio(primary_width, primary_height,
496                                      display_width, display_height);
497 }
498
499 void PhysicalDisplay::CloneDisplay(NativeDisplay *source_display) {
500   if (source_display_) {
501     source_display_->DisOwnPresentation(this);
502     display_queue_->SetCloneMode(false);
503     source_display_ = NULL;
504   }
505
506   source_display_ = source_display;
507   if (source_display_) {
508     source_display_->OwnPresentation(this);
509     display_queue_->SetCloneMode(true);
510   }
511 }
512
513 void PhysicalDisplay::OwnPresentation(NativeDisplay *clone) {
514   cloned_displays_.emplace_back(clone);
515   display_state_ |= kRefreshClonedDisplays;
516 }
517
518 void PhysicalDisplay::DisOwnPresentation(NativeDisplay *clone) {
519   if (cloned_displays_.empty())
520     return;
521
522   std::vector<NativeDisplay *> displays;
523   size_t size = cloned_displays_.size();
524   for (size_t i = 0; i < size; i++) {
525     NativeDisplay *display = cloned_displays_.at(i);
526     if (display == clone)
527       continue;
528
529     displays.emplace_back(display);
530   }
531
532   cloned_displays_.swap(displays);
533   display_state_ |= kRefreshClonedDisplays;
534 }
535
536 void PhysicalDisplay::SetDisplayOrder(uint32_t display_order) {
537   ordered_display_id_ = display_order;
538 }
539
540 void PhysicalDisplay::RotateDisplay(HWCRotation rotation) {
541   display_queue_->RotateDisplay(rotation);
542 }
543
544 void PhysicalDisplay::RefreshClones() {
545   display_state_ &= ~kRefreshClonedDisplays;
546   std::vector<NativeDisplay *>().swap(clones_);
547   if (cloned_displays_.empty())
548     return;
549
550   size_t size = cloned_displays_.size();
551   for (size_t i = 0; i < size; i++) {
552     NativeDisplay *display = cloned_displays_.at(i);
553     if (!display->IsConnected())
554       continue;
555
556     clones_.emplace_back(display);
557   }
558
559   uint32_t primary_width = Width();
560   uint32_t primary_height = Height();
561   for (auto display : clones_) {
562     uint32_t display_width = display->Width();
563     uint32_t display_height = display->Height();
564     if ((primary_width == display_width) && (primary_height == display_height))
565       return;
566
567     display->UpdateScalingRatio(primary_width, primary_height, display_width,
568                                 display_height);
569   }
570 }
571
572 bool PhysicalDisplay::GetDisplayAttribute(uint32_t /*config*/,
573                                           HWCDisplayAttribute attribute,
574                                           int32_t *value) {
575   // We always get the values from preferred mode config.
576   switch (attribute) {
577     case HWCDisplayAttribute::kWidth:
578       *value = 1920;
579       break;
580     case HWCDisplayAttribute::kHeight:
581       *value = 1080;
582       break;
583     case HWCDisplayAttribute::kRefreshRate:
584       // in nanoseconds
585       *value = 16666666;
586       break;
587     case HWCDisplayAttribute::kDpiX:
588       // Dots per 1000 inches
589       *value = 1;
590       break;
591     case HWCDisplayAttribute::kDpiY:
592       // Dots per 1000 inches
593       *value = 1;
594       break;
595     default:
596       *value = -1;
597       return false;
598   }
599
600   return true;
601 }
602
603 /* Setting custom resolution instead of preferred as fetched from display */
604 bool PhysicalDisplay::SetCustomResolution(const HwcRect<int32_t> &rect) {
605   if ((rect.right - rect.left) && (rect.bottom - rect.top)) {
606     // Custom rectangle with valid width and height
607     rect_.left = rect.left;
608     rect_.top = rect.top;
609     rect_.right = rect.right;
610     rect_.bottom = rect.bottom;
611     custom_resolution_ = true;
612
613     IHOTPLUGEVENTTRACE(
614         "SetCustomResolution: custom width %d, height %d, bool %d",
615         rect_.right - rect_.left, rect_.bottom - rect_.top, custom_resolution_);
616
617     return true;
618   } else {
619     // Default display rectangle
620     custom_resolution_ = false;
621     return false;
622   }
623 }
624
625 bool PhysicalDisplay::GetDisplayConfigs(uint32_t *num_configs,
626                                         uint32_t *configs) {
627   if (!num_configs)
628     return false;
629   *num_configs = 1;
630   if (configs) {
631     configs[0] = DEFAULT_CONFIG_ID;
632   }
633   connection_state_ |= kFakeConnected;
634   return true;
635 }
636
637 bool PhysicalDisplay::GetDisplayName(uint32_t *size, char *name) {
638   std::ostringstream stream;
639   stream << "Headless";
640   std::string string = stream.str();
641   size_t length = string.length();
642   if (!name) {
643     *size = length;
644     return true;
645   }
646
647   *size = std::min<uint32_t>(static_cast<uint32_t>(length + 1), *size);
648   strncpy(name, string.c_str(), *size);
649   return true;
650 }
651 }  // namespace hwcomposer