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