• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
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 <stdint.h>
18 #include <string.h>
19 #include <time.h>
20 #include <utils/Thread.h>
21 
22 #include <map>
23 #include <set>
24 #include <string>
25 #include <tuple>
26 #include <utility>
27 
28 #include <cutils/log.h>
29 
30 #include <sys/resource.h>
31 
32 #include <system/graphics.h>
33 
34 #include <hardware/hwcomposer2.h>
35 
36 extern hw_module_t HAL_MODULE_INFO_SYM;
37 
38 namespace {
39 
40 const int32_t kNumColorModes = 9;
41 
42 const hwc2_config_t kDummyConfig = 0;
43 
44 // We're arbitrarily choosing these values to make the fake display not look
45 // suspicious.
46 const int32_t kDummyVSyncPeriod = 16666667;  // 60Hz
47 const int32_t kDummyDpiX = 160;
48 const int32_t kDummyDpiY = 160;
49 
50 class DummyDisplay;
51 
52 hwc2_display_t nextId = 1;
53 std::map<hwc2_display_t, DummyDisplay> displays;
54 
55 HWC2_PFN_VSYNC vsync_callback = nullptr;
56 hwc2_callback_data_t vsync_data = nullptr;
57 
58 HWC2_PFN_HOTPLUG hotplug_callback = nullptr;
59 hwc2_callback_data_t hotplug_data = nullptr;
60 
61 class DummyDisplay;
62 DummyDisplay* physical_display = nullptr;
63 
64 class DummyDisplay {
65  public:
DummyDisplay(hwc2_display_t id,uint32_t width,uint32_t height)66   DummyDisplay(hwc2_display_t id, uint32_t width, uint32_t height)
67       : id_(id), width_(width), height_(height) {}
68 
GetId()69   hwc2_display_t GetId() { return id_; }
IsPhysical()70   bool IsPhysical() { return physical_display == this; }
IsConfigured()71   bool IsConfigured() { return configured_; }
Configure()72   void Configure() { configured_ = true; }
GetWidth()73   uint32_t GetWidth() { return width_; }
GetHeight()74   uint32_t GetHeight() { return height_; }
75 
MakePhysical()76   void MakePhysical() {
77     if (physical_display != nullptr) {
78       ALOGE("Dummy composer does not support multiple physical displays.");
79     } else {
80       physical_display = this;
81     }
82   }
83 
CreateLayer()84   hwc2_layer_t CreateLayer() {
85     hwc2_layer_t layer = nextLayer_++;
86     layers_.insert(layer);
87     return layer;
88   }
89 
IsValidLayer(hwc2_layer_t layer)90   bool IsValidLayer(hwc2_layer_t layer) {
91     return layers_.find(layer) != layers_.end();
92   }
93 
DestroyLayer(hwc2_layer_t layer)94   void DestroyLayer(hwc2_layer_t layer) {
95     isClientComposed_.erase(layer);
96     layers_.erase(layer);
97   }
98 
SetClientComposed(hwc2_layer_t layer,bool value)99   bool SetClientComposed(hwc2_layer_t layer, bool value) {
100     if (layers_.find(layer) == layers_.end()) {
101       return false;
102     }
103 
104     isClientComposed_[layer] = value;
105     return true;
106   }
107 
NumNotClientComposed()108   uint32_t NumNotClientComposed() {
109     uint32_t ret = 0;
110 
111     for (const auto& layer : layers_) {
112       if (!isClientComposed_[layer]) {
113         ret++;
114       }
115     }
116 
117     return ret;
118   }
119 
GetNonClientComposedIDs(hwc2_layer_t * layers,uint32_t size)120   void GetNonClientComposedIDs(hwc2_layer_t* layers, uint32_t size) {
121     if (!layers) {
122       return;
123     }
124 
125     for (const auto& layer : layers_) {
126       if (size == 0) {
127         break;
128       }
129 
130       if (!isClientComposed_[layer]) {
131         *(layers++) = layer;
132         size--;
133       }
134     }
135   }
136 
137  private:
138 
139   hwc2_display_t id_;
140   uint32_t width_;
141   uint32_t height_;
142   bool configured_ = false;
143   hwc2_layer_t nextLayer_ = 1;
144   std::set<hwc2_layer_t> layers_;
145   std::map<hwc2_layer_t, bool> isClientComposed_;
146 };
147 
148 class VSyncThread : public android::Thread {
149  public:
VSyncThread()150   VSyncThread() : Thread(false) {}
151 
152  private:
threadLoop()153   bool threadLoop() override {
154     struct timespec ts;
155     clock_gettime(CLOCK_MONOTONIC, &ts);
156 
157     ts.tv_nsec += kDummyVSyncPeriod;
158 
159     if (ts.tv_nsec >= 1000000000) {
160       ts.tv_nsec -= 1000000000;
161       ts.tv_sec += 1;
162     }
163 
164     while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, nullptr))
165       ;
166 
167     int64_t timestamp = ts.tv_sec * 1000000000 + ts.tv_nsec;
168 
169     if (vsync_callback == nullptr) {
170       return true;
171     }
172 
173     vsync_callback(vsync_data, physical_display->GetId(), timestamp);
174 
175     return true;
176   }
177 };
178 
179 android::sp<VSyncThread> vsyncThread;
180 
181 const uint32_t kPhysicalDummyWidth = 640;
182 const uint32_t kPhysicalDummyHeight = 480;
183 
Hwc2ImplCreateVirtualDisplay(hwc2_device_t *,uint32_t width,uint32_t height,int32_t *,hwc2_display_t * out_display)184 int32_t Hwc2ImplCreateVirtualDisplay(hwc2_device_t* /*device*/, uint32_t width,
185                                      uint32_t height, int32_t* /*format*/,
186                                      hwc2_display_t* out_display) {
187   hwc2_display_t id = nextId++;
188   *out_display = id;
189 
190   displays.emplace(std::piecewise_construct, std::forward_as_tuple(id),
191                    std::forward_as_tuple(id, width, height));
192 
193   if (hotplug_callback != nullptr) {
194     hotplug_callback(hotplug_data, id, HWC2_CONNECTION_CONNECTED);
195   }
196 
197   return HWC2_ERROR_NONE;
198 }
199 
Hwc2ImplDestroyVirtualDisplay(hwc2_device_t *,hwc2_display_t display)200 int32_t Hwc2ImplDestroyVirtualDisplay(hwc2_device_t* /*device*/,
201                                       hwc2_display_t display) {
202   auto iter = displays.find(display);
203 
204   if (iter == displays.end()) {
205     return HWC2_ERROR_BAD_DISPLAY;
206   }
207 
208   if (iter->second.IsPhysical()) {
209     return HWC2_ERROR_BAD_PARAMETER;
210   }
211 
212   if (hotplug_callback != nullptr) {
213     hotplug_callback(hotplug_data, display, HWC2_CONNECTION_DISCONNECTED);
214   }
215 
216   displays.erase(iter);
217   return HWC2_ERROR_NONE;
218 }
219 
Hwc2ImplDump(hwc2_device_t *,uint32_t * out_size,char * out_buffer)220 void Hwc2ImplDump(hwc2_device_t* /*device*/, uint32_t* out_size,
221                   char* out_buffer) {
222   const char* dump_data = u8"hwcomposer is a dummy";
223 
224   if (out_buffer) {
225     strncpy(out_buffer, dump_data, *out_size);
226   }
227 
228   *out_size = static_cast<uint32_t>(strlen(dump_data));
229 }
230 
Hwc2ImplGetMaxVirtualDisplayCount(hwc2_device_t *)231 uint32_t Hwc2ImplGetMaxVirtualDisplayCount(hwc2_device_t* /*device*/) {
232   return UINT32_MAX;
233 }
234 
Hwc2ImplRegisterCallback(hwc2_device_t *,int32_t descriptor,hwc2_callback_data_t callback_data,hwc2_function_pointer_t pointer)235 int32_t Hwc2ImplRegisterCallback(hwc2_device_t* /*device*/, int32_t descriptor,
236                                  hwc2_callback_data_t callback_data,
237                                  hwc2_function_pointer_t pointer) {
238   switch (descriptor) {
239     case HWC2_CALLBACK_HOTPLUG:
240       hotplug_callback = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
241       hotplug_data = callback_data;
242 
243       for (const auto& disp : displays) {
244         hotplug_callback(hotplug_data, disp.first, HWC2_CONNECTION_CONNECTED);
245       }
246 
247       return HWC2_ERROR_NONE;
248     case HWC2_CALLBACK_VSYNC:
249       vsync_callback = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
250       vsync_data = callback_data;
251 
252       return HWC2_ERROR_NONE;
253     case HWC2_CALLBACK_REFRESH:
254       return HWC2_ERROR_NONE;
255     default:
256       return HWC2_ERROR_BAD_PARAMETER;
257   }
258 }
259 
Hwc2ImplAcceptDisplayChanges(hwc2_device_t *,hwc2_display_t display)260 int32_t Hwc2ImplAcceptDisplayChanges(hwc2_device_t* /*device*/,
261                                      hwc2_display_t display) {
262   if (displays.find(display) == displays.end()) {
263     return HWC2_ERROR_BAD_DISPLAY;
264   }
265 
266   return HWC2_ERROR_NONE;
267 }
268 
Hwc2ImplCreateLayer(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t * out_layer)269 int32_t Hwc2ImplCreateLayer(hwc2_device_t* /*device*/, hwc2_display_t display,
270                             hwc2_layer_t* out_layer) {
271   auto iter = displays.find(display);
272 
273   if (iter == displays.end()) {
274     return HWC2_ERROR_BAD_DISPLAY;
275   }
276 
277   *out_layer = iter->second.CreateLayer();
278 
279   return HWC2_ERROR_NONE;
280 }
281 
Hwc2ImplDestroyLayer(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer)282 int32_t Hwc2ImplDestroyLayer(hwc2_device_t* /*device*/, hwc2_display_t display,
283                              hwc2_layer_t layer) {
284   auto iter = displays.find(display);
285 
286   if (iter == displays.end()) {
287     return HWC2_ERROR_BAD_DISPLAY;
288   }
289 
290   iter->second.DestroyLayer(layer);
291 
292   return HWC2_ERROR_NONE;
293 }
294 
Hwc2ImplGetActiveConfig(hwc2_device_t *,hwc2_display_t display,hwc2_config_t * out_config)295 int32_t Hwc2ImplGetActiveConfig(hwc2_device_t* /*device*/,
296                                 hwc2_display_t display,
297                                 hwc2_config_t* out_config) {
298   auto iter = displays.find(display);
299 
300   if (iter == displays.end()) {
301     return HWC2_ERROR_BAD_DISPLAY;
302   }
303 
304   if (!iter->second.IsConfigured()) {
305     return HWC2_ERROR_BAD_CONFIG;
306   }
307 
308   *out_config = kDummyConfig;
309   return HWC2_ERROR_NONE;
310 }
311 
Hwc2ImplGetChangedCompositionTypes(hwc2_device_t *,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)312 int32_t Hwc2ImplGetChangedCompositionTypes(hwc2_device_t* /*device*/,
313                                            hwc2_display_t display,
314                                            uint32_t* out_num_elements,
315                                            hwc2_layer_t* out_layers,
316                                            int32_t* out_types) {
317   auto iter = displays.find(display);
318 
319   if (iter == displays.end()) {
320     return HWC2_ERROR_BAD_DISPLAY;
321   }
322 
323   uint32_t out_size = *out_num_elements;
324   uint32_t not_composed = iter->second.NumNotClientComposed();
325 
326   if (iter->second.IsPhysical()) {
327     *out_num_elements = 0;
328     return HWC2_ERROR_NONE;
329   }
330 
331 
332   if (out_layers == nullptr || out_types == nullptr) {
333     *out_num_elements = not_composed;
334     return HWC2_ERROR_NONE;
335   }
336 
337   iter->second.GetNonClientComposedIDs(out_layers, out_size);
338 
339   for (uint32_t i = 0; i < out_size; i++) {
340     out_types[i] = HWC2_COMPOSITION_CLIENT;
341   }
342 
343   if (not_composed < out_size) {
344     *out_num_elements = not_composed;
345   }
346 
347   return HWC2_ERROR_NONE;
348 }
349 
Hwc2ImplGetClientTargetSupport(hwc2_device_t *,hwc2_display_t,uint32_t,uint32_t,int32_t,int32_t)350 int32_t Hwc2ImplGetClientTargetSupport(hwc2_device_t* /*device*/,
351                                        hwc2_display_t /*display*/,
352                                        uint32_t /*width*/, uint32_t /*height*/,
353                                        int32_t /*format*/,
354                                        int32_t /*dataspace*/) {
355   return HWC2_ERROR_NONE;
356 }
357 
Hwc2ImplGetColorModes(hwc2_device_t *,hwc2_display_t display,uint32_t * out_num_modes,int32_t * out_modes)358 int32_t Hwc2ImplGetColorModes(hwc2_device_t* /*device*/, hwc2_display_t display,
359                               uint32_t* out_num_modes, int32_t* out_modes) {
360   if (displays.find(display) == displays.end()) {
361     return HWC2_ERROR_BAD_DISPLAY;
362   }
363 
364   if (*out_num_modes > kNumColorModes) {
365     *out_num_modes = kNumColorModes;
366   }
367 
368   if (!out_modes) {
369     return HWC2_ERROR_NONE;
370   }
371 
372   for (uint32_t i = 0; i < *out_num_modes; i++) {
373     *(out_modes++) = static_cast<int32_t>(i);
374   }
375 
376   return HWC2_ERROR_NONE;
377 }
378 
Hwc2ImplGetDisplayAttribute(hwc2_device_t *,hwc2_display_t display,hwc2_config_t config,int32_t attribute,int32_t * out_value)379 int32_t Hwc2ImplGetDisplayAttribute(hwc2_device_t* /*device*/,
380                                     hwc2_display_t display,
381                                     hwc2_config_t config, int32_t attribute,
382                                     int32_t* out_value) {
383   auto iter = displays.find(display);
384 
385   if (iter == displays.end()) {
386     return HWC2_ERROR_BAD_DISPLAY;
387   }
388 
389   if (config != kDummyConfig) {
390     return HWC2_ERROR_BAD_CONFIG;
391   }
392 
393   switch (attribute) {
394     case HWC2_ATTRIBUTE_WIDTH:
395       *out_value =  720;//static_cast<int32_t>(iter->second.GetWidth());
396       return HWC2_ERROR_NONE;
397     case HWC2_ATTRIBUTE_HEIGHT:
398       *out_value = 1280;//static_cast<int32_t>(iter->second.GetHeight());
399       return HWC2_ERROR_NONE;
400     case HWC2_ATTRIBUTE_VSYNC_PERIOD:
401       *out_value = kDummyVSyncPeriod;
402       return HWC2_ERROR_NONE;
403     case HWC2_ATTRIBUTE_DPI_X:
404       *out_value = kDummyDpiX;
405       return HWC2_ERROR_NONE;
406     case HWC2_ATTRIBUTE_DPI_Y:
407       *out_value = kDummyDpiY;
408       return HWC2_ERROR_NONE;
409     default:
410       *out_value = -1;
411       return HWC2_ERROR_NONE;
412   }
413 }
414 
Hwc2ImplGetDisplayConfigs(hwc2_device_t *,hwc2_display_t display,uint32_t * out_num_configs,hwc2_config_t * out_configs)415 int32_t Hwc2ImplGetDisplayConfigs(hwc2_device_t* /*device*/,
416                                   hwc2_display_t display,
417                                   uint32_t* out_num_configs,
418                                   hwc2_config_t* out_configs) {
419   if (displays.find(display) == displays.end()) {
420     return HWC2_ERROR_BAD_DISPLAY;
421   }
422 
423   if (out_configs) {
424     if (*out_num_configs >= 1) {
425       out_configs[0] = kDummyConfig;
426     } else {
427       return HWC2_ERROR_NONE;
428     }
429   }
430 
431   *out_num_configs = 1;
432 
433   return HWC2_ERROR_NONE;
434 }
435 
Hwc2ImplGetDisplayName(hwc2_device_t *,hwc2_display_t display,uint32_t * out_size,char * out_name)436 int32_t Hwc2ImplGetDisplayName(hwc2_device_t* /*device*/,
437                                hwc2_display_t display, uint32_t* out_size,
438                                char* out_name) {
439   if (displays.find(display) == displays.end()) {
440     return HWC2_ERROR_BAD_DISPLAY;
441   }
442 
443   auto str = std::to_string(display);
444 
445   if (out_name) {
446     strncpy(out_name, str.c_str(), *out_size);
447   }
448 
449   if (*out_size > (str.size() + 1)) {
450     *out_size = static_cast<uint32_t>( str.size() + 1);
451   }
452 
453   return HWC2_ERROR_NONE;
454 }
455 
Hwc2ImplGetDisplayRequests(hwc2_device_t *,hwc2_display_t display,int32_t * out_display_requests,uint32_t * out_num_elements,hwc2_layer_t *,int32_t *)456 int32_t Hwc2ImplGetDisplayRequests(hwc2_device_t* /*device*/,
457                                    hwc2_display_t display,
458                                    int32_t* out_display_requests,
459                                    uint32_t* out_num_elements,
460                                    hwc2_layer_t* /*out_layers*/,
461                                    int32_t* /*out_layer_requests*/) {
462   if (displays.find(display) == displays.end()) {
463     return HWC2_ERROR_BAD_DISPLAY;
464   }
465 
466   *out_num_elements = 0;
467   *out_display_requests = 0;
468 
469   return HWC2_ERROR_NONE;
470 }
471 
Hwc2ImplGetDisplayType(hwc2_device_t *,hwc2_display_t display,int32_t * out_type)472 int32_t Hwc2ImplGetDisplayType(hwc2_device_t* /*device*/,
473                                hwc2_display_t display, int32_t* out_type) {
474   auto iter = displays.find(display);
475 
476   if (iter == displays.end()) {
477     return HWC2_ERROR_BAD_DISPLAY;
478   }
479 
480   if (iter->second.IsPhysical()) {
481     *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
482   } else {
483     *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
484   }
485 
486   return HWC2_ERROR_NONE;
487 }
488 
Hwc2ImplGetDozeSupport(hwc2_device_t *,hwc2_display_t display,int32_t * out_support)489 int32_t Hwc2ImplGetDozeSupport(hwc2_device_t* /*device*/,
490                                hwc2_display_t display, int32_t* out_support) {
491   if (displays.find(display) == displays.end()) {
492     return HWC2_ERROR_BAD_DISPLAY;
493   }
494 
495   *out_support = 0;
496   return HWC2_ERROR_NONE;
497 }
498 
Hwc2ImplGetHdrCapabilities(hwc2_device_t *,hwc2_display_t display,uint32_t * out_num_types,int32_t *,float *,float *,float *)499 int32_t Hwc2ImplGetHdrCapabilities(
500     hwc2_device_t* /*device*/, hwc2_display_t display, uint32_t* out_num_types,
501     int32_t* /*out_types*/, float* /*out_max_luminance*/,
502     float* /*out_max_average_luminance*/, float* /*out_min_luminance*/) {
503   if (displays.find(display) == displays.end()) {
504     return HWC2_ERROR_BAD_DISPLAY;
505   }
506 
507   *out_num_types = 0;
508   return HWC2_ERROR_NONE;
509 }
510 
Hwc2ImplGetReleaseFences(hwc2_device_t *,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t *,int32_t *)511 int32_t Hwc2ImplGetReleaseFences(hwc2_device_t* /*device*/,
512                                  hwc2_display_t display,
513                                  uint32_t* out_num_elements,
514                                  hwc2_layer_t* /*out_layers*/,
515                                  int32_t* /*out_fences*/) {
516   if (displays.find(display) == displays.end()) {
517     return HWC2_ERROR_BAD_DISPLAY;
518   }
519 
520   *out_num_elements = 0;
521 
522   return HWC2_ERROR_NONE;
523 }
524 
Hwc2ImplPresentDisplay(hwc2_device_t *,hwc2_display_t display,int32_t * out_retire_fence)525 int32_t Hwc2ImplPresentDisplay(hwc2_device_t* /*device*/,
526                                hwc2_display_t display,
527                                int32_t* out_retire_fence) {
528   if (displays.find(display) == displays.end()) {
529     return HWC2_ERROR_BAD_DISPLAY;
530   }
531 
532   /* Hope this works... */
533   *out_retire_fence = -1;
534 
535   return HWC2_ERROR_NONE;
536 }
537 
Hwc2ImplSetActiveConfig(hwc2_device_t *,hwc2_display_t display,hwc2_config_t config)538 int32_t Hwc2ImplSetActiveConfig(hwc2_device_t* /*device*/,
539                                 hwc2_display_t display, hwc2_config_t config) {
540   auto iter = displays.find(display);
541 
542   if (iter == displays.end()) {
543     return HWC2_ERROR_BAD_DISPLAY;
544   }
545 
546   if (config != kDummyConfig) {
547     return HWC2_ERROR_BAD_CONFIG;
548   }
549 
550   iter->second.Configure();
551 
552   return HWC2_ERROR_NONE;
553 }
554 
Hwc2ImplSetClientTarget(hwc2_device_t *,hwc2_display_t display,buffer_handle_t,int32_t,int32_t,hwc_region_t)555 int32_t Hwc2ImplSetClientTarget(hwc2_device_t* /*device*/,
556                                 hwc2_display_t display,
557                                 buffer_handle_t /*target*/,
558                                 int32_t /*acquire_fence*/,
559                                 int32_t /*dataspace*/,
560                                 hwc_region_t /*damage*/) {
561   if (displays.find(display) == displays.end()) {
562     return HWC2_ERROR_BAD_DISPLAY;
563   }
564 
565   return HWC2_ERROR_NONE;
566 }
567 
Hwc2ImplSetColorMode(hwc2_device_t *,hwc2_display_t display,int32_t mode)568 int32_t Hwc2ImplSetColorMode(hwc2_device_t* /*device*/, hwc2_display_t display,
569                              int32_t mode) {
570   if (displays.find(display) == displays.end()) {
571     return HWC2_ERROR_BAD_DISPLAY;
572   }
573 
574   if (mode < 0 || mode >= kNumColorModes) {
575     return HWC2_ERROR_BAD_PARAMETER;
576   }
577 
578   return HWC2_ERROR_NONE;
579 }
580 
Hwc2ImplSetColorTransform(hwc2_device_t *,hwc2_display_t display,const float *,int32_t)581 int32_t Hwc2ImplSetColorTransform(hwc2_device_t* /*device*/,
582                                   hwc2_display_t display,
583                                   const float* /*matrix*/, int32_t /*hint*/) {
584   if (displays.find(display) == displays.end()) {
585     return HWC2_ERROR_BAD_DISPLAY;
586   }
587 
588   /* A bad hint value should yield HWC2_ERROR_BAD_PARAMETER but the
589    * documentation is incomplete and inaccurate as to what is and is not a
590    * valid hint value.
591    */
592 
593   return HWC2_ERROR_NONE;
594 }
595 
Hwc2ImplSetOutputBuffer(hwc2_device_t *,hwc2_display_t display,buffer_handle_t,int32_t)596 int32_t Hwc2ImplSetOutputBuffer(hwc2_device_t* /*device*/,
597                                 hwc2_display_t display,
598                                 buffer_handle_t /*buffer*/,
599                                 int32_t /*release_fence*/) {
600   auto iter = displays.find(display);
601 
602   if (iter == displays.end()) {
603     return HWC2_ERROR_BAD_DISPLAY;
604   }
605 
606   if (iter->second.IsPhysical()) {
607     return HWC2_ERROR_UNSUPPORTED;
608   }
609 
610   return HWC2_ERROR_NONE;
611 }
612 
Hwc2ImplSetPowerMode(hwc2_device_t *,hwc2_display_t display,int32_t mode)613 int32_t Hwc2ImplSetPowerMode(hwc2_device_t* /*device*/, hwc2_display_t display,
614                              int32_t mode) {
615   if (displays.find(display) == displays.end()) {
616     return HWC2_ERROR_BAD_DISPLAY;
617   }
618 
619   switch (mode) {
620     case HWC2_POWER_MODE_OFF:
621     case HWC2_POWER_MODE_ON:
622       return HWC2_ERROR_NONE;
623     case HWC2_POWER_MODE_DOZE:
624     case HWC2_POWER_MODE_DOZE_SUSPEND:
625       return HWC2_ERROR_UNSUPPORTED;
626     default:
627       return HWC2_ERROR_BAD_PARAMETER;
628   }
629 }
630 
Hwc2ImplSetVsyncEnabled(hwc2_device_t *,hwc2_display_t display,int32_t enabled)631 int32_t Hwc2ImplSetVsyncEnabled(hwc2_device_t* /*device*/,
632                                 hwc2_display_t display, int32_t enabled) {
633   auto iter = displays.find(display);
634 
635   if (iter == displays.end()) {
636     return HWC2_ERROR_BAD_DISPLAY;
637   }
638 
639   if (!iter->second.IsPhysical()) {
640     return HWC2_ERROR_NONE;
641   }
642 
643 
644   if (enabled == HWC2_VSYNC_ENABLE) {
645     if (vsyncThread.get() != nullptr) {
646       return HWC2_ERROR_NONE;
647     }
648 
649     vsyncThread = new VSyncThread();
650 
651     android::status_t ret =
652         vsyncThread->run("dummy_vsync", HAL_PRIORITY_URGENT_DISPLAY);
653 
654     if (ret != android::OK) {
655       ALOGE("Could not create vsync thread (%d)", ret);
656     }
657 
658     return HWC2_ERROR_NONE;
659   }
660 
661   if (enabled != HWC2_VSYNC_DISABLE) {
662     return HWC2_ERROR_BAD_PARAMETER;
663   }
664 
665   vsyncThread->requestExit();
666   vsyncThread.clear();
667 
668   return HWC2_ERROR_NONE;
669 }
670 
Hwc2ImplValidateDisplay(hwc2_device_t *,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)671 int32_t Hwc2ImplValidateDisplay(hwc2_device_t* /*device*/,
672                                 hwc2_display_t display, uint32_t* out_num_types,
673                                 uint32_t* out_num_requests) {
674   auto iter = displays.find(display);
675 
676   if (iter == displays.end()) {
677     return HWC2_ERROR_BAD_DISPLAY;
678   }
679 
680   *out_num_requests = 0;
681   if (iter->second.IsPhysical()) {
682     *out_num_types = 0;
683   } else {
684     *out_num_types = iter->second.NumNotClientComposed();
685   }
686 
687   return HWC2_ERROR_NONE;
688 }
689 
validateLayer(hwc2_display_t display,hwc2_layer_t layer)690 int32_t validateLayer(hwc2_display_t display, hwc2_layer_t layer) {
691   auto iter = displays.find(display);
692 
693   if (iter == displays.end()) {
694     return HWC2_ERROR_BAD_DISPLAY;
695   }
696 
697   if (!iter->second.IsValidLayer(layer)) {
698     return HWC2_ERROR_BAD_LAYER;
699   }
700 
701   return HWC2_ERROR_NONE;
702 }
703 
Hwc2ImplSetCursorPosition(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,int32_t,int32_t)704 int32_t Hwc2ImplSetCursorPosition(hwc2_device_t* /*device*/,
705                                   hwc2_display_t display, hwc2_layer_t layer,
706                                   int32_t /*x*/, int32_t /*y*/) {
707   return validateLayer(display, layer);
708 }
709 
Hwc2ImplSetLayerBuffer(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t,int32_t)710 int32_t Hwc2ImplSetLayerBuffer(hwc2_device_t* /*device*/,
711                                hwc2_display_t display, hwc2_layer_t layer,
712                                buffer_handle_t /*buffer*/,
713                                int32_t /*acquireFence*/) {
714   return validateLayer(display, layer);
715 }
716 
Hwc2ImplSetLayerSurfaceDamage(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t)717 int32_t Hwc2ImplSetLayerSurfaceDamage(hwc2_device_t* /*device*/,
718                                       hwc2_display_t display,
719                                       hwc2_layer_t layer,
720                                       hwc_region_t /*damage*/) {
721   return validateLayer(display, layer);
722 }
723 
Hwc2ImplSetLayerBlendMode(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,int32_t)724 int32_t Hwc2ImplSetLayerBlendMode(hwc2_device_t* /*device*/,
725                                   hwc2_display_t display, hwc2_layer_t layer,
726                                   int32_t /*mode*/) {
727   return validateLayer(display, layer);
728 }
729 
Hwc2ImplSetLayerColor(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,hwc_color_t)730 int32_t Hwc2ImplSetLayerColor(hwc2_device_t* /*device*/, hwc2_display_t display,
731                               hwc2_layer_t layer, hwc_color_t /*color*/) {
732   return validateLayer(display, layer);
733 }
734 
Hwc2ImplSetLayerCompositionType(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,int32_t type)735 int32_t Hwc2ImplSetLayerCompositionType(hwc2_device_t* /*device*/,
736                                         hwc2_display_t display,
737                                         hwc2_layer_t layer, int32_t type) {
738   auto iter = displays.find(display);
739 
740   if (iter == displays.end()) {
741     return HWC2_ERROR_BAD_DISPLAY;
742   }
743 
744   if (type == HWC2_COMPOSITION_SIDEBAND) {
745     return HWC2_ERROR_UNSUPPORTED;
746   }
747 
748   if (!iter->second.SetClientComposed(layer, type == HWC2_COMPOSITION_CLIENT)) {
749     return HWC2_ERROR_BAD_LAYER;
750   }
751 
752   return HWC2_ERROR_NONE;
753 }
754 
Hwc2ImplSetLayerDataspace(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,int32_t)755 int32_t Hwc2ImplSetLayerDataspace(hwc2_device_t* /*device*/,
756                                   hwc2_display_t display, hwc2_layer_t layer,
757                                   int32_t /*dataspace*/) {
758   return validateLayer(display, layer);
759 }
760 
Hwc2ImplSetLayerDisplayFrame(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t)761 int32_t Hwc2ImplSetLayerDisplayFrame(hwc2_device_t* /*device*/,
762                                      hwc2_display_t display, hwc2_layer_t layer,
763                                      hwc_rect_t /*frame*/) {
764   return validateLayer(display, layer);
765 }
766 
Hwc2ImplSetLayerPlaneAlpha(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,float)767 int32_t Hwc2ImplSetLayerPlaneAlpha(hwc2_device_t* /*device*/,
768                                    hwc2_display_t display, hwc2_layer_t layer,
769                                    float /*alpha*/) {
770   return validateLayer(display, layer);
771 }
772 
Hwc2ImplSetLayerSidebandStream(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,const native_handle_t *)773 int32_t Hwc2ImplSetLayerSidebandStream(hwc2_device_t* /*device*/,
774                                        hwc2_display_t display,
775                                        hwc2_layer_t layer,
776                                        const native_handle_t* /*stream*/) {
777   return validateLayer(display, layer);
778 }
779 
Hwc2ImplSetLayerSourceCrop(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t)780 int32_t Hwc2ImplSetLayerSourceCrop(hwc2_device_t* /*device*/,
781                                    hwc2_display_t display, hwc2_layer_t layer,
782                                    hwc_frect_t /*crop*/) {
783   return validateLayer(display, layer);
784 }
785 
Hwc2ImplSetLayerTransform(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,int32_t)786 int32_t Hwc2ImplSetLayerTransform(hwc2_device_t* /*device*/,
787                                   hwc2_display_t display, hwc2_layer_t layer,
788                                   int32_t /*transform*/) {
789   return validateLayer(display, layer);
790 }
791 
Hwc2ImplSetLayerVisibleRegion(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t)792 int32_t Hwc2ImplSetLayerVisibleRegion(hwc2_device_t* /*device*/,
793                                       hwc2_display_t display,
794                                       hwc2_layer_t layer,
795                                       hwc_region_t /*visible*/) {
796   return validateLayer(display, layer);
797 }
798 
Hwc2ImplSetLayer_z_order(hwc2_device_t *,hwc2_display_t display,hwc2_layer_t layer,uint32_t)799 int32_t Hwc2ImplSetLayer_z_order(hwc2_device_t* /*device*/,
800                                  hwc2_display_t display, hwc2_layer_t layer,
801                                  uint32_t /*z*/) {
802   return validateLayer(display, layer);
803 }
804 
Hwc2DeviceClose(struct hw_device_t *)805 int Hwc2DeviceClose(struct hw_device_t* /*dev*/) { return 0; }
806 
Hwc2GetCapabilities(struct hwc2_device *,uint32_t * out_count,int32_t *)807 void Hwc2GetCapabilities(struct hwc2_device* /*device*/, uint32_t* out_count,
808                          int32_t* /*out_capabilities*/) {
809   *out_count = 0;
810 }
811 
Hwc2GetFunction(struct hwc2_device *,int32_t descriptor)812 hwc2_function_pointer_t Hwc2GetFunction(struct hwc2_device* /*device*/,
813                                         int32_t descriptor) {
814   switch (descriptor) {
815     case HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES:
816       return reinterpret_cast<hwc2_function_pointer_t>(
817           Hwc2ImplAcceptDisplayChanges);
818     case HWC2_FUNCTION_CREATE_LAYER:
819       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplCreateLayer);
820     case HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY:
821       return reinterpret_cast<hwc2_function_pointer_t>(
822           Hwc2ImplCreateVirtualDisplay);
823     case HWC2_FUNCTION_DESTROY_LAYER:
824       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplDestroyLayer);
825     case HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY:
826       return reinterpret_cast<hwc2_function_pointer_t>(
827           Hwc2ImplDestroyVirtualDisplay);
828     case HWC2_FUNCTION_DUMP:
829       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplDump);
830     case HWC2_FUNCTION_GET_ACTIVE_CONFIG:
831       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplGetActiveConfig);
832     case HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES:
833       return reinterpret_cast<hwc2_function_pointer_t>(
834           Hwc2ImplGetChangedCompositionTypes);
835     case HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT:
836       return reinterpret_cast<hwc2_function_pointer_t>(
837           Hwc2ImplGetClientTargetSupport);
838     case HWC2_FUNCTION_GET_COLOR_MODES:
839       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplGetColorModes);
840     case HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE:
841       return reinterpret_cast<hwc2_function_pointer_t>(
842           Hwc2ImplGetDisplayAttribute);
843     case HWC2_FUNCTION_GET_DISPLAY_CONFIGS:
844       return reinterpret_cast<hwc2_function_pointer_t>(
845           Hwc2ImplGetDisplayConfigs);
846     case HWC2_FUNCTION_GET_DISPLAY_NAME:
847       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplGetDisplayName);
848     case HWC2_FUNCTION_GET_DISPLAY_REQUESTS:
849       return reinterpret_cast<hwc2_function_pointer_t>(
850           Hwc2ImplGetDisplayRequests);
851     case HWC2_FUNCTION_GET_DISPLAY_TYPE:
852       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplGetDisplayType);
853     case HWC2_FUNCTION_GET_DOZE_SUPPORT:
854       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplGetDozeSupport);
855     case HWC2_FUNCTION_GET_HDR_CAPABILITIES:
856       return reinterpret_cast<hwc2_function_pointer_t>(
857           Hwc2ImplGetHdrCapabilities);
858     case HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT:
859       return reinterpret_cast<hwc2_function_pointer_t>(
860           Hwc2ImplGetMaxVirtualDisplayCount);
861     case HWC2_FUNCTION_GET_RELEASE_FENCES:
862       return reinterpret_cast<hwc2_function_pointer_t>(
863           Hwc2ImplGetReleaseFences);
864     case HWC2_FUNCTION_PRESENT_DISPLAY:
865       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplPresentDisplay);
866     case HWC2_FUNCTION_REGISTER_CALLBACK:
867       return reinterpret_cast<hwc2_function_pointer_t>(
868           Hwc2ImplRegisterCallback);
869     case HWC2_FUNCTION_SET_ACTIVE_CONFIG:
870       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetActiveConfig);
871     case HWC2_FUNCTION_SET_CLIENT_TARGET:
872       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetClientTarget);
873     case HWC2_FUNCTION_SET_COLOR_MODE:
874       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetColorMode);
875     case HWC2_FUNCTION_SET_COLOR_TRANSFORM:
876       return reinterpret_cast<hwc2_function_pointer_t>(
877           Hwc2ImplSetColorTransform);
878     case HWC2_FUNCTION_SET_CURSOR_POSITION:
879       return reinterpret_cast<hwc2_function_pointer_t>(
880           Hwc2ImplSetCursorPosition);
881     case HWC2_FUNCTION_SET_LAYER_BLEND_MODE:
882       return reinterpret_cast<hwc2_function_pointer_t>(
883           Hwc2ImplSetLayerBlendMode);
884     case HWC2_FUNCTION_SET_LAYER_BUFFER:
885       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetLayerBuffer);
886     case HWC2_FUNCTION_SET_LAYER_COLOR:
887       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetLayerColor);
888     case HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE:
889       return reinterpret_cast<hwc2_function_pointer_t>(
890           Hwc2ImplSetLayerCompositionType);
891     case HWC2_FUNCTION_SET_LAYER_DATASPACE:
892       return reinterpret_cast<hwc2_function_pointer_t>(
893           Hwc2ImplSetLayerDataspace);
894     case HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME:
895       return reinterpret_cast<hwc2_function_pointer_t>(
896           Hwc2ImplSetLayerDisplayFrame);
897     case HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA:
898       return reinterpret_cast<hwc2_function_pointer_t>(
899           Hwc2ImplSetLayerPlaneAlpha);
900     case HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM:
901       return reinterpret_cast<hwc2_function_pointer_t>(
902           Hwc2ImplSetLayerSidebandStream);
903     case HWC2_FUNCTION_SET_LAYER_SOURCE_CROP:
904       return reinterpret_cast<hwc2_function_pointer_t>(
905           Hwc2ImplSetLayerSourceCrop);
906     case HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE:
907       return reinterpret_cast<hwc2_function_pointer_t>(
908           Hwc2ImplSetLayerSurfaceDamage);
909     case HWC2_FUNCTION_SET_LAYER_TRANSFORM:
910       return reinterpret_cast<hwc2_function_pointer_t>(
911           Hwc2ImplSetLayerTransform);
912     case HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION:
913       return reinterpret_cast<hwc2_function_pointer_t>(
914           Hwc2ImplSetLayerVisibleRegion);
915     case HWC2_FUNCTION_SET_LAYER_Z_ORDER:
916       return reinterpret_cast<hwc2_function_pointer_t>(
917           Hwc2ImplSetLayer_z_order);
918     case HWC2_FUNCTION_SET_OUTPUT_BUFFER:
919       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetOutputBuffer);
920     case HWC2_FUNCTION_SET_POWER_MODE:
921       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetPowerMode);
922     case HWC2_FUNCTION_SET_VSYNC_ENABLED:
923       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplSetVsyncEnabled);
924     case HWC2_FUNCTION_VALIDATE_DISPLAY:
925       return reinterpret_cast<hwc2_function_pointer_t>(Hwc2ImplValidateDisplay);
926     default:
927       return nullptr;
928   }
929 }
930 
931 hwc2_device_t dummy_device = {
932     .common = {.tag = HARDWARE_DEVICE_TAG,
933                .version = HWC_DEVICE_API_VERSION_2_0,
934                .module = &HAL_MODULE_INFO_SYM,
935                .close = Hwc2DeviceClose},
936     .getCapabilities = Hwc2GetCapabilities,
937     .getFunction = Hwc2GetFunction,
938 };
939 
Hwc2DeviceOpen(const struct hw_module_t *,const char * name,struct hw_device_t ** device)940 int Hwc2DeviceOpen(const struct hw_module_t* /*module*/, const char* name,
941                    struct hw_device_t** device) {
942   if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
943     return -EINVAL;
944   }
945 
946   if (physical_display == nullptr) {
947     hwc2_display_t physical_dummy;
948 
949     Hwc2ImplCreateVirtualDisplay(&dummy_device, kPhysicalDummyWidth,
950                                  kPhysicalDummyHeight, nullptr,
951                                  &physical_dummy);
952 
953     displays.find(physical_dummy)->second.MakePhysical();
954 
955     Hwc2ImplSetActiveConfig(&dummy_device, physical_dummy, kDummyConfig);
956   }
957 
958   *device = &dummy_device.common;
959   return 0;
960 }
961 
962 struct hw_module_methods_t Hwc2ModuleMethods = {
963     .open = Hwc2DeviceOpen,
964 };
965 
966 }  // namespace
967 
968 hw_module_t HAL_MODULE_INFO_SYM = {
969     .tag = HARDWARE_MODULE_TAG,
970     .version_major = 2,
971     .version_minor = 0,
972     .id = HWC_HARDWARE_MODULE_ID,
973     .name = "Dummy hwcomposer module",
974     .author = "The Android Open Source Project",
975     .methods = &Hwc2ModuleMethods,
976 };
977