blob: d45a955c117b2b27652e11590e71c4ed8f863155 [file] [log] [blame]
Chia-I Wu7f8d3962016-09-28 21:04:23 +08001/*
2 * Copyright 2016 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#define LOG_TAG "HwcPassthrough"
18
19#include <mutex>
20#include <type_traits>
21#include <unordered_map>
22#include <unordered_set>
23#include <utility>
24#include <vector>
25
26#include <hardware/gralloc.h>
27#include <hardware/gralloc1.h>
28#include <hardware/hwcomposer2.h>
29#include <log/log.h>
30
31#include "Hwc.h"
32
33namespace android {
34namespace hardware {
35namespace graphics {
36namespace composer {
37namespace V2_1 {
38namespace implementation {
39
40using android::hardware::graphics::allocator::V2_0::PixelFormat;
41
42namespace {
43
44class HandleImporter {
45public:
46 HandleImporter() : mInitialized(false) {}
47
48 bool initialize()
49 {
50 // allow only one client
51 if (mInitialized) {
52 return false;
53 }
54
55 if (!openGralloc()) {
56 return false;
57 }
58
59 mInitialized = true;
60 return true;
61 }
62
63 void cleanup()
64 {
65 if (!mInitialized) {
66 return;
67 }
68
69 closeGralloc();
70 mInitialized = false;
71 }
72
73 // In IComposer, any buffer_handle_t is owned by the caller and we need to
74 // make a clone for hwcomposer2. We also need to translate empty handle
75 // to nullptr. This function does that, in-place.
76 bool importBuffer(buffer_handle_t& handle)
77 {
78 if (!handle->numFds && !handle->numInts) {
79 handle = nullptr;
80 return true;
81 }
82
83 buffer_handle_t clone = cloneBuffer(handle);
84 if (!clone) {
85 return false;
86 }
87
88 handle = clone;
89 return true;
90 }
91
92 void freeBuffer(buffer_handle_t handle)
93 {
94 if (!handle) {
95 return;
96 }
97
98 releaseBuffer(handle);
99 }
100
101 bool importFence(const native_handle_t* handle, int& fd)
102 {
103 if (handle->numFds == 0) {
104 fd = -1;
105 } else if (handle->numFds == 1) {
106 fd = dup(handle->data[0]);
107 if (fd < 0) {
108 ALOGE("failed to dup fence fd %d", handle->data[0]);
109 return false;
110 }
111 } else {
112 ALOGE("invalid fence handle with %d file descriptors",
113 handle->numFds);
114 return false;
115 }
116
117 return true;
118 }
119
120 void closeFence(int fd)
121 {
122 if (fd >= 0) {
123 close(fd);
124 }
125 }
126
127private:
128 bool mInitialized;
129
130 // Some existing gralloc drivers do not support retaining more than once,
131 // when we are in passthrough mode.
132#ifdef BINDERIZED
133 bool openGralloc()
134 {
135 const hw_module_t* module;
136 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
137 if (err) {
138 ALOGE("failed to get gralloc module");
139 return false;
140 }
141
142 uint8_t major = (module->module_api_version >> 8) & 0xff;
143 if (major > 1) {
144 ALOGE("unknown gralloc module major version %d", major);
145 return false;
146 }
147
148 if (major == 1) {
149 err = gralloc1_open(module, &mDevice);
150 if (err) {
151 ALOGE("failed to open gralloc1 device");
152 return false;
153 }
154
155 mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
156 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
157 mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
158 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
159 if (!mRetain || !mRelease) {
160 ALOGE("invalid gralloc1 device");
161 gralloc1_close(mDevice);
162 return false;
163 }
164 } else {
165 mModule = reinterpret_cast<const gralloc_module_t*>(module);
166 }
167
168 return true;
169 }
170
171 void closeGralloc()
172 {
173 if (mDevice) {
174 gralloc1_close(mDevice);
175 }
176 }
177
178 buffer_handle_t cloneBuffer(buffer_handle_t handle)
179 {
180 native_handle_t* clone = native_handle_clone(handle);
181 if (!clone) {
182 ALOGE("failed to clone buffer %p", handle);
183 return nullptr;
184 }
185
186 bool err;
187 if (mDevice) {
188 err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
189 } else {
190 err = (mModule->registerBuffer(mModule, clone) != 0);
191 }
192
193 if (err) {
194 ALOGE("failed to retain/register buffer %p", clone);
195 native_handle_close(clone);
196 native_handle_delete(clone);
197 return nullptr;
198 }
199
200 return clone;
201 }
202
203 void releaseBuffer(buffer_handle_t handle)
204 {
205 if (mDevice) {
206 mRelease(mDevice, handle);
207 } else {
208 mModule->unregisterBuffer(mModule, handle);
209 native_handle_close(handle);
210 native_handle_delete(const_cast<native_handle_t*>(handle));
211 }
212 }
213
214 // gralloc1
215 gralloc1_device_t* mDevice;
216 GRALLOC1_PFN_RETAIN mRetain;
217 GRALLOC1_PFN_RELEASE mRelease;
218
219 // gralloc0
220 const gralloc_module_t* mModule;
221#else
222 bool openGralloc() { return true; }
223 void closeGralloc() {}
224 buffer_handle_t cloneBuffer(buffer_handle_t handle) { return handle; }
225 void releaseBuffer(buffer_handle_t) {}
226#endif
227};
228
229HandleImporter sHandleImporter;
230
231class BufferClone {
232public:
233 BufferClone() : mHandle(nullptr) {}
234
235 BufferClone(BufferClone&& other)
236 {
237 mHandle = other.mHandle;
238 other.mHandle = nullptr;
239 }
240
241 BufferClone(const BufferClone& other) = delete;
242 BufferClone& operator=(const BufferClone& other) = delete;
243
244 BufferClone& operator=(buffer_handle_t handle)
245 {
246 clear();
247 mHandle = handle;
248 return *this;
249 }
250
251 ~BufferClone()
252 {
253 clear();
254 }
255
256private:
257 void clear()
258 {
259 if (mHandle) {
260 sHandleImporter.freeBuffer(mHandle);
261 }
262 }
263
264 buffer_handle_t mHandle;
265};
266
267} // anonymous namespace
268
269class HwcHal : public IComposer {
270public:
271 HwcHal(const hw_module_t* module);
272 virtual ~HwcHal();
273
274 // IComposer interface
275 Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
276 Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
277 Return<void> registerCallback(const sp<IComposerCallback>& callback) override;
278 Return<uint32_t> getMaxVirtualDisplayCount() override;
279 Return<void> createVirtualDisplay(uint32_t width, uint32_t height,
280 PixelFormat formatHint, createVirtualDisplay_cb hidl_cb) override;
281 Return<Error> destroyVirtualDisplay(Display display) override;
282 Return<Error> acceptDisplayChanges(Display display) override;
283 Return<void> createLayer(Display display,
284 createLayer_cb hidl_cb) override;
285 Return<Error> destroyLayer(Display display, Layer layer) override;
286 Return<void> getActiveConfig(Display display,
287 getActiveConfig_cb hidl_cb) override;
288 Return<void> getChangedCompositionTypes(Display display,
289 getChangedCompositionTypes_cb hidl_cb) override;
290 Return<Error> getClientTargetSupport(Display display,
291 uint32_t width, uint32_t height,
292 PixelFormat format, Dataspace dataspace) override;
293 Return<void> getColorModes(Display display,
294 getColorModes_cb hidl_cb) override;
295 Return<void> getDisplayAttribute(Display display,
296 Config config, Attribute attribute,
297 getDisplayAttribute_cb hidl_cb) override;
298 Return<void> getDisplayConfigs(Display display,
299 getDisplayConfigs_cb hidl_cb) override;
300 Return<void> getDisplayName(Display display,
301 getDisplayName_cb hidl_cb) override;
302 Return<void> getDisplayRequests(Display display,
303 getDisplayRequests_cb hidl_cb) override;
304 Return<void> getDisplayType(Display display,
305 getDisplayType_cb hidl_cb) override;
306 Return<void> getDozeSupport(Display display,
307 getDozeSupport_cb hidl_cb) override;
308 Return<void> getHdrCapabilities(Display display,
309 getHdrCapabilities_cb hidl_cb) override;
310 Return<void> getReleaseFences(Display display,
311 getReleaseFences_cb hidl_cb) override;
312 Return<void> presentDisplay(Display display,
313 presentDisplay_cb hidl_cb) override;
314 Return<Error> setActiveConfig(Display display, Config config) override;
315 Return<Error> setClientTarget(Display display,
316 const native_handle_t* target,
317 const native_handle_t* acquireFence,
318 Dataspace dataspace, const hidl_vec<Rect>& damage) override;
319 Return<Error> setColorMode(Display display, ColorMode mode) override;
320 Return<Error> setColorTransform(Display display,
321 const hidl_vec<float>& matrix, ColorTransform hint) override;
322 Return<Error> setOutputBuffer(Display display,
323 const native_handle_t* buffer,
324 const native_handle_t* releaseFence) override;
325 Return<Error> setPowerMode(Display display, PowerMode mode) override;
326 Return<Error> setVsyncEnabled(Display display, Vsync enabled) override;
327 Return<void> validateDisplay(Display display,
328 validateDisplay_cb hidl_cb) override;
329 Return<Error> setCursorPosition(Display display,
330 Layer layer, int32_t x, int32_t y) override;
331 Return<Error> setLayerBuffer(Display display,
332 Layer layer, const native_handle_t* buffer,
333 const native_handle_t* acquireFence) override;
334 Return<Error> setLayerSurfaceDamage(Display display,
335 Layer layer, const hidl_vec<Rect>& damage) override;
336 Return<Error> setLayerBlendMode(Display display,
337 Layer layer, BlendMode mode) override;
338 Return<Error> setLayerColor(Display display,
339 Layer layer, const Color& color) override;
340 Return<Error> setLayerCompositionType(Display display,
341 Layer layer, Composition type) override;
342 Return<Error> setLayerDataspace(Display display,
343 Layer layer, Dataspace dataspace) override;
344 Return<Error> setLayerDisplayFrame(Display display,
345 Layer layer, const Rect& frame) override;
346 Return<Error> setLayerPlaneAlpha(Display display,
347 Layer layer, float alpha) override;
348 Return<Error> setLayerSidebandStream(Display display,
349 Layer layer, const native_handle_t* stream) override;
350 Return<Error> setLayerSourceCrop(Display display,
351 Layer layer, const FRect& crop) override;
352 Return<Error> setLayerTransform(Display display,
353 Layer layer, Transform transform) override;
354 Return<Error> setLayerVisibleRegion(Display display,
355 Layer layer, const hidl_vec<Rect>& visible) override;
356 Return<Error> setLayerZOrder(Display display,
357 Layer layer, uint32_t z) override;
358
359private:
360 void initCapabilities();
361
362 template<typename T>
363 void initDispatch(T& func, hwc2_function_descriptor_t desc);
364 void initDispatch();
365
366 bool hasCapability(Capability capability) const;
367
368 static void hotplugHook(hwc2_callback_data_t callbackData,
369 hwc2_display_t display, int32_t connected);
370 static void refreshHook(hwc2_callback_data_t callbackData,
371 hwc2_display_t display);
372 static void vsyncHook(hwc2_callback_data_t callbackData,
373 hwc2_display_t display, int64_t timestamp);
374
375 hwc2_device_t* mDevice;
376
377 std::unordered_set<Capability> mCapabilities;
378
379 struct {
380 HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
381 HWC2_PFN_CREATE_LAYER createLayer;
382 HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;
383 HWC2_PFN_DESTROY_LAYER destroyLayer;
384 HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;
385 HWC2_PFN_DUMP dump;
386 HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;
387 HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;
388 HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;
389 HWC2_PFN_GET_COLOR_MODES getColorModes;
390 HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;
391 HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;
392 HWC2_PFN_GET_DISPLAY_NAME getDisplayName;
393 HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;
394 HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;
395 HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;
396 HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;
397 HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;
398 HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;
399 HWC2_PFN_PRESENT_DISPLAY presentDisplay;
400 HWC2_PFN_REGISTER_CALLBACK registerCallback;
401 HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;
402 HWC2_PFN_SET_CLIENT_TARGET setClientTarget;
403 HWC2_PFN_SET_COLOR_MODE setColorMode;
404 HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;
405 HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;
406 HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;
407 HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;
408 HWC2_PFN_SET_LAYER_COLOR setLayerColor;
409 HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;
410 HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;
411 HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;
412 HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;
413 HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;
414 HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;
415 HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;
416 HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;
417 HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;
418 HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;
419 HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;
420 HWC2_PFN_SET_POWER_MODE setPowerMode;
421 HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;
422 HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
423 } mDispatch;
424
425 // cloned buffers for a display
426 struct DisplayBuffers {
427 BufferClone ClientTarget;
428 BufferClone OutputBuffer;
429
430 std::unordered_map<Layer, BufferClone> LayerBuffers;
431 std::unordered_map<Layer, BufferClone> LayerSidebandStreams;
432 };
433
434 std::mutex mCallbackMutex;
435 sp<IComposerCallback> mCallback;
436
437 std::mutex mDisplayMutex;
438 std::unordered_map<Display, DisplayBuffers> mDisplays;
439};
440
441HwcHal::HwcHal(const hw_module_t* module)
442 : mDevice(nullptr), mDispatch()
443{
444 if (!sHandleImporter.initialize()) {
445 LOG_ALWAYS_FATAL("failed to initialize handle importer");
446 }
447
448 int status = hwc2_open(module, &mDevice);
449 if (status) {
450 LOG_ALWAYS_FATAL("failed to open hwcomposer2 device: %s",
451 strerror(-status));
452 }
453
454 initCapabilities();
455 initDispatch();
456}
457
458HwcHal::~HwcHal()
459{
460 hwc2_close(mDevice);
461 mDisplays.clear();
462 sHandleImporter.cleanup();
463}
464
465void HwcHal::initCapabilities()
466{
467 uint32_t count = 0;
468 mDevice->getCapabilities(mDevice, &count, nullptr);
469
470 std::vector<Capability> caps(count);
471 mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
472 std::underlying_type<Capability>::type*>(caps.data()));
473 caps.resize(count);
474
475 mCapabilities.insert(caps.cbegin(), caps.cend());
476}
477
478template<typename T>
479void HwcHal::initDispatch(T& func, hwc2_function_descriptor_t desc)
480{
481 auto pfn = mDevice->getFunction(mDevice, desc);
482 if (!pfn) {
483 LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
484 }
485
486 func = reinterpret_cast<T>(pfn);
487}
488
489void HwcHal::initDispatch()
490{
491 initDispatch(mDispatch.acceptDisplayChanges,
492 HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES);
493 initDispatch(mDispatch.createLayer, HWC2_FUNCTION_CREATE_LAYER);
494 initDispatch(mDispatch.createVirtualDisplay,
495 HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY);
496 initDispatch(mDispatch.destroyLayer, HWC2_FUNCTION_DESTROY_LAYER);
497 initDispatch(mDispatch.destroyVirtualDisplay,
498 HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY);
499 initDispatch(mDispatch.dump, HWC2_FUNCTION_DUMP);
500 initDispatch(mDispatch.getActiveConfig, HWC2_FUNCTION_GET_ACTIVE_CONFIG);
501 initDispatch(mDispatch.getChangedCompositionTypes,
502 HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES);
503 initDispatch(mDispatch.getClientTargetSupport,
504 HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT);
505 initDispatch(mDispatch.getColorModes, HWC2_FUNCTION_GET_COLOR_MODES);
506 initDispatch(mDispatch.getDisplayAttribute,
507 HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE);
508 initDispatch(mDispatch.getDisplayConfigs,
509 HWC2_FUNCTION_GET_DISPLAY_CONFIGS);
510 initDispatch(mDispatch.getDisplayName, HWC2_FUNCTION_GET_DISPLAY_NAME);
511 initDispatch(mDispatch.getDisplayRequests,
512 HWC2_FUNCTION_GET_DISPLAY_REQUESTS);
513 initDispatch(mDispatch.getDisplayType, HWC2_FUNCTION_GET_DISPLAY_TYPE);
514 initDispatch(mDispatch.getDozeSupport, HWC2_FUNCTION_GET_DOZE_SUPPORT);
515 initDispatch(mDispatch.getHdrCapabilities,
516 HWC2_FUNCTION_GET_HDR_CAPABILITIES);
517 initDispatch(mDispatch.getMaxVirtualDisplayCount,
518 HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT);
519 initDispatch(mDispatch.getReleaseFences,
520 HWC2_FUNCTION_GET_RELEASE_FENCES);
521 initDispatch(mDispatch.presentDisplay, HWC2_FUNCTION_PRESENT_DISPLAY);
522 initDispatch(mDispatch.registerCallback, HWC2_FUNCTION_REGISTER_CALLBACK);
523 initDispatch(mDispatch.setActiveConfig, HWC2_FUNCTION_SET_ACTIVE_CONFIG);
524 initDispatch(mDispatch.setClientTarget, HWC2_FUNCTION_SET_CLIENT_TARGET);
525 initDispatch(mDispatch.setColorMode, HWC2_FUNCTION_SET_COLOR_MODE);
526 initDispatch(mDispatch.setColorTransform,
527 HWC2_FUNCTION_SET_COLOR_TRANSFORM);
528 initDispatch(mDispatch.setCursorPosition,
529 HWC2_FUNCTION_SET_CURSOR_POSITION);
530 initDispatch(mDispatch.setLayerBlendMode,
531 HWC2_FUNCTION_SET_LAYER_BLEND_MODE);
532 initDispatch(mDispatch.setLayerBuffer, HWC2_FUNCTION_SET_LAYER_BUFFER);
533 initDispatch(mDispatch.setLayerColor, HWC2_FUNCTION_SET_LAYER_COLOR);
534 initDispatch(mDispatch.setLayerCompositionType,
535 HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE);
536 initDispatch(mDispatch.setLayerDataspace,
537 HWC2_FUNCTION_SET_LAYER_DATASPACE);
538 initDispatch(mDispatch.setLayerDisplayFrame,
539 HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME);
540 initDispatch(mDispatch.setLayerPlaneAlpha,
541 HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA);
542
543 if (hasCapability(Capability::SIDEBAND_STREAM)) {
544 initDispatch(mDispatch.setLayerSidebandStream,
545 HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM);
546 }
547
548 initDispatch(mDispatch.setLayerSourceCrop,
549 HWC2_FUNCTION_SET_LAYER_SOURCE_CROP);
550 initDispatch(mDispatch.setLayerSurfaceDamage,
551 HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE);
552 initDispatch(mDispatch.setLayerTransform,
553 HWC2_FUNCTION_SET_LAYER_TRANSFORM);
554 initDispatch(mDispatch.setLayerVisibleRegion,
555 HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION);
556 initDispatch(mDispatch.setLayerZOrder, HWC2_FUNCTION_SET_LAYER_Z_ORDER);
557 initDispatch(mDispatch.setOutputBuffer, HWC2_FUNCTION_SET_OUTPUT_BUFFER);
558 initDispatch(mDispatch.setPowerMode, HWC2_FUNCTION_SET_POWER_MODE);
559 initDispatch(mDispatch.setVsyncEnabled, HWC2_FUNCTION_SET_VSYNC_ENABLED);
560 initDispatch(mDispatch.validateDisplay, HWC2_FUNCTION_VALIDATE_DISPLAY);
561}
562
563bool HwcHal::hasCapability(Capability capability) const
564{
565 return (mCapabilities.count(capability) > 0);
566}
567
568Return<void> HwcHal::getCapabilities(getCapabilities_cb hidl_cb)
569{
570 std::vector<Capability> caps(
571 mCapabilities.cbegin(), mCapabilities.cend());
572
573 hidl_vec<Capability> caps_reply;
574 caps_reply.setToExternal(caps.data(), caps.size());
575 hidl_cb(caps_reply);
576
577 return Void();
578}
579
580Return<void> HwcHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
581{
582 uint32_t len;
583 mDispatch.dump(mDevice, &len, nullptr);
584
585 std::vector<char> buf(len + 1);
586 mDispatch.dump(mDevice, &len, buf.data());
587 buf.resize(len + 1);
588 buf[len] = '\0';
589
590 hidl_string buf_reply;
591 buf_reply.setToExternal(buf.data(), len);
592 hidl_cb(buf_reply);
593
594 return Void();
595}
596
597void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
598 hwc2_display_t display, int32_t connected)
599{
600 auto hal = reinterpret_cast<HwcHal*>(callbackData);
601
602 {
603 std::lock_guard<std::mutex> lock(hal->mDisplayMutex);
604
605 if (connected == HWC2_CONNECTION_CONNECTED) {
606 hal->mDisplays.emplace(display, DisplayBuffers());
607 } else if (connected == HWC2_CONNECTION_DISCONNECTED) {
608 hal->mDisplays.erase(display);
609 }
610 }
611
612 hal->mCallback->onHotplug(display,
613 static_cast<IComposerCallback::Connection>(connected));
614}
615
616void HwcHal::refreshHook(hwc2_callback_data_t callbackData,
617 hwc2_display_t display)
618{
619 auto hal = reinterpret_cast<HwcHal*>(callbackData);
620 hal->mCallback->onRefresh(display);
621}
622
623void HwcHal::vsyncHook(hwc2_callback_data_t callbackData,
624 hwc2_display_t display, int64_t timestamp)
625{
626 auto hal = reinterpret_cast<HwcHal*>(callbackData);
627 hal->mCallback->onVsync(display, timestamp);
628}
629
630Return<void> HwcHal::registerCallback(const sp<IComposerCallback>& callback)
631{
632 std::lock_guard<std::mutex> lock(mCallbackMutex);
633
634 mCallback = callback;
635
636 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
637 reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
638 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
639 reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
640 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
641 reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
642
643 return Void();
644}
645
646Return<uint32_t> HwcHal::getMaxVirtualDisplayCount()
647{
648 return mDispatch.getMaxVirtualDisplayCount(mDevice);
649}
650
651Return<void> HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
652 PixelFormat formatHint, createVirtualDisplay_cb hidl_cb)
653{
654 int32_t format = static_cast<int32_t>(formatHint);
655 hwc2_display_t display;
656 auto error = mDispatch.createVirtualDisplay(mDevice, width, height,
657 &format, &display);
658 if (error == HWC2_ERROR_NONE) {
659 std::lock_guard<std::mutex> lock(mDisplayMutex);
660
661 mDisplays.emplace(display, DisplayBuffers());
662 }
663
664 hidl_cb(static_cast<Error>(error), display,
665 static_cast<PixelFormat>(format));
666
667 return Void();
668}
669
670Return<Error> HwcHal::destroyVirtualDisplay(Display display)
671{
672 auto error = mDispatch.destroyVirtualDisplay(mDevice, display);
673 if (error == HWC2_ERROR_NONE) {
674 std::lock_guard<std::mutex> lock(mDisplayMutex);
675
676 mDisplays.erase(display);
677 }
678
679 return static_cast<Error>(error);
680}
681
682Return<Error> HwcHal::acceptDisplayChanges(Display display)
683{
684 auto error = mDispatch.acceptDisplayChanges(mDevice, display);
685 return static_cast<Error>(error);
686}
687
688Return<void> HwcHal::createLayer(Display display, createLayer_cb hidl_cb)
689{
690 hwc2_layer_t layer;
691 auto error = mDispatch.createLayer(mDevice, display, &layer);
692
693 hidl_cb(static_cast<Error>(error), layer);
694
695 return Void();
696}
697
698Return<Error> HwcHal::destroyLayer(Display display, Layer layer)
699{
700 auto error = mDispatch.destroyLayer(mDevice, display, layer);
Chia-I Wu0c6b7f42016-10-19 06:57:54 +0800701 if (error == HWC2_ERROR_NONE) {
702 std::lock_guard<std::mutex> lock(mDisplayMutex);
703
704 auto dpy = mDisplays.find(display);
705 dpy->second.LayerBuffers.erase(layer);
706 dpy->second.LayerSidebandStreams.erase(layer);
707 }
708
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800709 return static_cast<Error>(error);
710}
711
712Return<void> HwcHal::getActiveConfig(Display display,
713 getActiveConfig_cb hidl_cb)
714{
715 hwc2_config_t config;
716 auto error = mDispatch.getActiveConfig(mDevice, display, &config);
717
718 hidl_cb(static_cast<Error>(error), config);
719
720 return Void();
721}
722
723Return<void> HwcHal::getChangedCompositionTypes(Display display,
724 getChangedCompositionTypes_cb hidl_cb)
725{
726 uint32_t count = 0;
727 auto error = mDispatch.getChangedCompositionTypes(mDevice, display,
728 &count, nullptr, nullptr);
729 if (error != HWC2_ERROR_NONE) {
730 count = 0;
731 }
732
733 std::vector<hwc2_layer_t> layers(count);
734 std::vector<Composition> types(count);
735 error = mDispatch.getChangedCompositionTypes(mDevice, display,
736 &count, layers.data(),
737 reinterpret_cast<std::underlying_type<Composition>::type*>(
738 types.data()));
739 if (error != HWC2_ERROR_NONE) {
740 count = 0;
741 }
742 layers.resize(count);
743 types.resize(count);
744
745 hidl_vec<Layer> layers_reply;
746 layers_reply.setToExternal(layers.data(), layers.size());
747
748 hidl_vec<Composition> types_reply;
749 types_reply.setToExternal(types.data(), types.size());
750
751 hidl_cb(static_cast<Error>(error), layers_reply, types_reply);
752
753 return Void();
754}
755
756Return<Error> HwcHal::getClientTargetSupport(Display display,
757 uint32_t width, uint32_t height,
758 PixelFormat format, Dataspace dataspace)
759{
760 auto error = mDispatch.getClientTargetSupport(mDevice, display,
761 width, height, static_cast<int32_t>(format),
762 static_cast<int32_t>(dataspace));
763 return static_cast<Error>(error);
764}
765
766Return<void> HwcHal::getColorModes(Display display, getColorModes_cb hidl_cb)
767{
768 uint32_t count = 0;
769 auto error = mDispatch.getColorModes(mDevice, display, &count, nullptr);
770 if (error != HWC2_ERROR_NONE) {
771 count = 0;
772 }
773
774 std::vector<ColorMode> modes(count);
775 error = mDispatch.getColorModes(mDevice, display, &count,
776 reinterpret_cast<std::underlying_type<ColorMode>::type*>(
777 modes.data()));
778 if (error != HWC2_ERROR_NONE) {
779 count = 0;
780 }
781 modes.resize(count);
782
783 hidl_vec<ColorMode> modes_reply;
784 modes_reply.setToExternal(modes.data(), modes.size());
785 hidl_cb(static_cast<Error>(error), modes_reply);
786
787 return Void();
788}
789
790Return<void> HwcHal::getDisplayAttribute(Display display,
791 Config config, Attribute attribute,
792 getDisplayAttribute_cb hidl_cb)
793{
794 int32_t value;
795 auto error = mDispatch.getDisplayAttribute(mDevice, display, config,
796 static_cast<int32_t>(attribute), &value);
797
798 hidl_cb(static_cast<Error>(error), value);
799
800 return Void();
801}
802
803Return<void> HwcHal::getDisplayConfigs(Display display,
804 getDisplayConfigs_cb hidl_cb)
805{
806 uint32_t count = 0;
807 auto error = mDispatch.getDisplayConfigs(mDevice, display,
808 &count, nullptr);
809 if (error != HWC2_ERROR_NONE) {
810 count = 0;
811 }
812
813 std::vector<hwc2_config_t> configs(count);
814 error = mDispatch.getDisplayConfigs(mDevice, display,
815 &count, configs.data());
816 if (error != HWC2_ERROR_NONE) {
817 count = 0;
818 }
819 configs.resize(count);
820
821 hidl_vec<Config> configs_reply;
822 configs_reply.setToExternal(configs.data(), configs.size());
823 hidl_cb(static_cast<Error>(error), configs_reply);
824
825 return Void();
826}
827
828Return<void> HwcHal::getDisplayName(Display display,
829 getDisplayName_cb hidl_cb)
830{
831 uint32_t count = 0;
832 auto error = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
833 if (error != HWC2_ERROR_NONE) {
834 count = 0;
835 }
836
837 std::vector<char> name(count + 1);
838 error = mDispatch.getDisplayName(mDevice, display, &count, name.data());
839 if (error != HWC2_ERROR_NONE) {
840 count = 0;
841 }
842 name.resize(count + 1);
843 name[count] = '\0';
844
845 hidl_string name_reply;
846 name_reply.setToExternal(name.data(), count);
847 hidl_cb(static_cast<Error>(error), name_reply);
848
849 return Void();
850}
851
852Return<void> HwcHal::getDisplayRequests(Display display,
853 getDisplayRequests_cb hidl_cb)
854{
855 int32_t display_reqs;
856 uint32_t count = 0;
857 auto error = mDispatch.getDisplayRequests(mDevice, display,
858 &display_reqs, &count, nullptr, nullptr);
859 if (error != HWC2_ERROR_NONE) {
860 count = 0;
861 }
862
863 std::vector<hwc2_layer_t> layers(count);
864 std::vector<int32_t> layer_reqs(count);
865 error = mDispatch.getDisplayRequests(mDevice, display,
866 &display_reqs, &count, layers.data(), layer_reqs.data());
867 if (error != HWC2_ERROR_NONE) {
868 count = 0;
869 }
870 layers.resize(count);
871 layer_reqs.resize(count);
872
873 hidl_vec<Layer> layers_reply;
874 layers_reply.setToExternal(layers.data(), layers.size());
875
876 hidl_vec<uint32_t> layer_reqs_reply;
877 layer_reqs_reply.setToExternal(
878 reinterpret_cast<uint32_t*>(layer_reqs.data()),
879 layer_reqs.size());
880
881 hidl_cb(static_cast<Error>(error), display_reqs,
882 layers_reply, layer_reqs_reply);
883
884 return Void();
885}
886
887Return<void> HwcHal::getDisplayType(Display display,
888 getDisplayType_cb hidl_cb)
889{
890 int32_t type;
891 auto error = mDispatch.getDisplayType(mDevice, display, &type);
892
893 hidl_cb(static_cast<Error>(error), static_cast<DisplayType>(type));
894
895 return Void();
896}
897
898Return<void> HwcHal::getDozeSupport(Display display,
899 getDozeSupport_cb hidl_cb)
900{
901 int32_t support;
902 auto error = mDispatch.getDozeSupport(mDevice, display, &support);
903
904 hidl_cb(static_cast<Error>(error), support);
905
906 return Void();
907}
908
909Return<void> HwcHal::getHdrCapabilities(Display display,
910 getHdrCapabilities_cb hidl_cb)
911{
912 float max_lumi, max_avg_lumi, min_lumi;
913 uint32_t count = 0;
914 auto error = mDispatch.getHdrCapabilities(mDevice, display,
915 &count, nullptr, &max_lumi, &max_avg_lumi, &min_lumi);
916 if (error != HWC2_ERROR_NONE) {
917 count = 0;
918 }
919
920 std::vector<Hdr> types(count);
921 error = mDispatch.getHdrCapabilities(mDevice, display, &count,
922 reinterpret_cast<std::underlying_type<Hdr>::type*>(types.data()),
923 &max_lumi, &max_avg_lumi, &min_lumi);
924 if (error != HWC2_ERROR_NONE) {
925 count = 0;
926 }
927 types.resize(count);
928
929 hidl_vec<Hdr> types_reply;
930 types_reply.setToExternal(types.data(), types.size());
931 hidl_cb(static_cast<Error>(error), types_reply,
932 max_lumi, max_avg_lumi, min_lumi);
933
934 return Void();
935}
936
937Return<void> HwcHal::getReleaseFences(Display display,
938 getReleaseFences_cb hidl_cb)
939{
940 uint32_t count = 0;
941 auto error = mDispatch.getReleaseFences(mDevice, display,
942 &count, nullptr, nullptr);
943 if (error != HWC2_ERROR_NONE) {
944 count = 0;
945 }
946
947 std::vector<hwc2_layer_t> layers(count);
948 std::vector<int32_t> fences(count);
949 error = mDispatch.getReleaseFences(mDevice, display,
950 &count, layers.data(), fences.data());
951 if (error != HWC2_ERROR_NONE) {
952 count = 0;
953 }
954 layers.resize(count);
955 fences.resize(count);
956
957 // filter out layers with release fence -1
958 std::vector<hwc2_layer_t> filtered_layers;
959 std::vector<int> filtered_fences;
960 for (size_t i = 0; i < layers.size(); i++) {
961 if (fences[i] >= 0) {
962 filtered_layers.push_back(layers[i]);
963 filtered_fences.push_back(fences[i]);
964 }
965 }
966
967 hidl_vec<Layer> layers_reply;
968 native_handle_t* fences_reply =
969 native_handle_create(filtered_fences.size(), 0);
970 if (fences_reply) {
971 layers_reply.setToExternal(filtered_layers.data(),
972 filtered_layers.size());
973 memcpy(fences_reply->data, filtered_fences.data(),
974 sizeof(int) * filtered_fences.size());
975
976 hidl_cb(static_cast<Error>(error), layers_reply, fences_reply);
977
978 native_handle_close(fences_reply);
979 native_handle_delete(fences_reply);
980 } else {
981 NATIVE_HANDLE_DECLARE_STORAGE(fences_storage, 0, 0);
982 fences_reply = native_handle_init(fences_storage, 0, 0);
983
984 hidl_cb(Error::NO_RESOURCES, layers_reply, fences_reply);
985
986 for (auto fence : filtered_fences) {
987 close(fence);
988 }
989 }
990
991 return Void();
992}
993
994Return<void> HwcHal::presentDisplay(Display display,
995 presentDisplay_cb hidl_cb)
996{
997 int32_t fence = -1;
998 auto error = mDispatch.presentDisplay(mDevice, display, &fence);
999
1000 NATIVE_HANDLE_DECLARE_STORAGE(fence_storage, 1, 0);
1001 native_handle_t* fence_reply;
1002 if (fence >= 0) {
1003 fence_reply = native_handle_init(fence_storage, 1, 0);
1004 fence_reply->data[0] = fence;
1005 } else {
1006 fence_reply = native_handle_init(fence_storage, 0, 0);
1007 }
1008
1009 hidl_cb(static_cast<Error>(error), fence_reply);
1010
1011 if (fence >= 0) {
1012 close(fence);
1013 }
1014
1015 return Void();
1016}
1017
1018Return<Error> HwcHal::setActiveConfig(Display display, Config config)
1019{
1020 auto error = mDispatch.setActiveConfig(mDevice, display, config);
1021 return static_cast<Error>(error);
1022}
1023
1024Return<Error> HwcHal::setClientTarget(Display display,
1025 const native_handle_t* target,
1026 const native_handle_t* acquireFence,
1027 Dataspace dataspace, const hidl_vec<Rect>& damage)
1028{
1029 if (!sHandleImporter.importBuffer(target)) {
1030 return Error::NO_RESOURCES;
1031 }
1032
1033 int32_t fence;
1034 if (!sHandleImporter.importFence(acquireFence, fence)) {
1035 sHandleImporter.freeBuffer(target);
1036 return Error::NO_RESOURCES;
1037 }
1038
1039 hwc_region_t damage_region = { damage.size(),
1040 reinterpret_cast<const hwc_rect_t*>(&damage[0]) };
1041
1042 int32_t error = mDispatch.setClientTarget(mDevice, display,
1043 target, fence, static_cast<int32_t>(dataspace),
1044 damage_region);
1045 if (error == HWC2_ERROR_NONE) {
1046 std::lock_guard<std::mutex> lock(mDisplayMutex);
1047
1048 auto dpy = mDisplays.find(display);
1049 dpy->second.ClientTarget = target;
1050 } else {
1051 sHandleImporter.freeBuffer(target);
1052 sHandleImporter.closeFence(fence);
1053 }
1054
1055 return static_cast<Error>(error);
1056}
1057
1058Return<Error> HwcHal::setColorMode(Display display, ColorMode mode)
1059{
1060 auto error = mDispatch.setColorMode(mDevice, display,
1061 static_cast<int32_t>(mode));
1062 return static_cast<Error>(error);
1063}
1064
1065Return<Error> HwcHal::setColorTransform(Display display,
1066 const hidl_vec<float>& matrix, ColorTransform hint)
1067{
1068 auto error = mDispatch.setColorTransform(mDevice, display,
1069 &matrix[0], static_cast<int32_t>(hint));
1070 return static_cast<Error>(error);
1071}
1072
1073Return<Error> HwcHal::setOutputBuffer(Display display,
1074 const native_handle_t* buffer,
1075 const native_handle_t* releaseFence)
1076{
1077 if (!sHandleImporter.importBuffer(buffer)) {
1078 return Error::NO_RESOURCES;
1079 }
1080
1081 int32_t fence;
1082 if (!sHandleImporter.importFence(releaseFence, fence)) {
1083 sHandleImporter.freeBuffer(buffer);
1084 return Error::NO_RESOURCES;
1085 }
1086
1087 int32_t error = mDispatch.setOutputBuffer(mDevice,
1088 display, buffer, fence);
1089 if (error == HWC2_ERROR_NONE) {
1090 std::lock_guard<std::mutex> lock(mDisplayMutex);
1091
1092 auto dpy = mDisplays.find(display);
1093 dpy->second.OutputBuffer = buffer;
1094 } else {
1095 sHandleImporter.freeBuffer(buffer);
1096 }
1097
1098 // unlike in setClientTarget, fence is owned by us and is always closed
1099 sHandleImporter.closeFence(fence);
1100
1101 return static_cast<Error>(error);
1102}
1103
1104Return<Error> HwcHal::setPowerMode(Display display, PowerMode mode)
1105{
1106 auto error = mDispatch.setPowerMode(mDevice, display,
1107 static_cast<int32_t>(mode));
1108 return static_cast<Error>(error);
1109}
1110
1111Return<Error> HwcHal::setVsyncEnabled(Display display,
1112 Vsync enabled)
1113{
1114 auto error = mDispatch.setVsyncEnabled(mDevice, display,
1115 static_cast<int32_t>(enabled));
1116 return static_cast<Error>(error);
1117}
1118
1119Return<void> HwcHal::validateDisplay(Display display,
1120 validateDisplay_cb hidl_cb)
1121{
1122 uint32_t types_count = 0;
1123 uint32_t reqs_count = 0;
1124 auto error = mDispatch.validateDisplay(mDevice, display,
1125 &types_count, &reqs_count);
1126
1127 hidl_cb(static_cast<Error>(error), types_count, reqs_count);
1128
1129 return Void();
1130}
1131
1132Return<Error> HwcHal::setCursorPosition(Display display,
1133 Layer layer, int32_t x, int32_t y)
1134{
1135 auto error = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
1136 return static_cast<Error>(error);
1137}
1138
1139Return<Error> HwcHal::setLayerBuffer(Display display,
1140 Layer layer, const native_handle_t* buffer,
1141 const native_handle_t* acquireFence)
1142{
1143 if (!sHandleImporter.importBuffer(buffer)) {
1144 return Error::NO_RESOURCES;
1145 }
1146
1147 int32_t fence;
1148 if (!sHandleImporter.importFence(acquireFence, fence)) {
1149 sHandleImporter.freeBuffer(buffer);
1150 return Error::NO_RESOURCES;
1151 }
1152
1153 int32_t error = mDispatch.setLayerBuffer(mDevice,
1154 display, layer, buffer, fence);
1155 if (error == HWC2_ERROR_NONE) {
1156 std::lock_guard<std::mutex> lock(mDisplayMutex);
1157
1158 auto dpy = mDisplays.find(display);
1159 dpy->second.LayerBuffers[layer] = buffer;
1160 } else {
1161 sHandleImporter.freeBuffer(buffer);
1162 sHandleImporter.closeFence(fence);
1163 }
1164
1165 return static_cast<Error>(error);
1166}
1167
1168Return<Error> HwcHal::setLayerSurfaceDamage(Display display,
1169 Layer layer, const hidl_vec<Rect>& damage)
1170{
1171 hwc_region_t damage_region = { damage.size(),
1172 reinterpret_cast<const hwc_rect_t*>(&damage[0]) };
1173
1174 auto error = mDispatch.setLayerSurfaceDamage(mDevice, display, layer,
1175 damage_region);
1176 return static_cast<Error>(error);
1177}
1178
1179Return<Error> HwcHal::setLayerBlendMode(Display display,
1180 Layer layer, BlendMode mode)
1181{
1182 auto error = mDispatch.setLayerBlendMode(mDevice, display, layer,
1183 static_cast<int32_t>(mode));
1184 return static_cast<Error>(error);
1185}
1186
1187Return<Error> HwcHal::setLayerColor(Display display,
1188 Layer layer, const Color& color)
1189{
1190 hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
1191 auto error = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
1192 return static_cast<Error>(error);
1193}
1194
1195Return<Error> HwcHal::setLayerCompositionType(Display display,
1196 Layer layer, Composition type)
1197{
1198 auto error = mDispatch.setLayerCompositionType(mDevice, display, layer,
1199 static_cast<int32_t>(type));
1200 return static_cast<Error>(error);
1201}
1202
1203Return<Error> HwcHal::setLayerDataspace(Display display,
1204 Layer layer, Dataspace dataspace)
1205{
1206 auto error = mDispatch.setLayerDataspace(mDevice, display, layer,
1207 static_cast<int32_t>(dataspace));
1208 return static_cast<Error>(error);
1209}
1210
1211Return<Error> HwcHal::setLayerDisplayFrame(Display display,
1212 Layer layer, const Rect& frame)
1213{
1214 hwc_rect_t hwc_frame{frame.left, frame.top, frame.right, frame.bottom};
1215 auto error = mDispatch.setLayerDisplayFrame(mDevice, display, layer,
1216 hwc_frame);
1217 return static_cast<Error>(error);
1218}
1219
1220Return<Error> HwcHal::setLayerPlaneAlpha(Display display,
1221 Layer layer, float alpha)
1222{
1223 auto error = mDispatch.setLayerPlaneAlpha(mDevice, display, layer, alpha);
1224 return static_cast<Error>(error);
1225}
1226
1227Return<Error> HwcHal::setLayerSidebandStream(Display display,
1228 Layer layer, const native_handle_t* stream)
1229{
1230 if (!sHandleImporter.importBuffer(stream)) {
1231 return Error::NO_RESOURCES;
1232 }
1233
1234 int32_t error = mDispatch.setLayerSidebandStream(mDevice,
1235 display, layer, stream);
1236 if (error == HWC2_ERROR_NONE) {
1237 std::lock_guard<std::mutex> lock(mDisplayMutex);
1238
1239 auto dpy = mDisplays.find(display);
1240 dpy->second.LayerSidebandStreams[layer] = stream;
1241 } else {
1242 sHandleImporter.freeBuffer(stream);
1243 }
1244
1245 return static_cast<Error>(error);
1246}
1247
1248Return<Error> HwcHal::setLayerSourceCrop(Display display,
1249 Layer layer, const FRect& crop)
1250{
1251 hwc_frect_t hwc_crop{crop.left, crop.top, crop.right, crop.bottom};
1252 auto error = mDispatch.setLayerSourceCrop(mDevice, display, layer,
1253 hwc_crop);
1254 return static_cast<Error>(error);
1255}
1256
1257Return<Error> HwcHal::setLayerTransform(Display display,
1258 Layer layer, Transform transform)
1259{
1260 auto error = mDispatch.setLayerTransform(mDevice, display, layer,
1261 static_cast<int32_t>(transform));
1262 return static_cast<Error>(error);
1263}
1264
1265Return<Error> HwcHal::setLayerVisibleRegion(Display display,
1266 Layer layer, const hidl_vec<Rect>& visible)
1267{
1268 hwc_region_t visible_region = { visible.size(),
1269 reinterpret_cast<const hwc_rect_t*>(&visible[0]) };
1270
1271 auto error = mDispatch.setLayerVisibleRegion(mDevice, display, layer,
1272 visible_region);
1273 return static_cast<Error>(error);
1274}
1275
1276Return<Error> HwcHal::setLayerZOrder(Display display,
1277 Layer layer, uint32_t z)
1278{
1279 auto error = mDispatch.setLayerZOrder(mDevice, display, layer, z);
1280 return static_cast<Error>(error);
1281}
1282
1283IComposer* HIDL_FETCH_IComposer(const char*)
1284{
1285 const hw_module_t* module;
1286 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
1287 if (err) {
1288 ALOGE("failed to get hwcomposer module");
1289 return nullptr;
1290 }
1291
1292 return new HwcHal(module);
1293}
1294
1295} // namespace implementation
1296} // namespace V2_1
1297} // namespace composer
1298} // namespace graphics
1299} // namespace hardware
1300} // namespace android