OSDN Git Service

Set HWC as DRM master when got exclusive lock of /vendor/hwc.lock.
[android-x86/external-IA-Hardware-Composer.git] / common / core / gpudevice.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 <gpudevice.h>
18
19 #include <sys/file.h>
20
21 #include "mosaicdisplay.h"
22
23 #include "hwctrace.h"
24
25 namespace hwcomposer {
26
27 GpuDevice::GpuDevice() : HWCThread(-8, "GpuDevice") {
28 }
29
30 GpuDevice::~GpuDevice() {
31   display_manager_.reset(nullptr);
32 }
33
34 bool GpuDevice::Initialize() {
35   initialization_state_lock_.lock();
36   if (initialization_state_ & kInitialized) {
37     initialization_state_lock_.unlock();
38     return true;
39   }
40
41   initialization_state_ |= kInitialized;
42   initialization_state_lock_.unlock();
43
44   display_manager_.reset(DisplayManager::CreateDisplayManager(this));
45
46   bool success = display_manager_->Initialize();
47   if (!success) {
48     return false;
49   }
50
51   display_manager_->InitializeDisplayResources();
52   display_manager_->StartHotPlugMonitor();
53
54   HandleHWCSettings();
55
56   lock_fd_ = open("/vendor/hwc.lock", O_RDONLY);
57   if (-1 != lock_fd_) {
58     if (!InitWorker()) {
59       ETRACE("Failed to initalize thread for GpuDevice. %s", PRINTERROR());
60     }
61   } else {
62     ITRACE("Failed to open " LOCK_DIR_PREFIX "/hwc.lock file!");
63   }
64
65   return true;
66 }
67
68 uint32_t GpuDevice::GetFD() const {
69   return display_manager_->GetFD();
70 }
71
72 NativeDisplay *GpuDevice::GetDisplay(uint32_t display_id) {
73   if (total_displays_.size() > display_id)
74     return total_displays_.at(display_id);
75
76   return NULL;
77 }
78
79 NativeDisplay *GpuDevice::CreateVirtualDisplay(uint32_t display_index) {
80   return display_manager_->CreateVirtualDisplay(display_index);
81 }
82
83 void GpuDevice::DestroyVirtualDisplay(uint32_t display_index) {
84   display_manager_->DestroyVirtualDisplay(display_index);
85 }
86
87 void GpuDevice::GetConnectedPhysicalDisplays(
88     std::vector<NativeDisplay *> &displays) {
89   size_t size = total_displays_.size();
90   for (size_t i = 0; i < size; i++) {
91     if (total_displays_.at(i)->IsConnected()) {
92       displays.emplace_back(total_displays_.at(i));
93     }
94   }
95 }
96
97 const std::vector<NativeDisplay *> &GpuDevice::GetAllDisplays() {
98   return total_displays_;
99 }
100
101 void GpuDevice::RegisterHotPlugEventCallback(
102     std::shared_ptr<DisplayHotPlugEventCallback> callback) {
103   display_manager_->RegisterHotPlugEventCallback(callback);
104 }
105
106 void GpuDevice::HandleHWCSettings() {
107   // Handle config file reading
108   const char *hwc_dp_cfg_path = HWC_DISPLAY_INI_PATH;
109   ITRACE("Hwc display config file is %s", hwc_dp_cfg_path);
110
111   bool use_logical = false;
112   bool use_mosaic = false;
113   bool use_cloned = false;
114   bool rotate_display = false;
115   bool use_float = false;
116   std::vector<uint32_t> logical_displays;
117   std::vector<uint32_t> physical_displays;
118   std::vector<uint32_t> display_rotation;
119   std::vector<uint32_t> float_display_indices;
120   std::vector<HwcRect<int32_t>> float_displays;
121   std::vector<std::vector<uint32_t>> cloned_displays;
122   std::vector<std::vector<uint32_t>> mosaic_displays;
123   std::ifstream fin(hwc_dp_cfg_path);
124   std::string cfg_line;
125   std::string key_logical("LOGICAL");
126   std::string key_mosaic("MOSAIC");
127   std::string key_clone("CLONE");
128   std::string key_rotate("ROTATION");
129   std::string key_float("FLOAT");
130   std::string key_logical_display("LOGICAL_DISPLAY");
131   std::string key_mosaic_display("MOSAIC_DISPLAY");
132   std::string key_physical_display("PHYSICAL_DISPLAY");
133   std::string key_physical_display_rotation("PHYSICAL_DISPLAY_ROTATION");
134   std::string key_clone_display("CLONE_DISPLAY");
135   std::string key_float_display("FLOAT_DISPLAY");
136   std::vector<uint32_t> mosaic_duplicate_check;
137   std::vector<uint32_t> clone_duplicate_check;
138   std::vector<uint32_t> physical_duplicate_check;
139   std::vector<uint32_t> rotation_display_index;
140   while (std::getline(fin, cfg_line)) {
141     std::istringstream i_line(cfg_line);
142     std::string key;
143     // Skip comments
144     if (cfg_line[0] != '#' && std::getline(i_line, key, '=')) {
145       std::string content;
146       std::string value;
147       std::getline(i_line, content, '=');
148       std::istringstream i_content(content);
149       while (std::getline(i_content, value, '"')) {
150         if (value.empty())
151           continue;
152
153         std::string enable_str("true");
154         // Got logical switch
155         if (!key.compare(key_logical)) {
156           if (!value.compare(enable_str)) {
157             use_logical = true;
158           }
159           // Got mosaic switch
160         } else if (!key.compare(key_mosaic)) {
161           if (!value.compare(enable_str)) {
162             use_mosaic = true;
163           }
164           // Got clone switch
165         } else if (!key.compare(key_clone)) {
166           if (!value.compare(enable_str)) {
167             use_cloned = true;
168           }
169           // Got rotation switch.
170         } else if (!key.compare(key_rotate)) {
171           if (!value.compare(enable_str)) {
172             rotate_display = true;
173           }
174           // Got float switch
175         } else if (!key.compare(key_float)) {
176           if (!value.compare(enable_str)) {
177             use_float = true;
178           }
179         } else if (!key.compare(key_logical_display)) {
180           std::string physical_index_str;
181           std::istringstream i_value(value);
182           // Got physical display index
183           std::getline(i_value, physical_index_str, ':');
184           if (physical_index_str.empty() ||
185               physical_index_str.find_first_not_of("0123456789") !=
186                   std::string::npos)
187             continue;
188           std::string logical_split_str;
189           // Got split num
190           std::getline(i_value, logical_split_str, ':');
191           if (logical_split_str.empty() ||
192               logical_split_str.find_first_not_of("0123456789") !=
193                   std::string::npos)
194             continue;
195           uint32_t physical_index = atoi(physical_index_str.c_str());
196           uint32_t logical_split_num = atoi(logical_split_str.c_str());
197           if (logical_split_num <= 1)
198             continue;
199           // Set logical num 1 for physical display which is not in config
200           while (physical_index > logical_displays.size()) {
201             logical_displays.emplace_back(1);
202           }
203           // Save logical split num for the physical display (don't care if the
204           // physical display is disconnected/connected here)
205           logical_displays.emplace_back(logical_split_num);
206           // Got mosaic config
207         } else if (!key.compare(key_mosaic_display)) {
208           std::istringstream i_value(value);
209           std::string i_mosaic_split_str;
210           // Got mosaic sub display num
211           std::vector<uint32_t> mosaic_display;
212           while (std::getline(i_value, i_mosaic_split_str, '+')) {
213             if (i_mosaic_split_str.empty() ||
214                 i_mosaic_split_str.find_first_not_of("0123456789") !=
215                     std::string::npos)
216               continue;
217             size_t i_mosaic_split_num = atoi(i_mosaic_split_str.c_str());
218             // Check and skip if the display already been used in other mosaic
219             bool skip_duplicate_display = false;
220             size_t mosaic_size = mosaic_duplicate_check.size();
221             for (size_t i = 0; i < mosaic_size; i++) {
222               if (mosaic_duplicate_check.at(i) == i_mosaic_split_num) {
223                 skip_duplicate_display = true;
224                 break;
225               }
226             }
227             if (!skip_duplicate_display) {
228               // save the sub display num for the mosaic display (don't care
229               // if
230               // the physical/logical display is existing/connected here)
231               mosaic_display.emplace_back(i_mosaic_split_num);
232               mosaic_duplicate_check.emplace_back(i_mosaic_split_num);
233             }
234           }
235           mosaic_displays.emplace_back(mosaic_display);
236         } else if (!key.compare(key_physical_display)) {
237           std::istringstream i_value(value);
238           std::string physical_split_str;
239           // Got physical display num
240           while (std::getline(i_value, physical_split_str, ':')) {
241             if (physical_split_str.empty() ||
242                 physical_split_str.find_first_not_of("0123456789") !=
243                     std::string::npos)
244               continue;
245             size_t physical_split_num = atoi(physical_split_str.c_str());
246             // Check and skip if the display already been used in other mosaic
247             bool skip_duplicate_display = false;
248             size_t physical_size = physical_duplicate_check.size();
249             for (size_t i = 0; i < physical_size; i++) {
250               if (physical_duplicate_check.at(i) == physical_split_num) {
251                 skip_duplicate_display = true;
252                 break;
253               }
254             }
255             if (!skip_duplicate_display) {
256               physical_displays.emplace_back(physical_split_num);
257               physical_duplicate_check.emplace_back(physical_split_num);
258             }
259           }
260         } else if (!key.compare(key_clone_display)) {
261           std::istringstream i_value(value);
262           std::string i_clone_split_str;
263           // Got mosaic sub display num
264           std::vector<uint32_t> clone_display;
265           while (std::getline(i_value, i_clone_split_str, '+')) {
266             if (i_clone_split_str.empty() ||
267                 i_clone_split_str.find_first_not_of("0123456789") !=
268                     std::string::npos)
269               continue;
270             size_t i_clone_split_num = atoi(i_clone_split_str.c_str());
271             // Check and skip if the display already been used in other clone
272             bool skip_duplicate_display = false;
273             size_t clone_size = clone_duplicate_check.size();
274             for (size_t i = 0; i < clone_size; i++) {
275               if (clone_duplicate_check.at(i) == i_clone_split_num) {
276                 skip_duplicate_display = true;
277                 break;
278               }
279             }
280             if (!skip_duplicate_display) {
281               // save the sub display num for the mosaic display (don't care
282               // if
283               // the physical/logical display is existing/connected here)
284               clone_display.emplace_back(i_clone_split_num);
285               clone_duplicate_check.emplace_back(i_clone_split_num);
286             }
287           }
288           cloned_displays.emplace_back(clone_display);
289         } else if (!key.compare(key_physical_display_rotation)) {
290           std::string physical_index_str;
291           std::istringstream i_value(value);
292           // Got physical display index
293           std::getline(i_value, physical_index_str, ':');
294           if (physical_index_str.empty() ||
295               physical_index_str.find_first_not_of("0123456789") !=
296                   std::string::npos)
297             continue;
298
299           uint32_t physical_index = atoi(physical_index_str.c_str());
300           // Check and skip if the display is already in use.
301           bool skip_duplicate_display = false;
302           size_t rotation_size = rotation_display_index.size();
303           for (size_t i = 0; i < rotation_size; i++) {
304             if (rotation_display_index.at(i) == physical_index) {
305               skip_duplicate_display = true;
306               break;
307             }
308           }
309
310           if (skip_duplicate_display) {
311             continue;
312           }
313
314           std::string rotation_str;
315           // Got split num
316           std::getline(i_value, rotation_str, ':');
317           if (rotation_str.empty() ||
318               rotation_str.find_first_not_of("0123") != std::string::npos)
319             continue;
320
321           uint32_t rotation_num = atoi(rotation_str.c_str());
322           display_rotation.emplace_back(rotation_num);
323           rotation_display_index.emplace_back(physical_index);
324         } else if (!key.compare(key_float_display)) {
325           std::string index_str;
326           std::string float_rect_str;
327           std::vector<int32_t> float_rect;
328           std::istringstream i_value(value);
329
330           // Got display index
331           std::getline(i_value, index_str, ':');
332           if (index_str.empty() ||
333               index_str.find_first_not_of("0123456789") != std::string::npos) {
334             continue;
335           }
336
337           int32_t index = atoi(index_str.c_str());
338
339           // Got rectangle configuration
340           while (std::getline(i_value, float_rect_str, '+')) {
341             if (float_rect_str.empty() ||
342                 float_rect_str.find_first_not_of("0123456789") !=
343                     std::string::npos) {
344               continue;
345             }
346             size_t float_rect_val = atoi(float_rect_str.c_str());
347
348             // Save the rectangle - left, top, right & bottom
349             float_rect.emplace_back(float_rect_val);
350           }
351
352           // If entire rect is available, store the parameters
353           // TODO remove hard code
354           if (float_rect.size() == 4) {
355             float_display_indices.emplace_back(index);
356             HwcRect<int32_t> rect =
357                 HwcRect<int32_t>(float_rect.at(0), float_rect.at(1),
358                                  float_rect.at(2), float_rect.at(3));
359             float_displays.emplace_back(rect);
360           }
361         }
362       }
363     }
364   };
365
366   std::vector<NativeDisplay *> displays;
367   std::vector<NativeDisplay *> unordered_displays =
368       display_manager_->GetAllDisplays();
369   size_t size = unordered_displays.size();
370   uint32_t dispmgr_display_size = (uint32_t) size;
371
372   if (physical_displays.empty()) {
373     displays.swap(unordered_displays);
374   } else {
375     size = physical_displays.size();
376     for (size_t i = 0; i < size; i++) {
377       uint32_t pdisp_index = physical_displays.at(i);
378       // Add the physical display only if it has been enumerated from DRM API.
379       // Skip the non-existence display defined in hwc_display.ini file.
380       if (pdisp_index < dispmgr_display_size) {
381         displays.emplace_back(unordered_displays.at(pdisp_index));
382       } else {
383         ETRACE(
384             "Physical display number: %u defined in hwc_display.ini "
385             "doesn't exist in enumerated DRM display list (total: %u).",
386             pdisp_index, dispmgr_display_size);
387       }
388     }
389
390     if (displays.size() != unordered_displays.size()) {
391       size = unordered_displays.size();
392       for (size_t i = 0; i < size; i++) {
393         NativeDisplay *display = unordered_displays.at(i);
394         uint32_t temp = displays.size();
395         for (size_t i = 0; i < temp; i++) {
396           if (displays.at(i) == display) {
397             display = NULL;
398             break;
399           }
400         }
401
402         if (display) {
403           displays.emplace_back(display);
404         }
405       }
406     }
407   }
408
409   // Re-order displays based on connection status.
410   std::vector<NativeDisplay *> connected_displays;
411   std::vector<NativeDisplay *> un_connected_displays;
412   size = displays.size();
413   for (size_t i = 0; i < size; i++) {
414     NativeDisplay *temp = displays.at(i);
415     if (temp->IsConnected()) {
416       connected_displays.emplace_back(temp);
417     } else {
418       un_connected_displays.emplace_back(temp);
419     }
420   }
421
422   displays.swap(connected_displays);
423
424   if (!un_connected_displays.empty()) {
425     size_t temp = un_connected_displays.size();
426     for (size_t i = 0; i < temp; i++) {
427       displays.emplace_back(un_connected_displays.at(i));
428     }
429   }
430
431   for (size_t i = 0; i < size; i++) {
432     displays.at(i)->SetDisplayOrder(i);
433   }
434
435   // We should have all displays ordered. Apply rotation settings.
436   if (rotate_display) {
437     size_t rotation_size = rotation_display_index.size();
438     for (size_t i = 0; i < rotation_size; i++) {
439       HWCRotation rotation = static_cast<HWCRotation>(display_rotation.at(i));
440       displays.at(rotation_display_index.at(i))->RotateDisplay(rotation);
441     }
442   }
443
444   // Now, we should have all physical displays ordered as required.
445   // Let's handle any Logical Display combinations or Mosaic.
446   std::vector<NativeDisplay *> temp_displays;
447   for (size_t i = 0; i < size; i++) {
448     hwcomposer::NativeDisplay *display = displays.at(i);
449     // Save logical displays to temp_displays, skip the physical display
450     if (use_logical && (logical_displays.size() >= i + 1) &&
451         logical_displays[i] > 1) {
452       std::unique_ptr<LogicalDisplayManager> manager(
453           new LogicalDisplayManager(display));
454       logical_display_manager_.emplace_back(std::move(manager));
455       // don't care if the displays is connected/disconnected here
456       logical_display_manager_.back()->InitializeLogicalDisplays(
457           logical_displays[i]);
458       std::vector<LogicalDisplay *> temp_logical_displays;
459       logical_display_manager_.back()->GetLogicalDisplays(
460           temp_logical_displays);
461       size_t logical_display_total_size = temp_logical_displays.size();
462       for (size_t j = 0; j < logical_display_total_size; j++) {
463         temp_displays.emplace_back(temp_logical_displays.at(j));
464       }
465       // Save no split physical displays to temp_displays
466     } else {
467       temp_displays.emplace_back(display);
468     }
469   }
470
471   std::vector<bool> available_displays(temp_displays.size(), true);
472   if (use_mosaic) {
473     size_t displays_size = temp_displays.size();
474     for (size_t t = 0; t < displays_size; t++) {
475       // Skip the displays which already be marked in other mosaic
476       if (!available_displays.at(t))
477         continue;
478       bool skip_display = false;
479       size_t mosaic_size = mosaic_displays.size();
480       for (size_t m = 0; m < mosaic_size; m++) {
481         std::vector<NativeDisplay *> i_available_mosaic_displays;
482         size_t mosaic_inner_size = mosaic_displays.at(m).size();
483         for (size_t l = 0; l < mosaic_inner_size; l++) {
484           // Check if the logical display is in mosaic, keep the order of
485           // logical displays list
486           // Get the smallest logical num of the mosaic for order keeping
487           if (t == mosaic_displays.at(m).at(l)) {
488             // Loop to get logical displays of mosaic, keep the order of config
489             for (size_t i = 0; i < mosaic_inner_size; i++) {
490               // Verify the logical display num
491               if (mosaic_displays.at(m).at(i) < displays_size) {
492                 // Skip the disconnected display here
493                 i_available_mosaic_displays.emplace_back(
494                     temp_displays.at(mosaic_displays.at(m).at(i)));
495                 // Add tag for mosaic-ed displays
496                 available_displays.at(mosaic_displays.at(m).at(i)) = false;
497               }
498             }
499             // Create mosaic for those logical displays
500             if (i_available_mosaic_displays.size() > 0) {
501               std::unique_ptr<MosaicDisplay> mosaic(
502                   new MosaicDisplay(i_available_mosaic_displays));
503               mosaic_displays_.emplace_back(std::move(mosaic));
504               // Save the mosaic to the final displays list
505               total_displays_.emplace_back(mosaic_displays_.back().get());
506             }
507             skip_display = true;
508             break;
509           }
510         }
511         if (skip_display)
512           break;
513       }
514       if (!skip_display) {
515         total_displays_.emplace_back(temp_displays.at(t));
516       }
517     }
518   } else {
519     total_displays_.swap(temp_displays);
520   }
521
522   if (use_cloned && !use_mosaic && !use_logical) {
523     std::vector<NativeDisplay *> temp_displays;
524     size_t displays_size = total_displays_.size();
525     size_t cloned_displays_size = cloned_displays.size();
526     for (size_t c = 0; c < cloned_displays_size; c++) {
527       std::vector<uint32_t> &temp = cloned_displays.at(c);
528       size_t c_size = temp.size();
529       NativeDisplay *physical_display = total_displays_.at(temp.at(0));
530       for (size_t clone = 1; clone < c_size; clone++) {
531         total_displays_.at(temp.at(clone))->CloneDisplay(physical_display);
532       }
533     }
534
535     for (size_t t = 0; t < displays_size; t++) {
536       bool found = false;
537       for (size_t c = 0; c < cloned_displays_size; c++) {
538         std::vector<uint32_t> &temp = cloned_displays.at(c);
539         size_t c_size = temp.size();
540         for (size_t clone = 1; clone < c_size; clone++) {
541           uint32_t temp_clone = temp.at(clone);
542           if (temp_clone == t) {
543             found = true;
544             break;
545           }
546         }
547
548         if (found) {
549           break;
550         }
551       }
552
553       // Don't advertise cloned display as another independent
554       // Physical Display.
555       if (found) {
556         continue;
557       }
558
559       temp_displays.emplace_back(total_displays_.at(t));
560     }
561
562     temp_displays.swap(total_displays_);
563   }
564
565   // Now set floating display configuration
566   // Get the floating display index and the respective rectangle
567   // TODO Logical display on & mosaic display on scenario
568   if (use_float && !use_logical && !use_mosaic) {
569     bool ret = false;
570     size_t size = float_display_indices.size();
571     size_t num_displays = total_displays_.size();
572
573     // Set custom resolution to desired display instance
574     for (size_t i = 0; i < size; i++) {
575       int index = float_display_indices.at(i);
576
577       // Ignore float index if out of range of connected displays
578       if ((size_t)index < num_displays) {
579         const HwcRect<int32_t> &rect = float_displays.at(i);
580         ret = total_displays_.at(index)->SetCustomResolution(rect);
581       }
582     }
583   }
584 }
585
586 void GpuDevice::EnableHDCPSessionForDisplay(uint32_t display,
587                                             HWCContentType content_type) {
588   if (total_displays_.size() <= display) {
589     ETRACE("Tried to enable HDCP for invalid display %u \n", display);
590     return;
591   }
592
593   NativeDisplay *native_display = total_displays_.at(display);
594   native_display->SetHDCPState(HWCContentProtection::kDesired, content_type);
595 }
596
597 void GpuDevice::EnableHDCPSessionForAllDisplays(HWCContentType content_type) {
598   size_t size = total_displays_.size();
599   for (size_t i = 0; i < size; i++) {
600     total_displays_.at(i)
601         ->SetHDCPState(HWCContentProtection::kDesired, content_type);
602   }
603 }
604
605 void GpuDevice::DisableHDCPSessionForDisplay(uint32_t display) {
606   if (total_displays_.size() <= display) {
607     ETRACE("Tried to enable HDCP for invalid display %u \n", display);
608     return;
609   }
610
611   NativeDisplay *native_display = total_displays_.at(display);
612   native_display->SetHDCPState(HWCContentProtection::kUnDesired,
613                                HWCContentType::kInvalid);
614 }
615
616 void GpuDevice::DisableHDCPSessionForAllDisplays() {
617   size_t size = total_displays_.size();
618   for (size_t i = 0; i < size; i++) {
619     total_displays_.at(i)->SetHDCPState(HWCContentProtection::kUnDesired,
620                                         HWCContentType::kInvalid);
621   }
622 }
623
624 void GpuDevice::SetPAVPSessionStatus(bool enabled, uint32_t pavp_session_id,
625                                      uint32_t pavp_instance_id) {
626   size_t size = total_displays_.size();
627   for (size_t i = 0; i < size; i++) {
628     total_displays_.at(i)->SetPAVPSessionStatus(enabled, pavp_session_id,
629                                                 pavp_instance_id);
630   }
631 }
632
633 void GpuDevice::SetHDCPSRMForAllDisplays(const int8_t *SRM,
634                                          uint32_t SRMLength) {
635   size_t size = total_displays_.size();
636   for (size_t i = 0; i < size; i++) {
637     total_displays_.at(i)->SetHDCPSRM(SRM, SRMLength);
638   }
639 }
640
641 void GpuDevice::SetHDCPSRMForDisplay(uint32_t display, const int8_t *SRM,
642                                      uint32_t SRMLength) {
643   if (total_displays_.size() <= display) {
644     ETRACE("Tried to enable HDCP for invalid display %u \n", display);
645     return;
646   }
647
648   NativeDisplay *native_display = total_displays_.at(display);
649   native_display->SetHDCPSRM(SRM, SRMLength);
650 }
651
652 void GpuDevice::HandleRoutine() {
653   bool update_ignored = false;
654
655   // Iniitialize resources to monitor external events.
656   // These can be two types:
657   // 1) We are showing splash screen and another App
658   //    needs to take the control. In this case splash
659   //    is true.
660   // 2) Another app is having control of display and we
661   //    we need to take control.
662   // TODO: Add splash screen support.
663   if (lock_fd_ != -1) {
664     display_manager_->IgnoreUpdates();
665     update_ignored = true;
666
667     if (flock(lock_fd_, LOCK_EX) != 0) {
668       ETRACE("Failed to wait on the hwc lock.");
669     } else {
670       ITRACE("Successfully grabbed the hwc lock.");
671     }
672
673     display_manager_->setDrmMaster();
674
675     close(lock_fd_);
676     lock_fd_ = -1;
677   }
678
679   if (update_ignored)
680     display_manager_->ForceRefresh();
681 }
682
683 void GpuDevice::HandleWait() {
684   if (lock_fd_ == -1) {
685     HWCThread::HandleWait();
686   }
687 }
688
689 void GpuDevice::DisableWatch() {
690   HWCThread::Exit();
691 }
692
693 }  // namespace hwcomposer