blob: 402009a45c05c3d74bdb755c1ee1f92f5250c75a [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 }
Dan Stoza651bf312015-10-23 17:03:17 -0700247 (*outDisplay)->setVirtual();
248 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 mIsVirtual(false),
535 mType(DisplayType::Invalid)
Dan Stoza651bf312015-10-23 17:03:17 -0700536{
537 ALOGV("Created display %" PRIu64, id);
Chris Forbes016d73c2017-04-11 10:04:31 -0700538
539#ifdef BYPASS_IHWC
540 int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
541 reinterpret_cast<int32_t *>(&mType));
542#else
543 auto intError = mDevice.mComposer->getDisplayType(mId,
544 reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType));
545#endif
546 auto error = static_cast<Error>(intError);
547 if (error != Error::None) {
548 ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)",
549 id, to_string(error).c_str(), intError);
550 }
Dan Stoza651bf312015-10-23 17:03:17 -0700551}
552
553Display::~Display()
554{
555 ALOGV("Destroyed display %" PRIu64, mId);
556 if (mIsVirtual) {
557 mDevice.destroyVirtualDisplay(mId);
558 }
559}
560
561Display::Config::Config(Display& display, hwc2_config_t id)
562 : mDisplay(display),
563 mId(id),
564 mWidth(-1),
565 mHeight(-1),
566 mVsyncPeriod(-1),
567 mDpiX(-1),
568 mDpiY(-1) {}
569
570Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
571 : mConfig(new Config(display, id)) {}
572
573float Display::Config::Builder::getDefaultDensity() {
574 // Default density is based on TVs: 1080p displays get XHIGH density, lower-
575 // resolution displays get TV density. Maybe eventually we'll need to update
576 // it for 4k displays, though hopefully those will just report accurate DPI
577 // information to begin with. This is also used for virtual displays and
578 // older HWC implementations, so be careful about orientation.
579
580 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
581 if (longDimension >= 1080) {
582 return ACONFIGURATION_DENSITY_XHIGH;
583 } else {
584 return ACONFIGURATION_DENSITY_TV;
585 }
586}
587
588// Required by HWC2 display
589
590Error Display::acceptChanges()
591{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800592#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700593 int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800594#else
595 auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
596#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700597 return static_cast<Error>(intError);
598}
599
600Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
601{
602 hwc2_layer_t layerId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800603#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700604 int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800605#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800606 auto intError = mDevice.mComposer->createLayer(mId, &layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800607#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700608 auto error = static_cast<Error>(intError);
609 if (error != Error::None) {
610 return error;
611 }
612
613 auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
614 mLayers.emplace(layerId, layer);
615 *outLayer = std::move(layer);
616 return Error::None;
617}
618
619Error Display::getActiveConfig(
620 std::shared_ptr<const Display::Config>* outConfig) const
621{
622 ALOGV("[%" PRIu64 "] getActiveConfig", mId);
623 hwc2_config_t configId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800624#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700625 int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
626 &configId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800627#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800628 auto intError = mDevice.mComposer->getActiveConfig(mId, &configId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800629#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700630 auto error = static_cast<Error>(intError);
631
632 if (error != Error::None) {
Fabien Sanglardb7432cc2016-11-11 09:40:27 -0800633 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
634 *outConfig = nullptr;
Dan Stoza651bf312015-10-23 17:03:17 -0700635 return error;
636 }
637
638 if (mConfigs.count(configId) != 0) {
639 *outConfig = mConfigs.at(configId);
640 } else {
641 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
642 configId);
643 // Return no error, but the caller needs to check for a null pointer to
644 // detect this case
645 *outConfig = nullptr;
646 }
647
648 return Error::None;
649}
650
651Error Display::getChangedCompositionTypes(
652 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
653{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800654#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700655 uint32_t numElements = 0;
656 int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
657 mId, &numElements, nullptr, nullptr);
658 auto error = static_cast<Error>(intError);
659 if (error != Error::None) {
660 return error;
661 }
662
663 std::vector<hwc2_layer_t> layerIds(numElements);
664 std::vector<int32_t> types(numElements);
665 intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
666 &numElements, layerIds.data(), types.data());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800667#else
668 std::vector<Hwc2::Layer> layerIds;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800669 std::vector<Hwc2::IComposerClient::Composition> types;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800670 auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800671 &layerIds, &types);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800672 uint32_t numElements = layerIds.size();
673 auto error = static_cast<Error>(intError);
674#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700675 error = static_cast<Error>(intError);
676 if (error != Error::None) {
677 return error;
678 }
679
680 outTypes->clear();
681 outTypes->reserve(numElements);
682 for (uint32_t element = 0; element < numElements; ++element) {
683 auto layer = getLayerById(layerIds[element]);
684 if (layer) {
685 auto type = static_cast<Composition>(types[element]);
686 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
687 layer->getId(), to_string(type).c_str());
688 outTypes->emplace(layer, type);
689 } else {
690 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
691 " on display %" PRIu64, layerIds[element], mId);
692 }
693 }
694
695 return Error::None;
696}
697
Michael Wright28f24d02016-07-12 13:30:53 -0700698Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
Dan Stoza076ac672016-03-14 10:47:53 -0700699{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800700#ifdef BYPASS_IHWC
Dan Stoza076ac672016-03-14 10:47:53 -0700701 uint32_t numModes = 0;
702 int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
703 &numModes, nullptr);
704 auto error = static_cast<Error>(intError);
705 if (error != Error::None) {
706 return error;
707 }
708
709 std::vector<int32_t> modes(numModes);
710 intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
711 modes.data());
712 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800713#else
714 std::vector<Hwc2::ColorMode> modes;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800715 auto intError = mDevice.mComposer->getColorModes(mId, &modes);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800716 uint32_t numModes = modes.size();
717 auto error = static_cast<Error>(intError);
718#endif
Dan Stoza076ac672016-03-14 10:47:53 -0700719 if (error != Error::None) {
720 return error;
721 }
722
Michael Wright28f24d02016-07-12 13:30:53 -0700723 outModes->resize(numModes);
724 for (size_t i = 0; i < numModes; i++) {
725 (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
726 }
Dan Stoza076ac672016-03-14 10:47:53 -0700727 return Error::None;
728}
729
Dan Stoza651bf312015-10-23 17:03:17 -0700730std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
731{
732 std::vector<std::shared_ptr<const Config>> configs;
733 for (const auto& element : mConfigs) {
734 configs.emplace_back(element.second);
735 }
736 return configs;
737}
738
739Error Display::getName(std::string* outName) const
740{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800741#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700742 uint32_t size;
743 int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
744 nullptr);
745 auto error = static_cast<Error>(intError);
746 if (error != Error::None) {
747 return error;
748 }
749
750 std::vector<char> rawName(size);
751 intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
752 rawName.data());
753 error = static_cast<Error>(intError);
754 if (error != Error::None) {
755 return error;
756 }
757
758 *outName = std::string(rawName.cbegin(), rawName.cend());
759 return Error::None;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800760#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800761 auto intError = mDevice.mComposer->getDisplayName(mId, outName);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800762 return static_cast<Error>(intError);
763#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700764}
765
766Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
767 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
768 outLayerRequests)
769{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800770#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700771 int32_t intDisplayRequests = 0;
772 uint32_t numElements = 0;
773 int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
774 &intDisplayRequests, &numElements, nullptr, nullptr);
775 auto error = static_cast<Error>(intError);
776 if (error != Error::None) {
777 return error;
778 }
779
780 std::vector<hwc2_layer_t> layerIds(numElements);
781 std::vector<int32_t> layerRequests(numElements);
782 intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
783 &intDisplayRequests, &numElements, layerIds.data(),
784 layerRequests.data());
785 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800786#else
787 uint32_t intDisplayRequests;
788 std::vector<Hwc2::Layer> layerIds;
789 std::vector<uint32_t> layerRequests;
790 auto intError = mDevice.mComposer->getDisplayRequests(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800791 &intDisplayRequests, &layerIds, &layerRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800792 uint32_t numElements = layerIds.size();
793 auto error = static_cast<Error>(intError);
794#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700795 if (error != Error::None) {
796 return error;
797 }
798
799 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
800 outLayerRequests->clear();
801 outLayerRequests->reserve(numElements);
802 for (uint32_t element = 0; element < numElements; ++element) {
803 auto layer = getLayerById(layerIds[element]);
804 if (layer) {
805 auto layerRequest =
806 static_cast<LayerRequest>(layerRequests[element]);
807 outLayerRequests->emplace(layer, layerRequest);
808 } else {
809 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
810 PRIu64, layerIds[element], mId);
811 }
812 }
813
814 return Error::None;
815}
816
817Error Display::getType(DisplayType* outType) const
818{
Chris Forbes016d73c2017-04-11 10:04:31 -0700819 *outType = mType;
Dan Stoza651bf312015-10-23 17:03:17 -0700820 return Error::None;
821}
822
823Error Display::supportsDoze(bool* outSupport) const
824{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800825#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700826 int32_t intSupport = 0;
827 int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
828 &intSupport);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800829#else
830 bool intSupport = false;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800831 auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800832#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700833 auto error = static_cast<Error>(intError);
834 if (error != Error::None) {
835 return error;
836 }
837 *outSupport = static_cast<bool>(intSupport);
838 return Error::None;
839}
840
Dan Stoza7d7ae732016-03-16 12:23:40 -0700841Error Display::getHdrCapabilities(
842 std::unique_ptr<HdrCapabilities>* outCapabilities) const
843{
844 uint32_t numTypes = 0;
845 float maxLuminance = -1.0f;
846 float maxAverageLuminance = -1.0f;
847 float minLuminance = -1.0f;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800848#ifdef BYPASS_IHWC
Dan Stoza7d7ae732016-03-16 12:23:40 -0700849 int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
850 &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
851 &minLuminance);
852 auto error = static_cast<HWC2::Error>(intError);
853 if (error != Error::None) {
854 return error;
855 }
856
857 std::vector<int32_t> types(numTypes);
858 intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
859 types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
860 error = static_cast<HWC2::Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800861#else
862 std::vector<Hwc2::Hdr> intTypes;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800863 auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes,
864 &maxLuminance, &maxAverageLuminance, &minLuminance);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800865 auto error = static_cast<HWC2::Error>(intError);
866
867 std::vector<int32_t> types;
868 for (auto type : intTypes) {
869 types.push_back(static_cast<int32_t>(type));
870 }
871 numTypes = types.size();
872#endif
Dan Stoza7d7ae732016-03-16 12:23:40 -0700873 if (error != Error::None) {
874 return error;
875 }
876
877 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
878 maxLuminance, maxAverageLuminance, minLuminance);
879 return Error::None;
880}
881
Dan Stoza651bf312015-10-23 17:03:17 -0700882Error Display::getReleaseFences(
883 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
884{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800885#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700886 uint32_t numElements = 0;
887 int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
888 &numElements, nullptr, nullptr);
889 auto error = static_cast<Error>(intError);
890 if (error != Error::None) {
891 return error;
892 }
893
894 std::vector<hwc2_layer_t> layerIds(numElements);
895 std::vector<int32_t> fenceFds(numElements);
896 intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
897 layerIds.data(), fenceFds.data());
898 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800899#else
900 std::vector<Hwc2::Layer> layerIds;
901 std::vector<int> fenceFds;
902 auto intError = mDevice.mComposer->getReleaseFences(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800903 &layerIds, &fenceFds);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800904 auto error = static_cast<Error>(intError);
905 uint32_t numElements = layerIds.size();
906#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700907 if (error != Error::None) {
908 return error;
909 }
910
911 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
912 releaseFences.reserve(numElements);
913 for (uint32_t element = 0; element < numElements; ++element) {
914 auto layer = getLayerById(layerIds[element]);
915 if (layer) {
916 sp<Fence> fence(new Fence(fenceFds[element]));
917 releaseFences.emplace(std::move(layer), fence);
918 } else {
919 ALOGE("getReleaseFences: invalid layer %" PRIu64
920 " found on display %" PRIu64, layerIds[element], mId);
921 return Error::BadLayer;
922 }
923 }
924
925 *outFences = std::move(releaseFences);
926 return Error::None;
927}
928
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800929Error Display::present(sp<Fence>* outPresentFence)
Dan Stoza651bf312015-10-23 17:03:17 -0700930{
Naseer Ahmed847650b2016-06-17 11:14:25 -0400931 int32_t presentFenceFd = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800932#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700933 int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800934 &presentFenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800935#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800936 auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800937#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700938 auto error = static_cast<Error>(intError);
939 if (error != Error::None) {
940 return error;
941 }
942
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800943 *outPresentFence = new Fence(presentFenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -0700944 return Error::None;
945}
946
947Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
948{
949 if (config->getDisplayId() != mId) {
950 ALOGE("setActiveConfig received config %u for the wrong display %"
951 PRIu64 " (expected %" PRIu64 ")", config->getId(),
952 config->getDisplayId(), mId);
953 return Error::BadConfig;
954 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800955#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700956 int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
957 config->getId());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800958#else
959 auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
960#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700961 return static_cast<Error>(intError);
962}
963
Chia-I Wu06d63de2017-01-04 14:58:51 +0800964Error Display::setClientTarget(uint32_t slot, buffer_handle_t target,
Dan Stoza651bf312015-10-23 17:03:17 -0700965 const sp<Fence>& acquireFence, android_dataspace_t dataspace)
966{
Dan Stoza5cf424b2016-05-20 14:02:39 -0700967 // TODO: Properly encode client target surface damage
Dan Stoza651bf312015-10-23 17:03:17 -0700968 int32_t fenceFd = acquireFence->dup();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800969#ifdef BYPASS_IHWC
Chia-I Wu06d63de2017-01-04 14:58:51 +0800970 (void) slot;
Dan Stoza651bf312015-10-23 17:03:17 -0700971 int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
Dan Stoza5cf424b2016-05-20 14:02:39 -0700972 fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
Chia-I Wuaab99f52016-10-05 12:59:58 +0800973#else
Chia-I Wu06d63de2017-01-04 14:58:51 +0800974 auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
975 fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800976 std::vector<Hwc2::IComposerClient::Rect>());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800977#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700978 return static_cast<Error>(intError);
979}
980
Michael Wright28f24d02016-07-12 13:30:53 -0700981Error Display::setColorMode(android_color_mode_t mode)
Dan Stoza076ac672016-03-14 10:47:53 -0700982{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800983#ifdef BYPASS_IHWC
Dan Stoza076ac672016-03-14 10:47:53 -0700984 int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800985#else
986 auto intError = mDevice.mComposer->setColorMode(mId,
987 static_cast<Hwc2::ColorMode>(mode));
988#endif
Dan Stoza076ac672016-03-14 10:47:53 -0700989 return static_cast<Error>(intError);
990}
991
Dan Stoza5df2a862016-03-24 16:19:37 -0700992Error Display::setColorTransform(const android::mat4& matrix,
993 android_color_transform_t hint)
994{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800995#ifdef BYPASS_IHWC
Dan Stoza5df2a862016-03-24 16:19:37 -0700996 int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
997 matrix.asArray(), static_cast<int32_t>(hint));
Chia-I Wuaab99f52016-10-05 12:59:58 +0800998#else
999 auto intError = mDevice.mComposer->setColorTransform(mId,
1000 matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
1001#endif
Dan Stoza5df2a862016-03-24 16:19:37 -07001002 return static_cast<Error>(intError);
1003}
1004
Dan Stoza651bf312015-10-23 17:03:17 -07001005Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
1006 const sp<Fence>& releaseFence)
1007{
1008 int32_t fenceFd = releaseFence->dup();
1009 auto handle = buffer->getNativeBuffer()->handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001010#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001011 int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
1012 fenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001013#else
1014 auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
1015#endif
Dan Stoza38628982016-07-13 15:48:58 -07001016 close(fenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -07001017 return static_cast<Error>(intError);
1018}
1019
1020Error Display::setPowerMode(PowerMode mode)
1021{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001022#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001023 auto intMode = static_cast<int32_t>(mode);
1024 int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001025#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001026 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001027 auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
1028#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001029 return static_cast<Error>(intError);
1030}
1031
1032Error Display::setVsyncEnabled(Vsync enabled)
1033{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001034#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001035 auto intEnabled = static_cast<int32_t>(enabled);
1036 int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
1037 intEnabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001038#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001039 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001040 auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
1041#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001042 return static_cast<Error>(intError);
1043}
1044
1045Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
1046{
1047 uint32_t numTypes = 0;
1048 uint32_t numRequests = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001049#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001050 int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
1051 &numTypes, &numRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001052#else
1053 auto intError = mDevice.mComposer->validateDisplay(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001054 &numTypes, &numRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001055#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001056 auto error = static_cast<Error>(intError);
1057 if (error != Error::None && error != Error::HasChanges) {
1058 return error;
1059 }
1060
1061 *outNumTypes = numTypes;
1062 *outNumRequests = numRequests;
1063 return error;
1064}
1065
1066// For use by Device
1067
1068int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
1069{
1070 int32_t value = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001071#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001072 int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
1073 configId, static_cast<int32_t>(attribute), &value);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001074#else
Chia-I Wu67e376d2016-12-19 11:36:22 +08001075 auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId,
1076 static_cast<Hwc2::IComposerClient::Attribute>(attribute),
1077 &value);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001078#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001079 auto error = static_cast<Error>(intError);
1080 if (error != Error::None) {
1081 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
1082 configId, to_string(attribute).c_str(),
1083 to_string(error).c_str(), intError);
1084 return -1;
1085 }
1086 return value;
1087}
1088
1089void Display::loadConfig(hwc2_config_t configId)
1090{
1091 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
1092
1093 auto config = Config::Builder(*this, configId)
1094 .setWidth(getAttribute(configId, Attribute::Width))
1095 .setHeight(getAttribute(configId, Attribute::Height))
1096 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
1097 .setDpiX(getAttribute(configId, Attribute::DpiX))
1098 .setDpiY(getAttribute(configId, Attribute::DpiY))
1099 .build();
1100 mConfigs.emplace(configId, std::move(config));
1101}
1102
1103void Display::loadConfigs()
1104{
1105 ALOGV("[%" PRIu64 "] loadConfigs", mId);
1106
Chia-I Wuaab99f52016-10-05 12:59:58 +08001107#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001108 uint32_t numConfigs = 0;
1109 int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
1110 &numConfigs, nullptr);
1111 auto error = static_cast<Error>(intError);
1112 if (error != Error::None) {
1113 ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
1114 to_string(error).c_str(), intError);
1115 return;
1116 }
1117
1118 std::vector<hwc2_config_t> configIds(numConfigs);
1119 intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
1120 configIds.data());
1121 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001122#else
1123 std::vector<Hwc2::Config> configIds;
Chia-I Wu67e376d2016-12-19 11:36:22 +08001124 auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001125 auto error = static_cast<Error>(intError);
1126#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001127 if (error != Error::None) {
1128 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
1129 to_string(error).c_str(), intError);
1130 return;
1131 }
1132
1133 for (auto configId : configIds) {
1134 loadConfig(configId);
1135 }
1136}
1137
1138// For use by Layer
1139
1140void Display::destroyLayer(hwc2_layer_t layerId)
1141{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001142#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001143 int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001144#else
1145 auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
1146#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001147 auto error = static_cast<Error>(intError);
1148 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
1149 " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
1150 intError);
1151 mLayers.erase(layerId);
1152}
1153
1154// Other Display methods
1155
1156std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
1157{
1158 if (mLayers.count(id) == 0) {
1159 return nullptr;
1160 }
1161
1162 auto layer = mLayers.at(id).lock();
1163 return layer;
1164}
1165
1166// Layer methods
1167
1168Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
1169 : mDisplay(display),
1170 mDisplayId(display->getId()),
1171 mDevice(display->getDevice()),
1172 mId(id)
1173{
1174 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
1175 display->getId());
1176}
1177
1178Layer::~Layer()
1179{
1180 auto display = mDisplay.lock();
1181 if (display) {
1182 display->destroyLayer(mId);
1183 }
1184}
1185
1186Error Layer::setCursorPosition(int32_t x, int32_t y)
1187{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001188#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001189 int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
1190 mDisplayId, mId, x, y);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001191#else
1192 auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
1193 mId, x, y);
1194#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001195 return static_cast<Error>(intError);
1196}
1197
Chia-I Wu06d63de2017-01-04 14:58:51 +08001198Error Layer::setBuffer(uint32_t slot, buffer_handle_t buffer,
Dan Stoza651bf312015-10-23 17:03:17 -07001199 const sp<Fence>& acquireFence)
1200{
1201 int32_t fenceFd = acquireFence->dup();
Chia-I Wuaab99f52016-10-05 12:59:58 +08001202#ifdef BYPASS_IHWC
Chia-I Wu06d63de2017-01-04 14:58:51 +08001203 (void) slot;
Dan Stoza651bf312015-10-23 17:03:17 -07001204 int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
1205 mId, buffer, fenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001206#else
1207 auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
Chia-I Wu06d63de2017-01-04 14:58:51 +08001208 mId, slot, buffer, fenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001209#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001210 return static_cast<Error>(intError);
1211}
1212
1213Error Layer::setSurfaceDamage(const Region& damage)
1214{
1215 // We encode default full-screen damage as INVALID_RECT upstream, but as 0
1216 // rects for HWC
Chia-I Wuaab99f52016-10-05 12:59:58 +08001217#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001218 int32_t intError = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001219#else
1220 Hwc2::Error intError = Hwc2::Error::NONE;
1221#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001222 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
Chia-I Wuaab99f52016-10-05 12:59:58 +08001223#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001224 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1225 mDisplayId, mId, {0, nullptr});
Chia-I Wuaab99f52016-10-05 12:59:58 +08001226#else
1227 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001228 mId, std::vector<Hwc2::IComposerClient::Rect>());
Chia-I Wuaab99f52016-10-05 12:59:58 +08001229#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001230 } else {
1231 size_t rectCount = 0;
1232 auto rectArray = damage.getArray(&rectCount);
1233
Chia-I Wuaab99f52016-10-05 12:59:58 +08001234#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001235 std::vector<hwc_rect_t> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001236#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001237 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001238#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001239 for (size_t rect = 0; rect < rectCount; ++rect) {
1240 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1241 rectArray[rect].right, rectArray[rect].bottom});
1242 }
1243
Chia-I Wuaab99f52016-10-05 12:59:58 +08001244#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001245 hwc_region_t hwcRegion = {};
1246 hwcRegion.numRects = rectCount;
1247 hwcRegion.rects = hwcRects.data();
1248
1249 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1250 mDisplayId, mId, hwcRegion);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001251#else
1252 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
1253 mId, hwcRects);
1254#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001255 }
1256
1257 return static_cast<Error>(intError);
1258}
1259
1260Error Layer::setBlendMode(BlendMode mode)
1261{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001262#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001263 auto intMode = static_cast<int32_t>(mode);
1264 int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
1265 mDisplayId, mId, intMode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001266#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001267 auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001268 auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
1269 mId, intMode);
1270#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001271 return static_cast<Error>(intError);
1272}
1273
1274Error Layer::setColor(hwc_color_t color)
1275{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001276#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001277 int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
1278 mId, color);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001279#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001280 Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
Chia-I Wuaab99f52016-10-05 12:59:58 +08001281 auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
1282 mId, hwcColor);
1283#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001284 return static_cast<Error>(intError);
1285}
1286
1287Error Layer::setCompositionType(Composition type)
1288{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001289#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001290 auto intType = static_cast<int32_t>(type);
1291 int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
1292 mDisplayId, mId, intType);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001293#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001294 auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001295 auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
1296 mId, intType);
1297#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001298 return static_cast<Error>(intError);
1299}
1300
Dan Stoza5df2a862016-03-24 16:19:37 -07001301Error Layer::setDataspace(android_dataspace_t dataspace)
1302{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001303#ifdef BYPASS_IHWC
Dan Stoza5df2a862016-03-24 16:19:37 -07001304 auto intDataspace = static_cast<int32_t>(dataspace);
1305 int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
1306 mDisplayId, mId, intDataspace);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001307#else
1308 auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
1309 auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
1310 mId, intDataspace);
1311#endif
Dan Stoza5df2a862016-03-24 16:19:37 -07001312 return static_cast<Error>(intError);
1313}
1314
Dan Stoza651bf312015-10-23 17:03:17 -07001315Error Layer::setDisplayFrame(const Rect& frame)
1316{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001317#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001318 hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
1319 int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
1320 mDisplayId, mId, hwcRect);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001321#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001322 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
Chia-I Wuaab99f52016-10-05 12:59:58 +08001323 frame.right, frame.bottom};
1324 auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
1325 mId, hwcRect);
1326#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001327 return static_cast<Error>(intError);
1328}
1329
1330Error Layer::setPlaneAlpha(float alpha)
1331{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001332#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001333 int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
1334 mDisplayId, mId, alpha);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001335#else
1336 auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
1337 mId, alpha);
1338#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001339 return static_cast<Error>(intError);
1340}
1341
1342Error Layer::setSidebandStream(const native_handle_t* stream)
1343{
Dan Stoza09e7a272016-04-14 12:31:01 -07001344 if (!mDevice.hasCapability(Capability::SidebandStream)) {
1345 ALOGE("Attempted to call setSidebandStream without checking that the "
1346 "device supports sideband streams");
1347 return Error::Unsupported;
1348 }
Chia-I Wuaab99f52016-10-05 12:59:58 +08001349#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001350 int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1351 mDisplayId, mId, stream);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001352#else
1353 auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
1354 mId, stream);
1355#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001356 return static_cast<Error>(intError);
1357}
1358
1359Error Layer::setSourceCrop(const FloatRect& crop)
1360{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001361#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001362 hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
1363 int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
1364 mDisplayId, mId, hwcRect);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001365#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001366 Hwc2::IComposerClient::FRect hwcRect{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001367 crop.left, crop.top, crop.right, crop.bottom};
1368 auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
1369 mId, hwcRect);
1370#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001371 return static_cast<Error>(intError);
1372}
1373
1374Error Layer::setTransform(Transform transform)
1375{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001376#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001377 auto intTransform = static_cast<int32_t>(transform);
1378 int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
1379 mDisplayId, mId, intTransform);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001380#else
1381 auto intTransform = static_cast<Hwc2::Transform>(transform);
1382 auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
1383 mId, intTransform);
1384#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001385 return static_cast<Error>(intError);
1386}
1387
1388Error Layer::setVisibleRegion(const Region& region)
1389{
1390 size_t rectCount = 0;
1391 auto rectArray = region.getArray(&rectCount);
1392
Chia-I Wuaab99f52016-10-05 12:59:58 +08001393#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001394 std::vector<hwc_rect_t> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001395#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001396 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001397#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001398 for (size_t rect = 0; rect < rectCount; ++rect) {
1399 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1400 rectArray[rect].right, rectArray[rect].bottom});
1401 }
1402
Chia-I Wuaab99f52016-10-05 12:59:58 +08001403#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001404 hwc_region_t hwcRegion = {};
1405 hwcRegion.numRects = rectCount;
1406 hwcRegion.rects = hwcRects.data();
1407
1408 int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
1409 mDisplayId, mId, hwcRegion);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001410#else
1411 auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
1412 mId, hwcRects);
1413#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001414 return static_cast<Error>(intError);
1415}
1416
1417Error Layer::setZOrder(uint32_t z)
1418{
Chia-I Wuaab99f52016-10-05 12:59:58 +08001419#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -07001420 int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
1421 mId, z);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001422#else
1423 auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
1424#endif
Dan Stoza651bf312015-10-23 17:03:17 -07001425 return static_cast<Error>(intError);
1426}
1427
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -05001428Error Layer::setInfo(uint32_t type, uint32_t appId)
1429{
1430#ifdef BYPASS_IHWC
1431 (void)type;
1432 (void)appId;
1433 int32_t intError = 0;
1434#else
1435 auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId);
1436#endif
1437 return static_cast<Error>(intError);
1438}
1439
Dan Stoza651bf312015-10-23 17:03:17 -07001440} // namespace HWC2