blob: 62c5affcb8520673ee5de9321971750d57d54da1 [file] [log] [blame]
Dan Stoza651bf312015-10-23 17:03:17 -07001/*
2 * Copyright 2015 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_NDEBUG 0
18
19#undef LOG_TAG
20#define LOG_TAG "HWC2"
21#define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
23#include "HWC2.h"
Chia-I Wuaab99f52016-10-05 12:59:58 +080024#include "ComposerHal.h"
Dan Stoza651bf312015-10-23 17:03:17 -070025
Dan Stoza651bf312015-10-23 17:03:17 -070026#include <ui/Fence.h>
Dan Stoza5a423ea2017-02-16 14:10:39 -080027#include <ui/FloatRect.h>
Dan Stoza651bf312015-10-23 17:03:17 -070028#include <ui/GraphicBuffer.h>
29#include <ui/Region.h>
30
31#include <android/configuration.h>
32
Dan Stoza09e7a272016-04-14 12:31:01 -070033#include <algorithm>
Dan Stoza651bf312015-10-23 17:03:17 -070034#include <inttypes.h>
35
36extern "C" {
37 static void hotplug_hook(hwc2_callback_data_t callbackData,
38 hwc2_display_t displayId, int32_t intConnected) {
39 auto device = static_cast<HWC2::Device*>(callbackData);
40 auto display = device->getDisplayById(displayId);
41 if (display) {
42 auto connected = static_cast<HWC2::Connection>(intConnected);
43 device->callHotplug(std::move(display), connected);
44 } else {
45 ALOGE("Hotplug callback called with unknown display %" PRIu64,
46 displayId);
47 }
48 }
49
50 static void refresh_hook(hwc2_callback_data_t callbackData,
51 hwc2_display_t displayId) {
52 auto device = static_cast<HWC2::Device*>(callbackData);
53 auto display = device->getDisplayById(displayId);
54 if (display) {
55 device->callRefresh(std::move(display));
56 } else {
57 ALOGE("Refresh callback called with unknown display %" PRIu64,
58 displayId);
59 }
60 }
61
62 static void vsync_hook(hwc2_callback_data_t callbackData,
63 hwc2_display_t displayId, int64_t timestamp) {
64 auto device = static_cast<HWC2::Device*>(callbackData);
65 auto display = device->getDisplayById(displayId);
66 if (display) {
67 device->callVsync(std::move(display), timestamp);
68 } else {
69 ALOGE("Vsync callback called with unknown display %" PRIu64,
70 displayId);
71 }
72 }
73}
74
75using android::Fence;
Dan Stoza5a423ea2017-02-16 14:10:39 -080076using android::FloatRect;
Dan Stoza651bf312015-10-23 17:03:17 -070077using android::GraphicBuffer;
Dan Stoza7d7ae732016-03-16 12:23:40 -070078using android::HdrCapabilities;
Dan Stoza651bf312015-10-23 17:03:17 -070079using android::Rect;
80using android::Region;
81using android::sp;
Chia-I Wuaab99f52016-10-05 12:59:58 +080082using android::hardware::Return;
83using android::hardware::Void;
Dan Stoza651bf312015-10-23 17:03:17 -070084
85namespace HWC2 {
86
Chia-I Wuaab99f52016-10-05 12:59:58 +080087namespace Hwc2 = android::Hwc2;
88
Dan Stoza651bf312015-10-23 17:03:17 -070089// Device methods
90
Chia-I Wuaab99f52016-10-05 12:59:58 +080091#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -070092Device::Device(hwc2_device_t* device)
93 : mHwcDevice(device),
94 mCreateVirtualDisplay(nullptr),
95 mDestroyVirtualDisplay(nullptr),
96 mDump(nullptr),
97 mGetMaxVirtualDisplayCount(nullptr),
98 mRegisterCallback(nullptr),
99 mAcceptDisplayChanges(nullptr),
100 mCreateLayer(nullptr),
101 mDestroyLayer(nullptr),
102 mGetActiveConfig(nullptr),
103 mGetChangedCompositionTypes(nullptr),
Dan Stoza076ac672016-03-14 10:47:53 -0700104 mGetColorModes(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700105 mGetDisplayAttribute(nullptr),
106 mGetDisplayConfigs(nullptr),
107 mGetDisplayName(nullptr),
108 mGetDisplayRequests(nullptr),
109 mGetDisplayType(nullptr),
110 mGetDozeSupport(nullptr),
Dan Stoza7d7ae732016-03-16 12:23:40 -0700111 mGetHdrCapabilities(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700112 mGetReleaseFences(nullptr),
113 mPresentDisplay(nullptr),
114 mSetActiveConfig(nullptr),
115 mSetClientTarget(nullptr),
Dan Stoza076ac672016-03-14 10:47:53 -0700116 mSetColorMode(nullptr),
Dan Stoza5df2a862016-03-24 16:19:37 -0700117 mSetColorTransform(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700118 mSetOutputBuffer(nullptr),
119 mSetPowerMode(nullptr),
120 mSetVsyncEnabled(nullptr),
121 mValidateDisplay(nullptr),
122 mSetCursorPosition(nullptr),
123 mSetLayerBuffer(nullptr),
124 mSetLayerSurfaceDamage(nullptr),
125 mSetLayerBlendMode(nullptr),
126 mSetLayerColor(nullptr),
127 mSetLayerCompositionType(nullptr),
Dan Stoza5df2a862016-03-24 16:19:37 -0700128 mSetLayerDataspace(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700129 mSetLayerDisplayFrame(nullptr),
130 mSetLayerPlaneAlpha(nullptr),
131 mSetLayerSidebandStream(nullptr),
132 mSetLayerSourceCrop(nullptr),
133 mSetLayerTransform(nullptr),
134 mSetLayerVisibleRegion(nullptr),
135 mSetLayerZOrder(nullptr),
Chia-I Wuaab99f52016-10-05 12:59:58 +0800136#else
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -0800137Device::Device(bool useVrComposer)
138 : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
Chia-I Wuaab99f52016-10-05 12:59:58 +0800139#endif // BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700140 mCapabilities(),
141 mDisplays(),
142 mHotplug(),
143 mPendingHotplugs(),
144 mRefresh(),
145 mPendingRefreshes(),
146 mVsync(),
147 mPendingVsyncs()
148{
149 loadCapabilities();
150 loadFunctionPointers();
151 registerCallbacks();
152}
153
154Device::~Device()
155{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800156#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700157 if (mHwcDevice == nullptr) {
158 return;
159 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800160#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700161
162 for (auto element : mDisplays) {
Dan Stoza38628982016-07-13 15:48:58 -0700163 auto display = element.second.lock();
164 if (!display) {
165 ALOGE("~Device: Found a display (%" PRId64 " that has already been"
166 " destroyed", element.first);
167 continue;
168 }
Dan Stoza651bf312015-10-23 17:03:17 -0700169
170 DisplayType displayType = HWC2::DisplayType::Invalid;
171 auto error = display->getType(&displayType);
172 if (error != Error::None) {
173 ALOGE("~Device: Failed to determine type of display %" PRIu64
174 ": %s (%d)", display->getId(), to_string(error).c_str(),
175 static_cast<int32_t>(error));
176 continue;
177 }
178
179 if (displayType == HWC2::DisplayType::Physical) {
180 error = display->setVsyncEnabled(HWC2::Vsync::Disable);
181 if (error != Error::None) {
182 ALOGE("~Device: Failed to disable vsync for display %" PRIu64
183 ": %s (%d)", display->getId(), to_string(error).c_str(),
184 static_cast<int32_t>(error));
185 }
186 }
187 }
188
Chia-I Wuaab99f52016-10-05 12:59:58 +0800189#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700190 hwc2_close(mHwcDevice);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800191#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700192}
193
194// Required by HWC2 device
195
196std::string Device::dump() const
197{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800198#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700199 uint32_t numBytes = 0;
200 mDump(mHwcDevice, &numBytes, nullptr);
201
202 std::vector<char> buffer(numBytes);
203 mDump(mHwcDevice, &numBytes, buffer.data());
204
205 return std::string(buffer.data(), buffer.size());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800206#else
207 return mComposer->dumpDebugInfo();
208#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700209}
210
211uint32_t Device::getMaxVirtualDisplayCount() const
212{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800213#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700214 return mGetMaxVirtualDisplayCount(mHwcDevice);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800215#else
216 return mComposer->getMaxVirtualDisplayCount();
217#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700218}
219
220Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
Dan Stoza5cf424b2016-05-20 14:02:39 -0700221 android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
Dan Stoza651bf312015-10-23 17:03:17 -0700222{
223 ALOGI("Creating virtual display");
224
225 hwc2_display_t displayId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800226#ifdef BYPASS_IHWC
Dan Stoza5cf424b2016-05-20 14:02:39 -0700227 int32_t intFormat = static_cast<int32_t>(*format);
Dan Stoza651bf312015-10-23 17:03:17 -0700228 int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
Dan Stoza5cf424b2016-05-20 14:02:39 -0700229 &intFormat, &displayId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800230#else
231 auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
232 auto intError = mComposer->createVirtualDisplay(width, height,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800233 &intFormat, &displayId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800234#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700235 auto error = static_cast<Error>(intError);
236 if (error != Error::None) {
237 return error;
238 }
239
240 ALOGI("Created virtual display");
Dan Stoza5cf424b2016-05-20 14:02:39 -0700241 *format = static_cast<android_pixel_format_t>(intFormat);
Dan Stoza651bf312015-10-23 17:03:17 -0700242 *outDisplay = getDisplayById(displayId);
Dan Stoza38628982016-07-13 15:48:58 -0700243 if (!*outDisplay) {
244 ALOGE("Failed to get display by id");
245 return Error::BadDisplay;
246 }
Chris Forbesceb67d12017-04-11 12:20:00 -0700247 (*outDisplay)->setConnected(true);
Dan Stoza651bf312015-10-23 17:03:17 -0700248 return Error::None;
249}
250
251void Device::registerHotplugCallback(HotplugCallback hotplug)
252{
253 ALOGV("registerHotplugCallback");
254 mHotplug = hotplug;
255 for (auto& pending : mPendingHotplugs) {
256 auto& display = pending.first;
257 auto connected = pending.second;
258 ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
259 to_string(connected).c_str());
260 mHotplug(std::move(display), connected);
261 }
262}
263
264void Device::registerRefreshCallback(RefreshCallback refresh)
265{
266 mRefresh = refresh;
267 for (auto& pending : mPendingRefreshes) {
268 mRefresh(std::move(pending));
269 }
270}
271
272void Device::registerVsyncCallback(VsyncCallback vsync)
273{
274 mVsync = vsync;
275 for (auto& pending : mPendingVsyncs) {
276 auto& display = pending.first;
277 auto timestamp = pending.second;
278 mVsync(std::move(display), timestamp);
279 }
280}
281
282// For use by Device callbacks
283
284void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
285{
286 if (connected == Connection::Connected) {
287 if (!display->isConnected()) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800288#ifndef BYPASS_IHWC
289 mComposer->setClientTargetSlotCount(display->getId());
290#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700291 display->loadConfigs();
292 display->setConnected(true);
293 }
294 } else {
295 display->setConnected(false);
296 mDisplays.erase(display->getId());
297 }
298
299 if (mHotplug) {
300 mHotplug(std::move(display), connected);
301 } else {
302 ALOGV("callHotplug called, but no valid callback registered, storing");
303 mPendingHotplugs.emplace_back(std::move(display), connected);
304 }
305}
306
307void Device::callRefresh(std::shared_ptr<Display> display)
308{
309 if (mRefresh) {
310 mRefresh(std::move(display));
311 } else {
312 ALOGV("callRefresh called, but no valid callback registered, storing");
313 mPendingRefreshes.emplace_back(std::move(display));
314 }
315}
316
317void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
318{
319 if (mVsync) {
320 mVsync(std::move(display), timestamp);
321 } else {
322 ALOGV("callVsync called, but no valid callback registered, storing");
323 mPendingVsyncs.emplace_back(std::move(display), timestamp);
324 }
325}
326
327// Other Device methods
328
329std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
330 if (mDisplays.count(id) != 0) {
Dan Stoza38628982016-07-13 15:48:58 -0700331 auto strongDisplay = mDisplays[id].lock();
332 ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
333 " longer alive", id);
334 return strongDisplay;
Dan Stoza651bf312015-10-23 17:03:17 -0700335 }
336
337 auto display = std::make_shared<Display>(*this, id);
338 mDisplays.emplace(id, display);
339 return display;
340}
341
342// Device initialization methods
343
344void Device::loadCapabilities()
345{
346 static_assert(sizeof(Capability) == sizeof(int32_t),
347 "Capability size has changed");
Chia-I Wuaab99f52016-10-05 12:59:58 +0800348#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700349 uint32_t numCapabilities = 0;
350 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
Dan Stoza9f26a9c2016-06-22 14:51:09 -0700351 std::vector<Capability> capabilities(numCapabilities);
352 auto asInt = reinterpret_cast<int32_t*>(capabilities.data());
Dan Stoza651bf312015-10-23 17:03:17 -0700353 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
Dan Stoza9f26a9c2016-06-22 14:51:09 -0700354 for (auto capability : capabilities) {
355 mCapabilities.emplace(capability);
356 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800357#else
358 auto capabilities = mComposer->getCapabilities();
359 for (auto capability : capabilities) {
360 mCapabilities.emplace(static_cast<Capability>(capability));
361 }
362#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700363}
364
Dan Stoza09e7a272016-04-14 12:31:01 -0700365bool Device::hasCapability(HWC2::Capability capability) const
366{
367 return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
368 capability) != mCapabilities.cend();
369}
370
Dan Stoza651bf312015-10-23 17:03:17 -0700371void Device::loadFunctionPointers()
372{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800373#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700374 // For all of these early returns, we log an error message inside
375 // loadFunctionPointer specifying which function failed to load
376
377 // Display function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700378 if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700379 mCreateVirtualDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700380 if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700381 mDestroyVirtualDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700382 if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
383 if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
Dan Stoza651bf312015-10-23 17:03:17 -0700384 mGetMaxVirtualDisplayCount)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700385 if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
Dan Stoza651bf312015-10-23 17:03:17 -0700386 mRegisterCallback)) return;
387
388 // Device function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700389 if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
Dan Stoza651bf312015-10-23 17:03:17 -0700390 mAcceptDisplayChanges)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700391 if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
Dan Stoza651bf312015-10-23 17:03:17 -0700392 mCreateLayer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700393 if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
Dan Stoza651bf312015-10-23 17:03:17 -0700394 mDestroyLayer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700395 if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
Dan Stoza651bf312015-10-23 17:03:17 -0700396 mGetActiveConfig)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700397 if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
Dan Stoza651bf312015-10-23 17:03:17 -0700398 mGetChangedCompositionTypes)) return;
Dan Stoza076ac672016-03-14 10:47:53 -0700399 if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
400 mGetColorModes)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700401 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
Dan Stoza651bf312015-10-23 17:03:17 -0700402 mGetDisplayAttribute)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700403 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
Dan Stoza651bf312015-10-23 17:03:17 -0700404 mGetDisplayConfigs)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700405 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
Dan Stoza651bf312015-10-23 17:03:17 -0700406 mGetDisplayName)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700407 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
Dan Stoza651bf312015-10-23 17:03:17 -0700408 mGetDisplayRequests)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700409 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
Dan Stoza651bf312015-10-23 17:03:17 -0700410 mGetDisplayType)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700411 if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
Dan Stoza651bf312015-10-23 17:03:17 -0700412 mGetDozeSupport)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700413 if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
414 mGetHdrCapabilities)) return;
415 if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
Dan Stoza651bf312015-10-23 17:03:17 -0700416 mGetReleaseFences)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700417 if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700418 mPresentDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700419 if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
Dan Stoza651bf312015-10-23 17:03:17 -0700420 mSetActiveConfig)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700421 if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
Dan Stoza651bf312015-10-23 17:03:17 -0700422 mSetClientTarget)) return;
Dan Stoza076ac672016-03-14 10:47:53 -0700423 if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
424 mSetColorMode)) return;
Dan Stoza5df2a862016-03-24 16:19:37 -0700425 if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
426 mSetColorTransform)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700427 if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
Dan Stoza651bf312015-10-23 17:03:17 -0700428 mSetOutputBuffer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700429 if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
Dan Stoza651bf312015-10-23 17:03:17 -0700430 mSetPowerMode)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700431 if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
Dan Stoza651bf312015-10-23 17:03:17 -0700432 mSetVsyncEnabled)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700433 if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700434 mValidateDisplay)) return;
435
436 // Layer function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700437 if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
Dan Stoza651bf312015-10-23 17:03:17 -0700438 mSetCursorPosition)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700439 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
Dan Stoza651bf312015-10-23 17:03:17 -0700440 mSetLayerBuffer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700441 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
Dan Stoza651bf312015-10-23 17:03:17 -0700442 mSetLayerSurfaceDamage)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700443 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
Dan Stoza651bf312015-10-23 17:03:17 -0700444 mSetLayerBlendMode)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700445 if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
Dan Stoza651bf312015-10-23 17:03:17 -0700446 mSetLayerColor)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700447 if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
Dan Stoza651bf312015-10-23 17:03:17 -0700448 mSetLayerCompositionType)) return;
Dan Stoza5df2a862016-03-24 16:19:37 -0700449 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
450 mSetLayerDataspace)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700451 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
Dan Stoza651bf312015-10-23 17:03:17 -0700452 mSetLayerDisplayFrame)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700453 if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
Dan Stoza651bf312015-10-23 17:03:17 -0700454 mSetLayerPlaneAlpha)) return;
Dan Stoza09e7a272016-04-14 12:31:01 -0700455 if (hasCapability(Capability::SidebandStream)) {
456 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
457 mSetLayerSidebandStream)) return;
458 }
Dan Stoza7d7ae732016-03-16 12:23:40 -0700459 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
Dan Stoza651bf312015-10-23 17:03:17 -0700460 mSetLayerSourceCrop)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700461 if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
Dan Stoza651bf312015-10-23 17:03:17 -0700462 mSetLayerTransform)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700463 if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
Dan Stoza651bf312015-10-23 17:03:17 -0700464 mSetLayerVisibleRegion)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700465 if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
Dan Stoza651bf312015-10-23 17:03:17 -0700466 mSetLayerZOrder)) return;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800467#endif // BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700468}
469
Chia-I Wuaab99f52016-10-05 12:59:58 +0800470namespace {
471class ComposerCallback : public Hwc2::IComposerCallback {
472public:
473 ComposerCallback(Device* device) : mDevice(device) {}
474
475 Return<void> onHotplug(Hwc2::Display display,
476 Connection connected) override
477 {
478 hotplug_hook(mDevice, display, static_cast<int32_t>(connected));
479 return Void();
480 }
481
482 Return<void> onRefresh(Hwc2::Display display) override
483 {
484 refresh_hook(mDevice, display);
485 return Void();
486 }
487
488 Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
489 {
490 vsync_hook(mDevice, display, timestamp);
491 return Void();
492 }
493
494private:
495 Device* mDevice;
496};
497} // namespace anonymous
498
Dan Stoza651bf312015-10-23 17:03:17 -0700499void Device::registerCallbacks()
500{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800501#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700502 registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
503 registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
504 registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800505#else
506 sp<ComposerCallback> callback = new ComposerCallback(this);
507 mComposer->registerCallback(callback);
508#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700509}
510
511
512// For use by Display
513
514void Device::destroyVirtualDisplay(hwc2_display_t display)
515{
516 ALOGI("Destroying virtual display");
Chia-I Wuaab99f52016-10-05 12:59:58 +0800517#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700518 int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800519#else
520 auto intError = mComposer->destroyVirtualDisplay(display);
521#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700522 auto error = static_cast<Error>(intError);
523 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
524 " %s (%d)", display, to_string(error).c_str(), intError);
Dan Stoza38628982016-07-13 15:48:58 -0700525 mDisplays.erase(display);
Dan Stoza651bf312015-10-23 17:03:17 -0700526}
527
528// Display methods
529
530Display::Display(Device& device, hwc2_display_t id)
531 : mDevice(device),
532 mId(id),
533 mIsConnected(false),
Chris Forbes016d73c2017-04-11 10:04:31 -0700534 mType(DisplayType::Invalid)
Dan Stoza651bf312015-10-23 17:03:17 -0700535{
536 ALOGV("Created display %" PRIu64, id);
Chris Forbes016d73c2017-04-11 10:04:31 -0700537
538#ifdef BYPASS_IHWC
539 int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
540 reinterpret_cast<int32_t *>(&mType));
541#else
542 auto intError = mDevice.mComposer->getDisplayType(mId,
543 reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType));
544#endif
545 auto error = static_cast<Error>(intError);
546 if (error != Error::None) {
547 ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)",
548 id, to_string(error).c_str(), intError);
549 }
Dan Stoza651bf312015-10-23 17:03:17 -0700550}
551
552Display::~Display()
553{
554 ALOGV("Destroyed display %" PRIu64, mId);
Chris Forbesceb67d12017-04-11 12:20:00 -0700555 if (mType == DisplayType::Virtual) {
Dan Stoza651bf312015-10-23 17:03:17 -0700556 mDevice.destroyVirtualDisplay(mId);
557 }
558}
559
560Display::Config::Config(Display& display, hwc2_config_t id)
561 : mDisplay(display),
562 mId(id),
563 mWidth(-1),
564 mHeight(-1),
565 mVsyncPeriod(-1),
566 mDpiX(-1),
567 mDpiY(-1) {}
568
569Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
570 : mConfig(new Config(display, id)) {}
571
572float Display::Config::Builder::getDefaultDensity() {
573 // Default density is based on TVs: 1080p displays get XHIGH density, lower-
574 // resolution displays get TV density. Maybe eventually we'll need to update
575 // it for 4k displays, though hopefully those will just report accurate DPI
576 // information to begin with. This is also used for virtual displays and
577 // older HWC implementations, so be careful about orientation.
578
579 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
580 if (longDimension >= 1080) {
581 return ACONFIGURATION_DENSITY_XHIGH;
582 } else {
583 return ACONFIGURATION_DENSITY_TV;
584 }
585}
586
587// Required by HWC2 display
588
589Error Display::acceptChanges()
590{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800591#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700592 int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800593#else
594 auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
595#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700596 return static_cast<Error>(intError);
597}
598
599Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
600{
601 hwc2_layer_t layerId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800602#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700603 int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800604#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800605 auto intError = mDevice.mComposer->createLayer(mId, &layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800606#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700607 auto error = static_cast<Error>(intError);
608 if (error != Error::None) {
609 return error;
610 }
611
612 auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
613 mLayers.emplace(layerId, layer);
614 *outLayer = std::move(layer);
615 return Error::None;
616}
617
618Error Display::getActiveConfig(
619 std::shared_ptr<const Display::Config>* outConfig) const
620{
621 ALOGV("[%" PRIu64 "] getActiveConfig", mId);
622 hwc2_config_t configId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800623#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700624 int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
625 &configId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800626#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800627 auto intError = mDevice.mComposer->getActiveConfig(mId, &configId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800628#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700629 auto error = static_cast<Error>(intError);
630
631 if (error != Error::None) {
Fabien Sanglardb7432cc2016-11-11 09:40:27 -0800632 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
633 *outConfig = nullptr;
Dan Stoza651bf312015-10-23 17:03:17 -0700634 return error;
635 }
636
637 if (mConfigs.count(configId) != 0) {
638 *outConfig = mConfigs.at(configId);
639 } else {
640 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
641 configId);
642 // Return no error, but the caller needs to check for a null pointer to
643 // detect this case
644 *outConfig = nullptr;
645 }
646
647 return Error::None;
648}
649
650Error Display::getChangedCompositionTypes(
651 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
652{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800653#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700654 uint32_t numElements = 0;
655 int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
656 mId, &numElements, nullptr, nullptr);
657 auto error = static_cast<Error>(intError);
658 if (error != Error::None) {
659 return error;
660 }
661
662 std::vector<hwc2_layer_t> layerIds(numElements);
663 std::vector<int32_t> types(numElements);
664 intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
665 &numElements, layerIds.data(), types.data());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800666#else
667 std::vector<Hwc2::Layer> layerIds;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800668 std::vector<Hwc2::IComposerClient::Composition> types;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800669 auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800670 &layerIds, &types);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800671 uint32_t numElements = layerIds.size();
672 auto error = static_cast<Error>(intError);
673#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700674 error = static_cast<Error>(intError);
675 if (error != Error::None) {
676 return error;
677 }
678
679 outTypes->clear();
680 outTypes->reserve(numElements);
681 for (uint32_t element = 0; element < numElements; ++element) {
682 auto layer = getLayerById(layerIds[element]);
683 if (layer) {
684 auto type = static_cast<Composition>(types[element]);
685 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
686 layer->getId(), to_string(type).c_str());
687 outTypes->emplace(layer, type);
688 } else {
689 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
690 " on display %" PRIu64, layerIds[element], mId);
691 }
692 }
693
694 return Error::None;
695}
696
Michael Wright28f24d02016-07-12 13:30:53 -0700697Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
Dan Stoza076ac672016-03-14 10:47:53 -0700698{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800699#ifdef BYPASS_IHWC
Dan Stoza076ac672016-03-14 10:47:53 -0700700 uint32_t numModes = 0;
701 int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
702 &numModes, nullptr);
703 auto error = static_cast<Error>(intError);
704 if (error != Error::None) {
705 return error;
706 }
707
708 std::vector<int32_t> modes(numModes);
709 intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
710 modes.data());
711 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800712#else
713 std::vector<Hwc2::ColorMode> modes;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800714 auto intError = mDevice.mComposer->getColorModes(mId, &modes);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800715 uint32_t numModes = modes.size();
716 auto error = static_cast<Error>(intError);
717#endif
Dan Stoza076ac672016-03-14 10:47:53 -0700718 if (error != Error::None) {
719 return error;
720 }
721
Michael Wright28f24d02016-07-12 13:30:53 -0700722 outModes->resize(numModes);
723 for (size_t i = 0; i < numModes; i++) {
724 (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
725 }
Dan Stoza076ac672016-03-14 10:47:53 -0700726 return Error::None;
727}
728
Dan Stoza651bf312015-10-23 17:03:17 -0700729std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
730{
731 std::vector<std::shared_ptr<const Config>> configs;
732 for (const auto& element : mConfigs) {
733 configs.emplace_back(element.second);
734 }
735 return configs;
736}
737
738Error Display::getName(std::string* outName) const
739{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800740#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700741 uint32_t size;
742 int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
743 nullptr);
744 auto error = static_cast<Error>(intError);
745 if (error != Error::None) {
746 return error;
747 }
748
749 std::vector<char> rawName(size);
750 intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
751 rawName.data());
752 error = static_cast<Error>(intError);
753 if (error != Error::None) {
754 return error;
755 }
756
757 *outName = std::string(rawName.cbegin(), rawName.cend());
758 return Error::None;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800759#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800760 auto intError = mDevice.mComposer->getDisplayName(mId, outName);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800761 return static_cast<Error>(intError);
762#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700763}
764
765Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
766 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
767 outLayerRequests)
768{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800769#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700770 int32_t intDisplayRequests = 0;
771 uint32_t numElements = 0;
772 int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
773 &intDisplayRequests, &numElements, nullptr, nullptr);
774 auto error = static_cast<Error>(intError);
775 if (error != Error::None) {
776 return error;
777 }
778
779 std::vector<hwc2_layer_t> layerIds(numElements);
780 std::vector<int32_t> layerRequests(numElements);
781 intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
782 &intDisplayRequests, &numElements, layerIds.data(),
783 layerRequests.data());
784 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800785#else
786 uint32_t intDisplayRequests;
787 std::vector<Hwc2::Layer> layerIds;
788 std::vector<uint32_t> layerRequests;
789 auto intError = mDevice.mComposer->getDisplayRequests(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800790 &intDisplayRequests, &layerIds, &layerRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800791 uint32_t numElements = layerIds.size();
792 auto error = static_cast<Error>(intError);
793#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700794 if (error != Error::None) {
795 return error;
796 }
797
798 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
799 outLayerRequests->clear();
800 outLayerRequests->reserve(numElements);
801 for (uint32_t element = 0; element < numElements; ++element) {
802 auto layer = getLayerById(layerIds[element]);
803 if (layer) {
804 auto layerRequest =
805 static_cast<LayerRequest>(layerRequests[element]);
806 outLayerRequests->emplace(layer, layerRequest);
807 } else {
808 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
809 PRIu64, layerIds[element], mId);
810 }
811 }
812
813 return Error::None;
814}
815
816Error Display::getType(DisplayType* outType) const
817{
Chris Forbes016d73c2017-04-11 10:04:31 -0700818 *outType = mType;
Dan Stoza651bf312015-10-23 17:03:17 -0700819 return Error::None;
820}
821
822Error Display::supportsDoze(bool* outSupport) const
823{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800824#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700825 int32_t intSupport = 0;
826 int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
827 &intSupport);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800828#else
829 bool intSupport = false;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800830 auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800831#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700832 auto error = static_cast<Error>(intError);
833 if (error != Error::None) {
834 return error;
835 }
836 *outSupport = static_cast<bool>(intSupport);
837 return Error::None;
838}
839
Dan Stoza7d7ae732016-03-16 12:23:40 -0700840Error Display::getHdrCapabilities(
841 std::unique_ptr<HdrCapabilities>* outCapabilities) const
842{
843 uint32_t numTypes = 0;
844 float maxLuminance = -1.0f;
845 float maxAverageLuminance = -1.0f;
846 float minLuminance = -1.0f;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800847#ifdef BYPASS_IHWC
Dan Stoza7d7ae732016-03-16 12:23:40 -0700848 int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
849 &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
850 &minLuminance);
851 auto error = static_cast<HWC2::Error>(intError);
852 if (error != Error::None) {
853 return error;
854 }
855
856 std::vector<int32_t> types(numTypes);
857 intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
858 types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
859 error = static_cast<HWC2::Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800860#else
861 std::vector<Hwc2::Hdr> intTypes;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800862 auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes,
863 &maxLuminance, &maxAverageLuminance, &minLuminance);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800864 auto error = static_cast<HWC2::Error>(intError);
865
866 std::vector<int32_t> types;
867 for (auto type : intTypes) {
868 types.push_back(static_cast<int32_t>(type));
869 }
870 numTypes = types.size();
871#endif
Dan Stoza7d7ae732016-03-16 12:23:40 -0700872 if (error != Error::None) {
873 return error;
874 }
875
876 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
877 maxLuminance, maxAverageLuminance, minLuminance);
878 return Error::None;
879}
880
Dan Stoza651bf312015-10-23 17:03:17 -0700881Error Display::getReleaseFences(
882 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
883{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800884#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700885 uint32_t numElements = 0;
886 int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
887 &numElements, nullptr, nullptr);
888 auto error = static_cast<Error>(intError);
889 if (error != Error::None) {
890 return error;
891 }
892
893 std::vector<hwc2_layer_t> layerIds(numElements);
894 std::vector<int32_t> fenceFds(numElements);
895 intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
896 layerIds.data(), fenceFds.data());
897 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800898#else
899 std::vector<Hwc2::Layer> layerIds;
900 std::vector<int> fenceFds;
901 auto intError = mDevice.mComposer->getReleaseFences(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800902 &layerIds, &fenceFds);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800903 auto error = static_cast<Error>(intError);
904 uint32_t numElements = layerIds.size();
905#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700906 if (error != Error::None) {
907 return error;
908 }
909
910 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
911 releaseFences.reserve(numElements);
912 for (uint32_t element = 0; element < numElements; ++element) {
913 auto layer = getLayerById(layerIds[element]);
914 if (layer) {
915 sp<Fence> fence(new Fence(fenceFds[element]));
916 releaseFences.emplace(std::move(layer), fence);
917 } else {
918 ALOGE("getReleaseFences: invalid layer %" PRIu64
919 " found on display %" PRIu64, layerIds[element], mId);
920 return Error::BadLayer;
921 }
922 }
923
924 *outFences = std::move(releaseFences);
925 return Error::None;
926}
927
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800928Error Display::present(sp<Fence>* outPresentFence)
Dan Stoza651bf312015-10-23 17:03:17 -0700929{
Naseer Ahmed847650b2016-06-17 11:14:25 -0400930 int32_t presentFenceFd = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800931#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700932 int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800933 &presentFenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800934#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800935 auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800936#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700937 auto error = static_cast<Error>(intError);
938 if (error != Error::None) {
939 return error;
940 }
941
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800942 *outPresentFence = new Fence(presentFenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -0700943 return Error::None;
944}
945
946Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
947{
948 if (config->getDisplayId() != mId) {
949 ALOGE("setActiveConfig received config %u for the wrong display %"
950 PRIu64 " (expected %" PRIu64 ")", config->getId(),
951 config->getDisplayId(), mId);
952 return Error::BadConfig;
953 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800954#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700955 int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
956 config->getId());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800957#else
958 auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
959#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700960 return static_cast<Error>(intError);
961}
962
Chia-I Wu06d63de2017-01-04 14:58:51 +0800963Error Display::setClientTarget(uint32_t slot, buffer_handle_t target,
Dan Stoza651bf312015-10-23 17:03:17 -0700964 const sp<Fence>& acquireFence, android_dataspace_t dataspace)
965{
Dan Stoza5cf424b2016-05-20 14:02:39 -0700966 // TODO: Properly encode client target surface damage
Dan Stoza651bf312015-10-23 17:03:17 -0700967 int32_t fenceFd = acquireFence->dup();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800968#ifdef BYPASS_IHWC
Chia-I Wu06d63de2017-01-04 14:58:51 +0800969 (void) slot;
Dan Stoza651bf312015-10-23 17:03:17 -0700970 int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
Dan Stoza5cf424b2016-05-20 14:02:39 -0700971 fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
Chia-I Wuaab99f52016-10-05 12:59:58 +0800972#else
Chia-I Wu06d63de2017-01-04 14:58:51 +0800973 auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
974 fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800975 std::vector<Hwc2::IComposerClient::Rect>());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800976#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700977 return static_cast<Error>(intError);
978}
979
Michael Wright28f24d02016-07-12 13:30:53 -0700980Error Display::setColorMode(android_color_mode_t mode)
Dan Stoza076ac672016-03-14 10:47:53 -0700981{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800982#ifdef BYPASS_IHWC
Dan Stoza076ac672016-03-14 10:47:53 -0700983 int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800984#else
985 auto intError = mDevice.mComposer->setColorMode(mId,
986 static_cast<Hwc2::ColorMode>(mode));
987#endif
Dan Stoza076ac672016-03-14 10:47:53 -0700988 return static_cast<Error>(intError);
989}
990
Dan Stoza5df2a862016-03-24 16:19:37 -0700991Error Display::setColorTransform(const android::mat4& matrix,
992 android_color_transform_t hint)
993{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800994#ifdef BYPASS_IHWC
Dan Stoza5df2a862016-03-24 16:19:37 -0700995 int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
996 matrix.asArray(), static_cast<int32_t>(hint));
Chia-I Wuaab99f52016-10-05 12:59:58 +0800997#else
998 auto intError = mDevice.mComposer->setColorTransform(mId,
999 matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
1000#endif
Dan Stoza5df2a862016-03-24 16:19:37 -07001001 return static_cast<Error>(intError);
1002}
1003
Dan Stoza651bf312015-10-23 17:03:17 -07001004Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
1005 const sp<Fence>& releaseFence)
1006{
1007 int32_t fenceFd = releaseFence->dup();
1008 auto handle = buffer->getNativeBuffer()->handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001009#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001010 int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
1011 fenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001012#else
1013 auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
1014#endif
Dan Stoza38628982016-07-13 15:48:58 -07001015 close(fenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -07001016 return static_cast<Error>(intError);
1017}
1018
1019Error Display::setPowerMode(PowerMode mode)
1020{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001021#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001022 auto intMode = static_cast<int32_t>(mode);
1023 int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001024#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001025 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001026 auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
1027#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001028 return static_cast<Error>(intError);
1029}
1030
1031Error Display::setVsyncEnabled(Vsync enabled)
1032{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001033#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001034 auto intEnabled = static_cast<int32_t>(enabled);
1035 int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
1036 intEnabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001037#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001038 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001039 auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
1040#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001041 return static_cast<Error>(intError);
1042}
1043
1044Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
1045{
1046 uint32_t numTypes = 0;
1047 uint32_t numRequests = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001048#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001049 int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
1050 &numTypes, &numRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001051#else
1052 auto intError = mDevice.mComposer->validateDisplay(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001053 &numTypes, &numRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001054#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001055 auto error = static_cast<Error>(intError);
1056 if (error != Error::None && error != Error::HasChanges) {
1057 return error;
1058 }
1059
1060 *outNumTypes = numTypes;
1061 *outNumRequests = numRequests;
1062 return error;
1063}
1064
1065// For use by Device
1066
1067int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
1068{
1069 int32_t value = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001070#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001071 int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
1072 configId, static_cast<int32_t>(attribute), &value);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001073#else
Chia-I Wu67e376d2016-12-19 11:36:22 +08001074 auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId,
1075 static_cast<Hwc2::IComposerClient::Attribute>(attribute),
1076 &value);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001077#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001078 auto error = static_cast<Error>(intError);
1079 if (error != Error::None) {
1080 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
1081 configId, to_string(attribute).c_str(),
1082 to_string(error).c_str(), intError);
1083 return -1;
1084 }
1085 return value;
1086}
1087
1088void Display::loadConfig(hwc2_config_t configId)
1089{
1090 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
1091
1092 auto config = Config::Builder(*this, configId)
1093 .setWidth(getAttribute(configId, Attribute::Width))
1094 .setHeight(getAttribute(configId, Attribute::Height))
1095 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
1096 .setDpiX(getAttribute(configId, Attribute::DpiX))
1097 .setDpiY(getAttribute(configId, Attribute::DpiY))
1098 .build();
1099 mConfigs.emplace(configId, std::move(config));
1100}
1101
1102void Display::loadConfigs()
1103{
1104 ALOGV("[%" PRIu64 "] loadConfigs", mId);
1105
Chia-I Wuaab99f52016-10-05 12:59:58 +08001106#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001107 uint32_t numConfigs = 0;
1108 int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
1109 &numConfigs, nullptr);
1110 auto error = static_cast<Error>(intError);
1111 if (error != Error::None) {
1112 ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
1113 to_string(error).c_str(), intError);
1114 return;
1115 }
1116
1117 std::vector<hwc2_config_t> configIds(numConfigs);
1118 intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
1119 configIds.data());
1120 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001121#else
1122 std::vector<Hwc2::Config> configIds;
Chia-I Wu67e376d2016-12-19 11:36:22 +08001123 auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001124 auto error = static_cast<Error>(intError);
1125#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001126 if (error != Error::None) {
1127 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
1128 to_string(error).c_str(), intError);
1129 return;
1130 }
1131
1132 for (auto configId : configIds) {
1133 loadConfig(configId);
1134 }
1135}
1136
1137// For use by Layer
1138
1139void Display::destroyLayer(hwc2_layer_t layerId)
1140{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001141#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001142 int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001143#else
1144 auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
1145#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001146 auto error = static_cast<Error>(intError);
1147 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
1148 " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
1149 intError);
1150 mLayers.erase(layerId);
1151}
1152
1153// Other Display methods
1154
1155std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
1156{
1157 if (mLayers.count(id) == 0) {
1158 return nullptr;
1159 }
1160
1161 auto layer = mLayers.at(id).lock();
1162 return layer;
1163}
1164
1165// Layer methods
1166
1167Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
1168 : mDisplay(display),
1169 mDisplayId(display->getId()),
1170 mDevice(display->getDevice()),
1171 mId(id)
1172{
1173 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
1174 display->getId());
1175}
1176
1177Layer::~Layer()
1178{
1179 auto display = mDisplay.lock();
1180 if (display) {
1181 display->destroyLayer(mId);
1182 }
1183}
1184
1185Error Layer::setCursorPosition(int32_t x, int32_t y)
1186{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001187#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001188 int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
1189 mDisplayId, mId, x, y);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001190#else
1191 auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
1192 mId, x, y);
1193#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001194 return static_cast<Error>(intError);
1195}
1196
Chia-I Wu06d63de2017-01-04 14:58:51 +08001197Error Layer::setBuffer(uint32_t slot, buffer_handle_t buffer,
Dan Stoza651bf312015-10-23 17:03:17 -07001198 const sp<Fence>& acquireFence)
1199{
1200 int32_t fenceFd = acquireFence->dup();
Chia-I Wuaab99f52016-10-05 12:59:58 +08001201#ifdef BYPASS_IHWC
Chia-I Wu06d63de2017-01-04 14:58:51 +08001202 (void) slot;
Dan Stoza651bf312015-10-23 17:03:17 -07001203 int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
1204 mId, buffer, fenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001205#else
1206 auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
Chia-I Wu06d63de2017-01-04 14:58:51 +08001207 mId, slot, buffer, fenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001208#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001209 return static_cast<Error>(intError);
1210}
1211
1212Error Layer::setSurfaceDamage(const Region& damage)
1213{
1214 // We encode default full-screen damage as INVALID_RECT upstream, but as 0
1215 // rects for HWC
Chia-I Wuaab99f52016-10-05 12:59:58 +08001216#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001217 int32_t intError = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001218#else
1219 Hwc2::Error intError = Hwc2::Error::NONE;
1220#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001221 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
Chia-I Wuaab99f52016-10-05 12:59:58 +08001222#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001223 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1224 mDisplayId, mId, {0, nullptr});
Chia-I Wuaab99f52016-10-05 12:59:58 +08001225#else
1226 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001227 mId, std::vector<Hwc2::IComposerClient::Rect>());
Chia-I Wuaab99f52016-10-05 12:59:58 +08001228#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001229 } else {
1230 size_t rectCount = 0;
1231 auto rectArray = damage.getArray(&rectCount);
1232
Chia-I Wuaab99f52016-10-05 12:59:58 +08001233#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001234 std::vector<hwc_rect_t> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001235#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001236 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001237#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001238 for (size_t rect = 0; rect < rectCount; ++rect) {
1239 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1240 rectArray[rect].right, rectArray[rect].bottom});
1241 }
1242
Chia-I Wuaab99f52016-10-05 12:59:58 +08001243#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001244 hwc_region_t hwcRegion = {};
1245 hwcRegion.numRects = rectCount;
1246 hwcRegion.rects = hwcRects.data();
1247
1248 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1249 mDisplayId, mId, hwcRegion);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001250#else
1251 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
1252 mId, hwcRects);
1253#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001254 }
1255
1256 return static_cast<Error>(intError);
1257}
1258
1259Error Layer::setBlendMode(BlendMode mode)
1260{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001261#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001262 auto intMode = static_cast<int32_t>(mode);
1263 int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
1264 mDisplayId, mId, intMode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001265#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001266 auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001267 auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
1268 mId, intMode);
1269#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001270 return static_cast<Error>(intError);
1271}
1272
1273Error Layer::setColor(hwc_color_t color)
1274{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001275#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001276 int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
1277 mId, color);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001278#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001279 Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
Chia-I Wuaab99f52016-10-05 12:59:58 +08001280 auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
1281 mId, hwcColor);
1282#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001283 return static_cast<Error>(intError);
1284}
1285
1286Error Layer::setCompositionType(Composition type)
1287{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001288#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001289 auto intType = static_cast<int32_t>(type);
1290 int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
1291 mDisplayId, mId, intType);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001292#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001293 auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001294 auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
1295 mId, intType);
1296#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001297 return static_cast<Error>(intError);
1298}
1299
Dan Stoza5df2a862016-03-24 16:19:37 -07001300Error Layer::setDataspace(android_dataspace_t dataspace)
1301{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001302#ifdef BYPASS_IHWC
Dan Stoza5df2a862016-03-24 16:19:37 -07001303 auto intDataspace = static_cast<int32_t>(dataspace);
1304 int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
1305 mDisplayId, mId, intDataspace);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001306#else
1307 auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
1308 auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
1309 mId, intDataspace);
1310#endif
Dan Stoza5df2a862016-03-24 16:19:37 -07001311 return static_cast<Error>(intError);
1312}
1313
Dan Stoza651bf312015-10-23 17:03:17 -07001314Error Layer::setDisplayFrame(const Rect& frame)
1315{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001316#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001317 hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
1318 int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
1319 mDisplayId, mId, hwcRect);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001320#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001321 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
Chia-I Wuaab99f52016-10-05 12:59:58 +08001322 frame.right, frame.bottom};
1323 auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
1324 mId, hwcRect);
1325#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001326 return static_cast<Error>(intError);
1327}
1328
1329Error Layer::setPlaneAlpha(float alpha)
1330{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001331#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001332 int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
1333 mDisplayId, mId, alpha);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001334#else
1335 auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
1336 mId, alpha);
1337#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001338 return static_cast<Error>(intError);
1339}
1340
1341Error Layer::setSidebandStream(const native_handle_t* stream)
1342{
Dan Stoza09e7a272016-04-14 12:31:01 -07001343 if (!mDevice.hasCapability(Capability::SidebandStream)) {
1344 ALOGE("Attempted to call setSidebandStream without checking that the "
1345 "device supports sideband streams");
1346 return Error::Unsupported;
1347 }
Chia-I Wuaab99f52016-10-05 12:59:58 +08001348#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001349 int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1350 mDisplayId, mId, stream);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001351#else
1352 auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
1353 mId, stream);
1354#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001355 return static_cast<Error>(intError);
1356}
1357
1358Error Layer::setSourceCrop(const FloatRect& crop)
1359{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001360#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001361 hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
1362 int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
1363 mDisplayId, mId, hwcRect);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001364#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001365 Hwc2::IComposerClient::FRect hwcRect{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001366 crop.left, crop.top, crop.right, crop.bottom};
1367 auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
1368 mId, hwcRect);
1369#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001370 return static_cast<Error>(intError);
1371}
1372
1373Error Layer::setTransform(Transform transform)
1374{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001375#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001376 auto intTransform = static_cast<int32_t>(transform);
1377 int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
1378 mDisplayId, mId, intTransform);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001379#else
1380 auto intTransform = static_cast<Hwc2::Transform>(transform);
1381 auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
1382 mId, intTransform);
1383#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001384 return static_cast<Error>(intError);
1385}
1386
1387Error Layer::setVisibleRegion(const Region& region)
1388{
1389 size_t rectCount = 0;
1390 auto rectArray = region.getArray(&rectCount);
1391
Chia-I Wuaab99f52016-10-05 12:59:58 +08001392#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001393 std::vector<hwc_rect_t> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001394#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001395 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001396#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001397 for (size_t rect = 0; rect < rectCount; ++rect) {
1398 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1399 rectArray[rect].right, rectArray[rect].bottom});
1400 }
1401
Chia-I Wuaab99f52016-10-05 12:59:58 +08001402#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001403 hwc_region_t hwcRegion = {};
1404 hwcRegion.numRects = rectCount;
1405 hwcRegion.rects = hwcRects.data();
1406
1407 int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
1408 mDisplayId, mId, hwcRegion);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001409#else
1410 auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
1411 mId, hwcRects);
1412#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001413 return static_cast<Error>(intError);
1414}
1415
1416Error Layer::setZOrder(uint32_t z)
1417{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001418#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001419 int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
1420 mId, z);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001421#else
1422 auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
1423#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001424 return static_cast<Error>(intError);
1425}
1426
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -05001427Error Layer::setInfo(uint32_t type, uint32_t appId)
1428{
1429#ifdef BYPASS_IHWC
1430 (void)type;
1431 (void)appId;
1432 int32_t intError = 0;
1433#else
1434 auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId);
1435#endif
1436 return static_cast<Error>(intError);
1437}
1438
Dan Stoza651bf312015-10-23 17:03:17 -07001439} // namespace HWC2